summaryrefslogtreecommitdiff
path: root/sys/dev/ic/ciss.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-06-02 13:34:22 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-06-02 13:34:22 +0000
commitd60669af92a8b9bc1a51912a2b93e1ea7227a84c (patch)
treeb99fd3b78d266ee746c433fddc01880a6e2ee8dc /sys/dev/ic/ciss.c
parent8f81d491bfaa879deb0d76f5667a2ca2c66946c7 (diff)
convert ciss(4) over to using iopools. this is fairly easy after the recent
tweaks ive made. this provides better concurrent access to multiple volumes on the same hba, while improving the reliability of the ioctl and sensor codepaths. tested by okan@ halex@ ok krw@ okan@ halex@
Diffstat (limited to 'sys/dev/ic/ciss.c')
-rw-r--r--sys/dev/ic/ciss.c72
1 files changed, 35 insertions, 37 deletions
diff --git a/sys/dev/ic/ciss.c b/sys/dev/ic/ciss.c
index 2b1c7afc7df..013a94c2f8a 100644
--- a/sys/dev/ic/ciss.c
+++ b/sys/dev/ic/ciss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ciss.c,v 1.50 2010/06/02 05:38:00 dlg Exp $ */
+/* $OpenBSD: ciss.c,v 1.51 2010/06/02 13:34:21 dlg Exp $ */
/*
* Copyright (c) 2005,2006 Michael Shalayeff
@@ -93,8 +93,8 @@ void ciss_kthread(void *v);
void ciss_sensors(void *);
#endif
-struct ciss_ccb *ciss_get_ccb(struct ciss_softc *sc);
-void ciss_put_ccb(struct ciss_ccb *ccb);
+void * ciss_get_ccb(void *);
+void ciss_put_ccb(void *, void *);
int ciss_cmd(struct ciss_ccb *ccb, int flags, int wait);
int ciss_done(struct ciss_ccb *ccb);
int ciss_error(struct ciss_ccb *ccb);
@@ -107,9 +107,10 @@ int ciss_ldstat(struct ciss_softc *, int, struct ciss_ldstat *);
int ciss_pdid(struct ciss_softc *, u_int8_t, struct ciss_pdid *, int);
int ciss_blink(struct ciss_softc *, int, int, int, struct ciss_blink *);
-struct ciss_ccb *
-ciss_get_ccb(struct ciss_softc *sc)
+void *
+ciss_get_ccb(void *xsc)
{
+ struct ciss_softc *sc = xsc;
struct ciss_ccb *ccb;
mtx_enter(&sc->sc_free_ccb_mtx);
@@ -124,9 +125,10 @@ ciss_get_ccb(struct ciss_softc *sc)
}
void
-ciss_put_ccb(struct ciss_ccb *ccb)
+ciss_put_ccb(void *xsc, void *xccb)
{
- struct ciss_softc *sc = ccb->ccb_sc;
+ struct ciss_softc *sc = xsc;
+ struct ciss_ccb *ccb = xccb;
ccb->ccb_state = CISS_CCB_FREE;
ccb->ccb_xs = NULL;
@@ -284,6 +286,8 @@ ciss_attach(struct ciss_softc *sc)
TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link);
}
+ scsi_iopool_init(&sc->sc_iopool, sc, ciss_get_ccb, ciss_put_ccb);
+
if (i < sc->maxcmd) {
printf(": cannot create ccb#%d dmamap (%d)\n", i, error);
if (i == 0) {
@@ -382,6 +386,7 @@ ciss_attach(struct ciss_softc *sc)
sc->sc_link.luns = 1;
sc->sc_link.adapter_target = sc->maxunits;
sc->sc_link.adapter_buswidth = sc->maxunits;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
scsibus = (struct scsibus_softc *)config_found_sm(&sc->sc_dev,
@@ -490,7 +495,6 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
ccb->ccb_xs->error = XS_DRIVER_STUFFUP;
scsi_done(ccb->ccb_xs);
}
- ciss_put_ccb(ccb);
return (error);
}
cmd->sgin = dmap->dm_nsegs;
@@ -522,10 +526,6 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
bus_dmamap_sync(sc->dmat, sc->cmdmap, 0, sc->cmdmap->dm_mapsize,
BUS_DMASYNC_PREWRITE);
- if ((wait & (SCSI_POLL|SCSI_NOSLEEP)) == (SCSI_POLL|SCSI_NOSLEEP))
- bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
- bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) | sc->iem);
-
ccb->ccb_state = CISS_CCB_ONQ;
CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id));
if (sc->cfg.methods & (CISS_METH_FIFO64|CISS_METH_FIFO64_RRO)) {
@@ -612,23 +612,17 @@ ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
error = ciss_done(ccb1);
if (ccb1 == ccb)
- break;
+ return (error);
}
/* if never got a chance to be done above... */
- if (ccb->ccb_state != CISS_CCB_FREE) {
- ccb->ccb_err.cmd_stat = CISS_ERR_TMO;
- error = ciss_done(ccb);
- }
+ ccb->ccb_err.cmd_stat = CISS_ERR_TMO;
+ error = ciss_done(ccb);
CISS_DPRINTF(CISS_D_CMD, ("done %d:%d",
ccb->ccb_err.cmd_stat, ccb->ccb_err.scsi_stat));
}
- if ((wait & (SCSI_POLL|SCSI_NOSLEEP)) == (SCSI_POLL|SCSI_NOSLEEP))
- bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
- bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) & ~sc->iem);
-
return (error);
}
@@ -666,8 +660,6 @@ ciss_done(struct ciss_ccb *ccb)
scsi_done(ccb->ccb_xs);
}
- ciss_put_ccb(ccb);
-
CISS_UNLOCK(sc, lock);
return error;
@@ -745,7 +737,7 @@ ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq)
int rv;
int s;
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL|SCSI_NOSLEEP);
if (ccb == NULL)
return ENOMEM;
@@ -767,6 +759,8 @@ ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq)
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL|SCSI_NOSLEEP);
splx(s);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
return (rv);
}
@@ -784,7 +778,7 @@ ciss_ldmap(struct ciss_softc *sc)
lmap->size = htobe32(sc->maxunits * sizeof(lmap->map));
total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map);
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL|SCSI_NOSLEEP);
if (ccb == NULL)
return ENOMEM;
@@ -802,6 +796,7 @@ ciss_ldmap(struct ciss_softc *sc)
cmd->cdb[9] = total & 0xff;
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL|SCSI_NOSLEEP);
+ scsi_io_put(&sc->sc_iopool, ccb);
CISS_UNLOCK_SCRATCH(sc, lock);
if (rv)
@@ -827,7 +822,7 @@ ciss_sync(struct ciss_softc *sc)
bzero(flush, sizeof(*flush));
flush->flush = sc->sc_flush;
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL|SCSI_NOSLEEP);
if (ccb == NULL)
return ENOMEM;
@@ -846,6 +841,7 @@ ciss_sync(struct ciss_softc *sc)
cmd->cdb[8] = sizeof(*flush) & 0xff;
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL|SCSI_NOSLEEP);
+ scsi_io_put(&sc->sc_iopool, ccb);
CISS_UNLOCK_SCRATCH(sc, lock);
return rv;
@@ -855,7 +851,6 @@ void
ciss_scsi_cmd(struct scsi_xfer *xs)
{
struct scsi_link *link = xs->sc_link;
- struct ciss_softc *sc = link->adapter_softc;
u_int8_t target = link->target;
struct ciss_ccb *ccb;
struct ciss_cmd *cmd;
@@ -878,12 +873,7 @@ ciss_scsi_cmd(struct scsi_xfer *xs)
/* XXX emulate SYNCHRONIZE_CACHE ??? */
- ccb = ciss_get_ccb(sc);
- if (ccb == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- return;
- }
+ ccb = xs->io;
cmd = &ccb->ccb_cmd;
ccb->ccb_len = xs->datalen;
@@ -1231,7 +1221,7 @@ ciss_ldid(struct ciss_softc *sc, int target, struct ciss_ldid *id)
int rv;
int s;
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
if (ccb == NULL)
return ENOMEM;
@@ -1254,6 +1244,8 @@ ciss_ldid(struct ciss_softc *sc, int target, struct ciss_ldid *id)
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL);
splx(s);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
return (rv);
}
@@ -1265,7 +1257,7 @@ ciss_ldstat(struct ciss_softc *sc, int target, struct ciss_ldstat *stat)
int rv;
int s;
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
if (ccb == NULL)
return ENOMEM;
@@ -1288,6 +1280,8 @@ ciss_ldstat(struct ciss_softc *sc, int target, struct ciss_ldstat *stat)
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL);
splx(s);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
return (rv);
}
@@ -1299,7 +1293,7 @@ ciss_pdid(struct ciss_softc *sc, u_int8_t drv, struct ciss_pdid *id, int wait)
int rv;
int s;
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
if (ccb == NULL)
return ENOMEM;
@@ -1322,6 +1316,8 @@ ciss_pdid(struct ciss_softc *sc, u_int8_t drv, struct ciss_pdid *id, int wait)
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, wait);
splx(s);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
return (rv);
}
@@ -1383,7 +1379,7 @@ ciss_blink(struct ciss_softc *sc, int ld, int pd, int stat,
CISS_BLINK_ALL;
bcopy(&ldp->bling, blink, sizeof(*blink));
- ccb = ciss_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
if (ccb == NULL)
return ENOMEM;
@@ -1405,6 +1401,8 @@ ciss_blink(struct ciss_softc *sc, int ld, int pd, int stat,
rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, SCSI_POLL);
splx(s);
+ scsi_io_put(&sc->sc_iopool, ccb);
+
return (rv);
}
#endif