this cuts ips over to using iopools. it gets the usual benefits of more reliable ioctl paths, better io scheduling between volumes and the pt busses, and a removal of NO_CCB.
i dont have an ips, so i cant test this. id like more than an ok from gcc before committing this. Index: ips.c =================================================================== RCS file: /cvs/src/sys/dev/pci/ips.c,v retrieving revision 1.104 diff -u -p -r1.104 ips.c --- ips.c 12 Oct 2010 00:53:32 -0000 1.104 +++ ips.c 3 Apr 2011 11:57:20 -0000 @@ -417,6 +417,8 @@ struct ips_softc { struct ips_ccb * sc_ccb; int sc_nccbs; struct ips_ccbq sc_ccbq_free; + struct mutex sc_ccb_mtx; + struct scsi_iopool sc_iopool; struct dmamem sc_sqm; paddr_t sc_sqtail; @@ -480,8 +482,8 @@ u_int32_t ips_morpheus_status(struct ips struct ips_ccb *ips_ccb_alloc(struct ips_softc *, int); void ips_ccb_free(struct ips_softc *, struct ips_ccb *, int); -struct ips_ccb *ips_ccb_get(struct ips_softc *); -void ips_ccb_put(struct ips_softc *, struct ips_ccb *); +void *ips_ccb_get(void *); +void ips_ccb_put(void *, void *); int ips_dmamem_alloc(struct dmamem *, bus_dma_tag_t, bus_size_t); void ips_dmamem_free(struct dmamem *); @@ -660,6 +662,8 @@ ips_attach(struct device *parent, struct ccb0.c_cmdbpa = sc->sc_cmdbm.dm_paddr; SLIST_INIT(&sc->sc_ccbq_free); SLIST_INSERT_HEAD(&sc->sc_ccbq_free, &ccb0, c_link); + mtx_init(&sc->sc_ccb_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, ips_ccb_get, ips_ccb_put); /* Get adapter info */ if (ips_getadapterinfo(sc, SCSI_NOSLEEP)) { @@ -731,6 +735,7 @@ ips_attach(struct device *parent, struct sc->sc_scsi_link.adapter_buswidth = sc->sc_nunits; sc->sc_scsi_link.adapter = &ips_scsi_adapter; sc->sc_scsi_link.adapter_softc = sc; + sc->sc_scsi_link.pool = &sc->sc_iopool; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_scsi_link; @@ -774,6 +779,7 @@ ips_attach(struct device *parent, struct link->adapter_buswidth = lastarget + 1; link->adapter = &ips_scsi_pt_adapter; link->adapter_softc = pt; + link->pool = &sc->sc_iopool; saa.saa_sc_link = link; config_found(self, &saa, scsiprint); @@ -841,11 +847,11 @@ ips_scsi_cmd(struct scsi_xfer *xs) struct scsi_sense_data sd; struct scsi_rw *rw; struct scsi_rw_big *rwb; - struct ips_ccb *ccb; + struct ips_ccb *ccb = xs->io; struct ips_cmd *cmd; int target = link->target; u_int32_t blkno, blkcnt; - int code, s; + int code; DPRINTF(IPS_D_XFER, ("%s: ips_scsi_cmd: xs %p, target %d, " "opcode 0x%02x, flags 0x%x\n", sc->sc_dev.dv_xname, xs, target, @@ -894,16 +900,7 @@ ips_scsi_cmd(struct scsi_xfer *xs) else code = IPS_CMD_WRITE; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); - if (ccb == NULL) { - DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: no ccb\n", - sc->sc_dev.dv_xname)); - xs->error = XS_NO_CCB; - scsi_done(xs); - return; - } + ccb = xs->io; cmd = ccb->c_cmdbva; cmd->code = code; @@ -914,12 +911,9 @@ ips_scsi_cmd(struct scsi_xfer *xs) if (ips_load_xs(sc, ccb, xs)) { DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: ips_load_xs " "failed\n", sc->sc_dev.dv_xname)); - - s = splbio(); - ips_ccb_put(sc, ccb); - splx(s); xs->error = XS_DRIVER_STUFFUP; - break; + scsi_done(xs); + return; } if (cmd->sgcnt > 0) @@ -954,17 +948,6 @@ ips_scsi_cmd(struct scsi_xfer *xs) memcpy(xs->data, &sd, MIN(xs->datalen, sizeof(sd))); break; case SYNCHRONIZE_CACHE: - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); - if (ccb == NULL) { - DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: no ccb\n", - sc->sc_dev.dv_xname)); - xs->error = XS_NO_CCB; - scsi_done(xs); - return; - } - cmd = ccb->c_cmdbva; cmd->code = IPS_CMD_FLUSH; @@ -991,12 +974,11 @@ ips_scsi_pt_cmd(struct scsi_xfer *xs) struct ips_pt *pt = link->adapter_softc; struct ips_softc *sc = pt->pt_sc; struct device *dev = link->device_softc; - struct ips_ccb *ccb; + struct ips_ccb *ccb = xs->io; struct ips_cmdb *cmdb; struct ips_cmd *cmd; struct ips_dcdb *dcdb; int chan = pt->pt_chan, target = link->target; - int s; DPRINTF(IPS_D_XFER, ("%s: ips_scsi_pt_cmd: xs %p, chan %d, target %d, " "opcode 0x%02x, flags 0x%x\n", sc->sc_dev.dv_xname, xs, chan, @@ -1020,17 +1002,6 @@ ips_scsi_pt_cmd(struct scsi_xfer *xs) xs->error = XS_NOERROR; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); - if (ccb == NULL) { - DPRINTF(IPS_D_ERR, ("%s: ips_scsi_pt_cmd: no ccb\n", - sc->sc_dev.dv_xname)); - xs->error = XS_NO_CCB; - scsi_done(xs); - return; - } - cmdb = ccb->c_cmdbva; cmd = &cmdb->cmd; dcdb = &cmdb->dcdb; @@ -1067,10 +1038,6 @@ ips_scsi_pt_cmd(struct scsi_xfer *xs) if (ips_load_xs(sc, ccb, xs)) { DPRINTF(IPS_D_ERR, ("%s: ips_scsi_pt_cmd: ips_load_xs " "failed\n", sc->sc_dev.dv_xname)); - - s = splbio(); - ips_ccb_put(sc, ccb); - splx(s); xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); return; @@ -1490,7 +1457,6 @@ ips_poll(struct ips_softc *sc, struct ip ips_done(sc, ccb); error = ccb->c_error; - ips_ccb_put(sc, ccb); return (error); } @@ -1576,6 +1542,7 @@ ips_done_mgmt(struct ips_softc *sc, stru sc->sc_infom.dm_map->dm_mapsize, ccb->c_flags & SCSI_DATA_IN ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + scsi_io_put(&sc->sc_iopool, ccb); } int @@ -1726,7 +1693,6 @@ ips_intr(void *arg) wakeup(ccb); } else { ips_done(sc, ccb); - ips_ccb_put(sc, ccb); } } @@ -1755,7 +1721,6 @@ ips_timeout(void *arg) */ ccb->c_stat = IPS_STAT_TIMO; ips_done(sc, ccb); - ips_ccb_put(sc, ccb); splx(s); } @@ -1764,11 +1729,8 @@ ips_getadapterinfo(struct ips_softc *sc, { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1788,11 +1750,8 @@ ips_getdriveinfo(struct ips_softc *sc, i { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1812,11 +1771,8 @@ ips_getconf(struct ips_softc *sc, int fl { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1836,11 +1792,8 @@ ips_getpg5(struct ips_softc *sc, int fla { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1862,11 +1815,8 @@ ips_getrblstat(struct ips_softc *sc, int { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1886,11 +1836,8 @@ ips_setstate(struct ips_softc *sc, int c { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -1912,11 +1859,8 @@ ips_rebuild(struct ips_softc *sc, int ch { struct ips_ccb *ccb; struct ips_cmd *cmd; - int s; - s = splbio(); - ccb = ips_ccb_get(sc); - splx(s); + ccb = scsi_io_get(&sc->sc_iopool, 0); if (ccb == NULL) return (1); @@ -2072,30 +2016,34 @@ ips_ccb_free(struct ips_softc *sc, struc free(ccb, M_DEVBUF); } -struct ips_ccb * -ips_ccb_get(struct ips_softc *sc) +void * +ips_ccb_get(void *xsc) { + struct ips_softc *sc = xsc; struct ips_ccb *ccb; - splassert(IPL_BIO); - + mtx_enter(&sc->sc_ccb_mtx); if ((ccb = SLIST_FIRST(&sc->sc_ccbq_free)) != NULL) { SLIST_REMOVE_HEAD(&sc->sc_ccbq_free, c_link); ccb->c_flags = 0; ccb->c_xfer = NULL; bzero(ccb->c_cmdbva, sizeof(struct ips_cmdb)); } + mtx_leave(&sc->sc_ccb_mtx); return (ccb); } void -ips_ccb_put(struct ips_softc *sc, struct ips_ccb *ccb) +ips_ccb_put(void *xsc, void *xccb) { - splassert(IPL_BIO); + struct ips_softc *sc = xsc; + struct ips_ccb *ccb = xccb; ccb->c_state = IPS_CCB_FREE; + mtx_enter(&sc->sc_ccb_mtx); SLIST_INSERT_HEAD(&sc->sc_ccbq_free, ccb, c_link); + mtx_leave(&sc->sc_ccb_mtx); } int