I put the diff below together to add NO_CCB handling to ciss(4). It has been beat on with on some new HP systems and no regressions reported so far.
This diff removes the reservation of a couple of ccb's for bioctl and sensor i/o's and let's the NO_CCB backpressure mechanism handle the situations where an i/o could not be started. It also adds some paranoia checks when allocating ccb's. Any ciss and teller's out there want to do more testing? .... Ken Index: ciss.c =================================================================== RCS file: /cvs/src/sys/dev/ic/ciss.c,v retrieving revision 1.34 diff -u -p -r1.34 ciss.c --- ciss.c 29 Apr 2009 08:24:26 -0000 1.34 +++ ciss.c 6 Nov 2009 02:28:15 -0000 @@ -382,11 +382,6 @@ ciss_attach(struct ciss_softc *sc) sc->sc_link.device = &ciss_dev; sc->sc_link.adapter_softc = sc; sc->sc_link.openings = sc->maxcmd / (sc->maxunits? sc->maxunits : 1); -#if NBIO > 0 - /* XXX Reserve some ccb's for sensor and bioctl. */ - if (sc->maxunits < 2 && sc->sc_link.openings > 2) - sc->sc_link.openings -= 2; -#endif sc->sc_link.adapter = &ciss_switch; sc->sc_link.adapter_target = sc->maxunits; sc->sc_link.adapter_buswidth = sc->maxunits; @@ -409,8 +404,8 @@ ciss_attach(struct ciss_softc *sc) #endif #if NBIO > 0 - /* XXX for now we can only deal w/ one volume and need reserved ccbs. */ - if (!scsibus || sc->maxunits > 1 || sc->sc_link.openings == sc->maxcmd) + /* XXX for now we can only deal w/ one volume. */ + if (!scsibus || sc->maxunits > 1) return 0; /* now map all the physdevs into their lds */ @@ -764,6 +759,9 @@ ciss_inq(struct ciss_softc *sc, struct c struct ciss_cmd *cmd; ccb = ciss_get_ccb(sc); + if (ccb == NULL) + return ENOMEM; + ccb->ccb_len = sizeof(*inq); ccb->ccb_data = inq; cmd = &ccb->ccb_cmd; @@ -796,6 +794,9 @@ ciss_ldmap(struct ciss_softc *sc) total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map); ccb = ciss_get_ccb(sc); + if (ccb == NULL) + return ENOMEM; + ccb->ccb_len = total; ccb->ccb_data = lmap; cmd = &ccb->ccb_cmd; @@ -836,6 +837,9 @@ ciss_sync(struct ciss_softc *sc) flush->flush = sc->sc_flush; ccb = ciss_get_ccb(sc); + if (ccb == NULL) + return ENOMEM; + ccb->ccb_len = sizeof(*flush); ccb->ccb_data = flush; cmd = &ccb->ccb_cmd; @@ -886,13 +890,14 @@ ciss_scsi_raw_cmd(struct scsi_xfer *xs) /* TODO check this target has not yet employed w/ any volume */ ccb = ciss_get_ccb(sc); + if (ccb == NULL) + return NO_CCB; + cmd = &ccb->ccb_cmd; ccb->ccb_len = xs->datalen; ccb->ccb_data = xs->data; ccb->ccb_xs = xs; - - cmd->cdblen = xs->cmdlen; cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL; if (xs->flags & SCSI_DATA_IN) @@ -945,6 +950,9 @@ ciss_scsi_cmd(struct scsi_xfer *xs) /* XXX emulate SYNCHRONIZE_CACHE ??? */ ccb = ciss_get_ccb(sc); + if (ccb == NULL) + return NO_CCB; + cmd = &ccb->ccb_cmd; ccb->ccb_len = xs->datalen; ccb->ccb_data = xs->data; @@ -1291,6 +1299,7 @@ ciss_ldid(struct ciss_softc *sc, int tar ccb = ciss_get_ccb(sc); if (ccb == NULL) return ENOMEM; + ccb->ccb_len = sizeof(*id); ccb->ccb_data = id; ccb->ccb_xs = NULL; @@ -1319,6 +1328,7 @@ ciss_ldstat(struct ciss_softc *sc, int t ccb = ciss_get_ccb(sc); if (ccb == NULL) return ENOMEM; + ccb->ccb_len = sizeof(*stat); ccb->ccb_data = stat; ccb->ccb_xs = NULL; @@ -1347,6 +1357,7 @@ ciss_pdid(struct ciss_softc *sc, u_int8_ ccb = ciss_get_ccb(sc); if (ccb == NULL) return ENOMEM; + ccb->ccb_len = sizeof(*id); ccb->ccb_data = id; ccb->ccb_xs = NULL; @@ -1425,6 +1436,7 @@ ciss_blink(struct ciss_softc *sc, int ld ccb = ciss_get_ccb(sc); if (ccb == NULL) return ENOMEM; + ccb->ccb_len = sizeof(*blink); ccb->ccb_data = blink; ccb->ccb_xs = NULL;