Merge in various pieces of current NetBSD scsi code, including but not limited
authordownsj <downsj@openbsd.org>
Mon, 14 Apr 1997 04:09:03 +0000 (04:09 +0000)
committerdownsj <downsj@openbsd.org>
Mon, 14 Apr 1997 04:09:03 +0000 (04:09 +0000)
to:

* New changer driver.
* Better optical support.
* Different `done' semantics.
* New quirks for SCSI QIC tape driver, SCSI floppy drives.
* Better support for SCSI-I devices.

Everybody needs to test this.

12 files changed:
sys/scsi/cd.c
sys/scsi/ch.c
sys/scsi/scsi_all.h
sys/scsi/scsi_base.c
sys/scsi/scsi_debug.h
sys/scsi/scsi_disk.h
sys/scsi/scsi_ioctl.c
sys/scsi/scsi_tape.h
sys/scsi/scsiconf.c
sys/scsi/scsiconf.h
sys/scsi/sd.c
sys/scsi/st.c

index 0bb33ae..963b0c6 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: cd.c,v 1.22 1997/03/29 23:54:20 briggs Exp $  */
-/*     $NetBSD: cd.c,v 1.92 1996/05/05 19:52:50 christos Exp $ */
+/*     $OpenBSD: cd.c,v 1.23 1997/04/14 04:09:03 downsj Exp $  */
+/*     $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
 
 /*
- * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
+ * Copyright (c) 1994, 1995, 1997 Charles M. Hannum.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -111,7 +111,7 @@ void        cdunlock __P((struct cd_softc *));
 void   cdstart __P((void *));
 void   cdminphys __P((struct buf *));
 void   cdgetdisklabel __P((dev_t, struct cd_softc *));
-int    cddone __P((struct scsi_xfer *, int));
+void   cddone __P((struct scsi_xfer *));
 u_long cd_size __P((struct cd_softc *, int));
 int    cd_get_mode __P((struct cd_softc *, struct cd_mode_data *, int));
 int    cd_set_mode __P((struct cd_softc *, struct cd_mode_data *));
@@ -642,17 +642,14 @@ cdstart(v)
        }
 }
 
-int
-cddone(xs, complete)
+void
+cddone(xs)
        struct scsi_xfer *xs;
-       int complete;
 {
        struct cd_softc *cd = xs->sc_link->device_softc;
 
-       if (complete && (xs->bp != NULL))
-               disk_unbusy(&cd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid));
-
-       return (0);
+       if (xs->bp != NULL)
+               disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid);
 }
 
 void
@@ -1305,7 +1302,7 @@ cd_read_subchannel(cd, mode, format, track, data, len)
        _lto2b(len, scsi_cmd.data_len);
        return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
            sizeof(struct scsi_read_subchannel), (u_char *)data, len,
-           CDRETRIES, 5000, NULL, SCSI_DATA_IN);
+           CDRETRIES, 5000, NULL, SCSI_DATA_IN||SCSI_SILENT);
 }
 
 /*
index b4f6be9..c7fdea0 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: ch.c,v 1.6 1996/08/12 10:21:41 deraadt Exp $  */
-/*     $NetBSD: ch.c,v 1.21 1996/04/19 00:02:29 christos Exp $ */
+/*     $OpenBSD: ch.c,v 1.7 1997/04/14 04:09:05 downsj Exp $   */
+/*     $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $  */
 
 /*
- * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
+ * Copyright (c) 1996, 1997 Jason R. Thorpe <thorpej@and.com>
  * All rights reserved.
  *
  * Partially based on an autochanger driver written by Stefan Grefen
@@ -48,6 +48,7 @@
 #include <sys/device.h>
 #include <sys/malloc.h>
 #include <sys/conf.h>
+#include <sys/fcntl.h>
 
 #include <scsi/scsi_all.h>
 #include <scsi/scsi_changer.h>
@@ -81,6 +82,12 @@ struct ch_softc {
        u_int8_t        sc_exchangemask[4];
 
        int             flags;          /* misc. info */
+
+       /*
+        * Quirks; see below.
+        */
+       int             sc_settledelay; /* delay for settle */
+
 };
 
 /* sc_flags */
@@ -114,6 +121,21 @@ int        ch_position __P((struct ch_softc *, struct changer_position *));
 int    ch_usergetelemstatus __P((struct ch_softc *, int, u_int8_t *));
 int    ch_getelemstatus __P((struct ch_softc *, int, int, caddr_t, size_t));
 int    ch_get_params __P((struct ch_softc *, int));
+void   ch_get_quirks __P((struct ch_softc *, struct scsi_inquiry_data *));
+
+/*
+ * SCSI changer quirks.
+ */
+struct chquirk {
+       struct  scsi_inquiry_pattern cq_match; /* device id pattern */
+       int     cq_settledelay; /* settle delay, in seconds */
+};
+
+struct chquirk chquirks[] = {
+       {{T_CHANGER, T_REMOV,
+         "SPECTRA",    "9000",         "0200"},
+        75},
+};
 
 int
 chmatch(parent, match, aux)
@@ -147,6 +169,21 @@ chattach(parent, self, aux)
 
        printf("\n");
 
+       /*
+        * Find out our device's quirks.
+        */
+       ch_get_quirks(sc, sa->sa_inqbuf);
+
+       /*
+        * Some changers require a long time to settle out, to do
+        * tape inventory, for instance.
+        */
+       if (sc->sc_settledelay) {
+               printf("%s: waiting %d seconds for changer to settle...\n",
+                   sc->sc_dev.dv_xname, sc->sc_settledelay);
+               delay(1000000 * sc->sc_settledelay);
+       }
+
        /*
         * Get information about the device.  Note we can't use
         * interrupts yet.
@@ -154,18 +191,14 @@ chattach(parent, self, aux)
        if (ch_get_params(sc, SCSI_AUTOCONF))
                printf("%s: offline\n", sc->sc_dev.dv_xname);
        else {
-               printf("%s: %d slot%s, %d drive%s, %d picker%s",
+#define PLURAL(c)      (c) == 1 ? "" : "s"
+               printf("%s: %d slot%s, %d drive%s, %d picker%s, %d portal%s\n",
                    sc->sc_dev.dv_xname,
-                   sc->sc_counts[CHET_ST], (sc->sc_counts[CHET_ST] > 1) ?
-                   "s" : "",
-                   sc->sc_counts[CHET_DT], (sc->sc_counts[CHET_DT] > 1) ?
-                   "s" : "",
-                   sc->sc_counts[CHET_MT], (sc->sc_counts[CHET_MT] > 1) ?
-                   "s" : "");
-               if (sc->sc_counts[CHET_IE])
-                       printf(", %d portal%s", sc->sc_counts[CHET_IE],
-                           (sc->sc_counts[CHET_IE] > 1) ? "s" : "");
-               printf("\n");
+                   sc->sc_counts[CHET_ST], PLURAL(sc->sc_counts[CHET_ST]),
+                   sc->sc_counts[CHET_DT], PLURAL(sc->sc_counts[CHET_DT]),
+                   sc->sc_counts[CHET_MT], PLURAL(sc->sc_counts[CHET_MT]),
+                   sc->sc_counts[CHET_IE], PLURAL(sc->sc_counts[CHET_IE]));
+#undef PLURAL
 #ifdef CHANGER_DEBUG
                printf("%s: move mask: 0x%x 0x%x 0x%x 0x%x\n",
                    sc->sc_dev.dv_xname,
@@ -250,6 +283,21 @@ chioctl(dev, cmd, data, flags, p)
        struct ch_softc *sc = ch_cd.cd_devs[CHUNIT(dev)];
        int error = 0;
 
+       /*
+        * If this command can change the device's state, we must
+        * have the device open for writing.
+        */
+       switch (cmd) {
+       case CHIOGPICKER:
+       case CHIOGPARAMS:
+       case CHIOGSTATUS:
+               break;
+
+       default:
+               if ((flags & FWRITE) == 0)
+                       return (EBADF);
+       }
+
        switch (cmd) {
        case CHIOMOVE:
                error = ch_move(sc, (struct changer_move *)data);
@@ -637,3 +685,22 @@ ch_get_params(sc, scsiflags)
        sc->sc_link->flags |= SDEV_MEDIA_LOADED;
        return (0);
 }
+
+void
+ch_get_quirks(sc, inqbuf)
+       struct ch_softc *sc;
+       struct scsi_inquiry_data *inqbuf;
+{
+       struct chquirk *match;
+       int priority;
+
+       sc->sc_settledelay = 0;
+
+       match = (struct chquirk *)scsi_inqmatch(inqbuf,
+           (caddr_t)chquirks,
+           sizeof(chquirks) / sizeof(chquirks[0]),
+           sizeof(chquirks[0]), &priority);
+       if (priority != 0) {
+               sc->sc_settledelay = match->cq_settledelay;
+       }
+}
index c9492a5..746d6db 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsi_all.h,v 1.4 1996/07/02 20:18:49 deraadt Exp $    */
-/*     $NetBSD: scsi_all.h,v 1.7 1996/03/19 03:06:10 mycroft Exp $     */
+/*     $OpenBSD: scsi_all.h,v 1.5 1997/04/14 04:09:06 downsj Exp $     */
+/*     $NetBSD: scsi_all.h,v 1.10 1996/09/12 01:57:17 thorpej Exp $    */
 
 /*
  * SCSI general  interface description
 #define SCSI_CTL_LINK          0x01
 #define SCSI_CTL_FLAG          0x02
 #define SCSI_CTL_VENDOR                0xC0
-#define        SCSI_CMD_LUN            0xA0    /* these two should not be needed */
-#define        SCSI_CMD_LUN_SHIFT      5       /* LUN in the cmd is no longer SCSI */
+
+
+/*
+ * Some old SCSI devices need the LUN to be set in the top 3 bits of the
+ * second byte of the CDB.
+ */
+#define        SCSI_CMD_LUN_MASK       0xe0
+#define        SCSI_CMD_LUN_SHIFT      5
 
 
 struct scsi_generic {
@@ -176,8 +182,6 @@ struct scsi_changedef {
 #define        CHANGE_DEFINITION       0x40
 #define        MODE_SENSE_BIG          0x54
 #define        MODE_SELECT_BIG         0x55
-#define MOVE_MEDIUM            0xa5
-#define READ_ELEMENT_STATUS    0xb8
 
 /*
  * Sort of an extra one, for SCSI_RESET.
index ac52d48..42e47db 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: scsi_base.c,v 1.10 1996/06/16 03:07:19 downsj Exp $   */
-/*     $NetBSD: scsi_base.c,v 1.36 1996/05/03 19:48:20 christos Exp $  */
+/*     $OpenBSD: scsi_base.c,v 1.11 1997/04/14 04:09:07 downsj Exp $   */
+/*     $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $   */
 
 /*
- * Copyright (c) 1994, 1995 Charles Hannum.  All rights reserved.
+ * Copyright (c) 1994, 1995, 1997 Charles M. Hannum.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -14,7 +14,7 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *     This product includes software developed by Charles Hannum.
+ *     This product includes software developed by Charles M. Hannum.
  * 4. The name of the author may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
@@ -49,8 +49,6 @@
 #include <scsi/scsi_disk.h>
 #include <scsi/scsiconf.h>
 
-void scsi_error __P((struct scsi_xfer *, int));
-
 LIST_HEAD(xs_free_list, scsi_xfer) xs_free_list;
 
 static __inline struct scsi_xfer *scsi_make_xs __P((struct scsi_link *,
@@ -181,6 +179,14 @@ scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
        xs->timeout = timeout;
        xs->bp = bp;
 
+       /*
+        * Set the LUN in the CDB if we have an older device.  We also
+        * set it for more modern SCSI-II devices "just in case".
+        */
+       if ((sc_link->scsi_version & SID_ANSII) <= 2)
+               xs->cmd->bytes[0] |=
+                   ((sc_link->lun << SCSI_CMD_LUN_SHIFT) & SCSI_CMD_LUN_MASK);
+
        return xs;
 }
 
@@ -318,6 +324,7 @@ scsi_done(xs)
        struct scsi_xfer *xs;
 {
        struct scsi_link *sc_link = xs->sc_link;
+       struct buf *bp;
        int error;
 
        SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
@@ -341,23 +348,7 @@ scsi_done(xs)
                return;
        }
 
-       /*
-        * If the device has it's own done routine, call it first.
-        * If it returns a legit error value, return that, otherwise
-        * it wants us to continue with normal processing.
-        *
-        * Make sure the upper-level driver knows that this might not
-        * actually be the last time they hear from us.  We need to get
-        * status back.
-        */
-       if (sc_link->device->done) {
-               SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
-               error = (*sc_link->device->done)(xs, 0);
-               if (error == EJUSTRETURN)
-                       goto done;
-               SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
-       }
-       if (xs->bp == NULL) {
+       if (!((xs->flags & (SCSI_NOSLEEP | SCSI_POLL)) == SCSI_NOSLEEP)) {
                /*
                 * if it's a normal upper level request, then ask
                 * the upper level code to handle error checking
@@ -366,12 +357,14 @@ scsi_done(xs)
                wakeup(xs);
                return;
        }
+
        /*
         * Go and handle errors now.
         * If it returns ERESTART then we should RETRY
         */
 retry:
-       if (sc_err1(xs, 1) == ERESTART) {
+       error = sc_err1(xs, 1);
+       if (error == ERESTART) {
                switch ((*(sc_link->adapter->scsi_cmd)) (xs)) {
                case SUCCESSFULLY_QUEUED:
                        return;
@@ -382,7 +375,18 @@ retry:
                        goto retry;
                }
        }
-done:
+
+       bp = xs->bp;
+       if (bp) {
+               if (error) {
+                       bp->b_error = error;
+                       bp->b_flags |= B_ERROR;
+                       bp->b_resid = bp->b_bcount;
+               } else {
+                       bp->b_error = 0;
+                       bp->b_resid = xs->resid;
+               }
+       }
        if (sc_link->device->done) {
                /*
                 * Tell the device the operation is actually complete.
@@ -390,9 +394,11 @@ done:
                 * notification of the upper-level driver only; they
                 * won't be returning any meaningful information to us.
                 */
-               (void)(*sc_link->device->done)(xs, 1);
+               (*sc_link->device->done)(xs);
        }
        scsi_free_xs(xs, SCSI_NOSLEEP);
+       if (bp)
+               biodone(bp);
 }
 
 int
@@ -417,14 +423,19 @@ retry:
         * 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 processing
-        * and the buffer code both expect us to return straight
-        * to them, so as soon as the command is queued, return
+        * If we have a SCSI_NOSLEEP (typically because we have a buf)
+        * we just return.  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.
         */
        switch ((*(xs->sc_link->adapter->scsi_cmd)) (xs)) {
        case SUCCESSFULLY_QUEUED:
-               if (xs->bp)
+               if ((xs->flags & (SCSI_NOSLEEP | SCSI_POLL)) == SCSI_NOSLEEP)
                        return EJUSTRETURN;
+#ifdef DIAGNOSTIC
+               if (xs->flags & SCSI_NOSLEEP)
+                       panic("scsi_execute_xs: NOSLEEP and POLL");
+#endif
                s = splbio();
                while ((xs->flags & ITSDONE) == 0)
                        tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0);
@@ -561,30 +572,9 @@ sc_err1(xs, async)
                break;
        }
 
-       scsi_error(xs, error);
        return error;
 }
 
-void
-scsi_error(xs, error)
-       struct scsi_xfer *xs;
-       int error;
-{
-       struct buf *bp = xs->bp;
-
-       if (bp) {
-               if (error) {
-                       bp->b_error = error;
-                       bp->b_flags |= B_ERROR;
-                       bp->b_resid = bp->b_bcount;
-               } else {
-                       bp->b_error = 0;
-                       bp->b_resid = xs->resid;
-               }
-               biodone(bp);
-       }
-}
-
 /*
  * Look at the returned sense and act on the error, determining
  * the unix error number to pass back.  (0 = report no error)
index b190ade..b46012c 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsi_debug.h,v 1.4 1996/11/28 13:20:36 niklas Exp $   */
-/*     $NetBSD: scsi_debug.h,v 1.5 1994/12/28 19:43:00 mycroft Exp $   */
+/*     $OpenBSD: scsi_debug.h,v 1.5 1997/04/14 04:09:08 downsj Exp $   */
+/*     $NetBSD: scsi_debug.h,v 1.7 1996/10/12 23:23:16 christos Exp $  */
 
 /*
  * Written by Julian Elischer (julian@tfs.com)
index 614e40f..0028126 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsi_disk.h,v 1.5 1996/10/31 01:09:23 niklas Exp $    */
-/*     $NetBSD: scsi_disk.h,v 1.9 1996/03/19 03:07:02 mycroft Exp $    */
+/*     $OpenBSD: scsi_disk.h,v 1.6 1997/04/14 04:09:09 downsj Exp $    */
+/*     $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $  */
 
 /*
  * SCSI interface description
@@ -176,41 +176,34 @@ union disk_pages {
                u_int8_t reserved3;
        } rigid_geometry;
        struct page_flex_geometry {
-          u_char pg_code;              /* page code (should be 5) */
-          u_char pg_length;            /* page length (should be 0x1e) */
-          u_char xfr_rate1;
-          u_char xfr_rate0;
-          u_char nheads;               /* number of heads */
-          u_char ph_sec_t;             /* physical sectors per track */
-          u_char bytes_s_1;            /* bytes per sector (MSB) */
-          u_char bytes_s_0;            /* bytes per sector (LSB) */
-          u_char ncyl_1;               /* number of cylinders (MSB) */
-          u_char ncyl_0;               /* number of cylinders (LSB) */
-          u_char st_cyl_wp_1;          /* starting cyl., write precomp (MSB) */
-          u_char st_cyl_wp_0;          /* starting cyl., write precomp (LSB) */
-          u_char st_cyl_rwc_1;         /* starting cyl., red. write cur (MSB) */
-          u_char st_cyl_rwc_0;         /* starting cyl., red. write cur (LSB) */
-          u_char driv_step_1;          /* drive step rate (MSB) */
-          u_char driv_step_0;          /* drive step rate (LSB) */
-          u_char driv_step_w;          /* drive step pulse width */
-          u_char head_settle_1;        /* head settle delay (MSB) */
-          u_char head_settle_0;        /* head settle delay (LSB) */
-          u_char motor_on;             /* motor on delay */
-          u_char motor_off;            /* motor off delay */
-          u_char flags;                /* various flags */
-#define MO     0x20                    /* motor on (pin 16)? */
-#define SSN    0x40                    /* start at sector 1  */
-#define TRDY   0x20                    /* RDY (pin 34) valid */
-          u_char step_p_cyl;           /* step pulses per cylinder */
-          u_char write_pre;            /* write precompensation */
-          u_char head_load;            /* head load delay */
-          u_char head_unload;          /* head unload delay */
-          u_char pin_34_2;             /* pin 34 (6) and pin 2 (7/11) definition */
-          u_char pin_4_1;              /* pin 4 (8/9) and pin 1 (13) definition */
-          u_char reserved1;
-          u_char reserved2;
-          u_char reserved3;
-          u_char reserved4;
+               u_int8_t pg_code;       /* page code (should be 5) */
+               u_int8_t pg_length;     /* page length (should be 0x1e) */
+               u_int8_t xfr_rate[2];
+               u_int8_t nheads;        /* number of heads */
+               u_int8_t ph_sec_tr;     /* physical sectors per track */
+               u_int8_t bytes_s[2];    /* bytes per sector */
+               u_int8_t ncyl[2];       /* number of cylinders */
+               u_int8_t st_cyl_wp[2];  /* start cyl., write precomp */
+               u_int8_t st_cyl_rwc[2]; /* start cyl., red. write cur */
+               u_int8_t driv_step[2];  /* drive step rate */
+               u_int8_t driv_step_w;   /* drive step pulse width */
+               u_int8_t head_settle[2];/* head settle delay */
+               u_int8_t motor_on;      /* motor on delay */
+               u_int8_t motor_off;     /* motor off delay */
+               u_int8_t flags;         /* various flags */
+#define MOTOR_ON               0x20    /* motor on (pin 16)? */
+#define START_AT_SECTOR_1      0x40    /* start at sector 1  */
+#define READY_VALID            0x20    /* RDY (pin 34) valid */
+               u_int8_t step_p_cyl;    /* step pulses per cylinder */
+               u_int8_t write_pre;     /* write precompensation */
+               u_int8_t head_load;     /* head load delay */
+               u_int8_t head_unload;   /* head unload delay */
+               u_int8_t pin_34_2;      /* pin 34 (6) pin 2 (7/11) definition */
+               u_int8_t pin_4_1;       /* pin 4 (8/9) pin 1 (13) definition */
+               u_int8_t reserved1;
+               u_int8_t reserved2;
+               u_int8_t reserved3;
+               u_int8_t reserved4;
        } flex_geometry;
 };
 
index c9c5625..f1fc067 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsi_ioctl.c,v 1.6 1996/08/13 00:06:24 niklas Exp $   */
-/*     $NetBSD: scsi_ioctl.c,v 1.20 1996/02/14 21:47:22 christos Exp $ */
+/*     $OpenBSD: scsi_ioctl.c,v 1.7 1997/04/14 04:09:11 downsj Exp $   */
+/*     $NetBSD: scsi_ioctl.c,v 1.23 1996/10/12 23:23:17 christos Exp $ */
 
 /*
  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
@@ -46,6 +46,7 @@
 #include <sys/buf.h>
 #include <sys/proc.h>
 #include <sys/device.h>
+#include <sys/fcntl.h>
 
 #include <scsi/scsi_all.h>
 #include <scsi/scsiconf.h>
@@ -289,6 +290,16 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, flag, p)
 
        SC_DEBUG(sc_link, SDEV_DB2, ("scsi_do_ioctl(0x%lx)\n", cmd));
 
+       /* Check for the safe-ness of this request. */
+       switch (cmd) {
+       case SCIOCIDENTIFY:
+               break;
+
+       default:
+               if ((flag & FWRITE) == 0)
+                       return EBADF;
+       }
+
        switch(cmd) {
        case SCIOCCOMMAND: {
                scsireq_t *screq = (scsireq_t *)addr;
index 3ac4bc1..6b61387 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsi_tape.h,v 1.5 1996/10/31 01:09:24 niklas Exp $    */
-/*     $NetBSD: scsi_tape.h,v 1.8 1996/03/19 03:07:36 mycroft Exp $    */
+/*     $OpenBSD: scsi_tape.h,v 1.6 1997/04/14 04:09:13 downsj Exp $    */
+/*     $NetBSD: scsi_tape.h,v 1.9 1996/05/24 02:04:47 thorpej Exp $    */
 
 /*
  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
@@ -210,6 +210,7 @@ struct block_desc_cipher {
                 0x15    1     45434       RLL   CS    ECMA TC17    4
                 0x16   48     10000       MFM   C     X3.193-1990  1
                 0x17   48     42500       MFM   C     X3B5/91-174  1
+               0x45   73     67733       RLL   C     QIC3095
 
                 where Code means:
                 NRZI Non Return to Zero, change on ones
@@ -245,5 +246,6 @@ struct block_desc_cipher {
 #define QIC_1320       0x12
 #define DDS            0x13
 #define DAT_1          0x13
+#define QIC_3095       0x45
 
 #endif /* _SCSI_TAPE_H_ */
index 2f4859c..822ffaf 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: scsiconf.c,v 1.27 1997/04/02 08:01:56 deraadt Exp $   */
+/*     $OpenBSD: scsiconf.c,v 1.28 1997/04/14 04:09:14 downsj Exp $    */
 /*     $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $       */
 
 /*
@@ -332,6 +332,8 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
         "NEC     ", "CD-ROM DRIVE:210", "1.0"},  SDEV_NOLUNS},
        {{T_CDROM, T_REMOV,
         "NEC     ", "CD-ROM DRIVE:841", ""},     SDEV_NOLUNS},
+       {{T_CDROM, T_REMOV,
+        "PIONEER ", "CD-ROM DR-124X  ", "1.01"}, SDEV_NOLUNS},
        {{T_CDROM, T_REMOV,
         "SONY    ", "CD-ROM CDU-541  ", ""},     SDEV_NOLUNS},
        {{T_CDROM, T_REMOV,
@@ -361,7 +363,11 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
        {{T_DIRECT, T_FIXED,
         "DEC     ", "RZ55     (C) DEC", ""},     SDEV_AUTOSAVE},
        {{T_DIRECT, T_FIXED,
-        "EMULEX  ", "MD21/S2     ESDI", "A00"},  SDEV_FORCELUNS},
+        "EMULEX  ", "MD21/S2     ESDI", "A00"},  SDEV_FORCELUNS|SDEV_AUTOSAVE},
+       {{T_DIRECT, T_FIXED,
+        "IBMRAID ", "0662S",            ""},     SDEV_AUTOSAVE},
+       {{T_DIRECT, T_FIXED,
+        "IBM     ", "0663H",            ""},     SDEV_AUTOSAVE},
        {{T_DIRECT, T_FIXED,
         "MAXTOR  ", "XT-3280         ", ""},     SDEV_NOLUNS},
        {{T_DIRECT, T_FIXED,
@@ -392,6 +398,8 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
         "QUANTUM ", "PD210S   SUN0207", ""},     SDEV_NOLUNS},
        {{T_DIRECT, T_FIXED,
         "RODIME  ", "RO3000S         ", ""},     SDEV_NOLUNS},
+       {{T_DIRECT, T_FIXED,
+        "SEAGATE ", "ST125N          ", ""},     SDEV_NOLUNS},
        {{T_DIRECT, T_FIXED,
         "SEAGATE ", "ST157N          ", ""},     SDEV_NOLUNS},
        {{T_DIRECT, T_FIXED,
@@ -406,6 +414,9 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
         "IOMEGA", "ZIP 100",            ""},     SDEV_NOMODESENSE},
        {{T_DIRECT, T_FIXED,
         "IBM", "0661467",               "G"},    SDEV_NOMODESENSE},
+       /* Letting the motor run kills floppy drives and disks quit fast. */
+       {{T_DIRECT, T_REMOV,
+        "TEAC", "FC-1",                 ""},     SDEV_NOSTARTUNIT},
 
        /* XXX: QIC-36 tape behind Emulex adapter.  Very broken. */
        {{T_SEQUENTIAL, T_REMOV,
@@ -631,6 +642,7 @@ scsi_probedev(scsi, target, lun)
        if ((inqbuf.version & SID_ANSII) == 0 &&
            (sc_link->quirks & SDEV_FORCELUNS) == 0)
                sc_link->quirks |= SDEV_NOLUNS;
+       sc_link->scsi_version = inqbuf.version;
 
        if ((sc_link->quirks & SDEV_NOLUNS) == 0)
                scsi->moreluns |= (1 << target);
index bf3c603..d0a4607 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: scsiconf.h,v 1.11 1997/01/18 16:18:32 briggs Exp $    */
-/*     $NetBSD: scsiconf.h,v 1.29 1996/03/19 03:07:50 mycroft Exp $    */
+/*     $OpenBSD: scsiconf.h,v 1.12 1997/04/14 04:09:15 downsj Exp $    */
+/*     $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $    */
 
 /*
  * Copyright (c) 1993, 1994, 1995 Charles Hannum.  All rights reserved.
@@ -125,7 +125,7 @@ struct scsi_device {
         * we're simply notifying the upper-level driver that the command
         * is complete and expect no status back.
         */
-       int     (*done)  __P((struct scsi_xfer *, int));
+       void    (*done)  __P((struct scsi_xfer *));
 };
 
 /*
@@ -135,6 +135,7 @@ struct scsi_device {
  * as well.
  */
 struct scsi_link {
+       u_int8_t scsi_version;          /* SCSI-I, SCSI-II, etc. */
        u_int8_t scsibus;               /* the Nth scsibus */
        u_int8_t target;                /* targ of this dev */
        u_int8_t lun;                   /* lun of this dev */
@@ -155,6 +156,7 @@ struct scsi_link {
 #define        SDEV_NOLUNS             0x04    /* does not grok LUNs */
 #define        SDEV_FORCELUNS          0x08    /* prehistoric drive/ctlr groks LUNs */
 #define SDEV_NOMODESENSE       0x10    /* removable media/optical drives */
+#define SDEV_NOSTARTUNIT       0x20    /* do not issue start unit requests in sd.c */
        u_int8_t inquiry_flags;         /* copy of flags from probe INQUIRY */
        struct  scsi_device *device;    /* device entry points etc. */
        void    *device_softc;          /* needed for call to foo_start */
index 8a5331d..fa818ef 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: sd.c,v 1.22 1997/01/04 08:50:21 deraadt Exp $ */
-/*     $NetBSD: sd.c,v 1.100.4.1 1996/06/04 23:14:08 thorpej Exp $     */
+/*     $OpenBSD: sd.c,v 1.23 1997/04/14 04:09:16 downsj Exp $  */
+/*     $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
 
 /*
- * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
+ * Copyright (c) 1994, 1995, 1997 Charles M. Hannum.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -98,6 +98,13 @@ struct sd_softc {
                u_long disksize;        /* total number sectors */
        } params;
        struct buf buf_queue;
+       u_int8_t type;
+};
+
+struct scsi_mode_sense_data {
+       struct scsi_mode_header header;
+       struct scsi_blk_desc blk_desc;
+       union disk_pages pages;
 };
 
 int    sdmatch __P((struct device *, void *, void *));
@@ -107,9 +114,12 @@ void       sdunlock __P((struct sd_softc *));
 void   sdminphys __P((struct buf *));
 void   sdgetdisklabel __P((dev_t, struct sd_softc *));
 void   sdstart __P((void *));
-int    sddone __P((struct scsi_xfer *, int));
+void   sddone __P((struct scsi_xfer *));
 int    sd_reassign_blocks __P((struct sd_softc *, u_long));
+int    sd_get_optparms __P((struct sd_softc *, int, struct disk_parms *));
 int    sd_get_parms __P((struct sd_softc *, int));
+static int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *,
+                             int, int));
 
 struct cfattach sd_ca = {
        sizeof(struct sd_softc), sdmatch, sdattach
@@ -162,6 +172,7 @@ sdattach(parent, self, aux)
        struct device *parent, *self;
        void *aux;
 {
+       int error;
        struct sd_softc *sd = (void *)self;
        struct disk_parms *dp = &sd->params;
        struct scsibus_attach_args *sa = aux;
@@ -173,6 +184,7 @@ sdattach(parent, self, aux)
         * Store information needed to contact our base driver
         */
        sd->sc_link = sc_link;
+       sd->type = (sa->sa_inqbuf->device & SID_TYPE);
        sc_link->device = &sd_switch;
        sc_link->device_softc = sd;
        if (sc_link->openings > SDOUTSTANDING)
@@ -200,9 +212,15 @@ sdattach(parent, self, aux)
         */
        printf("\n");
        printf("%s: ", sd->sc_dev.dv_xname);
-       if (scsi_start(sd->sc_link, SSS_START,
-           SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT) ||
-           sd_get_parms(sd, SCSI_AUTOCONF) != 0)
+
+       if ((sd->sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {
+               error = scsi_start(sd->sc_link, SSS_START,
+                                  SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST |
+                                  SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);
+       } else
+               error = 0;
+
+       if (error || sd_get_parms(sd, SCSI_AUTOCONF) != 0)
                printf("drive offline\n");
        else
                printf("%ldMB, %d cyl, %d head, %d sec, %d bytes/sec\n",
@@ -295,11 +313,14 @@ sdopen(dev, flag, fmt, p)
                        goto bad3;
 
                /* Start the pack spinning if necessary. */
-               error = scsi_start(sc_link, SSS_START,
-                                  SCSI_IGNORE_ILLEGAL_REQUEST |
-                                  SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);
-               if (error)
-                       goto bad3;
+               if ((sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {
+                       error = scsi_start(sc_link, SSS_START,
+                                          SCSI_IGNORE_ILLEGAL_REQUEST |
+                                          SCSI_IGNORE_MEDIA_CHANGE |
+                                          SCSI_SILENT);
+                       if (error)
+                               goto bad3;
+               }
 
                sc_link->flags |= SDEV_OPEN;
 
@@ -600,7 +621,7 @@ sdstart(v)
                 */
                error = scsi_scsi_cmd(sc_link, cmdp, cmdlen,
                    (u_char *)bp->b_data, bp->b_bcount,
-                   SDRETRIES, 10000, bp, SCSI_NOSLEEP |
+                   SDRETRIES, 60000, bp, SCSI_NOSLEEP |
                    ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT));
                if (error) {
                        disk_unbusy(&sd->sc_dk, 0);
@@ -610,17 +631,14 @@ sdstart(v)
        }
 }
 
-int
-sddone(xs, complete)
+void
+sddone(xs)
        struct scsi_xfer *xs;
-       int complete;
 {
        struct sd_softc *sd = xs->sc_link->device_softc;
 
-       if (complete && (xs->bp != NULL))
+       if (xs->bp != NULL)
                disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid));
-
-       return (0);
 }
 
 void
@@ -792,7 +810,10 @@ sdgetdisklabel(dev, sd)
                /* as long as it's not 0 - readdisklabel divides by it (?) */
        }
 
-       strncpy(lp->d_typename, "SCSI disk", 16);
+       if (sd->type == T_OPTICAL)
+               strncpy(lp->d_typename, "SCSI optical", 16);
+       else
+               strncpy(lp->d_typename, "SCSI disk", 16);
        lp->d_type = DTYPE_SCSI;
        strncpy(lp->d_packname, "fictitious", 16);
        lp->d_secperunit = sd->params.disksize;
@@ -844,16 +865,41 @@ sd_reassign_blocks(sd, blkno)
            5000, NULL, SCSI_DATA_OUT);
 }
 
-/*
- * Get the scsi driver to send a full inquiry to the * device and use the
- * results to fill out the disk parameter structure.
- */
+
+static int
+sd_mode_sense(sd, scsi_sense, page, flags)
+       struct sd_softc *sd;
+       struct scsi_mode_sense_data *scsi_sense;
+       int page, flags;
+{
+       struct scsi_mode_sense scsi_cmd;
+
+       /*
+        * Make sure the sense buffer is clean before we do
+        * the mode sense, so that checks for bogus values of
+        * 0 will work in case the mode sense fails.
+        */
+       bzero(scsi_sense, sizeof(*scsi_sense));
+
+       bzero(&scsi_cmd, sizeof(scsi_cmd));
+       scsi_cmd.opcode = MODE_SENSE;
+       scsi_cmd.page = page;
+       scsi_cmd.length = 0x20;
+       /*
+        * If the command worked, use the results to fill out
+        * the parameter structure
+        */
+       return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
+           sizeof(scsi_cmd), (u_char *)scsi_sense, sizeof(*scsi_sense),
+           SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT);
+}
+
 int
-sd_get_parms(sd, flags)
+sd_get_optparms(sd, flags, dp)
        struct sd_softc *sd;
        int flags;
+       struct disk_parms *dp;
 {
-       struct disk_parms *dp = &sd->params;
        struct scsi_mode_sense scsi_cmd;
        struct scsi_mode_sense_data {
                struct scsi_mode_header header;
@@ -861,26 +907,67 @@ sd_get_parms(sd, flags)
                union disk_pages pages;
        } scsi_sense;
        u_long sectors;
+       int error;
 
-       if ((sd->sc_link->quirks & SDEV_NOMODESENSE) != 0)
-               goto fake_it;
-
-       /*
-        * do a "mode sense page 4"
+       dp->blksize = 512;
+       if ((sectors = scsi_size(sd->sc_link, flags)) == 0)
+               return 1;
+
+       /* XXX
+        * It is better to get the following params from the
+        * mode sense page 6 only (optical device parameter page).
+        * However, there are stupid optical devices which does NOT
+        * support the page 6. Ghaa....
         */
-       bzero(&scsi_sense, sizeof(scsi_sense));
        bzero(&scsi_cmd, sizeof(scsi_cmd));
        scsi_cmd.opcode = MODE_SENSE;
-       scsi_cmd.page = 4;
-       scsi_cmd.length = 0x20;
+       scsi_cmd.page = 0x3f;   /* all pages */
+       scsi_cmd.length = sizeof(struct scsi_mode_header) +
+           sizeof(struct scsi_blk_desc);
+
+       if ((error = scsi_scsi_cmd(sd->sc_link,  
+           (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd),  
+           (u_char *)&scsi_sense, sizeof(scsi_sense), SDRETRIES,
+           6000, NULL, flags | SCSI_DATA_IN)) != 0)
+               return error;
+
+       dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
+       if (dp->blksize == 0) 
+               dp->blksize = 512;
 
        /*
-        * If the command worked, use the results to fill out
-        * the parameter structure
+        * Create a pseudo-geometry.
         */
-       if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
-           sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
-           SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN) == 0) {
+       dp->heads = 64;
+       dp->sectors = 32;
+       dp->cyls = sectors / (dp->heads * dp->sectors);
+       dp->disksize = sectors;
+
+       return 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(sd, flags)
+       struct sd_softc *sd;
+       int flags;
+{
+       struct disk_parms *dp = &sd->params;
+       struct scsi_mode_sense_data scsi_sense;
+       u_long sectors;
+       int page;
+       int error;
+
+       if (sd->type == T_OPTICAL) {
+               if ((error = sd_get_optparms(sd, flags, dp)) != 0)
+                       sd->sc_link->flags &= ~SDEV_MEDIA_LOADED;
+               return error;
+       }
+
+       if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) {
                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),
@@ -899,11 +986,8 @@ sd_get_parms(sd, flags)
                dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl);
                dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
 
-               if (dp->heads == 0 || dp->cyls == 0) {
-                       printf("%s: mode sense (4) returned nonsense",
-                           sd->sc_dev.dv_xname);
+               if (dp->heads == 0 || dp->cyls == 0)
                        goto fake_it;
-               }
 
                if (dp->blksize == 0)
                        dp->blksize = 512;
@@ -912,48 +996,40 @@ sd_get_parms(sd, flags)
                dp->disksize = sectors;
                sectors /= (dp->heads * dp->cyls);
                dp->sectors = sectors;  /* XXX dubious on SCSI */
+
                return 0;
-       } else {
-               /*
-                * do a "mode sense page 5"
-                */
-               scsi_cmd.opcode = MODE_SENSE;
-               scsi_cmd.page = 5;
-               scsi_cmd.length = 0x20;
-               if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
-                   sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
-                   SDRETRIES, 6000, NULL,
-                   flags | SCSI_DATA_IN | SCSI_SILENT) == 0) {
-                       dp->heads = scsi_sense.pages.flex_geometry.nheads;
-                       dp->cyls =
-                           scsi_sense.pages.flex_geometry.ncyl_1 * 256 +
-                           scsi_sense.pages.flex_geometry.ncyl_0;
-                       dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
-                       dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_t;
-                       dp->disksize = dp->heads * dp->cyls * dp->sectors;
-                       if (dp->heads == 0 || dp->cyls == 0
-                           || dp->sectors == 0) {
-                               printf("%s: mode sense (5) returned nonsense",
-                                   sd->sc_dev.dv_xname);
-                               goto fake_it;
-                       }
+       }
 
-                       if (dp->blksize == 0)
-                               dp->blksize = 512;
+       if ((error = sd_mode_sense(sd, &scsi_sense, page = 5, flags)) == 0) {
+               dp->heads = scsi_sense.pages.flex_geometry.nheads;
+               dp->cyls = _2btol(scsi_sense.pages.flex_geometry.ncyl);
+               dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
+               dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr;
+               dp->disksize = dp->heads * dp->cyls * dp->sectors;
+               if (dp->disksize == 0)
+                       goto fake_it;
+
+               if (dp->blksize == 0)
+                       dp->blksize = 512;
 
-                       return 0;
-               } else
-                       printf("%s: could not mode sense (4/5)", sd->sc_dev.dv_xname);
+               return 0;
        }
 
 fake_it:
+       if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0) {
+               if (error == 0)
+                       printf("%s: mode sense (%d) returned nonsense",
+                           sd->sc_dev.dv_xname, page);
+               else
+                       printf("%s: could not mode sense (4/5)",
+                           sd->sc_dev.dv_xname);
+               printf("; using fictitious geometry\n");
+       }
        /*
         * use adaptec standard fictitious geometry
         * this depends on which controller (e.g. 1542C is
         * different. but we have to put SOMETHING here..)
         */
-       if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0)
-               printf("; using fictitious geometry\n");
        sectors = scsi_size(sd->sc_link, flags);
        dp->heads = 64;
        dp->sectors = 32;
index c11c3fa..f10c83d 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: st.c,v 1.14 1997/02/24 20:17:35 jkatz Exp $   */
-/*     $NetBSD: st.c,v 1.66 1996/05/05 19:53:01 christos Exp $ */
+/*     $OpenBSD: st.c,v 1.15 1997/04/14 04:09:17 downsj Exp $  */
+/*     $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $  */
 
 /*
  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
 #define STUNIT(z)      ((minor(z) >> 4)       )
 #define CTLMODE        3
 
-#define SCSI_2_MAX_DENSITY_CODE        0x17    /* maximum density code specified
-                                        * in SCSI II spec. */
+/*
+ * Maximum density code known.
+ */
+#define SCSI_2_MAX_DENSITY_CODE                0x45
+
 /*
  * Define various devices that we know mis-behave in some way,
  * and note how they are bad, so we can correct for them
@@ -99,6 +102,7 @@ struct quirkdata {
 #define        ST_Q_SENSE_HELP         0x0002  /* must do READ for good MODE SENSE */
 #define        ST_Q_IGNORE_LOADS       0x0004
 #define        ST_Q_BLKSIZE            0x0008  /* variable-block media_blksize > 0 */
+#define        ST_Q_UNIMODAL           0x0010  /* unimode drive rejects mode select */
        u_int page_0_size;
 #define        MAX_PAGE_0_SIZE 64
        struct modes modes[4];
@@ -202,6 +206,13 @@ struct st_quirk_inquiry_pattern st_quirk_patterns[] = {
                {0, 0, 0},                              /* minor 8-11 */
                {0, 0, 0}                               /* minor 12-15 */
        }}},
+       {{T_SEQUENTIAL, T_REMOV,
+        "HP      ", "T4000s          ", ""},     {ST_Q_UNIMODAL, 0, {
+               {0, 0, QIC_3095},                       /* minor 0-3 */
+               {0, 0, QIC_3095},                       /* minor 4-7 */
+               {0, 0, QIC_3095},                       /* minor 8-11 */
+               {0, 0, QIC_3095},                       /* minor 12-15 */
+       }}},
 #if 0
        {{T_SEQUENTIAL, T_REMOV,
         "EXABYTE ", "EXB-8200        ", ""},     {0, 12, {
@@ -1402,6 +1413,18 @@ st_mode_select(st, flags)
 
        scsi_select_len = 12 + st->page_0_size;
 
+       /*
+        * This quirk deals with drives that have only one valid mode
+        * and think this gives them license to reject all mode selects,
+        * even if the selected mode is the one that is supported.
+        */
+       if (st->quirks & ST_Q_UNIMODAL) {
+               SC_DEBUG(sc_link, SDEV_DB3,
+                   ("not setting density 0x%x blksize 0x%x\n",
+                   st->density, st->blksize));
+               return 0;
+       }
+
        /*
         * Set up for a mode select
         */