summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 01:04:25 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 01:04:25 +0000
commitc9ba7b34bf0ef30c5f9b25d7ee14c12bb0caa534 (patch)
treed3ae6a7f5054b862f00967688cfd7ed9c9feb0c9 /sys
parent1d7c7096c42ecfdbdb0619f20c1a7d8c5ce40e25 (diff)
modify mpi to provide an iopool as a way for the midlayer to manage access
to its free ccbs. this allows the midlayer to schedule access to the bus in a roundrobin fashion for all consumers on the bus, including io from devices and even the internal mpi management commands used to poll the state of raid devices. the result is fairer sharing between disks on the bus and more reliable sensor updates. ok krw@ beck@ marco@ tested by beck@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/mpi.c34
-rw-r--r--sys/dev/ic/mpivar.h3
2 files changed, 21 insertions, 16 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index 8239562bbc0..e3def998d69 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.136 2010/04/03 08:00:42 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.137 2010/04/06 01:04:22 dlg Exp $ */
/*
* Copyright (c) 2005, 2006, 2009 David Gwynne <dlg@openbsd.org>
@@ -294,6 +294,7 @@ mpi_attach(struct mpi_softc *sc)
sc->sc_link.adapter_target = sc->sc_target;
sc->sc_link.adapter_buswidth = sc->sc_buswidth;
sc->sc_link.openings = sc->sc_maxcmds / sc->sc_buswidth;
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -986,6 +987,7 @@ mpi_alloc_ccbs(struct mpi_softc *sc)
ccb->ccb_sc = sc;
ccb->ccb_id = i;
ccb->ccb_offset = MPI_REQUEST_SIZE * i;
+ ccb->ccb_state = MPI_CCB_READY;
ccb->ccb_cmd = &cmd[ccb->ccb_offset];
ccb->ccb_cmd_dva = (u_int32_t)MPI_DMA_DVA(sc->sc_requests) +
@@ -1000,6 +1002,10 @@ mpi_alloc_ccbs(struct mpi_softc *sc)
mpi_put_ccb(sc, ccb);
}
+ scsi_iopool_init(&sc->sc_iopool, sc,
+ (void *(*)(void *))mpi_get_ccb,
+ (void (*)(void *, void *))mpi_put_ccb);
+
return (0);
free_maps:
@@ -1036,6 +1042,11 @@ mpi_put_ccb(struct mpi_softc *sc, struct mpi_ccb *ccb)
{
DNPRINTF(MPI_D_CCB, "%s: mpi_put_ccb %p\n", DEVNAME(sc), ccb);
+#ifdef DIAGNOSTIC
+ if (ccb->ccb_state == MPI_CCB_FREE)
+ panic("mpi_put_ccb: double free");
+#endif
+
ccb->ccb_state = MPI_CCB_FREE;
ccb->ccb_cookie = NULL;
ccb->ccb_done = NULL;
@@ -1214,14 +1225,7 @@ mpi_scsi_cmd(struct scsi_xfer *xs)
return;
}
- ccb = mpi_get_ccb(sc);
- if (ccb == NULL) {
- xs->error = XS_NO_CCB;
- s = splbio();
- scsi_done(xs);
- splx(s);
- return;
- }
+ ccb = xs->io;
DNPRINTF(MPI_D_CMD, "%s: ccb_id: %d xs->flags: 0x%x\n",
DEVNAME(sc), ccb->ccb_id, xs->flags);
@@ -1320,7 +1324,6 @@ mpi_scsi_cmd_done(struct mpi_ccb *ccb)
if (ccb->ccb_rcb == NULL) {
/* no scsi error, we're ok so drop out early */
- mpi_put_ccb(sc, ccb);
xs->status = SCSI_OK;
s = splbio();
scsi_done(xs);
@@ -1409,7 +1412,6 @@ mpi_scsi_cmd_done(struct mpi_ccb *ccb)
xs->error, xs->status);
mpi_push_reply(sc, ccb->ccb_rcb);
- mpi_put_ccb(sc, ccb);
s = splbio();
scsi_done(xs);
splx(s);
@@ -2501,7 +2503,8 @@ mpi_req_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number,
"address: 0x%08x flags: 0x%b\n", DEVNAME(sc), type, number,
address, flags, MPI_PG_FMT);
- ccb = mpi_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool,
+ ISSET(flags, MPI_PG_POLL) ? SCSI_NOSLEEP : 0);
if (ccb == NULL) {
DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header ccb_get\n",
DEVNAME(sc));
@@ -2573,7 +2576,7 @@ mpi_req_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number,
*hdr = cp->config_header;
mpi_push_reply(sc, ccb->ccb_rcb);
- mpi_put_ccb(sc, ccb);
+ scsi_io_put(&sc->sc_iopool, ccb);
return (rv);
}
@@ -2602,7 +2605,8 @@ mpi_req_cfg_page(struct mpi_softc *sc, u_int32_t address, int flags,
len < page_length * 4)
return (1);
- ccb = mpi_get_ccb(sc);
+ ccb = scsi_io_get(&sc->sc_iopool,
+ ISSET(flags, MPI_PG_POLL) ? SCSI_NOSLEEP : 0);
if (ccb == NULL) {
DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page ccb_get\n", DEVNAME(sc));
return (1);
@@ -2683,7 +2687,7 @@ mpi_req_cfg_page(struct mpi_softc *sc, u_int32_t address, int flags,
bcopy(kva, page, len);
mpi_push_reply(sc, ccb->ccb_rcb);
- mpi_put_ccb(sc, ccb);
+ scsi_io_put(&sc->sc_iopool, ccb);
return (rv);
}
diff --git a/sys/dev/ic/mpivar.h b/sys/dev/ic/mpivar.h
index 9e29bf027c2..56aa32bb07b 100644
--- a/sys/dev/ic/mpivar.h
+++ b/sys/dev/ic/mpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpivar.h,v 1.29 2010/01/11 03:51:57 dlg Exp $ */
+/* $OpenBSD: mpivar.h,v 1.30 2010/04/06 01:04:24 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -127,6 +127,7 @@ struct mpi_softc {
struct mpi_ccb *sc_ccbs;
struct mpi_ccb_list sc_ccb_free;
struct mutex sc_ccb_mtx;
+ struct scsi_iopool sc_iopool;
struct mpi_dmamem *sc_replies;
struct mpi_rcb *sc_rcbs;