added my responsibility for the `cpm' port
[unix-history] / sys / scsi / sd.c
index 3ee38d2..22dce9a 100644 (file)
@@ -14,7 +14,7 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
  *
  *
  * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
  *
- *     $Id: sd.c,v 1.9 1993/09/20 06:27:04 rgrimes Exp $
+ *      $Id: sd.c,v 1.26 1994/05/26 00:23:24 jkh Exp $
  */
 
 #define SPLSD splbio
  */
 
 #define SPLSD splbio
@@ -22,6 +22,7 @@
 #include <sd.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sd.h>
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/kernel.h>
 #include <sys/dkbad.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/dkbad.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <scsi/scsi_all.h>
 #include <scsi/scsi_disk.h>
 #include <scsi/scsiconf.h>
 #include <scsi/scsi_all.h>
 #include <scsi/scsi_disk.h>
 #include <scsi/scsiconf.h>
+#include <vm/vm.h>
 
 
-long int sdstrats,sdqueues;
-
+u_int32 sdstrats, sdqueues;
 
 
+#ifdef NetBSD
+#ifdef DDB
+int     Debugger();
+#else  /* DDB */
+#define Debugger()
+#endif /* DDB */
+#else /* NetBSD */
 #include <ddb.h>
 #if    NDDB > 0
 #include <ddb.h>
 #if    NDDB > 0
-int    Debugger();
-#else  NDDB > 0
-#define Debugger()
-#endif NDDB > 0
-
+#else  /* NDDB > 0 */
+#define Debugger(s)
+#endif /* NDDB > 0 */
+#endif
 
 #define PAGESIZ        4096
 #define SECSIZE 512
 
 #define PAGESIZ        4096
 #define SECSIZE 512
-#define PDLOCATION     29      
+#define PDLOCATION     29
 #define BOOTRECORDSIGNATURE                    (0x55aa & 0x00ff)
 #define        SDOUTSTANDING   2
 #define SDQSIZE                4
 #define        SD_RETRIES      4
 #define BOOTRECORDSIGNATURE                    (0x55aa & 0x00ff)
 #define        SDOUTSTANDING   2
 #define SDQSIZE                4
 #define        SD_RETRIES      4
+#define        MAXTRANSFER     8               /* 1 page at a time */
 
 #define MAKESDDEV(maj, unit, part)     (makedev(maj,((unit<<3)+part)))
 #define        UNITSHIFT       3
 
 #define MAKESDDEV(maj, unit, part)     (makedev(maj,((unit<<3)+part)))
 #define        UNITSHIFT       3
@@ -64,838 +72,717 @@ int       Debugger();
 
 #define WHOLE_DISK(unit) ( (unit << UNITSHIFT) + RAW_PART )
 
 
 #define WHOLE_DISK(unit) ( (unit << UNITSHIFT) + RAW_PART )
 
-struct buf sd_buf_queue[NSD];
-int    sd_done();
-int    sdstrategy();
-
-#ifdef SDDEBUG
-int    sd_debug = 0;
-#endif /*SDDEBUG*/
-
-struct scsi_xfer       *sd_free_xfer[NSD];
-int                    sd_xfer_block_wait[NSD];
+errval sdgetdisklabel __P((unsigned char unit));
+errval sd_get_parms __P((int unit, int flags));
+void   sdstrategy __P((struct buf *));
+void    sdstart __P((u_int32));
 
 
-struct sd_data
+struct scsi_device sd_switch =
 {
 {
-       int     flags;
-#define        SDVALID         0x02            /* PARAMS LOADED        */
-#define        SDINIT          0x04            /* device has been init'd */
-#define        SDWAIT          0x08            /* device has someone waiting */
-#define SDHAVELABEL    0x10            /* have read the label */
-#define SDDOSPART      0x20            /* Have read the DOS partition table */
-#define SDWRITEPROT    0x40            /* Device in readonly mode (S/W)*/
-       struct  scsi_switch *sc_sw;     /* address of scsi low level switch */
-       int     ctlr;                   /* so they know which one we want */
-       int     targ;                   /* our scsi target ID */
-       int     lu;                     /* out scsi lu */
-       long int        ad_info;        /* info about the adapter */
-       int     cmdscount;              /* cmds allowed outstanding by board*/
-       int     wlabel;                 /* label is writable */
-       struct  disk_parms
-       {
-               u_char  heads;          /* Number of heads */
-               u_short cyls;           /* Number of cylinders */
-               u_char  sectors;/*dubious*/     /* Number of sectors/track */
-               u_short secsiz;         /* Number of bytes/sector */
-               u_long  disksize;               /* total number sectors */
-       }params;
-       struct  disklabel       disklabel;
-       struct  dos_partition dosparts[NDOSPART]; /* DOS view of disk */
-       int     partflags[MAXPARTITIONS];       /* per partition flags */
+    NULL,                      /* Use default error handler */
+    sdstart,                   /* have a queue, served by this */
+    NULL,                      /* have no async handler */
+    NULL,                      /* Use default 'done' routine */
+    "sd",
+    0,
+    { 0, 0 }
+};
+
+struct sd_data {
+       u_int32 flags;
+#define        SDINIT          0x04    /* device has been init'd */
+#define SDHAVELABEL    0x10    /* have read the label */
+#define SDDOSPART      0x20    /* Have read the DOS partition table */
+#define SDWRITEPROT    0x40    /* Device in readonly mode (S/W) */
+       struct scsi_link *sc_link;      /* contains our targ, lun etc. */
+       u_int32 ad_info;        /* info about the adapter */
+       u_int32 cmdscount;      /* cmds allowed outstanding by board */
+       boolean wlabel;         /* label is writable */
+       struct disk_parms {
+               u_char  heads;  /* Number of heads */
+               u_int16 cyls;   /* Number of cylinders */
+               u_char  sectors;        /*dubious *//* Number of sectors/track */
+               u_int16 secsiz; /* Number of bytes/sector */
+               u_int32 disksize;       /* total number sectors */
+       } params;
+       struct disklabel disklabel;
+#ifdef NetBSD
+       struct cpu_disklabel cpudisklabel;
+#else
+       struct dos_partition dosparts[NDOSPART];        /* DOS view of disk */
+#endif /* NetBSD */
+       u_int32 partflags[MAXPARTITIONS];       /* per partition flags */
 #define SDOPEN 0x01
 #define SDOPEN 0x01
-       int             openparts;              /* one bit for each open partition */
-       unsigned int    sd_start_of_unix;       /* unix vs dos partitions */
-}*sd_data[NSD];
+       u_int32 openparts;              /* one bit for each open partition */
+       u_int32 sd_start_of_unix;       /* unix vs dos partitions */
+       struct buf buf_queue;
+       u_int32 xfer_block_wait;
+}      *sd_data[NSD];
 
 
+static u_int32 next_sd_unit = 0;
 
 
-static int     next_sd_unit = 0;
-/***********************************************************************\
-* The routine called by the low level scsi routine when it discovers   *
-* A device suitable for this driver                                    *
-\***********************************************************************/
+static struct scsi_xfer sx;
 
 
-int    sdattach(ctlr,targ,lu,scsi_switch)
-struct scsi_switch *scsi_switch;
+/*
+ * The routine called by the low level scsi routine when it discovers
+ * a device suitable for this driver.
+ */
+errval 
+sdattach(sc_link)
+       struct scsi_link *sc_link;
 {
 {
-       int     unit,i;
-       unsigned char *tbl;
+       u_int32 unit;
        struct sd_data *sd;
        struct disk_parms *dp;
        struct sd_data *sd;
        struct disk_parms *dp;
-       long int        ad_info;
-       struct  scsi_xfer       *sd_scsi_xfer;
 
        unit = next_sd_unit++;
 
        unit = next_sd_unit++;
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("sdattach: "); 
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       * Check we have the resources for another drive         *
-       \*******************************************************/
-       if( unit >= NSD)
-       {
-               printf("Too many scsi disks..(%d > %d) reconfigure kernel\n",(unit + 1),NSD);
-               return(0);
+       SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: "));
+       /*
+        * Check we have the resources for another drive
+        */
+       if (unit >= NSD) {
+               printf("Too many scsi disks..(%d > %d) reconfigure kernel\n",
+                       (unit + 1), NSD);
+               return 0;
        }
        }
-       if(sd_data[unit])
-       {
-               printf("sd%d: unit already has storage allocated!\n",unit);
-               return(0);
+       if (sd_data[unit]) {
+               printf("sd%d: unit already has storage allocated!\n", unit);
+               return 0;
        }
        }
-       sd = sd_data[unit] = malloc(sizeof(struct sd_data),M_DEVBUF,M_NOWAIT);
-       if(!sd)
-       {
+       sd = sd_data[unit] = malloc(sizeof(struct sd_data), M_DEVBUF, M_NOWAIT);
+       if (!sd) {
                printf("malloc failed in sd.c\n");
                printf("malloc failed in sd.c\n");
-               return(0);
+               return (0);
        }
        }
-       bzero(sd,sizeof(struct sd_data));
-
-       dp  = &(sd->params);
-       /*******************************************************\
-       * Store information needed to contact our base driver   *
-       \*******************************************************/
-       sd->sc_sw       =       scsi_switch;
-       sd->ctlr        =       ctlr;
-       sd->targ        =       targ;
-       sd->lu          =       lu;
-       if(sd->sc_sw->adapter_info)
-       {
-               sd->ad_info = ( (*(sd->sc_sw->adapter_info))(ctlr));
-               sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
-               if(sd->cmdscount > SDOUTSTANDING)
-               {
+       bzero(sd, sizeof(struct sd_data));
+
+       dp = &(sd->params);
+       /*
+        * Store information needed to contact our base driver
+        */
+       sd->sc_link = sc_link;
+       sc_link->device = &sd_switch;
+       sc_link->dev_unit = unit;
+
+       if (sd->sc_link->adapter->adapter_info) {
+               sd->ad_info = ((*(sd->sc_link->adapter->adapter_info)) (sc_link->adapter_unit));
+               sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
+               if (sd->cmdscount > SDOUTSTANDING) {
                        sd->cmdscount = SDOUTSTANDING;
                }
                        sd->cmdscount = SDOUTSTANDING;
                }
-       }
-       else
-       {
+       } else {
                sd->ad_info = 1;
                sd->ad_info = 1;
-               sd->cmdscount = 1;
-       }
-
-       i = sd->cmdscount;
-       sd_scsi_xfer = (struct scsi_xfer *)malloc(sizeof(struct scsi_xfer) * i
-                               ,M_TEMP, M_NOWAIT);
-       while(i-- )
-       {
-               sd_scsi_xfer->next = sd_free_xfer[unit];
-               sd_free_xfer[unit] = sd_scsi_xfer;
-               sd_scsi_xfer++;
-       }
-       /*******************************************************\
-       * Use the subdriver to request information regarding    *
-       * the drive. We cannot use interrupts yet, so the       *
-       * request must specify this.                            *
-       \*******************************************************/
-       sd_get_parms(unit,  SCSI_NOSLEEP |  SCSI_NOMASK);
+               sd->cmdscount = 1;
+       } 
+       sc_link->opennings = sd->cmdscount;
+       /*
+        * Use the subdriver to request information regarding
+        * the drive. We cannot use interrupts yet, so the
+        * request must specify this.
+        */
+       sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK);
        printf("sd%d: %dMB (%d total sec), %d cyl, %d head, %d sec, bytes/sec %d\n",
        printf("sd%d: %dMB (%d total sec), %d cyl, %d head, %d sec, bytes/sec %d\n",
-               unit,
-               dp->disksize / ((1024L * 1024L) / dp->secsiz),
-               dp->disksize,
-               dp->cyls,
-               dp->heads,
-               dp->sectors,
-               dp->secsiz);
+           unit,
+           dp->disksize / ((1024L * 1024L) / dp->secsiz),
+           dp->disksize,
+           dp->cyls,
+           dp->heads,
+           dp->sectors,
+           dp->secsiz);
        sd->flags |= SDINIT;
        sd->flags |= SDINIT;
-       return;
-
+       return 0;
 }
 
 }
 
-
-
-/*******************************************************\
-*      open the device. Make sure the partition info   *
-* is a up-to-date as can be.                           *
-\*******************************************************/
+/*
+ * open the device. Make sure the partition info is a up-to-date as can be.
+ */
+errval
 sdopen(dev)
 sdopen(dev)
+       int     dev;    /* XXX should be dev_t, but avoid promotion problems for now */
 {
 {
-       int errcode = 0;
-       int unit, part;
-       struct disk_parms disk_parms;
-       struct sd_data *sd ;
+       errval  errcode = 0;
+       u_int32 unit, part;
+       struct sd_data *sd;
+       struct scsi_link *sc_link;
 
        unit = UNIT(dev);
        part = PARTITION(dev);
        sd = sd_data[unit];
 
        unit = UNIT(dev);
        part = PARTITION(dev);
        sd = sd_data[unit];
-#ifdef SDDEBUG
-       if(scsi_debug & (PRINTROUTINES | TRACEOPENS))
-               printf("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n"
-                               ,   dev,      unit,   NSD,         part);
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       * Check the unit is legal                               *
-       \*******************************************************/
-       if ( unit >= NSD )
-       {
-               return(ENXIO);
+       /*
+        * Check the unit is legal
+        */
+       if (unit >= NSD) {
+               return (ENXIO);
        }
        }
-       /*******************************************************\
-       * Make sure the disk has been initialised               *
-       * At some point in the future, get the scsi driver      *
-       * to look for a new device if we are not initted        *
-       \*******************************************************/
-       if (! (sd->flags & SDINIT))
-       {
-               return(ENXIO);
+       /*
+        * Make sure the disk has been initialised
+        * At some point in the future, get the scsi driver
+        * to look for a new device if we are not initted
+        */
+       if ((!sd) || (!(sd->flags & SDINIT))) {
+               return (ENXIO);
        }
        }
+       sc_link = sd->sc_link;
+
+       SC_DEBUG(sc_link, SDEV_DB1,
+           ("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n"
+               ,dev, unit, NSD, part));
+
+       /*
+        * "unit attention" errors should occur here if the 
+        * drive has been restarted or the pack changed.
+        * just ingnore the result, it's a decoy instruction
+        * The error code will act on the error though
+        * and invalidate any media information we had.
+        */
+       scsi_test_unit_ready(sc_link, 0);
+
+       /*
+        * If it's been invalidated, then forget the label
+        */
+       sc_link->flags |= SDEV_OPEN;    /* unit attn becomes an err now */
+       if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
+               sd->flags &= ~SDHAVELABEL;
 
 
-       /*******************************************************\
-       * If it's been invalidated, and not everybody has       *
-       * closed it then forbid re-entry.                       *
-       \*******************************************************/
-       if ((! (sd->flags & SDVALID))
-          && ( sd->openparts))
-               return(ENXIO);
-       /*******************************************************\
-       * "unit attention" errors should occur here if the      *
-       * drive has been restarted or the pack changed.         *
-       * just ingnore the result, it's a decoy instruction     *
-       * The error code will act on the error though           *
-       * and invalidate any media information we had.          *
-       \*******************************************************/
-       sd_test_unit_ready(unit,0);
-
-       /*******************************************************\
-       * In case it is a funny one, tell it to start           *
-       * not needed for  most hard drives (ignore failure)     *
-       \*******************************************************/
-       sd_start_unit(unit,SCSI_ERR_OK|SCSI_SILENT);
-
-       /*******************************************************\
-       * Check that it is still responding and ok.             *
-       \*******************************************************/
-       if (sd_test_unit_ready(unit,0))
-       {
-#ifdef SDDEBUG
-               if(scsi_debug & TRACEOPENS) printf("device not reponding\n");
-#endif /*SDDEBUG*/
-               return(ENXIO);
+               /*
+                * If somebody still has      it open, then forbid re-entry.
+                */
+               if (sd->openparts) {
+                       errcode = ENXIO;
+                       goto bad;
+               }
        }
        }
-#ifdef SDDEBUG
-       if(scsi_debug & TRACEOPENS)
-               printf("device ok\n");
-#endif /*SDDEBUG*/
-
-       /*******************************************************\
-       * Load the physical device parameters                   *
-       \*******************************************************/
-       sd_get_parms(unit, 0);  /* sets SDVALID */
-       if (sd->params.secsiz != SECSIZE)       /* XXX One day...*/
-       {
-               printf("sd%d: Can't deal with %d bytes logical blocks\n"
-                       ,unit, sd->params.secsiz);
-               Debugger();
-               return(ENXIO);
+       /*
+        * In case it is a funny one, tell it to start
+        * not needed for  most hard drives (ignore failure)
+        */
+       scsi_start_unit(sc_link, SCSI_ERR_OK | SCSI_SILENT);
+
+       /*
+        * Check that it is still responding and ok.
+        */
+       if (scsi_test_unit_ready(sc_link, 0)) {
+               SC_DEBUG(sc_link, SDEV_DB3, ("device not reponding\n"));
+               errcode = ENXIO;
+               goto bad;
        }
        }
-#ifdef SDDEBUG
-       if(scsi_debug & TRACEOPENS)
-               printf("Params loaded ");
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       * Load the partition info if not already loaded         *
-       * Lock the pack in                                      *
-       \*******************************************************/
-       sd_prevent(unit,PR_PREVENT,SCSI_ERR_OK|SCSI_SILENT);
-       if((errcode = sdgetdisklabel(unit)) && (part != RAW_PART))
-       {
-               sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT);
-               return(errcode);
+       SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
+
+       /*
+        * Load the physical device parameters 
+        */
+       sd_get_parms(unit, 0);  /* sets SDEV_MEDIA_LOADED */
+       if (sd->params.secsiz != SECSIZE) {     /* XXX One day... */
+               printf("sd%d: Can't deal with %d bytes logical blocks\n",
+                   unit, sd->params.secsiz);
+               Debugger("sd");
+               errcode = ENXIO;
+               goto bad;
        }
        }
-#ifdef SDDEBUG
-       if(scsi_debug & TRACEOPENS)
-               printf("Disklabel loaded ");
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       * Check the partition is legal                          *
-       \*******************************************************/
-       if ( part >= MAXPARTITIONS ) {
-               sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
-               return(ENXIO);
+       SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
+
+       /* Lock the pack in. */
+       scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
+
+       /*
+        * Load the partition info if not already loaded.
+        */
+       if ((errcode = sdgetdisklabel(unit)) && (part != RAW_PART)) {
+               goto bad;
        }
        }
-#ifdef SDDEBUG
-       if(scsi_debug & TRACEOPENS)
-               printf("ok");
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       *  Check that the partition exists                      *
-       \*******************************************************/
-       if (( sd->disklabel.d_partitions[part].p_size == 0 )
-               && (part != RAW_PART))
-       {
-               sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
-               return(ENXIO);
+       SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded "));
+       /*
+        * Check the partition is legal
+        */
+       if (part >= MAXPARTITIONS) {
+               errcode = ENXIO;
+               goto bad;
+       }
+       SC_DEBUG(sc_link, SDEV_DB3, ("partition ok"));
+
+       /*
+        *  Check that the partition exists
+        */
+       if ((sd->disklabel.d_partitions[part].p_size == 0)
+           && (part != RAW_PART)) {
+               errcode = ENXIO;
+               goto bad;
        }
        sd->partflags[part] |= SDOPEN;
        sd->openparts |= (1 << part);
        }
        sd->partflags[part] |= SDOPEN;
        sd->openparts |= (1 << part);
-#ifdef SDDEBUG
-       if(scsi_debug & TRACEOPENS)
-               printf("open %d %d\n",sdstrats,sdqueues);
-#endif /*SDDEBUG*/
-       return(0);
-}
+       SC_DEBUG(sc_link, SDEV_DB3, ("open %d %d\n", sdstrats, sdqueues));
+       return 0;
 
 
-/*******************************************************\
-* Get ownership of a scsi_xfer                         *
-* If need be, sleep on it, until it comes free         *
-\*******************************************************/
-struct scsi_xfer *sd_get_xs(unit,flags)
-int    flags;
-int    unit;
-{
-       struct scsi_xfer *xs;
-       int     s;
-
-       if(flags & (SCSI_NOSLEEP |  SCSI_NOMASK))
-       {
-               if (xs = sd_free_xfer[unit])
-               {
-                       sd_free_xfer[unit] = xs->next;
-                       xs->flags = 0;
-               }
-       }
-       else
-       {
-               s = SPLSD();
-               while (!(xs = sd_free_xfer[unit]))
-               {
-                       sd_xfer_block_wait[unit]++;  /* someone waiting! */
-                       sleep((caddr_t)&sd_free_xfer[unit], PRIBIO+1);
-                       sd_xfer_block_wait[unit]--;
-               }
-               sd_free_xfer[unit] = xs->next;
-               splx(s);
-               xs->flags = 0;
+bad:
+       if (!(sd->openparts)) {
+               scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
+               sc_link->flags &= ~SDEV_OPEN;
        }
        }
-       return(xs);
+       return errcode;
 }
 
 }
 
-/*******************************************************\
-* Free a scsi_xfer, wake processes waiting for it      *
-\*******************************************************/
-sd_free_xs(unit,xs,flags)
-struct scsi_xfer *xs;
-int    unit;
-int    flags;
+/*
+ * close the device.. only called if we are the LAST occurence of an open
+ * device.  Convenient now but usually a pain.
+ */
+errval 
+sdclose(dev)
+       dev_t   dev;
 {
 {
-       int     s;
-       
-       if(flags & SCSI_NOMASK)
-       {
-               if (sd_xfer_block_wait[unit])
-               {
-                       printf("doing a wakeup from NOMASK mode\n");
-                       wakeup((caddr_t)&sd_free_xfer[unit]);
-               }
-               xs->next = sd_free_xfer[unit];
-               sd_free_xfer[unit] = xs;
-       }
-       else
-       {
-               s = SPLSD();
-               if (sd_xfer_block_wait[unit])
-                       wakeup((caddr_t)&sd_free_xfer[unit]);
-               xs->next = sd_free_xfer[unit];
-               sd_free_xfer[unit] = xs;
-               splx(s);
-       }
+       unsigned char unit, part;
+       struct sd_data *sd;
+
+       unit = UNIT(dev);
+       part = PARTITION(dev);
+       sd = sd_data[unit];
+       sd->partflags[part] &= ~SDOPEN;
+       sd->openparts &= ~(1 << part);
+       scsi_prevent(sd->sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK);
+       if (!(sd->openparts))
+               sd->sc_link->flags &= ~SDEV_OPEN;
+       return 0;
 }
 
 }
 
-/*******************************************************\
-* trim the size of the transfer if needed,             *
-* called by physio                                     *
-* basically the smaller of our max and the scsi driver's*
-* minphys (note we have no max)                                *
-\*******************************************************/
-/* Trim buffer length if buffer-size is bigger than page size */
-void   sdminphys(bp)
-struct buf     *bp;
+/*
+ * trim the size of the transfer if needed, called by physio
+ * basically the smaller of our max and the scsi driver's
+ * minphys (note we have no max)
+ *
+ * Trim buffer length if buffer-size is bigger than page size
+ */
+void 
+sdminphys(bp)
+       struct buf *bp;
 {
 {
-       (*(sd_data[UNIT(bp->b_dev)]->sc_sw->scsi_minphys))(bp);
+       (*(sd_data[UNIT(bp->b_dev)]->sc_link->adapter->scsi_minphys)) (bp);
 }
 
 }
 
-/*******************************************************\
-* Actually translate the requested transfer into       *
-* one the physical driver can understand               *
-* The transfer is described by a buf and will include  *
-* only one physical transfer.                          *
-\*******************************************************/
-
-int    sdstrategy(bp)
-struct buf     *bp;
+/*
+ * Actually translate the requested transfer into one the physical driver
+ * can understand.  The transfer is described by a buf and will include
+ * only one physical transfer.
+ */
+void
+sdstrategy(bp)
+       struct buf *bp;
 {
 {
-       struct  buf     *dp;
-       unsigned int opri;
-       struct sd_data *sd ;
-       int     unit;
+       struct buf *dp;
+       u_int32 opri;
+       struct sd_data *sd;
+       u_int32 unit;
 
        sdstrats++;
        unit = UNIT((bp->b_dev));
        sd = sd_data[unit];
 
        sdstrats++;
        unit = UNIT((bp->b_dev));
        sd = sd_data[unit];
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("\nsdstrategy ");
-       if(scsi_debug & SHOWREQUESTS) printf("sd%d: %d bytes @ blk%d\n",
-                                       unit,bp->b_bcount,bp->b_blkno);
-#endif /*SDDEBUG*/
+       SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy "));
+       SC_DEBUG(sd->sc_link, SDEV_DB1,
+           (" %d bytes @ blk%d\n", bp->b_bcount, bp->b_blkno));
        sdminphys(bp);
        sdminphys(bp);
-       /*******************************************************\
-       * If the device has been made invalid, error out        *
-       \*******************************************************/
-       if(!(sd->flags & SDVALID))
-       {
+       /*
+        * If the device has been made invalid, error out
+        */
+       if (!(sd->sc_link->flags & SDEV_MEDIA_LOADED)) {
+               sd->flags &= ~SDHAVELABEL;
                bp->b_error = EIO;
                goto bad;
        }
                bp->b_error = EIO;
                goto bad;
        }
-       /*******************************************************\
-       * "soft" write protect check                            *
-       \*******************************************************/
+       /*
+        * "soft" write protect check
+        */
        if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) {
                bp->b_error = EROFS;
                goto bad;
        }
        if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) {
                bp->b_error = EROFS;
                goto bad;
        }
-       /*******************************************************\
-       * If it's a null transfer, return immediatly            *
-       \*******************************************************/
-       if (bp->b_bcount == 0)
-       {
+       /*
+        * If it's a null transfer, return immediatly
+        */
+       if (bp->b_bcount == 0) {
                goto done;
        }
                goto done;
        }
-
-       /*******************************************************\
-       * Decide which unit and partition we are talking about  *
-       * only raw is ok if no label                            *
-       \*******************************************************/
-       if(PARTITION(bp->b_dev) != RAW_PART)
-       {
-               if (!(sd->flags & SDHAVELABEL))
-               {
+       /*
+        * Decide which unit and partition we are talking about
+        * only raw is ok if no label
+        */
+       if (PARTITION(bp->b_dev) != RAW_PART) {
+               if (!(sd->flags & SDHAVELABEL)) {
                        bp->b_error = EIO;
                        goto bad;
                }
                        bp->b_error = EIO;
                        goto bad;
                }
-
                /*
                 * do bounds checking, adjust transfer. if error, process.
                 * if end of partition, just return
                 */
                /*
                 * do bounds checking, adjust transfer. if error, process.
                 * if end of partition, just return
                 */
-               if (bounds_check_with_label(bp,&sd->disklabel,sd->wlabel) <= 0)
+               if (bounds_check_with_label(bp, &sd->disklabel, sd->wlabel) <= 0)
                        goto done;
                /* otherwise, process transfer request */
                        goto done;
                /* otherwise, process transfer request */
+       } else {
+               bp->b_pblkno = bp->b_blkno;
+               bp->b_resid = 0;
        }
        }
-
        opri = SPLSD();
        opri = SPLSD();
-       dp = &sd_buf_queue[unit];
+       dp = &sd->buf_queue;
+
+       /*      
+        * Use a bounce buffer if necessary
+        */      
+#ifndef NOBOUNCE
+       if (sd->sc_link->flags & SDEV_BOUNCE)
+               vm_bounce_alloc(bp);
+#endif
 
 
-       /*******************************************************\
-       * Place it in the queue of disk activities for this disk*
-       \*******************************************************/
-       disksort(dp, bp);
+       /*
+        * Place it in the queue of disk activities for this disk
+        */
+       cldisksort(dp, bp, 64*1024);
 
 
-       /*******************************************************\
-       * Tell the device to get going on the transfer if it's  *
-       * not doing anything, otherwise just wait for completion*
-       \*******************************************************/
+       /*
+        * Tell the device to get going on the transfer if it's
+        * not doing anything, otherwise just wait for completion
+        */
        sdstart(unit);
 
        splx(opri);
        sdstart(unit);
 
        splx(opri);
-       return;
+       return /*0*/;
 bad:
        bp->b_flags |= B_ERROR;
 done:
 
 bad:
        bp->b_flags |= B_ERROR;
 done:
 
-       /*******************************************************\
-       * Correctly set the buf to indicate a completed xfer    *
-       \*******************************************************/
-       bp->b_resid = bp->b_bcount;
+       /*
+        * Correctly set the buf to indicate a completed xfer
+        */
+       bp->b_resid = bp->b_bcount;
        biodone(bp);
        biodone(bp);
-       return;
+       return /*0*/;
 }
 
 }
 
-/***************************************************************\
-* sdstart looks to see if there is a buf waiting for the device        *
-* and that the device is not already busy. If both are true,   *
-* It dequeues the buf and creates a scsi command to perform the        *
-* transfer in the buf. The transfer request will call sd_done  *
-* on completion, which will in turn call this routine again    *
-* so that the next queued transfer is performed.               *
-* The bufs are queued by the strategy routine (sdstrategy)     *
-*                                                              *
-* This routine is also called after other non-queued requests  *
-* have been made of the scsi driver, to ensure that the queue  *
-* continues to be drained.                                     *
-*                                                              *
-* must be called at the correct (highish) spl level            *
-\***************************************************************/
-/* sdstart() is called at SPLSD  from sdstrategy and sd_done*/
+/*
+ * sdstart looks to see if there is a buf waiting for the device
+ * and that the device is not already busy. If both are true,
+ * It dequeues the buf and creates a scsi command to perform the
+ * transfer in the buf. The transfer request will call scsi_done
+ * on completion, which will in turn call this routine again
+ * so that the next queued transfer is performed.
+ * The bufs are queued by the strategy routine (sdstrategy)
+ *
+ * This routine is also called after other non-queued requests
+ * have been made of the scsi driver, to ensure that the queue
+ * continues to be drained.
+ *
+ * must be called at the correct (highish) spl level
+ * sdstart() is called at SPLSD  from sdstrategy and scsi_done
+ */
+void 
 sdstart(unit)
 sdstart(unit)
-int    unit;
+       u_int32 unit;
 {
 {
-       int                     drivecount;
-       register struct buf     *bp = 0;
-       register struct buf     *dp;
-       struct  scsi_xfer       *xs;
-       struct  scsi_rw_big     cmd;
-       int                     blkno, nblk;
-       struct sd_data *sd = sd_data[unit];
-       struct partition *p ;
-
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("sdstart%d ",unit);
-#endif /*SDDEBUG*/
-       /*******************************************************\
-       * Check if the device is already running full capacity  *
-       \*******************************************************/
-       if(!sd_free_xfer[unit])
-       {
-               return;    /* none for us, unit already underway */
-       }
-
-       /*******************************************************\
-       * there is excess capacity, but a special waits         *
-       * It'll need the adapter as soon as we clear out of the *
-       * way and let it run (user level wait).                 *
-       \*******************************************************/
-       if(sd_xfer_block_wait[unit])  
-       {
-               return;
-       }
+       register struct sd_data *sd = sd_data[unit];
+       register struct scsi_link *sc_link = sd->sc_link;
+       struct buf *bp = 0;
+       struct buf *dp;
+       struct scsi_rw_big cmd;
+       u_int32 blkno, nblk;
+       struct partition *p;
+
+       SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
+       /*
+        * Check if the device has room for another command
+        */
+       while (sc_link->opennings) {
 
 
-       /*******************************************************\
-       * See if there is a buf with work for us to do..        *
-       \*******************************************************/
-       dp = &sd_buf_queue[unit];
-       if ((bp = dp->b_actf) == NULL)  /* yes, an assign */
-       {
-               return;
-       }
+               /*
+                * there is excess capacity, but a special waits 
+                * It'll need the adapter as soon as we clear out of the
+                * way and let it run (user level wait).
+                */
+               if (sc_link->flags & SDEV_WAITING) {
+                       return;
+               }
+               /*
+                * See if there is a buf with work for us to do..
+                */
+               dp = &sd->buf_queue;
+               if ((bp = dp->b_actf) == NULL) {        /* yes, an assign */
+                       return;
+               }
+               dp->b_actf = bp->av_forw;
 
 
-       dp->b_actf = bp->av_forw;
+               /*
+                *  If the device has become invalid, abort all the
+                * reads and writes until all files have been closed and
+                * re-openned
+                */
+               if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
+                       sd->flags &= ~SDHAVELABEL;
+                       goto bad;
+               }
+               /*
+                * We have a buf, now we know we are going to go through
+                * With this thing..
+                *
+                *  First, translate the block to absolute
+                */
+               p = sd->disklabel.d_partitions + PARTITION(bp->b_dev);
+               blkno = bp->b_blkno + p->p_offset;
+               nblk = (bp->b_bcount + 511) >> 9;
 
 
-       /*******************************************************\
-       *  If the device has become invalid, abort all the      *
-       * reads and writes until all files have been closed and *
-       * re-openned                                            *
-       \*******************************************************/
-       if(!(sd->flags & SDVALID))
-       {
-               goto bad;
-       }
-       /*******************************************************\
-       * We have a buf, now we know we are going to go through *
-       * With this thing..                                     *
-       *                                                       *
-       *  First, translate the block to absolute               *
-       \*******************************************************/
-       p = sd->disklabel.d_partitions + PARTITION(bp->b_dev);
-       blkno = bp->b_blkno + p->p_offset;
-       nblk = (bp->b_bcount + 511) >> 9;
-
-       /*******************************************************\
-       *  Fill out the scsi command                            *
-       \*******************************************************/
-       bzero(&cmd, sizeof(cmd));
-       cmd.op_code             =       (bp->b_flags & B_READ) 
-                                               ? READ_BIG : WRITE_BIG;
-       cmd.addr_3      =       (blkno & 0xff000000) >> 24;
-       cmd.addr_2      =       (blkno & 0xff0000) >> 16;
-       cmd.addr_1      =       (blkno & 0xff00) >> 8;
-       cmd.addr_0      =       blkno & 0xff;
-       cmd.length2     =       (nblk & 0xff00) >> 8;
-       cmd.length1     =       (nblk & 0xff);
-       /*******************************************************\
-       * Call the routine that chats with the adapter          *
-       *       Note: we cannot sleep as we may be an interrupt *
-       \*******************************************************/
-       if (sd_scsi_cmd(unit,
-                       &cmd,
+               /*
+                *  Fill out the scsi command
+                */
+               bzero(&cmd, sizeof(cmd));
+               cmd.op_code = (bp->b_flags & B_READ)
+                   ? READ_BIG : WRITE_BIG;
+               cmd.addr_3 = (blkno & 0xff000000UL) >> 24;
+               cmd.addr_2 = (blkno & 0xff0000) >> 16;
+               cmd.addr_1 = (blkno & 0xff00) >> 8;
+               cmd.addr_0 = blkno & 0xff;
+               cmd.length2 = (nblk & 0xff00) >> 8;
+               cmd.length1 = (nblk & 0xff);
+               /*
+                * Call the routine that chats with the adapter.
+                * Note: we cannot sleep as we may be an interrupt
+                */
+               if (scsi_scsi_cmd(sc_link,
+                       (struct scsi_generic *) &cmd,
                        sizeof(cmd),
                        sizeof(cmd),
-                       (u_char *)bp->b_un.b_addr,
+                       (u_char *) bp->b_un.b_addr,
                        bp->b_bcount,
                        bp->b_bcount,
+                       SD_RETRIES,
                        10000,
                        bp,
                        10000,
                        bp,
-                       SCSI_NOSLEEP| ((bp->b_flags & B_READ)?
-                               SCSI_DATA_IN : SCSI_DATA_OUT))
-               != SUCCESSFULLY_QUEUED)
-       {
+                       SCSI_NOSLEEP | ((bp->b_flags & B_READ) ?
+                           SCSI_DATA_IN : SCSI_DATA_OUT))
+                   == SUCCESSFULLY_QUEUED) {
+                       sdqueues++;
+               } else {
 bad:
 bad:
-               printf("sd%d: oops not queued",unit);
-               bp->b_error = EIO;
-               bp->b_flags |= B_ERROR;
-               biodone(bp);
-               return ;
+                       printf("sd%d: oops not queued", unit);
+                       bp->b_error = EIO;
+                       bp->b_flags |= B_ERROR;
+                       biodone(bp);
+               }
        }
        }
-       sdqueues++;
 }
 
 }
 
-/*******************************************************\
-* Perform special action on behalf of the user         *
-* Knows about the internals of this device             *
-\*******************************************************/
+/*
+ * Perform special action on behalf of the user
+ * Knows about the internals of this device
+ */
+errval 
 sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
 {
 sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
 {
-       /* struct sd_cmd_buf *args;*/
-       int error = 0;
-       unsigned int opri;
+       /* struct sd_cmd_buf *args; */
+       errval  error = 0;
        unsigned char unit, part;
        register struct sd_data *sd;
 
        unsigned char unit, part;
        register struct sd_data *sd;
 
-
-       /*******************************************************\
-       * Find the device that the user is talking about        *
-       \*******************************************************/
+       /*
+        * Find the device that the user is talking about
+        */
        unit = UNIT(dev);
        part = PARTITION(dev);
        sd = sd_data[unit];
        unit = UNIT(dev);
        part = PARTITION(dev);
        sd = sd_data[unit];
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("sdioctl%d ",unit);
-#endif /*SDDEBUG*/
-
-       /*******************************************************\
-       * If the device is not valid.. abandon ship             *
-       \*******************************************************/
-       if (!(sd->flags & SDVALID))
-               return(EIO);
-       switch(cmd)
-       {
+       SC_DEBUG(sd->sc_link, SDEV_DB1, ("sdioctl (0x%x)", cmd));
+
+       /*
+        * If the device is not valid.. abandon ship
+        */
+       if (!(sd->sc_link->flags & SDEV_MEDIA_LOADED))
+               return (EIO);
+       switch (cmd) {
 
        case DIOCSBAD:
 
        case DIOCSBAD:
-                        error = EINVAL;
+               error = EINVAL;
                break;
 
        case DIOCGDINFO:
                break;
 
        case DIOCGDINFO:
-               *(struct disklabel *)addr = sd->disklabel;
+               *(struct disklabel *) addr = sd->disklabel;
                break;
 
                break;
 
-        case DIOCGPART:
-                ((struct partinfo *)addr)->disklab = &sd->disklabel;
-                ((struct partinfo *)addr)->part =
-                    &sd->disklabel.d_partitions[PARTITION(dev)];
-                break;
-
-        case DIOCSDINFO:
-                if ((flag & FWRITE) == 0)
-                        error = EBADF;
-                else
-                        error = setdisklabel(&sd->disklabel,
-                                       (struct disklabel *)addr,
-                         /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */0,
-                               sd->dosparts);
-                if (error == 0) {
+       case DIOCGPART:
+               ((struct partinfo *) addr)->disklab = &sd->disklabel;
+               ((struct partinfo *) addr)->part =
+                   &sd->disklabel.d_partitions[PARTITION(dev)];
+               break;
+
+       case DIOCSDINFO:
+               if ((flag & FWRITE) == 0)
+                       error = EBADF;
+               else
+                       error = setdisklabel(&sd->disklabel,
+                           (struct disklabel *)addr,
+                       /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */ 0,
+#ifdef NetBSD
+                           &sd->cpudisklabel
+#else
+                           sd->dosparts
+#endif
+                           );
+               if (error == 0) {
                        sd->flags |= SDHAVELABEL;
                }
                        sd->flags |= SDHAVELABEL;
                }
-                break;
+               break;
 
 
-        case DIOCWLABEL:
+       case DIOCWLABEL:
                sd->flags &= ~SDWRITEPROT;
                sd->flags &= ~SDWRITEPROT;
-                if ((flag & FWRITE) == 0)
-                        error = EBADF;
-                else
-                        sd->wlabel = *(int *)addr;
-                break;
+               if ((flag & FWRITE) == 0)
+                       error = EBADF;
+               else
+                       sd->wlabel = *(boolean *) addr;
+               break;
 
 
-        case DIOCWDINFO:
+       case DIOCWDINFO:
                sd->flags &= ~SDWRITEPROT;
                sd->flags &= ~SDWRITEPROT;
-                if ((flag & FWRITE) == 0)
-                        error = EBADF;
-                else
-               {
-                       if ((error = setdisklabel(&sd->disklabel
-                                               , (struct disklabel *)addr
-                       , /*(sd->flags & SDHAVELABEL) ? sd->openparts :*/ 0
-                                               , sd->dosparts)) == 0)
-                       {
-                               int wlab;
-
-                               sd->flags |= SDHAVELABEL; /* ok write will succeed */
-
-                               /* simulate opening partition 0 so write succeeds */
-                               sd->openparts |= (1 << 0);            /* XXX */
-                               wlab = sd->wlabel;
-                               sd->wlabel = 1;
-                               error = writedisklabel(dev, sdstrategy,
-                                       &sd->disklabel, sd->dosparts);
-                               sd->wlabel = wlab;
-                       }
-               }
-                break;
-
+               if ((flag & FWRITE) == 0)
+                       error = EBADF;
+               else {
+                       error = setdisklabel(&sd->disklabel,
+                           (struct disklabel *)addr,
+                           /*(sd->flags & SDHAVELABEL) ? sd->openparts : */ 0,
+#ifdef NetBSD
+                           &sd->cpudisklabel
+#else
+                           sd->dosparts
+#endif
+                           );
+                       if (!error) {
+                               boolean wlab;
+
+                               /* ok - write will succeed */
+                               sd->flags |= SDHAVELABEL;
+
+                               /* simulate opening partition 0 so write succeeds */
+                               sd->openparts |= (1 << 0);      /* XXX */
+                               wlab = sd->wlabel;
+                               sd->wlabel = 1;
+                               error = writedisklabel(dev, sdstrategy,
+                                   &sd->disklabel,
+#ifdef NetBSD
+                                   &sd->cpudisklabel
+#else
+                                   sd->dosparts
+#endif
+                                   );
+                               sd->wlabel = wlab;
+                       }
+               } 
+               break;
 
        default:
 
        default:
-               error = ENOTTY;
+               if (part == RAW_PART)
+                       error = scsi_do_ioctl(sd->sc_link, cmd, addr, flag);
+               else
+                       error = ENOTTY;
                break;
        }
                break;
        }
-       return (error);
+       return error;
 }
 
 }
 
-
-/*******************************************************\
-* Load the label information on the named device       *
-\*******************************************************/
-int sdgetdisklabel(unit)
-unsigned char  unit;
+/*
+ * Load the label information on the named device
+ */
+errval 
+sdgetdisklabel(unsigned char unit)
 {
 {
-       /*unsigned int n, m;*/
-       char *errstring;
-       struct dos_partition *dos_partition_p;
+       char   *errstring;
        struct sd_data *sd = sd_data[unit];
 
        struct sd_data *sd = sd_data[unit];
 
-       /*******************************************************\
-       * If the inflo is already loaded, use it                *
-       \*******************************************************/
-       if(sd->flags & SDHAVELABEL) return(ESUCCESS);
-
-       bzero(&sd->disklabel,sizeof(struct disklabel));
-       /*******************************************************\
-       * make partition 3 the whole disk in case of failure    *
-       *   then get pdinfo                                     *
-       * for historical reasons, make part a same as raw part  *
-       \*******************************************************/
+       /*
+        * If the inflo is already loaded, use it
+        */
+       if (sd->flags & SDHAVELABEL)
+               return (ESUCCESS);
+
+       bzero(&sd->disklabel, sizeof(struct disklabel));
+       /*
+        * make partition 3 the whole disk in case of failure then get pdinfo
+        * for historical reasons, make part a same as raw part
+        */
        sd->disklabel.d_partitions[0].p_offset = 0;
        sd->disklabel.d_partitions[0].p_size = sd->params.disksize;
        sd->disklabel.d_partitions[RAW_PART].p_offset = 0;
        sd->disklabel.d_partitions[RAW_PART].p_size = sd->params.disksize;
        sd->disklabel.d_npartitions = MAXPARTITIONS;
        sd->disklabel.d_partitions[0].p_offset = 0;
        sd->disklabel.d_partitions[0].p_size = sd->params.disksize;
        sd->disklabel.d_partitions[RAW_PART].p_offset = 0;
        sd->disklabel.d_partitions[RAW_PART].p_size = sd->params.disksize;
        sd->disklabel.d_npartitions = MAXPARTITIONS;
-       sd->disklabel.d_secsize = 512; /* as long as it's not 0 */
+       sd->disklabel.d_secsize = SECSIZE;      /* as long as it's not 0 */
        sd->disklabel.d_ntracks = sd->params.heads;
        sd->disklabel.d_nsectors = sd->params.sectors;
        sd->disklabel.d_ncylinders = sd->params.cyls;
        sd->disklabel.d_secpercyl = sd->params.heads * sd->params.sectors;
        sd->disklabel.d_ntracks = sd->params.heads;
        sd->disklabel.d_nsectors = sd->params.sectors;
        sd->disklabel.d_ncylinders = sd->params.cyls;
        sd->disklabel.d_secpercyl = sd->params.heads * sd->params.sectors;
-       if (sd->disklabel.d_secpercyl == 0)
-       {
+       if (sd->disklabel.d_secpercyl == 0) {
                sd->disklabel.d_secpercyl = 100;
                sd->disklabel.d_secpercyl = 100;
-                                       /* as long as it's not 0 */
-                                       /* readdisklabel divides by it (?)*/
+               /* as long as it's not 0 - readdisklabel divides by it (?) */
        }
        }
-
-       /*******************************************************\
-       * Call the generic disklabel extraction routine         *
-       \*******************************************************/
-       if(errstring = readdisklabel(makedev(0 ,(unit<<UNITSHIFT )+3)
-                                       , sdstrategy
-                                       , &sd->disklabel
-                                       , sd->dosparts
-                                       , 0
-                                       , 0))
-       {
-               printf("sd%d: %s\n",unit, errstring);
-               return(ENXIO);
+       /*
+        * Call the generic disklabel extraction routine
+        */
+       if (errstring = readdisklabel(makedev(0, (unit << UNITSHIFT) + 3),
+           sdstrategy,
+           &sd->disklabel,
+#ifdef NetBSD
+           &sd->cpudisklabel
+#else
+           sd->dosparts,
+           0,
+           0
+#endif
+           )) {
+               printf("sd%d: %s\n", unit, errstring);
+               return ENXIO;
        }
        }
-
-       sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */
-       return(ESUCCESS);
+       sd->flags |= SDHAVELABEL;       /* WE HAVE IT ALL NOW */
+       return ESUCCESS;
 }
 
 }
 
-/*******************************************************\
-* Find out from the device what it's capacity is       *
-\*******************************************************/
+/*
+ * Find out from the device what it's capacity is
+ */
+u_int32 
 sd_size(unit, flags)
 sd_size(unit, flags)
+       int     unit, flags;
 {
        struct scsi_read_cap_data rdcap;
        struct scsi_read_capacity scsi_cmd;
 {
        struct scsi_read_cap_data rdcap;
        struct scsi_read_capacity scsi_cmd;
-       int size;
+       u_int32 size;
 
 
-       /*******************************************************\
-       * make up a scsi command and ask the scsi driver to do  *
-       * it for you.                                           *
-       \*******************************************************/
+       /*
+        * make up a scsi command and ask the scsi driver to do
+        * it for you.
+        */
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        scsi_cmd.op_code = READ_CAPACITY;
 
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        scsi_cmd.op_code = READ_CAPACITY;
 
-       /*******************************************************\
-       * If the command works, interpret the result as a 4 byte*
-       * number of blocks                                      *
-       \*******************************************************/
-       if (sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       &rdcap,
-                       sizeof(rdcap),  
-                       6000,
-                       NULL,
-                       flags | SCSI_DATA_IN) != 0)
-       {
+       /*
+        * If the command works, interpret the result as a 4 byte
+        * number of blocks
+        */
+       if (scsi_scsi_cmd(sd_data[unit]->sc_link,
+               (struct scsi_generic *) &scsi_cmd,
+               sizeof(scsi_cmd),
+               (u_char *) & rdcap,
+               sizeof(rdcap),
+               SD_RETRIES,
+               2000,
+               NULL,
+               flags | SCSI_DATA_IN) != 0) {
                printf("sd%d: could not get size\n", unit);
                printf("sd%d: could not get size\n", unit);
-               return(0);
+               return (0);
        } else {
        } else {
-               size = rdcap.addr_0 + 1 ;
+               size = rdcap.addr_0 + 1;
                size += rdcap.addr_1 << 8;
                size += rdcap.addr_2 << 16;
                size += rdcap.addr_3 << 24;
        }
                size += rdcap.addr_1 << 8;
                size += rdcap.addr_2 << 16;
                size += rdcap.addr_3 << 24;
        }
-       return(size);
-}
-       
-/*******************************************************\
-* Get scsi driver to send a "are you ready?" command   *
-\*******************************************************/
-sd_test_unit_ready(unit,flags)
-int    unit,flags;
-{
-       struct  scsi_test_unit_ready scsi_cmd;
-
-       bzero(&scsi_cmd, sizeof(scsi_cmd));
-       scsi_cmd.op_code = TEST_UNIT_READY;
-
-       return (sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       0,
-                       0,
-                       100000,
-                       NULL,
-                       flags));
-}
-
-/*******************************************************\
-* Prevent or allow the user to remove the tape         *
-* Don't change this status if any partitions are open  *
-\*******************************************************/
-sd_prevent(unit,type,flags)
-int    unit,type,flags;
-{
-       struct  scsi_prevent    scsi_cmd;
-
-       if(sd_data[unit]->openparts) return;
-
-       bzero(&scsi_cmd, sizeof(scsi_cmd));
-       scsi_cmd.op_code = PREVENT_ALLOW;
-       scsi_cmd.how=type;
-       return (sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       0,
-                       0,
-                       5000,
-                       NULL,
-                       flags) );
-}
-/*******************************************************\
-* Get scsi driver to send a "start up" command         *
-\*******************************************************/
-sd_start_unit(unit,flags)
-int    unit,flags;
-{
-       struct scsi_start_stop scsi_cmd;
-
-       bzero(&scsi_cmd, sizeof(scsi_cmd));
-       scsi_cmd.op_code = START_STOP;
-       scsi_cmd.how = SSS_START;
-
-       return (sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       0,
-                       0,
-                       2000,
-                       NULL,
-                       flags));
+       return (size);
 }
 
 }
 
-/*******************************************************\
-* Tell the device to map out a defective block         *
-\*******************************************************/
-sd_reassign_blocks(unit,block)
+/*
+ * Tell the device to map out a defective block
+ */
+errval 
+sd_reassign_blocks(unit, block)
+       int     unit, block;
 {
 {
-       struct  scsi_reassign_blocks            scsi_cmd;
-       struct  scsi_reassign_blocks_data       rbdata;
-
+       struct scsi_reassign_blocks scsi_cmd;
+       struct scsi_reassign_blocks_data rbdata;
 
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        bzero(&rbdata, sizeof(rbdata));
 
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        bzero(&rbdata, sizeof(rbdata));
@@ -905,108 +792,67 @@ sd_reassign_blocks(unit,block)
        rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
        rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
        rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
        rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
        rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
        rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
-       rbdata.defect_descriptor[0].dlbaddr_1 = ((block >>  8) & 0xff);
-       rbdata.defect_descriptor[0].dlbaddr_0 = ((block      ) & 0xff);
-
-       return(sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       &rbdata,
-                       sizeof(rbdata),
-                       5000,
-                       NULL,
-                       SCSI_DATA_OUT));
+       rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
+       rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff);
+
+       return (scsi_scsi_cmd(sd_data[unit]->sc_link,
+               (struct scsi_generic *) &scsi_cmd,
+               sizeof(scsi_cmd),
+               (u_char *) & rbdata,
+               sizeof(rbdata),
+               SD_RETRIES,
+               5000,
+               NULL,
+               SCSI_DATA_OUT));
 }
 }
-
 #define b2tol(a)       (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
 
 #define b2tol(a)       (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
 
-/*******************************************************\
-* Get the scsi driver to send a full inquiry to the    *
-* device and use the results to fill out the disk      *
-* parameter structure.                                 *
-\*******************************************************/
-
-int    sd_get_parms(unit, flags)
+/*
+ * Get the scsi driver to send a full inquiry to the
+ * device and use the results to fill out the disk 
+ * parameter structure.
+ */
+errval 
+sd_get_parms(unit, flags)
+       int     unit, flags;
 {
        struct sd_data *sd = sd_data[unit];
        struct disk_parms *disk_parms = &sd->params;
 {
        struct sd_data *sd = sd_data[unit];
        struct disk_parms *disk_parms = &sd->params;
-       struct  scsi_mode_sense         scsi_cmd;
-       struct  scsi_mode_sense_data
-       {
-               struct  scsi_mode_header        header;
-               struct  blk_desc                blk_desc;
-               union   disk_pages              pages;
-       }scsi_sense;
-       int sectors;
-
-       /*******************************************************\
-       * First check if we have it all loaded                  *
-       \*******************************************************/
-               if(sd->flags & SDVALID) return(0);
-       /*******************************************************\
-       * First do a mode sense page 3                          *
-       \*******************************************************/
-#ifdef SDDEBUG
-       if (sd_debug)
-       {
-               bzero(&scsi_cmd, sizeof(scsi_cmd));
-               scsi_cmd.op_code = MODE_SENSE;
-               scsi_cmd.page = 3;
-               scsi_cmd.length = 0x24;
-               /*******************************************************\
-               * do the command, but we don't need the results         *
-               * just print them for our interest's sake               *
-               \*******************************************************/
-               if (sd_scsi_cmd(unit,
-                               &scsi_cmd,
-                               sizeof(scsi_cmd),
-                               &scsi_sense,
-                               sizeof(scsi_sense),
-                               2000,
-                               NULL,
-                               flags | SCSI_DATA_IN) != 0)
-               {
-                       printf("sd%d: could not mode sense (3)\n", unit);
-               } 
-               else
-               {
-               printf("unit %d: %d trk/zone, %d alt_sec/zone, %d alt_trk/zone, %d alt_trk/lun\n",
-                       unit,
-                       b2tol(scsi_sense.pages.disk_format.trk_z),
-                       b2tol(scsi_sense.pages.disk_format.alt_sec),
-                       b2tol(scsi_sense.pages.disk_format.alt_trk_z),
-                       b2tol(scsi_sense.pages.disk_format.alt_trk_v));
-               printf("         %d sec/trk, %d bytes/sec, %d interleave, %d %d bytes/log_blk\n",
-                       b2tol(scsi_sense.pages.disk_format.ph_sec_t),
-                       b2tol(scsi_sense.pages.disk_format.bytes_s),
-                       b2tol(scsi_sense.pages.disk_format.interleave),
-                       sd_size(unit, flags),
-                       _3btol(scsi_sense.blk_desc.blklen));
-               }
-       }
-#endif /*SDDEBUG*/
-
-
-       /*******************************************************\
-       * do a "mode sense page 4"                              *
-       \*******************************************************/
+       struct scsi_mode_sense scsi_cmd;
+       struct scsi_mode_sense_data {
+               struct scsi_mode_header header;
+               struct blk_desc blk_desc;
+               union disk_pages pages;
+       } scsi_sense;
+       u_int32 sectors;
+
+       /*
+        * First check if we have it all loaded
+        */
+       if (sd->sc_link->flags & SDEV_MEDIA_LOADED)
+               return 0;
+
+       /*
+        * do a "mode sense page 4"
+        */
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        scsi_cmd.op_code = MODE_SENSE;
        scsi_cmd.page = 4;
        scsi_cmd.length = 0x20;
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        scsi_cmd.op_code = MODE_SENSE;
        scsi_cmd.page = 4;
        scsi_cmd.length = 0x20;
-       /*******************************************************\
-       * If the command worked, use the results to fill out    *
-       * the parameter structure                               *
-       \*******************************************************/
-       if (sd_scsi_cmd(unit,
-                       &scsi_cmd,
-                       sizeof(scsi_cmd),
-                       &scsi_sense,
-                       sizeof(scsi_sense),
-                       2000,
-                       NULL,
-                       flags | SCSI_DATA_IN) != 0)
-       {
+       /*
+        * If the command worked, use the results to fill out
+        * the parameter structure
+        */
+       if (scsi_scsi_cmd(sd->sc_link,
+               (struct scsi_generic *) &scsi_cmd,
+               sizeof(scsi_cmd),
+               (u_char *) & scsi_sense,
+               sizeof(scsi_sense),
+               SD_RETRIES,
+               2000,
+               NULL,
+               flags | SCSI_DATA_IN) != 0) {
+
                printf("sd%d could not mode sense (4).", unit);
                printf(" Using ficticious geometry\n");
                /*
                printf("sd%d could not mode sense (4).", unit);
                printf(" Using ficticious geometry\n");
                /*
@@ -1017,631 +863,196 @@ int    sd_get_parms(unit, flags)
                sectors = sd_size(unit, flags);
                disk_parms->heads = 64;
                disk_parms->sectors = 32;
                sectors = sd_size(unit, flags);
                disk_parms->heads = 64;
                disk_parms->sectors = 32;
-               disk_parms->cyls = sectors/(64 * 32);
+               disk_parms->cyls = sectors / (64 * 32);
                disk_parms->secsiz = SECSIZE;
                disk_parms->disksize = sectors;
                disk_parms->secsiz = SECSIZE;
                disk_parms->disksize = sectors;
-       } 
-       else
-       {
+       } else {
 
 
-#ifdef SDDEBUG
-               if (sd_debug)
-               {
-               printf("         %d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
+               SC_DEBUG(sd->sc_link, SDEV_DB3,
+                   ("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
                        _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2),
                        scsi_sense.pages.rigid_geometry.nheads,
                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
                        _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2),
                        scsi_sense.pages.rigid_geometry.nheads,
                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
-                       b2tol(scsi_sense.pages.rigid_geometry.land_zone));
-               }
-#endif /*SDDEBUG*/
-
-               /*******************************************************\
-               * KLUDGE!!(for zone recorded disks)                     *
-               * give a number of sectors so that sec * trks * cyls    *
-               * is <= disk_size                                       *
-               * can lead to wasted space! THINK ABOUT THIS !          *
-               \*******************************************************/
+                       b2tol(scsi_sense.pages.rigid_geometry.land_zone)));
+
+               /*
+                * KLUDGE!!(for zone recorded disks)
+                * give a number of sectors so that sec * trks * cyls
+                * is <= disk_size 
+                * can lead to wasted space! THINK ABOUT THIS !
+                */
                disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
                disk_parms->cyls = _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2);
                disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
                disk_parms->cyls = _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2);
-               disk_parms->secsiz = _3btol(&scsi_sense.blk_desc.blklen);
+               disk_parms->secsiz = _3btol(scsi_sense.blk_desc.blklen);
 
                sectors = sd_size(unit, flags);
                disk_parms->disksize = sectors;
 
                sectors = sd_size(unit, flags);
                disk_parms->disksize = sectors;
-               sectors /= (disk_parms->heads * disk_parms->cyls);
-               disk_parms->sectors = sectors; /* dubious on SCSI*//*XXX*/
-       }
-
-       sd->flags |= SDVALID;
-       return(0);
-}
-
-/*******************************************************\
-* close the device.. only called if we are the LAST    *
-* occurence of an open device                          *
-* convenient now but usually a pain                    *
-\*******************************************************/
-sdclose(dev)
-dev_t dev;
-{
-       unsigned char unit, part;
-       unsigned int old_priority;
-       struct sd_data *sd;
-
-       unit = UNIT(dev);
-       part = PARTITION(dev);
-       sd = sd_data[unit];
-       sd->partflags[part] &= ~SDOPEN;
-       sd->openparts &= ~(1 << part);
-       sd_prevent(unit,PR_ALLOW,SCSI_SILENT|SCSI_ERR_OK);
-       return(0);
-}
-
-/*******************************************************\
-* This routine is called by the scsi interrupt when    *
-* the transfer is complete.
-\*******************************************************/
-int    sd_done(unit,xs)
-int    unit;
-struct scsi_xfer       *xs;
-{
-       struct  buf             *bp;
-       int     retval;
-       int     retries = 0;
-
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("sd_done%d ",unit);
-#endif /*SDDEBUG*/
-#ifdef PARANOID
-       if (! (xs->flags & INUSE))
-               panic("scsi_xfer not in use!");
-#endif
-       if((bp = xs->bp) == NULL)
-       {
-               /***********************************************\
-               * if it's a normal user level request, then ask *
-               * The user level code to handle error checking  *
-               * rather than doing it here at interrupt time   *
-               \***********************************************/
-               wakeup(xs);
-               return;
-       }
-
-       /***********************************************\
-       * If it has a buf, we might be working with     *
-       * a request from the buffer cache or some other *
-       * piece of code that requires us to process     *
-       * errors right now, despite cost                *
-       \***********************************************/
-       switch(xs->error)
-       {
-       case    XS_NOERROR:
-               bp->b_error = 0;
-               bp->b_resid = 0;
-               break;
-
-       case    XS_SENSE:
-               retval = (sd_interpret_sense(unit,xs));
-               if(retval)
-               {
-                       bp->b_flags |= B_ERROR;
-                       bp->b_error = retval;
-               }
-               break;
-
-       case    XS_BUSY:        
-               /*should somehow arange for a 1 sec delay here (how?)*/
-       case    XS_TIMEOUT:
-               /***********************************************\
-               * If we can, resubmit it to the adapter.        *
-               \***********************************************/
-               if(xs->retries--)
-               {
-                       xs->error = XS_NOERROR;
-                       xs->flags &= ~ITSDONE;
-                       if ( (*(sd_data[unit]->sc_sw->scsi_cmd))(xs)
-                               == SUCCESSFULLY_QUEUED)
-                       {       /* don't wake the job, ok? */
-                               return;
-                       }
-                       xs->flags |= ITSDONE;
-               } /* fall through */
-
-       case    XS_DRIVER_STUFFUP:
-               bp->b_flags |= B_ERROR;
-               bp->b_error = EIO;
-               break;
-       default:
-               printf("sd%d: unknown error category from scsi driver\n"
-                       ,unit);
-       }       
-       /*******************************\
-       * tell the owner we're done     *
-       * then free our resources       *
-       * and see if there's more work  *
-       \*******************************/
-       biodone(bp);
-       sd_free_xs(unit,xs,0);
-       sdstart(unit);  /* If there's anything waiting.. do it */
-}
-
-/*******************************************************\
-* ask the scsi driver to perform a command for us.     *
-* Call it through the switch table, and tell it which  *
-* sub-unit we want, and what target and lu we wish to  *
-* talk to. Also tell it where to find the command      *
-* and how long it is.                                  *
-* Also tell it where to read/write the data, and how   *
-* long the data is supposed to be. If we have  a buf   *
-* to associate with the transfer, we need that too.    *
-\*******************************************************/
-int    sd_scsi_cmd(unit,scsi_cmd,cmdlen,data_addr,datalen,timeout,bp,flags)
-
-int    unit,flags;
-struct scsi_generic *scsi_cmd;
-int    cmdlen;
-int    timeout;
-u_char *data_addr;
-int    datalen;
-struct buf *bp;
-{
-       struct  scsi_xfer *xs;
-       int     retval;
-       int     s;
-       struct sd_data *sd = sd_data[unit];
-
-#ifdef SDDEBUG
-       if(scsi_debug & PRINTROUTINES) printf("\nsd_scsi_cmd%d ",unit);
-#endif /*SDDEBUG*/
-
-#ifdef PARANOID
-       if(!(sd->sc_sw))        /* If we have a scsi driver */
-       {/* How we got here is anyone's guess */
-               printf("sd%d: not set up\n",unit);
-               return(EINVAL);
-       }
-#endif
-       xs = sd_get_xs(unit,flags); /* should wait unless booting */
-#ifdef PARANOID
-       if(!xs)
-       {
-               printf("sd_scsi_cmd%d: controller busy"
-                               " (this should never happen)\n",unit); 
-                       return(EBUSY);
-       }
-#endif
-       /*******************************************************\
-       * Fill out the scsi_xfer structure                      *
-       \*******************************************************/
-       xs->flags       =       INUSE | flags;
-       xs->adapter     =       sd->ctlr;
-       xs->targ        =       sd->targ;
-       xs->lu          =       sd->lu;
-       xs->retries     =       SD_RETRIES;
-       xs->timeout     =       timeout;
-       xs->cmd         =       scsi_cmd;
-       xs->cmdlen      =       cmdlen;
-       xs->data        =       data_addr;
-       xs->datalen     =       datalen;
-       xs->resid       =       datalen;
-       xs->when_done   =       sd_done;
-       xs->done_arg    =       unit;
-       xs->done_arg2   =       (int)xs;
-       xs->bp          =       bp;
-retry: xs->error       =       XS_NOERROR;
-
-       /*******************************************************\
-       * Do the transfer. If we are polling we will return:    *
-       * COMPLETE,     Was poll, and sd_done has been called   *
-       * HAD_ERROR,    Was poll and an error was encountered   *
-       * TRY_AGAIN_LATER, Adapter short resources, try again   *
-       *                                                       *
-       * if under full steam (interrupts) it will return:      *
-       * SUCCESSFULLY_QUEUED, will do a wakeup when complete   *
-       * HAD_ERROR,    had an erro before it could queue       *
-       * TRY_AGAIN_LATER, (as for polling)                     *
-       * After the wakeup, we must still check if it succeeded *
-       *                                                       *
-       * If we have a bp however, all the error proccessing    *
-       * and the buffer code both expect us to return straight *
-       * to them, so as soon as the command is queued, return  *
-       \*******************************************************/
-       retval = (*(sd->sc_sw->scsi_cmd))(xs);
-       if(bp) return retval; /* will sleep (or not) elsewhere */
-
-       /*******************************************************\
-       * Only here for non I/O cmds. It's cheaper to process   *
-       * the error status here than at interrupt time so       *
-       * sd_done will have done nothing except wake us up.     *
-       \*******************************************************/
-       switch(retval)
-       {
-       case    SUCCESSFULLY_QUEUED:
-               s = splbio();
-               while(!(xs->flags & ITSDONE))
-                       sleep(xs,PRIBIO+1);
-               splx(s);
-               /* fall through to check success of completed command */
-
-       case    HAD_ERROR:
-               switch(xs->error)
-               {
-               case    XS_NOERROR: /* nearly always hit this one */
-                       retval = ESUCCESS;
-                       break;
-
-               case    XS_SENSE:
-                       retval = (sd_interpret_sense(unit,xs));
-                       break;
-               case    XS_BUSY:
-                       /* should sleep 1 sec here */
-               case    XS_TIMEOUT:
-                       if(xs->retries-- )
-                       {
-                               xs->flags &= ~ITSDONE;
-                               goto retry;
-                       }
-               case    XS_DRIVER_STUFFUP:
-                       retval = EIO;
-                       break;
-               default:
-                       retval = EIO;
-                       printf("sd%d: unknown error category from scsi driver\n"
-                               ,unit);
-               }       
-               break;
-       case    COMPLETE:       /* Polling command completed ok */
-               retval = ESUCCESS;
-               break;
-
-       case    TRY_AGAIN_LATER:        /* adapter resource shortage */
-               /* should sleep 1 sec here */
-               if(xs->retries-- )
-               {
-                       xs->flags &= ~ITSDONE;
-                       goto retry;
+               /* Check if none of these values are zero */
+               if(disk_parms->heads && disk_parms->cyls) {
+                       sectors /= (disk_parms->heads * disk_parms->cyls);
                }
                }
-       default:
-               retval = EIO;
-       }
-       /*******************************************************\
-       * we have finished with the xfer stuct, free it and     *
-       * check if anyone else needs to be started up.          *
-       \*******************************************************/
-       sd_free_xs(unit,xs,flags);
-       sdstart(unit); /* check queue */
-       return(retval);
-}
-
-/***************************************************************\
-* Look at the returned sense and act on the error and detirmine        *
-* The unix error number to pass back... (0 = report no error)  *
-\***************************************************************/
-
-int    sd_interpret_sense(unit,xs)
-int    unit;
-struct scsi_xfer *xs;
-{
-       struct  scsi_sense_data *sense;
-       int     key;
-       int     silent;
-       long int        info;
-
-       /***************************************************************\
-       * If the flags say errs are ok, then always return ok.          *
-       \***************************************************************/
-       if (xs->flags & SCSI_ERR_OK) return(ESUCCESS);
-       silent = (xs->flags & SCSI_SILENT);
-
-       sense = &(xs->sense);
-       info = ((sense->ext.extended.info[0] <<24)|
-               (sense->ext.extended.info[1] <<16)|
-               (sense->ext.extended.info[2] <<8)|
-               (sense->ext.extended.info[3] ));
-       switch(sense->error_code & SSD_ERRCODE)
-       {
-       case 0x70:
-               {
-               key=sense->ext.extended.flags & SSD_KEY;
-               switch(key)
-               {
-               case    0x0:
-                       return(ESUCCESS);
-               case    0x1:
-                       if(!silent)
-                       {
-                               printf("sd%d: soft error(corrected) ", unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)",info);
-                               }
-                               printf("\n");
-                       }
-                       return(ESUCCESS);
-               case    0x2:
-                       if(!silent)printf("sd%d: not ready\n ",
-                               unit); 
-                       return(ENODEV);
-               case    0x3:
-                       if(!silent)
-                       {
-                               printf("sd%d: medium error ", unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)",info);
-                               }
-                               printf("\n");
-                       }
-                       return(EIO);
-               case    0x4:
-                       if(!silent)printf("sd%d: non-media hardware failure\n ",
-                               unit); 
-                       return(EIO);
-               case    0x5:
-                       if(!silent)printf("sd%d: illegal request\n ",
-                               unit); 
-                       return(EINVAL);
-               case    0x6:
-                       /***********************************************\
-                       * If we are not open, then this is not an error *
-                       * as we don't have state yet. Either way, make  *
-                       * sure that we don't have any residual state    *
-                       \***********************************************/
-                       if(!silent)printf("sd%d: Unit attention.\n ", unit); 
-                       sd_data[unit]->flags &= ~(SDVALID | SDHAVELABEL);
-                       if (sd_data[unit]->openparts)
-                       {
-                               return(EIO);
-                       }
-                       return(ESUCCESS); /* not an error if nothing's open */
-               case    0x7:
-                       if(!silent)
-                       {
-                               printf("sd%d: attempted protection violation ",
-                                               unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)\n",info);
-                               }
-                               printf("\n");
-                       }
-                       return(EACCES);
-               case    0x8:
-                       if(!silent)
-                       {
-                               printf("sd%d: block wrong state (format?)\n ",
-                               unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)\n",info);
-                               }
-                               printf("\n");
-                       }
-                       return(EIO);
-               case    0x9:
-                       if(!silent)printf("sd%d: vendor unique\n",
-                               unit); 
-                       return(EIO);
-               case    0xa:
-                       if(!silent)printf("sd%d: copy aborted\n ",
-                               unit); 
-                       return(EIO);
-               case    0xb:
-                       if(!silent)printf("sd%d: command aborted\n ",
-                               unit); 
-                       return(EIO);
-               case    0xc:
-                       if(!silent)
-                       {
-                               printf("sd%d: search returned\n ",
-                                       unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)\n",info);
-                               }
-                               printf("\n");
-                       }
-                       return(ESUCCESS);
-               case    0xd:
-                       if(!silent)printf("sd%d: volume overflow\n ",
-                               unit); 
-                       return(ENOSPC);
-               case    0xe:
-                       if(!silent)
-                       {
-                               printf("sd%d: verify miscompare\n ",
-                               unit); 
-                               if(sense->error_code & SSD_ERRCODE_VALID)
-                               {
-                                       printf("block no. %d (decimal)\n",info);
-                               }
-                               printf("\n");
-                       }
-                       return(EIO);
-               case    0xf:
-                       if(!silent)printf("sd%d: unknown error key\n ",
-                               unit); 
-                       return(EIO);
-               }
-               break;
-       }
-       default:
-               {
-                       if(!silent)printf("sd%d: code %d\n",
-                               unit,
-                               sense->error_code & SSD_ERRCODE);
-               if(sense->error_code & SSD_ERRCODE_VALID)
-                       if(!silent)printf("block no. %d (decimal)\n",
-                       (sense->ext.unextended.blockhi <<16)
-                       + (sense->ext.unextended.blockmed <<8)
-                       + (sense->ext.unextended.blocklow ));
+               else {
+                       /* set it to something reasonable */
+                       disk_parms->heads = 64;
+                       disk_parms->cyls = sectors / (64 * 32);
+                       sectors = 32;
                }
                }
-               return(EIO);
+               /* keep secsiz sane too - we may divide by it later */
+               if(disk_parms->secsiz == 0)
+                       disk_parms->secsiz = SECSIZE;
+               disk_parms->sectors = sectors;  /* dubious on SCSI *//*XXX */
        }
        }
+       sd->sc_link->flags |= SDEV_MEDIA_LOADED;
+       return 0;
 }
 
 }
 
-
-
-
 int
 sdsize(dev_t dev)
 {
 int
 sdsize(dev_t dev)
 {
-       int unit = UNIT(dev), part = PARTITION(dev), val;
+       u_int32 unit = UNIT(dev), part = PARTITION(dev), val;
        struct sd_data *sd;
 
        if (unit >= NSD)
        struct sd_data *sd;
 
        if (unit >= NSD)
-               return(-1);
+               return -1;
 
        sd = sd_data[unit];
 
        sd = sd_data[unit];
-       if(!sd) return(-1);
-       if((sd->flags & SDINIT) == 0) return(-1);
-       if (sd == 0 || (sd->flags & SDHAVELABEL) == 0)
-               val = sdopen (MAKESDDEV(major(dev), unit, RAW_PART), FREAD, S_IFBLK, 0);
-       if ( val != 0 || sd->flags & SDWRITEPROT)
-               return (-1);
-
-       return((int)sd->disklabel.d_partitions[part].p_size);
+       if (!sd)
+               return -1;
+       if ((sd->flags & SDINIT) == 0)
+               return -1;
+       if (sd == 0 || (sd->flags & SDHAVELABEL) == 0) {
+               val = sdopen(MAKESDDEV(major(dev), unit, RAW_PART), FREAD, S_IFBLK, 0);
+               if (val != 0)
+                       return -1;
+       }
+       if (sd->flags & SDWRITEPROT)
+               return -1;
+
+       return (int)sd->disklabel.d_partitions[part].p_size;
 }
 }
-/*#define SCSIDUMP*/
-#ifdef SCSIDUMP
-#include <vm/vm.h>
-/***********************************************************************\
-* dump all of physical memory into the partition specified, starting   *
-* at offset 'dumplo' into the partition.                               *
-\***********************************************************************/
-static struct  scsi_xfer sx;
-#define        MAXTRANSFER 8 /* 1 page at a time */
-int
-sddump(dev_t dev)                      /* dump core after a system crash */
-{
+
+/*
+ * dump all of physical memory into the partition specified, starting
+ * at offset 'dumplo' into the partition.
+ */
+errval
+sddump(dev_t dev)
+{                              /* dump core after a system crash */
        register struct sd_data *sd;    /* disk unit to do the IO */
        register struct sd_data *sd;    /* disk unit to do the IO */
-       long    num;                    /* number of sectors to write */
-       int     unit, part, sdc;
-       long    blkoff, blknum, blkcnt;
-       long    nblocks;
+       int32   num;            /* number of sectors to write */
+       u_int32 unit, part;
+       int32   blkoff, blknum, blkcnt = MAXTRANSFER;
+       int32   nblocks;
        char    *addr;
        char    *addr;
-       struct  scsi_rw_big     cmd;
+       struct  scsi_rw_big cmd;
        extern  int Maxmem;
        extern  int Maxmem;
-       static  sddoingadump = 0 ;
-       extern  caddr_t CADDR1; /* map the page we are about to write, here*/
-       struct scsi_xfer *xs = &sx;
-       int     retval;
+       static  int sddoingadump = 0;
+       extern  caddr_t CADDR1; /* map the page we are about to write, here */
+       extern  struct pte *CMAP1;
+       struct  scsi_xfer *xs = &sx;
+       errval  retval;
+       int     c;
 
 
-       addr = (char *) 0;              /* starting address */
+       addr = (char *) 0;      /* starting address */
 
        /* toss any characters present prior to dump */
 
        /* toss any characters present prior to dump */
-       while (sgetc(1))
-               ;
+       while ((c = sgetc(1)) && (c != 0x100)); /*syscons and pccons differ */
 
        /* size of memory to dump */
        num = Maxmem;
 
        /* size of memory to dump */
        num = Maxmem;
-       unit = UNIT(dev);               /* eventually support floppies? */
-       part = PARTITION(dev);          /* file system */
+       unit = UNIT(dev);       /* eventually support floppies? */
+       part = PARTITION(dev);  /* file system */
        /* check for acceptable drive number */
        /* check for acceptable drive number */
-       if (unit >= NSD) return(ENXIO);         /* 31 Jul 92*/
+       if (unit >= NSD)
+               return (ENXIO);
 
        sd = sd_data[unit];
 
        sd = sd_data[unit];
-       if(!sd) return (ENXIO);
+       if (!sd)
+               return (ENXIO);
        /* was it ever initialized etc. ? */
        /* was it ever initialized etc. ? */
-       if (!(sd->flags & SDINIT))              return (ENXIO);
-       if (sd->flags & SDVALID != SDVALID)     return (ENXIO) ;
-       if (sd->flags & SDWRITEPROT)            return (ENXIO);
+       if (!(sd->flags & SDINIT))
+               return (ENXIO);
+       if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
+               return (ENXIO);
+       if (sd->flags & SDWRITEPROT)
+               return (ENXIO);
 
        /* Convert to disk sectors */
 
        /* Convert to disk sectors */
-       num = (u_long) num * NBPG / sd->disklabel.d_secsize;
+       num = (u_int32) num * NBPG / sd->disklabel.d_secsize;
 
        /* check if controller active */
 
        /* check if controller active */
-       if (sddoingadump) return(EFAULT);
+       if (sddoingadump)
+               return (EFAULT);
 
        nblocks = sd->disklabel.d_partitions[part].p_size;
        blkoff = sd->disklabel.d_partitions[part].p_offset;
 
        /* check transfer bounds against partition size */
        if ((dumplo < 0) || ((dumplo + num) > nblocks))
 
        nblocks = sd->disklabel.d_partitions[part].p_size;
        blkoff = sd->disklabel.d_partitions[part].p_offset;
 
        /* check transfer bounds against partition size */
        if ((dumplo < 0) || ((dumplo + num) > nblocks))
-               return(EINVAL);
+               return (EINVAL);
 
 
-       sddoingadump = 1  ;
+       sddoingadump = 1;
 
        blknum = dumplo + blkoff;
 
        blknum = dumplo + blkoff;
-       while (num > 0)
-       {
-               if (blkcnt > MAXTRANSFER) blkcnt = MAXTRANSFER;
-               pmap_enter(     kernel_pmap,
-                               CADDR1,
-                               trunc_page(addr),
-                               VM_PROT_READ,
-                               TRUE);
-#ifndef        NOT_TRUSTED
-               /*******************************************************\
-               *  Fill out the scsi command                            *
-               \*******************************************************/
+       while (num > 0) {
+                *(int *)CMAP1 =
+                       PG_V | PG_KW | trunc_page(addr);
+                tlbflush();
+               /*
+                *  Fill out the scsi command
+                */
                bzero(&cmd, sizeof(cmd));
                bzero(&cmd, sizeof(cmd));
-               cmd.op_code     =       WRITE_BIG;
-               cmd.addr_3      =       (blknum & 0xff000000) >> 24;
-               cmd.addr_2      =       (blknum & 0xff0000) >> 16;
-               cmd.addr_1      =       (blknum & 0xff00) >> 8;
-               cmd.addr_0      =       blknum & 0xff;
-               cmd.length2     =       (blkcnt & 0xff00) >> 8;
-               cmd.length1     =       (blkcnt & 0xff);
-               /*******************************************************\
-               * Fill out the scsi_xfer structure                      *
-               *       Note: we cannot sleep as we may be an interrupt *
-               \*******************************************************/
+               cmd.op_code = WRITE_BIG;
+               cmd.addr_3 = (blknum & 0xff000000) >> 24;
+               cmd.addr_2 = (blknum & 0xff0000) >> 16;
+               cmd.addr_1 = (blknum & 0xff00) >> 8;
+               cmd.addr_0 = blknum & 0xff;
+               cmd.length2 = (blkcnt & 0xff00) >> 8;
+               cmd.length1 = (blkcnt & 0xff);
+               /*
+                * Fill out the scsi_xfer structure
+                *    Note: we cannot sleep as we may be an interrupt
+                * don't use scsi_scsi_cmd() as it may want 
+                * to wait for an xs.
+                */
                bzero(xs, sizeof(sx));
                bzero(xs, sizeof(sx));
-               xs->flags       |=      SCSI_NOMASK|SCSI_NOSLEEP|INUSE;
-               xs->adapter     =       sd->ctlr;
-               xs->targ        =       sd->targ;
-               xs->lu          =       sd->lu;
-               xs->retries     =       SD_RETRIES;
-               xs->timeout     =       10000;/* 10000 millisecs for a disk !*/
-               xs->cmd         =       (struct scsi_generic *)&cmd;
-               xs->cmdlen      =       sizeof(cmd);
-               xs->resid       =       blkcnt * 512;
-               xs->when_done   =       0;
-               xs->done_arg    =       unit;
-               xs->done_arg2   =       (int)xs;
-               xs->error       =       XS_NOERROR;
-               xs->bp          =       0;
-               xs->data        =       (u_char *)CADDR1;
-               xs->datalen     =       blkcnt * 512;
-
-               /*******************************************************\
-               * Pass all this info to the scsi driver.                *
-               \*******************************************************/
-               retval = (*(sd->sc_sw->scsi_cmd))(xs);
-               switch(retval)
-               {
-               case    SUCCESSFULLY_QUEUED:
-               case    HAD_ERROR:
-                       return(ENXIO); /* we said not to sleep! */
-               case    COMPLETE:
+               xs->flags |= SCSI_NOMASK | SCSI_NOSLEEP | INUSE;
+               xs->sc_link = sd->sc_link;
+               xs->retries = SD_RETRIES;
+               xs->timeout = 10000;    /* 10000 millisecs for a disk ! */
+               xs->cmd = (struct scsi_generic *) &cmd;
+               xs->cmdlen = sizeof(cmd);
+               xs->resid = blkcnt * 512;
+               xs->error = XS_NOERROR;
+               xs->bp = 0;
+               xs->data = (u_char *) CADDR1;
+               xs->datalen = blkcnt * 512;
+
+               /*
+                * Pass all this info to the scsi driver.
+                */
+               retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs);
+               switch (retval) {
+               case SUCCESSFULLY_QUEUED:
+               case HAD_ERROR:
+                       return (ENXIO);         /* we said not to sleep! */
+               case COMPLETE:
                        break;
                default:
                        break;
                default:
-                       return(ENXIO); /* we said not to sleep! */
+                       return (ENXIO);         /* we said not to sleep! */
                }
                }
-#else  NOT_TRUSTED
-               /* lets just talk about this first...*/
-               printf ("sd%d: dump addr 0x%x, blk %d\n",unit,addr,blknum);
-#endif NOT_TRUSTED
-               
-               if ((unsigned)addr % (1024*1024) == 0) printf("%d ", num/2048) ;
+
+               if ((unsigned) addr % (1024 * 1024) == 0)
+                       printf("%d ", num / 2048);
                /* update block count */
                /* update block count */
-               num -= MAXTRANSFER;
-               blknum += MAXTRANSFER ;
-               (int) addr += 512 * MAXTRANSFER;
+               num -= blkcnt;
+               blknum += blkcnt;
+               (int) addr += 512 * blkcnt;
 
                /* operator aborting dump? */
 
                /* operator aborting dump? */
-               if (sgetc(1))
-                       return(EINTR);
+               if ((c = sgetc(1)) && (c != 0x100))
+                       return (EINTR);
        }
        }
-       return(0);
+       return (0);
 }
 }
-#else  SCSIDUMP
-sddump()
-{
-       printf("\nsddump()        -- not implemented\n");
-       DELAY(20000000);        /* 20 seconds */
-       return(-1);
-}
-#endif SCSIDUMP
-