summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <matthew@cvs.openbsd.org>2011-04-26 22:46:26 +0000
committerMatthew Dempsky <matthew@cvs.openbsd.org>2011-04-26 22:46:26 +0000
commit718e2a1dacdcc46a1796f4aa71da45b006fa9d83 (patch)
treed4a623b69d3e9b65866a693e01451ed87ca88231
parent7b6cf4784bcd871b96b72bcb3f4e19c8524db22c (diff)
A plausible attempt at iopoolifying dpt(4).
ok dlg@; miod@ warns me to not hold my breath on anyone testing this diff though...
-rw-r--r--sys/dev/ic/dpt.c84
-rw-r--r--sys/dev/ic/dptvar.h6
2 files changed, 34 insertions, 56 deletions
diff --git a/sys/dev/ic/dpt.c b/sys/dev/ic/dpt.c
index a24085bbee9..4d4e691c221 100644
--- a/sys/dev/ic/dpt.c
+++ b/sys/dev/ic/dpt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dpt.c,v 1.30 2011/04/26 18:31:16 matthew Exp $ */
+/* $OpenBSD: dpt.c,v 1.31 2011/04/26 22:46:25 matthew Exp $ */
/* $NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $ */
/*-
@@ -83,6 +83,8 @@ struct cfdriver dpt_cd = {
NULL, "dpt", DV_DULL
};
+void *dpt_ccb_alloc(void *);
+void dpt_ccb_free(void *, void *);
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
@@ -297,6 +299,9 @@ dpt_init(sc, intrstr)
SLIST_INIT(&sc->sc_free_ccb);
i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
+ mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ scsi_iopool_init(&sc->sc_iopool, sc, dpt_ccb_alloc, dpt_ccb_free);
+
if (i == 0) {
printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
return;
@@ -360,6 +365,7 @@ dpt_init(sc, intrstr)
link->adapter = &sc->sc_adapter;
link->adapter_softc = sc;
link->openings = sc->sc_nccbs;
+ link->pool = &sc->sc_iopool;
config_found(&sc->sc_dv, link, scsiprint);
}
}
@@ -602,18 +608,16 @@ dpt_minphys(struct buf *bp, struct scsi_link *sl)
* Put a CCB onto the freelist.
*/
void
-dpt_free_ccb(sc, ccb)
- struct dpt_softc *sc;
- struct dpt_ccb *ccb;
+dpt_ccb_free(void *xsc, void *xccb)
{
- int s;
+ struct dpt_softc *sc = xsc;
+ struct dpt_ccb *ccb = xccb;
- s = splbio();
ccb->ccb_flg = 0;
- if (SLIST_NEXT(ccb, ccb_chain) == NULL)
- wakeup(&sc->sc_free_ccb);
- splx(s);
+ mtx_enter(&sc->sc_ccb_mtx);
+ SLIST_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
+ mtx_leave(&sc->sc_ccb_mtx);
}
/*
@@ -675,31 +679,20 @@ dpt_create_ccbs(sc, ccbstore, count)
* none are available right now and we are permitted to sleep, then wait
* until one becomes free, otherwise return an error.
*/
-struct dpt_ccb *
-dpt_alloc_ccb(sc, flg)
- struct dpt_softc *sc;
- int flg;
+void *
+dpt_ccb_alloc(void *xsc)
{
+ struct dpt_softc *sc = xsc;
struct dpt_ccb *ccb;
- int s;
-
- s = splbio();
- for (;;) {
- ccb = SLIST_FIRST(&sc->sc_free_ccb);
- if (ccb) {
- SLIST_REMOVE_HEAD(&sc->sc_free_ccb, ccb_chain);
- break;
- }
- if ((flg & SCSI_NOSLEEP) != 0) {
- splx(s);
- return (NULL);
- }
- tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
+ mtx_enter(&sc->sc_ccb_mtx);
+ ccb = SLIST_FIRST(&sc->sc_free_ccb);
+ if (ccb != NULL) {
+ SLIST_REMOVE_HEAD(&sc->sc_free_ccb, ccb_chain);
+ ccb->ccb_flg |= CCB_ALLOC;
}
+ mtx_leave(&sc->sc_ccb_mtx);
- ccb->ccb_flg |= CCB_ALLOC;
- splx(s);
return (ccb);
}
@@ -781,8 +774,7 @@ dpt_done_ccb(sc, ccb)
xs->status = ccb->ccb_scsi_status;
}
- /* Free up the CCB and mark the command as done */
- dpt_free_ccb(sc, ccb);
+ /* Mark the command as done */
scsi_done(xs);
}
@@ -808,34 +800,22 @@ dpt_scsi_cmd(struct scsi_xfer *xs)
SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
- /* Protect the queue */
- s = splbio();
-
/* Cmds must be no more than 12 bytes for us */
if (xs->cmdlen > 12) {
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
- splx(s);
return;
}
- /* XXX we can't reset devices just yet */
- if ((xs->flags & SCSI_RESET) != 0) {
- xs->error = XS_DRIVER_STUFFUP;
- scsi_done(xs);
- splx(s);
- return;
- }
-
- /* Get a CCB */
- if ((ccb = dpt_alloc_ccb(sc, xs->flags)) == NULL) {
- xs->error = XS_NO_CCB;
+ /* XXX we can't reset devices just yet */
+ if ((xs->flags & SCSI_RESET) != 0) {
+ xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
- splx(s);
return;
}
- splx(s);
+ ccb = xs->io;
+ ccb->ccb_flg &= ~CCB_ALLOC;
ccb->ccb_xs = xs;
ccb->ccb_timeout = xs->timeout;
@@ -878,7 +858,6 @@ dpt_scsi_cmd(struct scsi_xfer *xs)
printf("error %d loading dma map\n", error);
xs->error = XS_DRIVER_STUFFUP;
- dpt_free_ccb(sc, ccb);
scsi_done(xs);
return;
}
@@ -932,8 +911,7 @@ dpt_scsi_cmd(struct scsi_xfer *xs)
if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
- dpt_free_ccb(sc, ccb);
- xs->error = XS_NO_CCB;
+ xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
return;
}
@@ -1040,7 +1018,7 @@ dpt_hba_inquire(sc, ei)
dmat = sc->sc_dmat;
/* Get a CCB and mark as private */
- if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
+ if ((ccb = scsi_io_get(&sc->sc_iopool, SCSI_NOSLEEP)) == NULL)
panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
ccb->ccb_flg |= CCB_PRIVATE;
@@ -1095,5 +1073,5 @@ dpt_hba_inquire(sc, ei)
/* Sync up the DMA map and free CCB, returning */
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
- dpt_free_ccb(sc, ccb);
+ scsi_io_put(&sc->sc_iopool, ccb);
}
diff --git a/sys/dev/ic/dptvar.h b/sys/dev/ic/dptvar.h
index cb08c4e0552..d2ec14cd9b7 100644
--- a/sys/dev/ic/dptvar.h
+++ b/sys/dev/ic/dptvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dptvar.h,v 1.7 2011/04/26 18:05:12 matthew Exp $ */
+/* $OpenBSD: dptvar.h,v 1.8 2011/04/26 22:46:25 matthew Exp $ */
/* $NetBSD: dptvar.h,v 1.5 1999/10/23 16:26:32 ad Exp $ */
/*
@@ -77,6 +77,8 @@ struct dpt_softc {
int sc_nccbs; /* number of CCBs available */
int sc_open; /* device is open */
SLIST_HEAD(, dpt_ccb) sc_free_ccb;/* free ccb list */
+ struct mutex sc_ccb_mtx; /* free ccb list mutex */
+ struct scsi_iopool sc_iopool;
};
int dpt_intr(void *);
@@ -91,11 +93,9 @@ int dpt_poll(struct dpt_softc *, struct dpt_ccb *);
int dpt_cmd(struct dpt_softc *, struct eata_cp *, u_int32_t, int, int);
void dpt_hba_inquire(struct dpt_softc *, struct eata_inquiry_data **);
void dpt_reset_ccb(struct dpt_softc *, struct dpt_ccb *);
-void dpt_free_ccb(struct dpt_softc *, struct dpt_ccb *);
void dpt_done_ccb(struct dpt_softc *, struct dpt_ccb *);
int dpt_init_ccb(struct dpt_softc *, struct dpt_ccb *);
int dpt_create_ccbs(struct dpt_softc *, struct dpt_ccb *, int);
-struct dpt_ccb *dpt_alloc_ccb(struct dpt_softc *, int);
#ifdef DEBUG
void dpt_dump_sp(struct eata_sp *);
#endif