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;