Module Name: src
Committed By: pgoyette
Date: Sat Aug 15 12:44:55 UTC 2009
Modified Files:
src/sys/dev/scsipi: st.c st_atapi.c st_scsi.c stvar.h
Log Message:
1. Move the mode_select functionality into common code (in st.c) and
invoke the common routine for both scsi and atapi tapes.
2. Replace a numeric constant with some sizeof's when calculating the
size of the mode_select command buffer, clear the entire buffer, and
KASSERT to ensure the page_0_size loaded from quirk table is valid.
3. Add a quirk for my Seagate Travan-40 tape drive.
As discussed on tech-kern@
Addresses my PR kern/34832
To generate a diff of this commit:
cvs rdiff -u -r1.211 -r1.212 src/sys/dev/scsipi/st.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/scsipi/st_atapi.c
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/scsipi/st_scsi.c
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/scsipi/stvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/scsipi/st.c
diff -u src/sys/dev/scsipi/st.c:1.211 src/sys/dev/scsipi/st.c:1.212
--- src/sys/dev/scsipi/st.c:1.211 Tue May 12 14:44:31 2009
+++ src/sys/dev/scsipi/st.c Sat Aug 15 12:44:55 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: st.c,v 1.211 2009/05/12 14:44:31 cegger Exp $ */
+/* $NetBSD: st.c,v 1.212 2009/08/15 12:44:55 pgoyette Exp $ */
/*-
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.211 2009/05/12 14:44:31 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.212 2009/08/15 12:44:55 pgoyette Exp $");
#include "opt_scsi.h"
@@ -306,6 +306,13 @@
{0, 0, 0}, /* minor 8-11 */
{0, 0, 0} /* minor 12-15 */
}}},
+ {{T_SEQUENTIAL, T_REMOV,
+ "Seagate STT3401A", "hp0atxa", ""}, {0, 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->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);
}
}
@@ -2401,3 +2409,57 @@
/* Not implemented. */
return (ENXIO);
}
+
+/*
+ * Send a filled out parameter structure to the drive to
+ * set it into the desire modes etc.
+ */
+int
+st_mode_select(struct st_softc *st, int flags)
+{
+ u_int select_len;
+ struct select {
+ struct scsi_mode_parameter_header_6 header;
+ struct scsi_general_block_descriptor blk_desc;
+ u_char sense_data[MAX_PAGE_0_SIZE];
+ } select;
+ struct scsipi_periph *periph = st->sc_periph;
+
+ select_len = sizeof(select.header) + sizeof(select.blk_desc) +
+ 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(periph, SCSIPI_DB3,
+ ("not setting density 0x%x blksize 0x%x\n",
+ st->density, st->blksize));
+ return (0);
+ }
+
+ /*
+ * Set up for a mode select
+ */
+ memset(&select, 0, sizeof(select));
+ select.header.blk_desc_len = sizeof(struct scsi_general_block_descriptor);
+ select.header.dev_spec &= ~SMH_DSP_BUFF_MODE;
+ select.blk_desc.density = st->density;
+ if (st->flags & ST_DONTBUFFER)
+ select.header.dev_spec |= SMH_DSP_BUFF_MODE_OFF;
+ else
+ select.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
+ if (st->flags & ST_FIXEDBLOCKS)
+ _lto3b(st->blksize, select.blk_desc.blklen);
+ if (st->page_0_size)
+ memcpy(select.sense_data, st->sense_data, st->page_0_size);
+
+ /*
+ * do the command
+ */
+ return scsipi_mode_select(periph, 0, &select.header, select_len,
+ flags | XS_CTL_DATA_ONSTACK, ST_RETRIES,
+ ST_CTL_TIME);
+}
Index: src/sys/dev/scsipi/st_atapi.c
diff -u src/sys/dev/scsipi/st_atapi.c:1.22 src/sys/dev/scsipi/st_atapi.c:1.23
--- src/sys/dev/scsipi/st_atapi.c:1.22 Tue May 12 14:44:31 2009
+++ src/sys/dev/scsipi/st_atapi.c Sat Aug 15 12:44:55 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: st_atapi.c,v 1.22 2009/05/12 14:44:31 cegger Exp $ */
+/* $NetBSD: st_atapi.c,v 1.23 2009/08/15 12:44:55 pgoyette Exp $ */
/*
* Copyright (c) 2001 Manuel Bouyer.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: st_atapi.c,v 1.22 2009/05/12 14:44:31 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: st_atapi.c,v 1.23 2009/08/15 12:44:55 pgoyette Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@@ -51,7 +51,6 @@
static void st_atapibus_attach(device_t, device_t, void *);
static int st_atapibus_ops(struct st_softc *, int, int);
static int st_atapibus_mode_sense(struct st_softc *, int);
-static int st_atapibus_mode_select(struct st_softc *, int);
CFATTACH_DECL(st_atapibus, sizeof(struct st_softc),
st_atapibus_match, st_atapibus_attach, stdetach, stactivate);
@@ -122,7 +121,7 @@
case ST_OPS_MODESENSE:
return st_atapibus_mode_sense(st, flags);
case ST_OPS_MODESELECT:
- return st_atapibus_mode_select(st, flags);
+ return st_mode_select(st, flags);
case ST_OPS_CMPRSS_ON:
case ST_OPS_CMPRSS_OFF:
return ENODEV;
@@ -176,9 +175,3 @@
}
return error;
}
-
-static int
-st_atapibus_mode_select(struct st_softc *st, int flags)
-{
- return ENODEV; /* for now ... */
-}
Index: src/sys/dev/scsipi/st_scsi.c
diff -u src/sys/dev/scsipi/st_scsi.c:1.29 src/sys/dev/scsipi/st_scsi.c:1.30
--- src/sys/dev/scsipi/st_scsi.c:1.29 Tue May 12 14:44:31 2009
+++ src/sys/dev/scsipi/st_scsi.c Sat Aug 15 12:44:55 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: st_scsi.c,v 1.29 2009/05/12 14:44:31 cegger Exp $ */
+/* $NetBSD: st_scsi.c,v 1.30 2009/08/15 12:44:55 pgoyette Exp $ */
/*-
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: st_scsi.c,v 1.29 2009/05/12 14:44:31 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: st_scsi.c,v 1.30 2009/08/15 12:44:55 pgoyette Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@@ -72,7 +72,6 @@
static int st_scsibus_ops(struct st_softc *, int, int);
static int st_scsibus_read_block_limits(struct st_softc *, int);
static int st_scsibus_mode_sense(struct st_softc *, int);
-static int st_scsibus_mode_select(struct st_softc *, int);
static int st_scsibus_cmprss(struct st_softc *, int, int);
CFATTACH_DECL(st_scsibus, sizeof(struct st_softc),
@@ -118,7 +117,7 @@
case ST_OPS_MODESENSE:
return st_scsibus_mode_sense(st, flags);
case ST_OPS_MODESELECT:
- return st_scsibus_mode_select(st, flags);
+ return st_mode_select(st, flags);
case ST_OPS_CMPRSS_ON:
case ST_OPS_CMPRSS_OFF:
return st_scsibus_cmprss(st, flags,
@@ -187,7 +186,9 @@
} 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
@@ -222,59 +223,6 @@
return (0);
}
-/*
- * Send a filled out parameter structure to the drive to
- * set it into the desire modes etc.
- */
-static int
-st_scsibus_mode_select(struct st_softc *st, int flags)
-{
- u_int scsi_select_len;
- struct scsi_select {
- struct scsi_mode_parameter_header_6 header;
- struct scsi_general_block_descriptor blk_desc;
- u_char sense_data[MAX_PAGE_0_SIZE];
- } scsi_select;
- struct scsipi_periph *periph = st->sc_periph;
-
- 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(periph, SCSIPI_DB3,
- ("not setting density 0x%x blksize 0x%x\n",
- st->density, st->blksize));
- return (0);
- }
-
- /*
- * Set up for a mode select
- */
- memset(&scsi_select, 0, scsi_select_len);
- 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;
- if (st->flags & ST_DONTBUFFER)
- scsi_select.header.dev_spec |= SMH_DSP_BUFF_MODE_OFF;
- else
- scsi_select.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
- if (st->flags & ST_FIXEDBLOCKS)
- _lto3b(st->blksize, scsi_select.blk_desc.blklen);
- if (st->page_0_size)
- memcpy(scsi_select.sense_data, st->sense_data, st->page_0_size);
-
- /*
- * do the command
- */
- return scsipi_mode_select(periph, 0, &scsi_select.header,
- scsi_select_len, flags | XS_CTL_DATA_ONSTACK,
- ST_RETRIES, ST_CTL_TIME);
-}
-
static int
st_scsibus_cmprss(struct st_softc *st, int flags, int onoff)
{
Index: src/sys/dev/scsipi/stvar.h
diff -u src/sys/dev/scsipi/stvar.h:1.19 src/sys/dev/scsipi/stvar.h:1.20
--- src/sys/dev/scsipi/stvar.h:1.19 Tue May 12 14:44:31 2009
+++ src/sys/dev/scsipi/stvar.h Sat Aug 15 12:44:55 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: stvar.h,v 1.19 2009/05/12 14:44:31 cegger Exp $ */
+/* $NetBSD: stvar.h,v 1.20 2009/08/15 12:44:55 pgoyette Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -181,5 +181,6 @@
void stattach(device_t, struct st_softc *, void *);
int stactivate(device_t, enum devact);
int stdetach(device_t, int);
+int st_mode_select(struct st_softc *, int);
extern struct cfdriver st_cd;