tech-kern archive

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

Re: Implement mode_select for atapi tape drives



On Sat, 8 Aug 2009, Paul Goyette wrote:

Revision 3 of the patch is attached to this E-mail. Unless anyone objects, I'll commit this towards the end of next week. (If someone thinks there's some urgency in committing sooner, please let me know.)

As Manuel pointed out so politely, I forgot to attach the patch! Here's the latest revision.

And, as David pointed out, it might be better to extract the set_mode code out from both st_atapi.c and st_scsi.c into something common. I'll take a look at doing that, and see if I can reconcile the differences between them.


-------------------------------------------------------------------------
|   Paul Goyette   | PGP DSS Key fingerprint: |  E-mail addresses:      |
| Customer Service | FA29 0E3B 35AF E8AE 6651 |  paul at whooppee.com   |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at juniper.net |
| Kernel Developer |                          | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
Index: st.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v
retrieving revision 1.211
diff -u -p -r1.211 st.c
--- st.c        12 May 2009 14:44:31 -0000      1.211
+++ st.c        8 Aug 2009 18:24:46 -0000
@@ -306,6 +306,13 @@ static const struct st_quirk_inquiry_pat
                {0, 0, 0},                             /* minor 8-11 */
                {0, 0, 0}                              /* minor 12-15 */
        }}},
+       {{T_SEQUENTIAL, T_REMOV,
+        "Seagate STT3401A", "hp0atxa", ""},    {ST_Q_ATAPI_MODESEL, 0, {
+               {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 0-3 */
+               {ST_Q_FORCE_BLKSIZE, 1024, 0},          /* minor 4-7 */
+               {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 8-11 */
+               {ST_Q_FORCE_BLKSIZE, 512, 0}            /* minor 12-15 */
+       }}},
 };
 
 #define NOEJECT 0
@@ -488,6 +495,7 @@ st_identify_drive(struct st_softc *st, s
                st->drive_quirks = finger->quirkdata.quirks;
                st->quirks = finger->quirkdata.quirks;  /* start value */
                st->page_0_size = finger->quirkdata.page_0_size;
+               KASSERT(st->page_0_size <= MAX_PAGE_0_SIZE);
                st_loadquirks(st);
        }
 }
Index: st_atapi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st_atapi.c,v
retrieving revision 1.22
diff -u -p -r1.22 st_atapi.c
--- st_atapi.c  12 May 2009 14:44:31 -0000      1.22
+++ st_atapi.c  8 Aug 2009 18:24:46 -0000
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: st_atapi.c,v
 
 #include <dev/scsipi/stvar.h>
 #include <dev/scsipi/atapi_tape.h>
+#include <dev/scsipi/scsi_spc.h>
 
 static int     st_atapibus_match(device_t, cfdata_t, void *);
 static void    st_atapibus_attach(device_t, device_t, void *);
@@ -177,8 +178,43 @@ st_atapibus_mode_sense(struct st_softc *
        return error;
 }
 
+/*
+ * Send a filled out parameter structure to the drive to
+ * set it into the desire modes etc.
+ */
 static int
 st_atapibus_mode_select(struct st_softc *st, int flags)
 {
-       return ENODEV; /* for now ... */
+       u_int atapi_select_len;
+       struct atapi_select {
+               struct scsi_mode_parameter_header_6  header;
+               struct scsi_general_block_descriptor blk_desc;
+               u_char sense_data[MAX_PAGE_0_SIZE];
+       } atapi_select;
+       struct scsipi_periph *periph = st->sc_periph;
+
+       if (!(st->quirkdata->quirks & ST_Q_ATAPI_MODESEL))
+               return ENODEV;
+
+       atapi_select_len = sizeof(atapi_select.header) +
+                          sizeof(atapi_select.blk_desc) +
+                          st->page_0_size;
+
+       /*
+        * Set up for a mode select
+        */
+       memset(&atapi_select, 0, sizeof(atapi_select));
+       atapi_select.header.blk_desc_len = sizeof(struct 
scsi_general_block_descriptor);
+       atapi_select.blk_desc.density = st->density;
+       if (st->flags & ST_FIXEDBLOCKS)
+               _lto3b(st->blksize, atapi_select.blk_desc.blklen);
+       if (st->page_0_size)
+               memcpy(atapi_select.sense_data, st->sense_data, 
st->page_0_size);
+
+       /*
+        * do the command
+        */
+       return scsipi_mode_select(periph, 0, &atapi_select.header,
+           atapi_select_len, flags | XS_CTL_DATA_ONSTACK,
+           ST_RETRIES, ST_CTL_TIME);
 }
Index: st_scsi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st_scsi.c,v
retrieving revision 1.29
diff -u -p -r1.29 st_scsi.c
--- st_scsi.c   12 May 2009 14:44:31 -0000      1.29
+++ st_scsi.c   8 Aug 2009 18:24:46 -0000
@@ -187,7 +187,9 @@ st_scsibus_mode_sense(struct st_softc *s
        } scsipi_sense;
        struct scsipi_periph *periph = st->sc_periph;
 
-       scsipi_sense_len = 12 + st->page_0_size;
+       scsipi_sense_len = sizeof(scsipi_sense.header) +
+                          sizeof(scsipi_sense.blk_desc) +
+                          st->page_0_size;
 
        /*
         * Set up a mode sense
@@ -237,7 +239,9 @@ st_scsibus_mode_select(struct st_softc *
        } scsi_select;
        struct scsipi_periph *periph = st->sc_periph;
 
-       scsi_select_len = 12 + st->page_0_size;
+       scsi_select_len = sizeof(scsi_select.header) +
+                         sizeof(scsi_select.blk_desc) +
+                         st->page_0_size;
 
        /*
         * This quirk deals with drives that have only one valid mode
@@ -254,7 +258,7 @@ st_scsibus_mode_select(struct st_softc *
        /*
         * Set up for a mode select
         */
-       memset(&scsi_select, 0, scsi_select_len);
+       memset(&scsi_select, 0, sizeof(scsi_select));
        scsi_select.header.blk_desc_len = sizeof(struct 
scsi_general_block_descriptor);
        scsi_select.header.dev_spec &= ~SMH_DSP_BUFF_MODE;
        scsi_select.blk_desc.density = st->density;
Index: stvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/stvar.h,v
retrieving revision 1.19
diff -u -p -r1.19 stvar.h
--- stvar.h     12 May 2009 14:44:31 -0000      1.19
+++ stvar.h     8 Aug 2009 18:24:46 -0000
@@ -79,6 +79,7 @@ struct quirkdata {
 #define        ST_Q_NOPREVENT          0x0020  /* does not support PREVENT */
 #define        ST_Q_ERASE_NOIMM        0x0040  /* drive rejects ERASE/w Immed 
bit */
 #define        ST_Q_NOFILEMARKS        0x0080  /* can only write 0 filemarks */
+#define        ST_Q_ATAPI_MODESEL      0x0100  /* ATAPI drive does SCSI Mode 
Select */
        u_int page_0_size;
 #define        MAX_PAGE_0_SIZE 64
        struct modes modes[4];


Home | Main Index | Thread Index | Old Index