diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-06-05 21:27:08 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-06-05 21:27:08 +0000 |
commit | 9963da1d81006615c071513935289f75abd1f5e7 (patch) | |
tree | 1c3734cc7beb8cba191a504d78d35e6d45d4ba49 /sys/scsi | |
parent | 9cd6fb862e725e92124396941780f9a74cee2c1d (diff) |
Fix scsi_mode_select() and scsi_mode_select_big() to send just the
required number of bytes, rather than a full scsi_mode_sense_buf. Some
devices (e.g. my HP SureStore DAT/24) decline to accept such oversized
transfers. Instead, force callers to fill in the data_length field in
the header and use that information to set the size of the transfer.
Diffstat (limited to 'sys/scsi')
-rw-r--r-- | sys/scsi/cd.c | 20 | ||||
-rw-r--r-- | sys/scsi/scsi_base.c | 15 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 6 | ||||
-rw-r--r-- | sys/scsi/st.c | 15 |
4 files changed, 25 insertions, 31 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 3428b5f0e82..612262c1f45 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.83 2005/06/03 17:29:55 krw Exp $ */ +/* $OpenBSD: cd.c,v 1.84 2005/06/05 21:27:07 krw Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -1382,12 +1382,10 @@ cd_setchan(cd, p0, p1, p2, p3, flags) if (big) error = scsi_mode_select_big(cd->sc_link, SMS_PF, - (struct scsi_mode_header_big *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header_big *)&data, flags, 20000); else error = scsi_mode_select(cd->sc_link, SMS_PF, - (struct scsi_mode_header *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header *)&data, flags, 20000); return (error); } @@ -1455,12 +1453,10 @@ cd_setvol(cd, arg, flags) if (big) error = scsi_mode_select_big(cd->sc_link, SMS_PF, - (struct scsi_mode_header_big *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header_big *)&data, flags, 20000); else error = scsi_mode_select(cd->sc_link, SMS_PF, - (struct scsi_mode_header *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header *)&data, flags, 20000); return (error); } @@ -1509,12 +1505,10 @@ cd_set_pa_immed(cd, flags) if (big) error = scsi_mode_select_big(cd->sc_link, SMS_PF, - (struct scsi_mode_header_big *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header_big *)&data, flags, 20000); else error = scsi_mode_select(cd->sc_link, SMS_PF, - (struct scsi_mode_header *)&data, sizeof(data), flags, - 20000); + (struct scsi_mode_header *)&data, flags, 20000); return (error); } diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 7c6fa23e255..003ef7bcadd 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_base.c,v 1.79 2005/06/04 01:25:02 krw Exp $ */ +/* $OpenBSD: scsi_base.c,v 1.80 2005/06/05 21:27:07 krw Exp $ */ /* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */ /* @@ -560,10 +560,9 @@ eight_byte: } int -scsi_mode_select(sc_link, byte2, data, len, flags, timeout) +scsi_mode_select(sc_link, byte2, data, flags, timeout) struct scsi_link *sc_link; int byte2, flags, timeout; - size_t len; struct scsi_mode_header *data; { struct scsi_mode_select scsi_cmd; @@ -572,13 +571,13 @@ scsi_mode_select(sc_link, byte2, data, len, flags, timeout) bzero(&scsi_cmd, sizeof(scsi_cmd)); scsi_cmd.opcode = MODE_SELECT; scsi_cmd.byte2 = byte2; - scsi_cmd.length = len & 0xff; + scsi_cmd.length = data->data_length + 1; /* 1 == sizeof(data_length) */ /* Length is reserved when doing mode select so zero it. */ data->data_length = 0; error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, len, 4, timeout, NULL, + sizeof(scsi_cmd), (u_char *)data, scsi_cmd.length, 4, timeout, NULL, flags | SCSI_DATA_OUT); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_mode_select: error = %d\n", error)); @@ -587,15 +586,17 @@ scsi_mode_select(sc_link, byte2, data, len, flags, timeout) } int -scsi_mode_select_big(sc_link, byte2, data, len, flags, timeout) +scsi_mode_select_big(sc_link, byte2, data, flags, timeout) struct scsi_link *sc_link; int byte2, flags, timeout; - size_t len; struct scsi_mode_header_big *data; { struct scsi_mode_select_big scsi_cmd; + u_int32_t len; int error; + len = _2btol(data->data_length) + 2; /* 2 == sizeof data->data_length */ + bzero(&scsi_cmd, sizeof(scsi_cmd)); scsi_cmd.opcode = MODE_SELECT_BIG; scsi_cmd.byte2 = byte2; diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 3d169a875fc..520a7c36f61 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.57 2005/06/03 15:50:10 krw Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.58 2005/06/05 21:27:07 krw Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -341,9 +341,9 @@ int scsi_do_mode_sense(struct scsi_link *, int, struct scsi_mode_sense_buf *, void **, u_int32_t *, u_int64_t *, u_int32_t *, int, int, int *); int scsi_mode_select(struct scsi_link *, int, struct scsi_mode_header *, - size_t, int, int); + int, int); int scsi_mode_select_big(struct scsi_link *, int, - struct scsi_mode_header_big *, size_t, int, int); + struct scsi_mode_header_big *, int, int); void scsi_done(struct scsi_xfer *); void scsi_user_done(struct scsi_xfer *); int scsi_scsi_cmd(struct scsi_link *, struct scsi_generic *, diff --git a/sys/scsi/st.c b/sys/scsi/st.c index 9bdb5ba1204..0cc920021de 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -1,4 +1,4 @@ -/* $OpenBSD: st.c,v 1.46 2005/05/14 00:20:43 krw Exp $ */ +/* $OpenBSD: st.c,v 1.47 2005/06/05 21:27:07 krw Exp $ */ /* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */ /* @@ -1479,7 +1479,6 @@ st_mode_select(st, flags) struct st_softc *st; int flags; { - u_int scsi_select_len; struct scsi_select { struct scsi_mode_header header; struct scsi_blk_desc blk_desc; @@ -1487,8 +1486,6 @@ st_mode_select(st, flags) } scsi_select; struct scsi_link *sc_link = st->sc_link; - 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, @@ -1505,9 +1502,12 @@ st_mode_select(st, flags) return 0; /* - * Set up for a mode select + * Set up for a mode select. Remember that data_length is the + * size less the size of the data_length field. */ - bzero(&scsi_select, scsi_select_len); + bzero(&scsi_select, sizeof(scsi_select)); + scsi_select.header.data_length = sizeof(scsi_select.header) + + sizeof(scsi_select.blk_desc) + st->page_0_size - 1; scsi_select.header.blk_desc_len = sizeof(struct scsi_blk_desc); scsi_select.header.dev_spec &= ~SMH_DSP_BUFF_MODE; scsi_select.blk_desc.density = st->density; @@ -1524,8 +1524,7 @@ st_mode_select(st, flags) * do the command */ return (scsi_mode_select(st->sc_link, 0, - (struct scsi_mode_header *)&scsi_select, scsi_select_len, flags, - ST_CTL_TIME)); + (struct scsi_mode_header *)&scsi_select, flags, ST_CTL_TIME)); } /* |