Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Refactored sd and cd to use common disk subroutines.



details:   https://anonhg.NetBSD.org/src/rev/a4dba879db71
branches:  trunk
changeset: 349412:a4dba879db71
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Dec 10 10:26:38 2016 +0000

description:
Refactored sd and cd to use common disk subroutines.

diffstat:

 sys/dev/files.dev      |     4 +-
 sys/dev/scsipi/cd.c    |  1433 ++++++++++++++++++-----------------------------
 sys/dev/scsipi/cdvar.h |    18 +-
 sys/dev/scsipi/sd.c    |  1279 +++++++++++++++---------------------------
 sys/dev/scsipi/sdvar.h |    12 +-
 5 files changed, 1020 insertions(+), 1726 deletions(-)

diffs (truncated from 3558 to 300 lines):

diff -r ce5acc9800f6 -r a4dba879db71 sys/dev/files.dev
--- a/sys/dev/files.dev Sat Dec 10 09:51:43 2016 +0000
+++ b/sys/dev/files.dev Sat Dec 10 10:26:38 2016 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.dev,v 1.1 2015/08/21 02:18:18 uebayasi Exp $
+#      $NetBSD: files.dev,v 1.2 2016/12/10 10:26:38 mlelstv Exp $
 
 file   dev/bio.c                       bio                     needs-flag
 file   dev/ccd.c                       ccd
@@ -6,7 +6,7 @@
 file   dev/cgd_crypto.c                cgd
 file   dev/clock_subr.c                kern    # XXX
 file   dev/clockctl.c                  clockctl
-file   dev/dksubr.c                    cgd | xbd | ccd | raid | dm | ld
+file   dev/dksubr.c                    cgd | xbd | ccd | raid | dm | ld | sd | cd
 file   dev/dkwedge/dk.c                kern    # XXX
 file   dev/dkwedge/dkwedge_apple.c     dkwedge_method_apple
 file   dev/dkwedge/dkwedge_bsdlabel.c  dkwedge_method_bsdlabel
diff -r ce5acc9800f6 -r a4dba879db71 sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c       Sat Dec 10 09:51:43 2016 +0000
+++ b/sys/dev/scsipi/cd.c       Sat Dec 10 10:26:38 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd.c,v 1.333 2016/11/20 15:37:19 mlelstv Exp $ */
+/*     $NetBSD: cd.c,v 1.334 2016/12/10 10:26:38 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 1998, 2001, 2003, 2004, 2005, 2008 The NetBSD Foundation,
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.333 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.334 2016/12/10 10:26:38 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -114,22 +114,26 @@
 };
 
 struct cdbounce {
-       struct buf     *obp;                    /* original buf */
-       int             doff;                   /* byte offset in orig. buf */
-       int             soff;                   /* byte offset in bounce buf */
-       int             resid;                  /* residual i/o in orig. buf */
-       int             bcount;                 /* actual obp bytes in bounce */
+       struct buf *obp;        /* original buf */
+       struct buf *lbp;        /* first buffer */
+       struct buf *rbp;        /* second buffer */
+       int lerr;               /* error returned for first buffer */
+       int rerr;               /* error returned for second buffer */
+       int head;               /* bytes skipped at the start */
+       int lcount;             /* bytes copied to first buffer */
+       int rcount;             /* bytes copied to second buffer */
 };
 
 static void    cdstart(struct scsipi_periph *);
 static void    cdrestart(void *);
 static void    cdminphys(struct buf *);
-static void    cdgetdefaultlabel(struct cd_softc *, struct cd_formatted_toc *,
-                   struct disklabel *);
-static void    cdgetdisklabel(struct cd_softc *);
 static void    cddone(struct scsipi_xfer *, int);
-static void    cdbounce(struct buf *);
 static int     cd_interpret_sense(struct scsipi_xfer *);
+static int     cd_diskstart(device_t, struct buf *);
+static void    cd_iosize(device_t, int *);
+static int     cd_lastclose(device_t);
+static int      cd_firstopen(device_t, dev_t, int, int);
+static void    cd_label(device_t, struct disklabel *);
 static u_long  cd_size(struct cd_softc *, int);
 static int     cd_play(struct cd_softc *, int, int);
 static int     cd_play_tracks(struct cd_softc *, struct cd_formatted_toc *,
@@ -230,8 +234,14 @@
 };
 
 static struct dkdriver cddkdriver = {
+       .d_open = cdopen,
+       .d_close = cdclose,
        .d_strategy = cdstrategy,
-       .d_minphys = cdminphys
+       .d_minphys = cdminphys,
+       .d_diskstart = cd_diskstart,
+       .d_firstopen = cd_firstopen,
+       .d_lastclose = cd_lastclose,
+       .d_label = cd_label,
 };
 
 static const struct scsipi_periphsw cd_switch = {
@@ -262,20 +272,37 @@
 cdattach(device_t parent, device_t self, void *aux)
 {
        struct cd_softc *cd = device_private(self);
+       struct dk_softc *dksc = &cd->sc_dksc;
        struct scsipibus_attach_args *sa = aux;
        struct scsipi_periph *periph = sa->sa_periph;
+       int dtype;
 
        SC_DEBUG(periph, SCSIPI_DB2, ("cdattach: "));
 
-       cd->sc_dev = self;
-
-       mutex_init(&cd->sc_lock, MUTEX_DEFAULT, IPL_NONE);
-
-       if (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph)) ==
-           SCSIPI_BUSTYPE_SCSI && periph->periph_version == 0)
-               cd->flags |= CDF_ANCIENT;
-
-       bufq_alloc(&cd->buf_queue, "disksort", BUFQ_SORT_RAWBLOCK);
+       switch (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph))) {
+       case SCSIPI_BUSTYPE_SCSI:
+               dtype = DKTYPE_SCSI;
+               if (periph->periph_version == 0)
+                       cd->flags |= CDF_ANCIENT;
+               break; 
+       case SCSIPI_BUSTYPE_ATAPI:
+               dtype = DKTYPE_ATAPI;
+               break;
+       default:
+               dtype = DKTYPE_UNKNOWN;
+               break; 
+       }
+
+       /*
+        * Initialize and attach the disk structure.
+        */
+       dk_init(dksc, self, dtype);
+       disk_init(&dksc->sc_dkdev, dksc->sc_xname, &cddkdriver);
+
+       dk_attach(dksc);
+       disk_attach(&dksc->sc_dkdev);
+
+       bufq_alloc(&dksc->sc_bufq, "disksort", BUFQ_SORT_RAWBLOCK);
 
        callout_init(&cd->sc_callout, 0);
 
@@ -284,7 +311,7 @@
         */
        cd->sc_periph = periph;
 
-       periph->periph_dev = cd->sc_dev;
+       periph->periph_dev = dksc->sc_dev;
        periph->periph_switch = &cd_switch;
 
        /*
@@ -296,17 +323,8 @@
            SCSIPI_CHAN_MAX_PERIPH(periph->periph_channel);
        periph->periph_flags |= PERIPH_GROW_OPENINGS;
 
-       /*
-        * Initialize and attach the disk structure.
-        */
-       disk_init(&cd->sc_dk, device_xname(cd->sc_dev), &cddkdriver);
-       disk_attach(&cd->sc_dk);
-
+       aprint_naive("\n");
        aprint_normal("\n");
-       aprint_naive("\n");
-
-       rnd_attach_source(&cd->rnd_source, device_xname(cd->sc_dev),
-                         RND_TYPE_DISK, RND_FLAG_DEFAULT);
 
        if (!pmf_device_register(self, NULL, NULL))
                aprint_error_dev(self, "couldn't establish power handler\n");
@@ -316,16 +334,18 @@
 cddetach(device_t self, int flags)
 {
        struct cd_softc *cd = device_private(self);
+       struct dk_softc *dksc = &cd->sc_dksc;
        struct scsipi_periph *periph = cd->sc_periph;
        struct scsipi_channel *chan = periph->periph_channel;
-       int bmaj, cmaj, i, mn;
-
-       if (cd->sc_dk.dk_openmask != 0 && (flags & DETACH_FORCE) == 0)
-               return EBUSY;
+       int bmaj, cmaj, i, mn, rc;
+
+       if ((rc = disk_begindetach(&dksc->sc_dkdev, cd_lastclose, self, flags)) != 0)
+               return rc;
 
        /* locate the major number */
        bmaj = bdevsw_lookup_major(&cd_bdevsw);
        cmaj = cdevsw_lookup_major(&cd_cdevsw);
+
        /* Nuke the vnodes for any open instances */
        for (i = 0; i < MAXPARTITIONS; i++) {
                mn = CDMINOR(device_unit(self), i);
@@ -336,183 +356,185 @@
        /* kill any pending restart */
        callout_stop(&cd->sc_callout);
 
-       mutex_enter(chan_mtx(chan));
-
-       /* Kill off any queued buffers. */
-       bufq_drain(cd->buf_queue);
+       dk_drain(dksc);
 
        /* Kill off any pending commands. */
+       mutex_enter(chan_mtx(chan));
        scsipi_kill_pending(cd->sc_periph);
-
        mutex_exit(chan_mtx(chan));
 
-       bufq_free(cd->buf_queue);
-
-       mutex_destroy(&cd->sc_lock);
+       bufq_free(dksc->sc_bufq);
 
        /* Detach from the disk list. */
-       disk_detach(&cd->sc_dk);
-       disk_destroy(&cd->sc_dk);
-
-       /* Unhook the entropy source. */
-       rnd_detach_source(&cd->rnd_source);
+       disk_detach(&dksc->sc_dkdev);
+       disk_destroy(&dksc->sc_dkdev);
+
+       dk_detach(dksc);
+
+       callout_destroy(&cd->sc_callout);
+
+       pmf_device_deregister(self);
 
        return (0);
 }
 
 /*
+ * Serialized by caller
+ */
+static int
+cd_firstopen(device_t self, dev_t dev, int flag, int fmt)
+{
+        struct cd_softc *cd = device_private(self);
+        struct scsipi_periph *periph = cd->sc_periph;
+        struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
+        int error, silent;
+        int part;
+
+       part = CDPART(dev);
+
+        error = scsipi_adapter_addref(adapt);
+        if (error)
+                return error;
+
+        if ((part == RAW_PART && fmt == S_IFCHR) || (flag & FSILENT))
+                silent = XS_CTL_SILENT;
+        else
+                silent = 0;
+
+       /* make cdclose() loud again */
+       cd->flags &= ~CDF_EJECTED;
+
+       /* Check that it is still responding and ok. */
+       error = scsipi_test_unit_ready(periph,
+           XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
+           XS_CTL_SILENT);
+
+       /*
+        * Start the pack spinning if necessary. Always allow the
+        * raw parition to be opened, for raw IOCTLs. Data transfers
+        * will check for SDEV_MEDIA_LOADED.
+        */
+       if (error == EIO) {
+               error = scsipi_start(periph, SSS_START, silent);
+               if (error == EINVAL)
+                       error = EIO;
+       }
+       if (error)
+               goto bad;
+
+       /* Lock the pack in. */
+       error = scsipi_prevent(periph, SPAMR_PREVENT_DT,
+           XS_CTL_IGNORE_ILLEGAL_REQUEST |
+           XS_CTL_IGNORE_MEDIA_CHANGE);
+       SC_DEBUG(periph, SCSIPI_DB1,
+           ("cdopen: scsipi_prevent, error=%d\n", error));
+       if (error)
+               goto bad;
+
+       if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
+               int param_error;
+
+               /* Load the physical device parameters. */
+               param_error = cd_get_parms(cd, 0);
+               if (param_error == CDGP_RESULT_OFFLINE) {
+                       error = ENXIO;
+                       goto bad2;
+               }
+               periph->periph_flags |= PERIPH_MEDIA_LOADED;
+
+               SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
+
+               cd_set_geometry(cd);
+       }
+
+       periph->periph_flags |= PERIPH_OPEN;
+       return 0;
+
+bad2:
+       scsipi_prevent(periph, SPAMR_ALLOW,
+           XS_CTL_IGNORE_ILLEGAL_REQUEST |



Home | Main Index | Thread Index | Old Index