tech-kern archive

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

Implement mode_select for atapi tape drives



The attached patch implements the mode_select operation for atapi tape drives. It is enabled only via a new quirk setting, so existing drives that haven't explicitly been determined to support this op won't even attempt it. (This is essentially the same patch as in PR kern/34832.)

I've been running this in my own systems for about 3 1/2 years now, with my Seagate STT3401A (Travan 20/40GB) drive. I'll submit a separate patch later with a cleaned-up quick setting for this drive.

This patch is actually required for the above tape drive to operate properly under NetBSD. The drive supports both 512-byte and 1024-byte block sizes, but defaults to 1024-bytes. Without this patch there it isn't possible to write 512-byte records to the tape!

Any objections to committing this?


-------------------------------------------------------------------------
|   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: sys/dev/scsipi/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
--- sys/dev/scsipi/st_atapi.c   12 May 2009 14:44:31 -0000      1.22
+++ sys/dev/scsipi/st_atapi.c   8 Aug 2009 11:52:48 -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,41 @@ 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 = 12 + st->page_0_size;
+
+       /*
+        * Set up for a mode select
+        */
+       memset(&atapi_select, 0, atapi_select_len);
+       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: sys/dev/scsipi/stvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/stvar.h,v
retrieving revision 1.19
diff -u -p -r1.19 stvar.h
--- sys/dev/scsipi/stvar.h      12 May 2009 14:44:31 -0000      1.19
+++ sys/dev/scsipi/stvar.h      8 Aug 2009 11:52:48 -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