summaryrefslogtreecommitdiff
path: root/sys/dev/ic/adw.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2000-02-19 16:44:31 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2000-02-19 16:44:31 +0000
commit7a8a9debb261e5de046f1ea9c233d2fbb86b394d (patch)
tree2013e42c6ba1b0ae2601c740842e50d4e87d734b /sys/dev/ic/adw.c
parent115d259bb128d4fd45547a2033438cd7f516ebcc (diff)
If we got an xfer from our backlog queue, don't allow sleeping; we're in
interrupt context. thorpej@netbsd.org
Diffstat (limited to 'sys/dev/ic/adw.c')
-rw-r--r--sys/dev/ic/adw.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/sys/dev/ic/adw.c b/sys/dev/ic/adw.c
index e5f5272fca7..b04b309103a 100644
--- a/sys/dev/ic/adw.c
+++ b/sys/dev/ic/adw.c
@@ -1,4 +1,4 @@
-/* $NetBSD: adw.c,v 1.13 2000/02/03 20:29:15 dante Exp $ */
+/* $NetBSD: adw.c,v 1.14 2000/02/12 19:19:42 thorpej Exp $ */
/*
* Generic driver for the Advanced Systems Inc. SCSI controllers
@@ -84,7 +84,7 @@ static ADW_CCB *adw_get_ccb __P((ADW_SOFTC *, int));
static int adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *, int));
static int adw_scsi_cmd __P((struct scsi_xfer *));
-static int adw_build_req __P((struct scsi_xfer *, ADW_CCB *));
+static int adw_build_req __P((struct scsi_xfer *, ADW_CCB *, int));
static void adw_build_sglist __P((ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *));
static void adwminphys __P((struct buf *));
static void adw_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *));
@@ -741,7 +741,8 @@ adw_scsi_cmd(xs)
struct scsi_link *sc_link = xs->sc_link;
ADW_SOFTC *sc = sc_link->adapter_softc;
ADW_CCB *ccb;
- int s, fromqueue = 1, dontqueue = 0, retry = 0;
+ int s, fromqueue = 1, dontqueue = 0, nowait = 0, retry = 0;
+ int flags;
s = splbio(); /* protect the queue */
@@ -752,6 +753,7 @@ adw_scsi_cmd(xs)
if (xs == sc->sc_queue.lh_first) {
xs = adw_dequeue(sc);
fromqueue = 1;
+ nowait = 1;
} else {
/* Polled requests can't be queued for later. */
@@ -786,7 +788,10 @@ adw_scsi_cmd(xs)
* then we can't allow it to sleep
*/
- if ((ccb = adw_get_ccb(sc, xs->flags)) == NULL) {
+ flags = xs->flags;
+ if (nowait)
+ flags |= SCSI_NOSLEEP;
+ if ((ccb = adw_get_ccb(sc, flags)) == NULL) {
/*
* If we can't queue, we lose.
*/
@@ -808,7 +813,7 @@ adw_scsi_cmd(xs)
ccb->xs = xs;
ccb->timeout = xs->timeout;
- if (adw_build_req(xs, ccb)) {
+ if (adw_build_req(xs, ccb, flags)) {
retryagain:
s = splbio();
retry = adw_queue_ccb(sc, ccb, retry);
@@ -847,9 +852,10 @@ retryagain:
* Build a request structure for the Wide Boards.
*/
static int
-adw_build_req(xs, ccb)
+adw_build_req(xs, ccb, flags)
struct scsi_xfer *xs;
ADW_CCB *ccb;
+ int flags;
{
struct scsi_link *sc_link = xs->sc_link;
ADW_SOFTC *sc = sc_link->adapter_softc;
@@ -878,7 +884,7 @@ adw_build_req(xs, ccb)
scsiqp->target_id = sc_link->target;
scsiqp->target_lun = sc_link->lun;
- scsiqp->vsense_addr = & ccb->scsi_sense;
+ scsiqp->vsense_addr = &ccb->scsi_sense;
scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense);
/* scsiqp->sense_addr = ccb->hashkey +
@@ -896,14 +902,14 @@ adw_build_req(xs, ccb)
if (xs->flags & SCSI_DATA_UIO) {
error = bus_dmamap_load_uio(dmat,
ccb->dmamap_xfer, (struct uio *) xs->data,
- (xs->flags & SCSI_NOSLEEP) ?
+ (flags & SCSI_NOSLEEP) ?
BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
} else
#endif /* TFS */
{
error = bus_dmamap_load(dmat,
ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
- (xs->flags & SCSI_NOSLEEP) ?
+ (flags & SCSI_NOSLEEP) ?
BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
}