If there's anyone out there still using dpt(4), I'd appreciate a quick
test of the diff below. No functional changes, just switching over to
using iopools.
dpt(4)'s not enabled by default in any kernel configs, and it didn't
even compile on 64-bit systems when I first started looking at it, so
I'm not holding my breath... anyway, I plan to just commit later this
week if I don't hear anything.
Index: dpt.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/dpt.c,v
retrieving revision 1.30
diff -u -p -r1.30 dpt.c
--- dpt.c 26 Apr 2011 18:31:16 -0000 1.30
+++ dpt.c 26 Apr 2011 19:27:24 -0000
@@ -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_
* 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);
}
Index: dptvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/dptvar.h,v
retrieving revision 1.7
diff -u -p -r1.7 dptvar.h
--- dptvar.h 26 Apr 2011 18:05:12 -0000 1.7
+++ dptvar.h 26 Apr 2011 19:27:24 -0000
@@ -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
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