Subject: kern/34832: Implement mode-select for ATAPI tape drives
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <paul@whooppee.com>
List: netbsd-bugs
Date: 10/16/2006 07:15:00
>Number: 34832
>Category: kern
>Synopsis: Implement mode-select for ATAPI tape drives
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Oct 16 07:15:00 +0000 2006
>Originator: Paul Goyette
>Release: NetBSD 4.99.3
>Organization:
----------------------------------------------------------------------
| Paul Goyette | PGP DSS Key fingerprint: | E-mail addresses: |
| Network Engineer | FA29 0E3B 35AF E8AE 6651 | paul@whooppee.com |
| | 0786 F758 55DE 53BA 7731 | pgoyette@juniper.net |
----------------------------------------------------------------------
>Environment:
System: NetBSD quicky.whooppee.com 4.99.3 NetBSD 4.99.3 (Quicky-A8N5X) #14: Sun Oct 15 19:25:19 PDT 2006 paul@quicky.whooppee.com:/usr/obj/sys/arch/amd64/compile.amd64/QUICKY amd64
Architecture: x86_64
Machine: amd64
>Description:
Useful to implement mode-select for ATAPI tape drives that support multi blocksizes
>How-To-Repeat:
N/A
>Fix:
The following diffs implement an ATAPI mode_select function that is
adequate to set the drive's block size. Tested with Seagate STT3401A
Travan-TR40 tape drive which supports both 512 and 1024 byte blocks.
Index: sys/dev/scsipi/st.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v
retrieving revision 1.193
diff -u -p -r1.193 st.c
--- sys/dev/scsipi/st.c 12 Oct 2006 01:31:58 -0000 1.193
+++ sys/dev/scsipi/st.c 16 Oct 2006 04:50:14 -0000
@@ -316,6 +316,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
Index: sys/dev/scsipi/st_atapi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st_atapi.c,v
retrieving revision 1.19
diff -u -p -r1.19 st_atapi.c
--- sys/dev/scsipi/st_atapi.c 12 Oct 2006 01:31:58 -0000 1.19
+++ sys/dev/scsipi/st_atapi.c 16 Oct 2006 04:50:14 -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(struct device *, struct cfdata *, void *);
static void st_atapibus_attach(struct device *, struct device *, 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 __unused, int flags __unused)
+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.17
diff -u -p -r1.17 stvar.h
--- sys/dev/scsipi/stvar.h 14 Apr 2006 13:09:06 -0000 1.17
+++ sys/dev/scsipi/stvar.h 16 Oct 2006 04:50:14 -0000
@@ -86,6 +86,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];
>Unformatted: