Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/scsipi Add support for "simplified direct" (aka RBC)...



details:   https://anonhg.NetBSD.org/src/rev/cac38a868a93
branches:  trunk
changeset: 543986:cac38a868a93
user:      drochner <drochner%NetBSD.org@localhost>
date:      Fri Mar 07 16:18:57 2003 +0000

description:
Add support for "simplified direct" (aka RBC) devices.

This reveals some ugly points in the sd driver, as
the PQUIRK_ONLYBIG flag (there are 6, 10, 12 and 16 byte
CDBs for r/w) and the handling of small/big mode
select/sense. This should be cleaned up.
Also the "long" struct disk_parms.disksize is worth
a thought...

diffstat:

 sys/dev/scsipi/sd_scsi.c |  78 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 76 insertions(+), 2 deletions(-)

diffs (127 lines):

diff -r 9f95aade63b6 -r cac38a868a93 sys/dev/scsipi/sd_scsi.c
--- a/sys/dev/scsipi/sd_scsi.c  Fri Mar 07 15:17:44 2003 +0000
+++ b/sys/dev/scsipi/sd_scsi.c  Fri Mar 07 16:18:57 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sd_scsi.c,v 1.26 2002/10/04 03:43:06 soren Exp $       */
+/*     $NetBSD: sd_scsi.c,v 1.27 2003/03/07 16:18:57 drochner Exp $    */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sd_scsi.c,v 1.26 2002/10/04 03:43:06 soren Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd_scsi.c,v 1.27 2003/03/07 16:18:57 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,6 +88,10 @@
         "",         "",                 ""},
        {T_OPTICAL, T_REMOV,
         "",         "",                 ""},
+       {T_SIMPLE_DIRECT, T_FIXED,
+        "",         "",                 ""},
+       {T_SIMPLE_DIRECT, T_REMOV,
+        "",         "",                 ""},
 };
 
 struct sd_scsibus_mode_sense_data {
@@ -102,6 +106,8 @@
                    struct disk_parms *, int));
 static int     sd_scsibus_get_optparms __P((struct sd_softc *,
                    struct disk_parms *, int));
+static int     sd_scsibus_get_simplifiedparms __P((struct sd_softc *,
+                   struct disk_parms *, int));
 static int     sd_scsibus_flush __P((struct sd_softc *, int));
 static int     sd_scsibus_getcache __P((struct sd_softc *, int *));
 static int     sd_scsibus_setcache __P((struct sd_softc *, int));
@@ -156,6 +162,10 @@
        if (periph->periph_version == 0)
                sd->flags |= SDF_ANCIENT;
 
+       if (sd->type == T_SIMPLE_DIRECT)
+               periph->periph_quirks |=
+                       (PQUIRK_ONLYBIG | PQUIRK_NOBIGMODESENSE);
+
        sdattach(parent, sd, periph, &sd_scsibus_ops);
 }
 
@@ -230,6 +240,67 @@
        return (SDGP_RESULT_OK);
 }
 
+static int
+sd_scsibus_get_simplifiedparms(sd, dp, flags)
+       struct sd_softc *sd;
+       struct disk_parms *dp;
+       int flags;
+{
+       struct {
+               struct scsipi_mode_header header;
+               /* no block descriptor */
+               u_int8_t pg_code; /* page code (should be 6) */
+               u_int8_t pg_length; /* page length (should be 11) */
+               u_int8_t wcd; /* bit0: cache disable */
+               u_int8_t lbs[2]; /* logical block size */
+               u_int8_t size[5]; /* number of log. blocks */
+               u_int8_t pp; /* power/performance */
+               u_int8_t flags;
+               u_int8_t resvd;
+       } scsipi_sense;
+       u_long sectors;
+       int error;
+
+       /*
+        * scsipi_size (ie "read capacity") and mode sense page 6
+        * give the same information. Do both for now, and check
+        * for consistency.
+        * XXX probably differs for removable media
+        */
+       dp->blksize = 512;
+       if ((sectors = scsipi_size(sd->sc_periph, flags)) == 0)
+               return (SDGP_RESULT_OFFLINE);           /* XXX? */
+
+       error = scsipi_mode_sense(sd->sc_periph, SMS_DBD, 6,
+           &scsipi_sense.header, sizeof(scsipi_sense),
+           flags | XS_CTL_DATA_ONSTACK, SDRETRIES, 6000);
+
+       if (error != 0)
+               return (SDGP_RESULT_OFFLINE);           /* XXX? */
+
+       dp->blksize = _2btol(scsipi_sense.lbs);
+       if (dp->blksize == 0) 
+               dp->blksize = 512;
+
+       /*
+        * Create a pseudo-geometry.
+        */
+       dp->heads = 64;
+       dp->sectors = 32;
+       dp->cyls = sectors / (dp->heads * dp->sectors);
+       /* XXX disksize is only a "long" currently */
+       dp->disksize = /* XXX _5btol */
+               (_3btol(scsipi_sense.size) << 16)
+               | (_2btol(&scsipi_sense.size[3]));
+       if (dp->disksize != sectors) {
+               printf("RBC size: mode sense=%ld, get cap=%ld\n",
+                      dp->disksize, sectors);
+               dp->disksize = sectors;
+       }
+
+       return (SDGP_RESULT_OK);
+}
+
 /*
  * Get the scsi driver to send a full inquiry to the * device and use the
  * results to fill out the disk parameter structure.
@@ -254,6 +325,9 @@
        if (sd->type == T_OPTICAL)
                return (sd_scsibus_get_optparms(sd, dp, flags));
 
+       if (sd->type == T_SIMPLE_DIRECT)
+               return (sd_scsibus_get_simplifiedparms(sd, dp, flags));
+
        if ((error = sd_scsibus_mode_sense(sd, &scsipi_sense, page = 4,
            flags)) == 0) {
                SC_DEBUG(sd->sc_periph, SCSIPI_DB3,



Home | Main Index | Thread Index | Old Index