summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2010-10-03 21:23:36 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2010-10-03 21:23:36 +0000
commit4aedd5487cbdf360d02b67b57e45de0429629b28 (patch)
tree94dfce3ed94149e58e631ea75127ea9c2998f0dc /sys
parent00359e9fc75d7c7e433856b813e5c0a8cd22cabe (diff)
iopoolification. Tested on my Advansys ASP-3940U2W. Various eyes
including miod@, oga@, dlg@, matthew@.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/adw.c84
-rw-r--r--sys/dev/ic/adwlib.h4
2 files changed, 29 insertions, 59 deletions
diff --git a/sys/dev/ic/adw.c b/sys/dev/ic/adw.c
index e66a45de659..3b4aee4597e 100644
--- a/sys/dev/ic/adw.c
+++ b/sys/dev/ic/adw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: adw.c,v 1.47 2010/08/07 03:50:01 krw Exp $ */
+/* $OpenBSD: adw.c,v 1.48 2010/10/03 21:23:35 krw Exp $ */
/* $NetBSD: adw.c,v 1.23 2000/05/27 18:24:50 dante Exp $ */
/*
@@ -59,10 +59,10 @@
int adw_alloc_controls(ADW_SOFTC *);
int adw_alloc_carriers(ADW_SOFTC *);
int adw_create_ccbs(ADW_SOFTC *, ADW_CCB *, int);
-void adw_free_ccb(ADW_SOFTC *, ADW_CCB *);
+void adw_ccb_free(void *, void *);
void adw_reset_ccb(ADW_CCB *);
int adw_init_ccb(ADW_SOFTC *, ADW_CCB *);
-ADW_CCB *adw_get_ccb(ADW_SOFTC *, int);
+void *adw_ccb_alloc(void *);
int adw_queue_ccb(ADW_SOFTC *, ADW_CCB *, int);
void adw_scsi_cmd(struct scsi_xfer *);
@@ -230,25 +230,17 @@ adw_create_ccbs(sc, ccbstore, count)
* A ccb is put onto the free list.
*/
void
-adw_free_ccb(sc, ccb)
- ADW_SOFTC *sc;
- ADW_CCB *ccb;
+adw_ccb_free(xsc, xccb)
+ void *xsc, *xccb;
{
- int s;
-
- s = splbio();
+ ADW_SOFTC *sc = xsc;
+ ADW_CCB *ccb = xccb;
adw_reset_ccb(ccb);
- TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
- /*
- * If there were none, wake anybody waiting for one to come free,
- * starting with queued entries.
- */
- if (TAILQ_NEXT(ccb, chain) == NULL)
- wakeup(&sc->sc_free_ccb);
-
- splx(s);
+ mtx_enter(&sc->sc_ccb_mtx);
+ TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
+ mtx_leave(&sc->sc_ccb_mtx);
}
@@ -300,36 +292,21 @@ adw_init_ccb(sc, ccb)
*
* If there are none, see if we can allocate a new one
*/
-ADW_CCB *
-adw_get_ccb(sc, flags)
- ADW_SOFTC *sc;
- int flags;
+void *
+adw_ccb_alloc(xsc)
+ void *xsc;
{
- ADW_CCB *ccb = 0;
- int s;
-
- s = splbio();
-
- /*
- * If we can and have to, sleep waiting for one to come free
- * but only if we can't allocate a new one.
- */
- for (;;) {
- ccb = TAILQ_FIRST(&sc->sc_free_ccb);
- if (ccb) {
- TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
- break;
- }
- if ((flags & SCSI_NOSLEEP) != 0)
- goto out;
-
- tsleep(&sc->sc_free_ccb, PRIBIO, "adwccb", 0);
+ ADW_SOFTC *sc = xsc;
+ ADW_CCB *ccb;
+
+ mtx_enter(&sc->sc_ccb_mtx);
+ ccb = TAILQ_FIRST(&sc->sc_free_ccb);
+ if (ccb) {
+ TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
+ ccb->flags |= CCB_ALLOC;
}
+ mtx_leave(&sc->sc_ccb_mtx);
- ccb->flags |= CCB_ALLOC;
-
-out:
- splx(s);
return (ccb);
}
@@ -455,6 +432,8 @@ adw_attach(sc)
TAILQ_INIT(&sc->sc_waiting_ccb);
TAILQ_INIT(&sc->sc_pending_ccb);
+ mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, adw_ccb_alloc, adw_ccb_free);
/*
* Allocate the Control Blocks.
@@ -554,6 +533,7 @@ adw_attach(sc)
sc->sc_link.adapter = &sc->sc_adapter;
sc->sc_link.openings = 4;
sc->sc_link.adapter_buswidth = ADW_MAX_TID+1;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -586,8 +566,6 @@ adw_scsi_cmd(xs)
int s, nowait = 0, retry = 0;
int flags;
- s = splbio(); /* protect the queue */
-
/*
* get a ccb to use. If the transfer
* is from a buf (possibly from interrupt time)
@@ -597,13 +575,7 @@ adw_scsi_cmd(xs)
flags = xs->flags;
if (nowait)
flags |= SCSI_NOSLEEP;
- if ((ccb = adw_get_ccb(sc, flags)) == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- splx(s);
- return;
- }
- splx(s); /* done playing with the queue */
+ ccb = xs->io;
ccb->xs = xs;
ccb->timeout = xs->timeout;
@@ -714,7 +686,6 @@ adw_build_req(xs, ccb, flags)
}
xs->error = XS_DRIVER_STUFFUP;
- adw_free_ccb(sc, ccb);
return (0);
}
bus_dmamap_sync(dmat, ccb->dmamap_xfer,
@@ -1046,7 +1017,6 @@ adw_isr_callback(sc, scsiq)
if ((ccb->flags & CCB_ALLOC) == 0) {
panic("%s: unallocated ccb found on pending list!",
sc->sc_dev.dv_xname);
- adw_free_ccb(sc, ccb);
return;
}
@@ -1206,8 +1176,6 @@ NO_ERROR:
break;
}
- adw_free_ccb(sc, ccb);
-
scsi_done(xs);
}
diff --git a/sys/dev/ic/adwlib.h b/sys/dev/ic/adwlib.h
index 3ba94db2285..83dad574fbd 100644
--- a/sys/dev/ic/adwlib.h
+++ b/sys/dev/ic/adwlib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: adwlib.h,v 1.12 2008/11/26 16:39:31 krw Exp $ */
+/* $OpenBSD: adwlib.h,v 1.13 2010/10/03 21:23:35 krw Exp $ */
/* $NetBSD: adwlib.h,v 1.14 2000/07/03 18:14:18 dante Exp $ */
/*
@@ -746,6 +746,8 @@ typedef struct adw_softc {
TAILQ_HEAD(adw_pending_ccb, adw_ccb) sc_pending_ccb;
struct scsi_link sc_link; /* prototype for devs */
struct scsi_adapter sc_adapter;
+ struct mutex sc_ccb_mtx;
+ struct scsi_iopool sc_iopool;
int sc_freeze_dev[ADW_MAX_TID+1];