diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2010-04-06 01:04:25 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2010-04-06 01:04:25 +0000 |
commit | c9ba7b34bf0ef30c5f9b25d7ee14c12bb0caa534 (patch) | |
tree | d3ae6a7f5054b862f00967688cfd7ed9c9feb0c9 /sys | |
parent | 1d7c7096c42ecfdbdb0619f20c1a7d8c5ce40e25 (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.c | 34 | ||||
-rw-r--r-- | sys/dev/ic/mpivar.h | 3 |
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; |