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