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