DF-4614 / fix.diff
diff --git a/sys/dev/raid/ips/ips.c b/sys/dev/raid/ips/ips.c index 1111111..2222222 100644 --- a/sys/dev/raid/ips/ips.c +++ b/sys/dev/raid/ips/ips.c @@ -118,6 +118,12 @@ static int ips_cmdqueue_free(ips_softc_t *sc) { int i, error = -1; ips_command_t *command; crit_enter(); + if (sc->commandarray == NULL) { + crit_exit(); + return 0; + } if (sc->used_commands == 0) { @@ -137,9 +143,11 @@ ips_cmdqueue_free(ips_softc_t *sc) error = 0; sc->state |= IPS_OFFLINE; + } else { + /* commands still outstanding: do not free the array under + * the interrupt handler; leave it mapped and report busy */ + crit_exit(); + return error; } sc->staticcmd = NULL; kfree(sc->commandarray, M_IPSBUF); + sc->commandarray = NULL; crit_exit(); return error; } @@ -411,7 +419,9 @@ ips_adapter_init(ips_softc_t *sc) * create one command buffer until we know how many commands this card * can handle */ sc->max_cmds = 1; - ips_cmdqueue_init(sc); + if (ips_cmdqueue_init(sc)) { + device_printf(sc->dev, "initial command queue alloc failed\n"); + goto error; + } callout_init(&sc->timer); |