diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2001-10-26 02:20:23 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2001-10-26 02:20:23 +0000 |
commit | c683226654033ba54f604a72d73d1a073d66daaf (patch) | |
tree | 380b0dad6f7cfe708bb59fb60432cfeebc06220f /sys | |
parent | c50ecf110bc16d1ec363efe57071e4b8be352d08 (diff) |
Allocate an appropriate number of cbd's for each discovered LUN
at probe time, rather than allocating them dynamically as
SCSI commands are started.
This should eliminate one possible way of calling bus_dmamem_map()
while in interrupt context.
Potential problem spotted by Art@.
Inspired by changes to achieve same effect in NetBSD by bouyer@.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/siop.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c index f57b087b33e..504a9deed3c 100644 --- a/sys/dev/ic/siop.c +++ b/sys/dev/ic/siop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siop.c,v 1.14 2001/10/08 01:25:06 krw Exp $ */ +/* $OpenBSD: siop.c,v 1.15 2001/10/26 02:20:22 krw Exp $ */ /* $NetBSD: siop.c,v 1.39 2001/02/11 18:04:49 bouyer Exp $ */ /* @@ -212,6 +212,8 @@ siop_attach(sc) sc->sc_dev.dv_xname, (int)sizeof(siop_script), (u_int32_t)sc->sc_scriptaddr, sc->sc_script); #endif + /* Start with one page worth of commands */ + siop_morecbd(sc); /* * sc->sc_link is the template for all device sc_link's @@ -1249,7 +1251,7 @@ siop_scsicmd(xs) { struct siop_softc *sc = (struct siop_softc *)xs->sc_link->adapter_softc; struct siop_cmd *siop_cmd; - int s, error, i; + int s, error, i, j; const int target = xs->sc_link->target; const int lun = xs->sc_link->lun; @@ -1258,19 +1260,9 @@ siop_scsicmd(xs) printf("starting cmd 0x%02x for %d:%d\n", xs->cmd->opcode, target, lun); #endif siop_cmd = TAILQ_FIRST(&sc->free_list); - if (siop_cmd) { + if (siop_cmd != NULL) { TAILQ_REMOVE(&sc->free_list, siop_cmd, next); } else { - if (siop_morecbd(sc) == 0) { - siop_cmd = TAILQ_FIRST(&sc->free_list); -#ifdef DIAGNOSTIC - if (siop_cmd == NULL) - panic("siop_morecbd succeed and does nothing"); -#endif - TAILQ_REMOVE(&sc->free_list, siop_cmd, next); - } - } - if (siop_cmd == NULL) { xs->error = XS_DRIVER_STUFFUP; splx(s); return(TRY_AGAIN_LATER); @@ -1379,6 +1371,15 @@ siop_scsicmd(xs) && (xs->error == XS_NOERROR)) { error = ((struct scsi_inquiry_data *)xs->data)->device & SID_QUAL; if (error != SID_QUAL_BAD_LU) { + /* + * Allocate enough commands to hold at least max openings + * worth of commands. Do this statically now 'cuz + * a) We can't rely on the upper layers to ask for more + * b) Doing it dynamically in siop_startcmd may cause + * calls to bus_dma* functions in interrupt context + */ + for (j = 0; j < SIOP_NTAG; j += SIOP_NCMDPB) + siop_morecbd(sc); if (sc->targets[target]->status == TARST_PROBING) sc->targets[target]->status = TARST_ASYNC; /* Can't do lun 0 here, because flags not set yet */ @@ -1608,7 +1609,7 @@ siop_timeout(v) int s; sc_print_addr(siop_cmd->xs->sc_link); - printf("command timeout\n"); + printf("timeout on SCSI command 0x%x\n", siop_cmd->xs->cmd->opcode); s = splbio(); /* reset the scsi bus */ @@ -1705,7 +1706,7 @@ siop_morecbd(sc) printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname, (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr); #endif - + for (i = 0; i < SIOP_NCMDPB; i++) { error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG, MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, |