summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/adv.c94
-rw-r--r--sys/dev/ic/advlib.h4
-rw-r--r--sys/dev/ic/aic6360.c52
-rw-r--r--sys/dev/ic/aic6360var.h5
-rw-r--r--sys/dev/ic/bha.c86
-rw-r--r--sys/dev/ic/bhavar.h5
-rw-r--r--sys/dev/ic/oosiop.c44
-rw-r--r--sys/dev/ic/oosiopvar.h5
-rw-r--r--sys/dev/ic/uha.c91
-rw-r--r--sys/dev/ic/uhavar.h6
10 files changed, 160 insertions, 232 deletions
diff --git a/sys/dev/ic/adv.c b/sys/dev/ic/adv.c
index ef274934cd0..ae2ef0e0215 100644
--- a/sys/dev/ic/adv.c
+++ b/sys/dev/ic/adv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: adv.c,v 1.33 2010/08/07 03:50:01 krw Exp $ */
+/* $OpenBSD: adv.c,v 1.34 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: adv.c,v 1.6 1998/10/28 20:39:45 dante Exp $ */
/*
@@ -58,10 +58,10 @@
static int adv_alloc_ccbs(ASC_SOFTC *);
static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int);
-static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *);
+void adv_ccb_free(void *, void *);
static void adv_reset_ccb(ADV_CCB *);
static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *);
-static ADV_CCB *adv_get_ccb(ASC_SOFTC *, int);
+void *adv_ccb_alloc(void *);
static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *);
static void adv_start_ccbs(ASC_SOFTC *);
@@ -178,26 +178,18 @@ adv_create_ccbs(sc, ccbstore, count)
/*
* A ccb is put onto the free list.
*/
-static void
-adv_free_ccb(sc, ccb)
- ASC_SOFTC *sc;
- ADV_CCB *ccb;
+void
+adv_ccb_free(xsc, xccb)
+ void *xsc, *xccb;
{
- int s;
-
- s = splbio();
+ ASC_SOFTC *sc = xsc;
+ ADV_CCB *ccb = xccb;
adv_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);
}
@@ -236,43 +228,25 @@ adv_init_ccb(sc, ccb)
/*
* Get a free ccb
- *
- * If there are none, see if we can allocate a new one
*/
-static ADV_CCB *
-adv_get_ccb(sc, flags)
- ASC_SOFTC *sc;
- int flags;
+void *
+adv_ccb_alloc(xsc)
+ void *xsc;
{
- ADV_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, "advccb", 0);
+ ASC_SOFTC *sc = xsc;
+ ADV_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);
}
-
/*
* Queue a CCB to be sent to the controller, and send it if possible.
*/
@@ -506,6 +480,11 @@ adv_attach(sc)
sc->sc_dev.dv_xname);
}
+ TAILQ_INIT(&sc->sc_free_ccb);
+ TAILQ_INIT(&sc->sc_waiting_ccb);
+
+ mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, adv_ccb_alloc, adv_ccb_free);
/*
* fill in the prototype scsi_link.
@@ -514,13 +493,9 @@ adv_attach(sc)
sc->sc_link.adapter_target = sc->chip_scsi_id;
sc->sc_link.adapter = &adv_switch;
sc->sc_link.openings = 4;
+ sc->sc_link.pool = &sc->sc_iopool;
sc->sc_link.adapter_buswidth = 7;
-
- TAILQ_INIT(&sc->sc_free_ccb);
- TAILQ_INIT(&sc->sc_waiting_ccb);
-
-
/*
* Allocate the Control Blocks.
*/
@@ -579,13 +554,7 @@ adv_scsi_cmd(xs)
*/
flags = xs->flags;
- if ((ccb = adv_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;
@@ -643,7 +612,6 @@ adv_scsi_cmd(xs)
}
xs->error = XS_DRIVER_STUFFUP;
- adv_free_ccb(sc, ccb);
scsi_done(xs);
return;
}
@@ -914,7 +882,5 @@ adv_narrow_isr_callback(sc, qdonep)
break;
}
-
- adv_free_ccb(sc, ccb);
scsi_done(xs);
}
diff --git a/sys/dev/ic/advlib.h b/sys/dev/ic/advlib.h
index a04ef71d54f..50f620fa043 100644
--- a/sys/dev/ic/advlib.h
+++ b/sys/dev/ic/advlib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: advlib.h,v 1.10 2008/11/26 16:39:31 krw Exp $ */
+/* $OpenBSD: advlib.h,v 1.11 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: advlib.h,v 1.5 1998/10/28 20:39:46 dante Exp $ */
/*
@@ -835,6 +835,8 @@ typedef struct asc_softc
struct adv_control *sc_control; /* control structures */
TAILQ_HEAD(, adv_ccb) sc_free_ccb, sc_waiting_ccb;
struct scsi_link sc_link; /* prototype for devs */
+ struct mutex sc_ccb_mtx;
+ struct scsi_iopool sc_iopool;
u_int8_t *overrun_buf;
diff --git a/sys/dev/ic/aic6360.c b/sys/dev/ic/aic6360.c
index ca796621ee1..1c77a61021e 100644
--- a/sys/dev/ic/aic6360.c
+++ b/sys/dev/ic/aic6360.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aic6360.c,v 1.25 2010/06/28 18:31:02 krw Exp $ */
+/* $OpenBSD: aic6360.c,v 1.26 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */
#ifdef DDB
@@ -166,8 +166,8 @@ void aic_timeout(void *);
void aic_sched(struct aic_softc *);
void aic_scsi_reset(struct aic_softc *);
void aic_reset(struct aic_softc *);
-void aic_free_acb(struct aic_softc *, struct aic_acb *, int);
-struct aic_acb* aic_get_acb(struct aic_softc *, int);
+void aic_acb_free(void *, void *);
+void *aic_acb_alloc(void *);
int aic_reselect(struct aic_softc *, int);
void aic_sense(struct aic_softc *, struct aic_acb *);
void aic_msgin(struct aic_softc *);
@@ -280,6 +280,7 @@ aicattach(struct aic_softc *sc)
sc->sc_link.adapter_target = sc->sc_initiator;
sc->sc_link.adapter = &aic_switch;
sc->sc_link.openings = 2;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -381,6 +382,9 @@ aic_init(struct aic_softc *sc)
TAILQ_INIT(&sc->ready_list);
TAILQ_INIT(&sc->nexus_list);
TAILQ_INIT(&sc->free_list);
+ mtx_init(&sc->sc_acb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, aic_acb_alloc,
+ aic_acb_free);
sc->sc_nexus = NULL;
acb = sc->sc_acb;
bzero(acb, sizeof(sc->sc_acb));
@@ -429,45 +433,34 @@ aic_init(struct aic_softc *sc)
}
void
-aic_free_acb(struct aic_softc *sc, struct aic_acb *acb, int flags)
+aic_acb_free(void *xsc, void *xacb)
{
- int s;
-
- s = splbio();
+ struct aic_softc *sc = xsc;
+ struct aic_acb *acb = xacb;
+ mtx_enter(&sc->sc_acb_mtx);
acb->flags = 0;
TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
-
- /*
- * If there were none, wake anybody waiting for one to come free,
- * starting with queued entries.
- */
- if (TAILQ_NEXT(acb, chain) == NULL)
- wakeup(&sc->free_list);
-
- splx(s);
+ mtx_leave(&sc->sc_acb_mtx);
}
-struct aic_acb *
-aic_get_acb(struct aic_softc *sc, int flags)
+void *
+aic_acb_alloc(void *xsc)
{
+ struct aic_softc *sc = xsc;
struct aic_acb *acb;
- int s;
-
- s = splbio();
- while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL &&
- (flags & SCSI_NOSLEEP) == 0)
- tsleep(&sc->free_list, PRIBIO, "aicacb", 0);
+ mtx_enter(&sc->sc_acb_mtx);
+ acb = TAILQ_FIRST(&sc->free_list);
if (acb) {
TAILQ_REMOVE(&sc->free_list, acb, chain);
acb->flags |= ACB_ALLOC;
}
+ mtx_leave(&sc->sc_acb_mtx);
- splx(s);
return acb;
}
-
+
/*
* DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
*/
@@ -507,11 +500,7 @@ aic_scsi_cmd(struct scsi_xfer *xs)
sc_link->target));
flags = xs->flags;
- if ((acb = aic_get_acb(sc, flags)) == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- return;
- }
+ acb = xs->io;
/* Initialize acb */
acb->xs = xs;
@@ -856,7 +845,6 @@ aic_done(struct aic_softc *sc, struct aic_acb *acb)
} else
aic_dequeue(sc, acb);
- aic_free_acb(sc, acb, xs->flags);
ti->cmds++;
scsi_done(xs);
}
diff --git a/sys/dev/ic/aic6360var.h b/sys/dev/ic/aic6360var.h
index 07a53c9bf85..228bedf8ce0 100644
--- a/sys/dev/ic/aic6360var.h
+++ b/sys/dev/ic/aic6360var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: aic6360var.h,v 1.6 2006/06/03 01:51:54 martin Exp $ */
+/* $OpenBSD: aic6360var.h,v 1.7 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */
/*
@@ -131,6 +131,9 @@ struct aic_softc {
struct aic_acb sc_acb[8];
struct aic_tinfo sc_tinfo[8];
+ struct mutex sc_acb_mtx;
+ struct scsi_iopool sc_iopool;
+
/* Data about the current nexus (updated for every cmd switch) */
u_char *sc_dp; /* Current data pointer */
size_t sc_dleft; /* Data bytes left to transfer */
diff --git a/sys/dev/ic/bha.c b/sys/dev/ic/bha.c
index 6150269c24c..3c38d2e49f2 100644
--- a/sys/dev/ic/bha.c
+++ b/sys/dev/ic/bha.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bha.c,v 1.26 2010/08/07 03:50:01 krw Exp $ */
+/* $OpenBSD: bha.c,v 1.27 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: bha.c,v 1.27 1998/11/19 21:53:00 thorpej Exp $ */
#undef BHADEBUG
@@ -82,9 +82,9 @@ int bha_debug = 1;
integrate void bha_finish_ccbs(struct bha_softc *);
integrate void bha_reset_ccb(struct bha_softc *, struct bha_ccb *);
-void bha_free_ccb(struct bha_softc *, struct bha_ccb *);
+void bha_ccb_free(void *, void *);
integrate int bha_init_ccb(struct bha_softc *, struct bha_ccb *);
-struct bha_ccb *bha_get_ccb(struct bha_softc *, int);
+void *bha_ccb_alloc(void *);
struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, u_long);
void bha_queue_ccb(struct bha_softc *, struct bha_ccb *);
void bha_collect_mbo(struct bha_softc *);
@@ -252,6 +252,12 @@ bha_attach(sc, bpd)
struct scsibus_attach_args saa;
int s;
+ TAILQ_INIT(&sc->sc_free_ccb);
+ TAILQ_INIT(&sc->sc_waiting_ccb);
+
+ mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, bha_ccb_alloc, bha_ccb_free);
+
/*
* Fill in the adapter.
*/
@@ -265,9 +271,7 @@ bha_attach(sc, bpd)
sc->sc_link.adapter_target = bpd->sc_scsi_dev;
sc->sc_link.adapter = &sc->sc_adapter;
sc->sc_link.openings = 4;
-
- TAILQ_INIT(&sc->sc_free_ccb);
- TAILQ_INIT(&sc->sc_waiting_ccb);
+ sc->sc_link.pool = &sc->sc_iopool;
s = splbio();
bha_inquire_setup_information(sc);
@@ -459,25 +463,17 @@ bha_reset_ccb(sc, ccb)
* A ccb is put onto the free list.
*/
void
-bha_free_ccb(sc, ccb)
- struct bha_softc *sc;
- struct bha_ccb *ccb;
+bha_ccb_free(xsc, xccb)
+ void *xsc, *xccb;
{
- int s;
-
- s = splbio();
+ struct bha_softc *sc = xsc;
+ struct bha_ccb *ccb;
bha_reset_ccb(sc, 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);
}
integrate int
@@ -541,39 +537,22 @@ bha_create_ccbs(sc, ccbstore, count)
/*
* Get a free ccb
- *
- * If there are none, see if we can allocate a new one. If so, put it in
- * the hash table too otherwise either return an error or sleep.
*/
-struct bha_ccb *
-bha_get_ccb(sc, flags)
- struct bha_softc *sc;
- int flags;
+void *
+bha_ccb_alloc(xsc)
+ void *xsc;
{
+ struct bha_softc *sc = xsc;
struct bha_ccb *ccb;
- 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, "bhaccb", 0);
+ 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);
}
@@ -781,7 +760,6 @@ bha_done(sc, ccb)
} else
xs->resid = 0;
}
- bha_free_ccb(sc, ccb);
scsi_done(xs);
}
@@ -1278,14 +1256,7 @@ bha_scsi_cmd(xs)
* then we can't allow it to sleep
*/
flags = xs->flags;
- if ((ccb = bha_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;
@@ -1395,7 +1366,6 @@ bha_scsi_cmd(xs)
bad:
xs->error = XS_DRIVER_STUFFUP;
- bha_free_ccb(sc, ccb);
scsi_done(xs);
}
diff --git a/sys/dev/ic/bhavar.h b/sys/dev/ic/bhavar.h
index a089845d397..577fb6de851 100644
--- a/sys/dev/ic/bhavar.h
+++ b/sys/dev/ic/bhavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bhavar.h,v 1.4 2008/11/26 16:38:00 krw Exp $ */
+/* $OpenBSD: bhavar.h,v 1.5 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: bhavar.h,v 1.12 1998/11/19 21:53:00 thorpej Exp $ */
/*-
@@ -84,6 +84,9 @@ struct bha_softc {
struct scsi_link sc_link; /* prototype for devs */
struct scsi_adapter sc_adapter;
+ struct mutex sc_ccb_mtx;
+ struct scsi_iopool sc_iopool;
+
char sc_model[7];
char sc_firmware[6];
};
diff --git a/sys/dev/ic/oosiop.c b/sys/dev/ic/oosiop.c
index 5f922ff3448..91cba5d4de3 100644
--- a/sys/dev/ic/oosiop.c
+++ b/sys/dev/ic/oosiop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: oosiop.c,v 1.17 2010/06/28 18:31:02 krw Exp $ */
+/* $OpenBSD: oosiop.c,v 1.18 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: oosiop.c,v 1.4 2003/10/29 17:45:55 tsutsui Exp $ */
/*
@@ -90,6 +90,9 @@ void oosiop_setup(struct oosiop_softc *, struct oosiop_cb *);
void oosiop_poll(struct oosiop_softc *, struct oosiop_cb *);
void oosiop_processintr(struct oosiop_softc *, u_int8_t);
+void *oosiop_cb_alloc(void *);
+void oosiop_cb_free(void *, void *);
+
/* Trap interrupt code for unexpected data I/O */
#define DATAIN_TRAP 0xdead0001
#define DATAOUT_TRAP 0xdead0002
@@ -135,6 +138,32 @@ struct scsi_adapter oosiop_adapter = {
NULL
};
+void *
+oosiop_cb_alloc(void *xsc)
+{
+ struct oosiop_softc *sc = xsc;
+ struct oosiop_cb *cb;
+
+ mtx_enter(&sc->sc_cb_mtx);
+ cb = TAILQ_FIRST(&sc->sc_free_cb);
+ if (cb)
+ TAILQ_REMOVE(&sc->sc_free_cb, cb, chain);
+ mtx_leave(&sc->sc_cb_mtx);
+
+ return (cb);
+}
+
+void
+oosiop_cb_free(void *xsc, void *xcb)
+{
+ struct oosiop_softc *sc = xsc;
+ struct oosiop_cb *cb = xcb;
+
+ mtx_enter(&sc->sc_cb_mtx);
+ TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
+ mtx_leave(&sc->sc_cb_mtx);
+}
+
void
oosiop_attach(struct oosiop_softc *sc)
{
@@ -715,8 +744,8 @@ oosiop_scsicmd(struct scsi_xfer *xs)
sc = (struct oosiop_softc *)xs->sc_link->adapter_softc;
s = splbio();
- cb = TAILQ_FIRST(&sc->sc_free_cb);
- TAILQ_REMOVE(&sc->sc_free_cb, cb, chain);
+
+ cb = xs->io;
cb->xs = xs;
cb->xsflags = xs->flags;
@@ -735,10 +764,9 @@ oosiop_scsicmd(struct scsi_xfer *xs)
if (err) {
printf("%s: unable to load cmd DMA map: %d",
sc->sc_dev.dv_xname, err);
+ splx(s);
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
- TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
- splx(s);
return;
}
bus_dmamap_sync(sc->sc_dmat, cb->cmddma, 0, xs->cmdlen,
@@ -757,11 +785,10 @@ oosiop_scsicmd(struct scsi_xfer *xs)
if (err) {
printf("%s: unable to load data DMA map: %d",
sc->sc_dev.dv_xname, err);
- xs->error = XS_DRIVER_STUFFUP;
bus_dmamap_unload(sc->sc_dmat, cb->cmddma);
- scsi_done(xs);
- TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
splx(s);
+ xs->error = XS_DRIVER_STUFFUP;
+ scsi_done(xs);
return;
}
bus_dmamap_sync(sc->sc_dmat, cb->datadma,
@@ -937,7 +964,6 @@ oosiop_done(struct oosiop_softc *sc, struct oosiop_cb *cb)
FREE:
xs->resid = 0;
scsi_done(xs);
- TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
if (cb == sc->sc_curcb)
sc->sc_curcb = NULL;
diff --git a/sys/dev/ic/oosiopvar.h b/sys/dev/ic/oosiopvar.h
index 85837139e5b..617673b198d 100644
--- a/sys/dev/ic/oosiopvar.h
+++ b/sys/dev/ic/oosiopvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: oosiopvar.h,v 1.4 2010/04/20 20:21:56 miod Exp $ */
+/* $OpenBSD: oosiopvar.h,v 1.5 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: oosiopvar.h,v 1.2 2003/05/03 18:11:23 wiz Exp $ */
/*
@@ -139,6 +139,9 @@ struct oosiop_softc {
TAILQ_HEAD(oosiop_cb_queue, oosiop_cb) sc_free_cb,
sc_cbq;
+ struct mutex sc_cb_mtx;
+ struct scsi_iopool sc_iopool;
+
struct oosiop_cb *sc_curcb; /* current command */
struct oosiop_cb *sc_lastcb; /* last activated command */
diff --git a/sys/dev/ic/uha.c b/sys/dev/ic/uha.c
index feb5379744e..2b511d86d0a 100644
--- a/sys/dev/ic/uha.c
+++ b/sys/dev/ic/uha.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uha.c,v 1.21 2010/08/07 03:50:01 krw Exp $ */
+/* $OpenBSD: uha.c,v 1.22 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: uha.c,v 1.3 1996/10/13 01:37:29 christos Exp $ */
#undef UHADEBUG
@@ -83,9 +83,9 @@
#define KVTOPHYS(x) vtophys((vaddr_t)x)
integrate void uha_reset_mscp(struct uha_softc *, struct uha_mscp *);
-void uha_free_mscp(struct uha_softc *, struct uha_mscp *);
+void uha_mscp_free(void *, void *);
integrate void uha_init_mscp(struct uha_softc *, struct uha_mscp *);
-struct uha_mscp *uha_get_mscp(struct uha_softc *, int);
+void *uha_mscp_alloc(void *);
void uhaminphys(struct buf *, struct scsi_link *);
void uha_scsi_cmd(struct scsi_xfer *);
@@ -129,6 +129,9 @@ uha_attach(sc)
(sc->init)(sc);
SLIST_INIT(&sc->sc_free_mscp);
+ mtx_init(&sc->sc_mscp_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, uha_mscp_alloc, uha_mscp_free);
+
/*
* fill in the prototype scsi_link.
*/
@@ -136,6 +139,7 @@ uha_attach(sc)
sc->sc_link.adapter_target = sc->sc_scsi_dev;
sc->sc_link.adapter = &uha_switch;
sc->sc_link.openings = 2;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -159,25 +163,17 @@ uha_reset_mscp(sc, mscp)
* A mscp (and hence a mbx-out) is put onto the free list.
*/
void
-uha_free_mscp(sc, mscp)
- struct uha_softc *sc;
- struct uha_mscp *mscp;
+uha_mscp_free(xsc, xmscp)
+ void *xsc, *xmscp;
{
- int s;
-
- s = splbio();
+ struct uha_softc *sc = xmscp;
+ struct uha_mscp *mscp;
uha_reset_mscp(sc, mscp);
- SLIST_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain);
- /*
- * If there were none, wake anybody waiting for one to come free,
- * starting with queued entries.
- */
- if (SLIST_NEXT(mscp, chain) == NULL)
- wakeup(&sc->sc_free_mscp);
-
- splx(s);
+ mtx_enter(&sc->sc_mscp_mtx);
+ SLIST_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain);
+ mtx_leave(&sc->sc_mscp_mtx);
}
integrate void
@@ -201,51 +197,22 @@ uha_init_mscp(sc, mscp)
/*
* Get a free mscp
- *
- * If there are none, see if we can allocate a new one. If so, put it in the
- * hash table too otherwise either return an error or sleep.
*/
-struct uha_mscp *
-uha_get_mscp(sc, flags)
- struct uha_softc *sc;
- int flags;
+void *
+uha_mscp_alloc(xsc)
+ void *xsc;
{
+ struct uha_softc *sc = xsc;
struct uha_mscp *mscp;
- 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 (;;) {
- mscp = SLIST_FIRST(&sc->sc_free_mscp);
- if (mscp) {
- SLIST_REMOVE_HEAD(&sc->sc_free_mscp, chain);
- break;
- }
- if (sc->sc_nummscps < UHA_MSCP_MAX) {
- mscp = (struct uha_mscp *) malloc(sizeof(struct uha_mscp),
- M_TEMP, M_NOWAIT);
- if (!mscp) {
- printf("%s: can't malloc mscp\n",
- sc->sc_dev.dv_xname);
- goto out;
- }
- uha_init_mscp(sc, mscp);
- sc->sc_nummscps++;
- break;
- }
- if ((flags & SCSI_NOSLEEP) != 0)
- goto out;
- tsleep(&sc->sc_free_mscp, PRIBIO, "uhamsc", 0);
+ mtx_enter(&sc->sc_mscp_mtx);
+ mscp = SLIST_FIRST(&sc->sc_free_mscp);
+ if (mscp) {
+ SLIST_REMOVE_HEAD(&sc->sc_free_mscp, chain);
+ mscp->flags |= MSCP_ALLOC;
}
+ mtx_leave(&sc->sc_mscp_mtx);
- mscp->flags |= MSCP_ALLOC;
-
-out:
- splx(s);
return (mscp);
}
@@ -319,7 +286,7 @@ uha_done(sc, mscp)
} else
xs->resid = 0;
}
- uha_free_mscp(sc, mscp);
+
scsi_done(xs);
}
@@ -355,11 +322,8 @@ uha_scsi_cmd(xs)
* then we can't allow it to sleep
*/
flags = xs->flags;
- if ((mscp = uha_get_mscp(sc, flags)) == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- return;
- }
+ mscp = xs->io;
+
mscp->xs = xs;
mscp->timeout = xs->timeout;
timeout_set(&xs->stimeout, uha_timeout, xs);
@@ -485,7 +449,6 @@ uha_scsi_cmd(xs)
bad:
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
- uha_free_mscp(sc, mscp);
return;
}
diff --git a/sys/dev/ic/uhavar.h b/sys/dev/ic/uhavar.h
index 64308b6b42e..93d9896e516 100644
--- a/sys/dev/ic/uhavar.h
+++ b/sys/dev/ic/uhavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhavar.h,v 1.3 2010/06/30 19:06:16 mk Exp $ */
+/* $OpenBSD: uhavar.h,v 1.4 2011/04/03 12:42:36 krw Exp $ */
/* $NetBSD: uhavar.h,v 1.3 1996/10/21 22:34:43 thorpej Exp $ */
/*
@@ -50,6 +50,10 @@ struct uha_softc {
struct uha_mscp *sc_mscphash[MSCP_HASH_SIZE];
SLIST_HEAD(, uha_mscp) sc_free_mscp;
+
+ struct mutex sc_mscp_mtx;
+ struct scsi_iopool sc_iopool;
+
int sc_nummscps;
int sc_scsi_dev; /* our scsi id */
struct scsi_link sc_link;