DF-4615 / 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 @@ -672,8 +672,12 @@ exit: bus_dmamem_free(dmatag, sc->copper_queue, dmamap); bus_dma_tag_destroy(dmatag); + sc->copper_queue = NULL; return error; } +/* free the current status queue (if any) - used before re-allocating on + * reinit and on driver teardown */ +static void ips_copperhead_queue_free(ips_softc_t *sc); + static int ips_copperhead_queue_init(ips_softc_t *sc) { @@ -647,6 +651,9 @@ static int bus_dmamap_t dmamap = NULL; int error; + /* DF-4615: a reinit must not leak the previous queue mapping */ + ips_copperhead_queue_free(sc); + if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, @@ -727,7 +734,10 @@ ips_copperhead_reinit(ips_softc_t *sc, int force) ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT); ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT); - ips_copperhead_queue_init(sc); + if (ips_copperhead_queue_init(sc) != 0) { + device_printf(sc->dev, "status queue init failed\n"); + return 1; + } ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT); |