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;

Reply via email to