Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/scsipi Make the xxstart() functions reentrant again, ...
details: https://anonhg.NetBSD.org/src/rev/1dd839711adc
branches: trunk
changeset: 569848:1dd839711adc
user: bouyer <bouyer%NetBSD.org@localhost>
date: Thu Sep 09 19:35:30 2004 +0000
description:
Make the xxstart() functions reentrant again, as some drivers HBA can call
scsipi_done() from their scsipi_request().
For this, add a struct scsipi_xfer * argument to scsipi_command().
If not NULL scsipi_command() will use this to enqueue this xfer, otherwise
it'll try to allocate a new one. This scsipi_xfer has to be allocated
and initialised by scsipi_make_xs() or equivalent.
In xxstart(), allocate a scsipi_xfer using scsipi_make_xs(), and if not NULL,
dequeue the buffer before calling scsipi_command(). This makes sure that
scsipi_command() will not fail, and also makes sure that xxstart() won't
be called again between the BUFQ_PEEK() and BUFQ_GET().
Fix "dequeued wrong buf" panics reported by Juergen Hannken-Illjes in
private mail and Andreas Wrede on current-users@.
Thanks to Jason Thorpe and Chuck Silver for review, and Andreas Wrede for
testing the patch.
diffstat:
sys/dev/scsipi/atapi_base.c | 18 +++++-----
sys/dev/scsipi/atapiconf.h | 7 ++-
sys/dev/scsipi/cd.c | 71 +++++++++++++++++++++++-------------------
sys/dev/scsipi/ch.c | 16 ++++----
sys/dev/scsipi/if_se.c | 6 +-
sys/dev/scsipi/scsi_base.c | 23 +++++++------
sys/dev/scsipi/scsiconf.h | 7 ++-
sys/dev/scsipi/scsipi_base.c | 38 ++++++++++++----------
sys/dev/scsipi/scsipi_ioctl.c | 6 +-
sys/dev/scsipi/scsipiconf.c | 12 +++---
sys/dev/scsipi/scsipiconf.h | 6 +-
sys/dev/scsipi/sd.c | 33 ++++++++++++-------
sys/dev/scsipi/ses.c | 6 +-
sys/dev/scsipi/ss_mustek.c | 61 +++++++++++++++++++-----------------
sys/dev/scsipi/ss_scanjet.c | 49 +++++++++++++++-------------
sys/dev/scsipi/st.c | 41 +++++++++++++++---------
sys/dev/scsipi/st_scsi.c | 6 +-
17 files changed, 221 insertions(+), 185 deletions(-)
diffs (truncated from 1296 to 300 lines):
diff -r c5316cf03ae8 -r 1dd839711adc sys/dev/scsipi/atapi_base.c
--- a/sys/dev/scsipi/atapi_base.c Thu Sep 09 14:56:00 2004 +0000
+++ b/sys/dev/scsipi/atapi_base.c Thu Sep 09 19:35:30 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atapi_base.c,v 1.21 2004/08/27 20:37:28 bouyer Exp $ */
+/* $NetBSD: atapi_base.c,v 1.22 2004/09/09 19:35:30 bouyer Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapi_base.c,v 1.21 2004/08/27 20:37:28 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapi_base.c,v 1.22 2004/09/09 19:35:30 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -213,11 +213,10 @@
* to associate with the transfer, we need that too.
*/
int
-atapi_scsipi_cmd(struct scsipi_periph *periph,
+atapi_scsipi_cmd(struct scsipi_periph *periph, struct scsipi_xfer *xs,
struct scsipi_generic *scsipi_cmd, int cmdlen, void *data, size_t datalen,
int retries, int timeout, struct buf *bp, int flags)
{
- struct scsipi_xfer *xs;
int error;
SC_DEBUG(periph, SCSIPI_DB2, ("atapi_cmd\n"));
@@ -226,11 +225,12 @@
if (bp != NULL && (flags & XS_CTL_ASYNC) == 0)
panic("atapi_scsipi_cmd: buffer without async");
#endif
-
- if ((xs = scsipi_make_xs(periph, scsipi_cmd, cmdlen, data,
- datalen, retries, timeout, bp, flags)) == NULL) {
- /* let the caller deal with this */
- return (ENOMEM);
+ if (xs == NULL) {
+ if ((xs = scsipi_make_xs(periph, scsipi_cmd, cmdlen, data,
+ datalen, retries, timeout, bp, flags)) == NULL) {
+ /* let the caller deal with this */
+ return (ENOMEM);
+ }
}
xs->cmdlen = (periph->periph_cap & PERIPH_CAP_CMD16) ? 16 : 12;
diff -r c5316cf03ae8 -r 1dd839711adc sys/dev/scsipi/atapiconf.h
--- a/sys/dev/scsipi/atapiconf.h Thu Sep 09 14:56:00 2004 +0000
+++ b/sys/dev/scsipi/atapiconf.h Thu Sep 09 19:35:30 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atapiconf.h,v 1.17 2004/08/21 17:41:18 thorpej Exp $ */
+/* $NetBSD: atapiconf.h,v 1.18 2004/09/09 19:35:30 bouyer Exp $ */
/*
* Copyright (c) 1996, 2001 Manuel Bouyer. All rights reserved.
@@ -57,7 +57,8 @@
int atapiprint(void *, const char *);
void atapi_print_addr(struct scsipi_periph *);
int atapi_interpret_sense(struct scsipi_xfer *);
-int atapi_scsipi_cmd(struct scsipi_periph *, struct scsipi_generic *,
- int, void *, size_t, int, int, struct buf *, int);
+int atapi_scsipi_cmd(struct scsipi_periph *, struct scsipi_xfer *,
+ struct scsipi_generic *, int, void *, size_t,
+ int, int, struct buf *, int);
#endif /* _DEV_SCSIPI_ATAPICONF_H */
diff -r c5316cf03ae8 -r 1dd839711adc sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c Thu Sep 09 14:56:00 2004 +0000
+++ b/sys/dev/scsipi/cd.c Thu Sep 09 19:35:30 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cd.c,v 1.204 2004/09/06 20:38:14 bouyer Exp $ */
+/* $NetBSD: cd.c,v 1.205 2004/09/09 19:35:30 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2001, 2003 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.204 2004/09/06 20:38:14 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.205 2004/09/09 19:35:30 bouyer Exp $");
#include "rnd.h"
@@ -88,6 +88,7 @@
/* from there */
#include <dev/scsipi/scsi_disk.h> /* rw comes from there */
#include <dev/scsipi/scsipiconf.h>
+#include <dev/scsipi/scsipi_base.h>
#include <dev/scsipi/cdvar.h>
#define CDUNIT(z) DISKUNIT(z)
@@ -772,6 +773,7 @@
struct scsipi_rw_big cmd_big;
struct scsi_rw cmd_small;
struct scsipi_generic *cmdp;
+ struct scsipi_xfer *xs;
int flags, nblks, cmdlen, error;
SC_DEBUG(periph, SCSIPI_DB2, ("cdstart "));
@@ -866,15 +868,10 @@
* Call the routine that chats with the adapter.
* Note: we cannot sleep as we may be an interrupt
*/
- error = scsipi_command(periph, cmdp, cmdlen,
+ xs = scsipi_make_xs(periph, cmdp, cmdlen,
(u_char *)bp->b_data, bp->b_bcount,
CDRETRIES, 30000, bp, flags);
- if (__predict_false(error)) {
- disk_unbusy(&cd->sc_dk, 0, 0);
- printf("%s: not queued, error %d\n",
- cd->sc_dev.dv_xname, error);
- }
- if (__predict_false(error == ENOMEM)) {
+ if (__predict_false(xs == NULL)) {
/*
* out of memory. Keep this buffer in the queue, and
* retry later.
@@ -883,12 +880,22 @@
periph);
return;
}
+ /*
+ * need to dequeue the buffer before queuing the command,
+ * because cdstart may be called recursively from the
+ * HBA driver
+ */
#ifdef DIAGNOSTIC
if (BUFQ_GET(&cd->buf_queue) != bp)
panic("cdstart(): dequeued wrong buf");
#else
BUFQ_GET(&cd->buf_queue);
#endif
+ error = scsipi_command(periph, xs, cmdp, cmdlen,
+ (u_char *)bp->b_data, bp->b_bcount,
+ CDRETRIES, 30000, bp, flags);
+ /* with a scsipi_xfer preallocated, scsipi_command can't fail */
+ KASSERT(error == 0);
}
}
@@ -1619,7 +1626,7 @@
* If the command works, interpret the result as a 4 byte
* number of blocks and a blocksize
*/
- if (scsipi_command(cd->sc_periph,
+ if (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
(u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 30000, NULL,
flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK) != 0)
@@ -1657,7 +1664,7 @@
scsipi_cmd.opcode = PLAY;
_lto4b(blkno, scsipi_cmd.blk_addr);
_lto2b(nblks, scsipi_cmd.xfer_len);
- return (scsipi_command(cd->sc_periph,
+ return (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
0, 0, CDRETRIES, 30000, NULL, 0));
}
@@ -1713,7 +1720,7 @@
scsipi_cmd.end_m = endm;
scsipi_cmd.end_s = ends;
scsipi_cmd.end_f = endf;
- return (scsipi_command(cd->sc_periph,
+ return (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
0, 0, CDRETRIES, 30000, NULL, 0));
}
@@ -1729,7 +1736,7 @@
memset(&scsipi_cmd, 0, sizeof(scsipi_cmd));
scsipi_cmd.opcode = PAUSE;
scsipi_cmd.resume = go & 0xff;
- return (scsipi_command(cd->sc_periph,
+ return (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
0, 0, CDRETRIES, 30000, NULL, 0));
}
@@ -1741,7 +1748,7 @@
cd_reset(struct cd_softc *cd)
{
- return (scsipi_command(cd->sc_periph, 0, 0, 0, 0,
+ return (scsipi_command(cd->sc_periph, NULL, 0, 0, 0, 0,
CDRETRIES, 30000, NULL, XS_CTL_RESET));
}
@@ -1762,7 +1769,7 @@
scsipi_cmd.subchan_format = format;
scsipi_cmd.track = track;
_lto2b(len, scsipi_cmd.data_len);
- return (scsipi_command(cd->sc_periph,
+ return (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd,
sizeof(struct scsipi_read_subchannel), (u_char *)data, len,
CDRETRIES, 30000, NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT));
@@ -1792,7 +1799,7 @@
scsipi_cmd.from_track = start;
_lto2b(ntoc, scsipi_cmd.data_len);
scsipi_cmd.control = control;
- return (scsipi_command(cd->sc_periph,
+ return (scsipi_command(cd->sc_periph, NULL,
(struct scsipi_generic *)&scsipi_cmd,
sizeof(struct scsipi_read_toc), (u_char *)data, len, CDRETRIES,
30000, NULL, flags | XS_CTL_DATA_IN));
@@ -1867,7 +1874,7 @@
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[8] = 8;
cmd.bytes[9] = 0 | (0 << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 8,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1879,7 +1886,7 @@
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[8] = 16;
cmd.bytes[9] = 1 | (a->lsc.agid << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 16,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1891,7 +1898,7 @@
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[8] = 12;
cmd.bytes[9] = 2 | (a->lsk.agid << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 12,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1904,7 +1911,7 @@
_lto4b(a->lstk.lba, &cmd.bytes[1]);
cmd.bytes[8] = 12;
cmd.bytes[9] = 4 | (a->lstk.agid << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 12,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1919,7 +1926,7 @@
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[8] = 8;
cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 8,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1933,7 +1940,7 @@
cmd.bytes[9] = 1 | (a->hsc.agid << 6);
buf[1] = 14;
dvd_copy_challenge(&buf[4], a->hsc.chal);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 16,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1947,7 +1954,7 @@
cmd.bytes[9] = 3 | (a->hsk.agid << 6);
buf[1] = 10;
dvd_copy_key(&buf[4], a->hsk.key);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 12,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
if (error) {
@@ -1960,7 +1967,7 @@
case DVD_INVALIDATE_AGID:
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[9] = 0x3f | (a->lsa.agid << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 16,
CDRETRIES, 30000, NULL, 0);
if (error)
return (error);
@@ -1970,7 +1977,7 @@
cmd.opcode = GPCMD_REPORT_KEY;
cmd.bytes[8] = 8;
cmd.bytes[9] = 8 | (0 << 6);
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 8,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
if (error)
@@ -1988,7 +1995,7 @@
cmd.bytes[9] = 6 | (0 << 6);
buf[1] = 6;
buf[4] = a->hrpcs.pdrc;
- error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
+ error = scsipi_command(cd->sc_periph, NULL, &cmd, 12, buf, 8,
CDRETRIES, 30000, NULL,
XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
if (error)
@@ -2016,7 +2023,7 @@
_lto2b(sizeof(buf), &cmd.bytes[7]);
Home |
Main Index |
Thread Index |
Old Index