diff --git a/sys/dev/disk/isp/isp_freebsd.h b/sys/dev/disk/isp/isp_freebsd.h --- a/sys/dev/disk/isp/isp_freebsd.h +++ b/sys/dev/disk/isp/isp_freebsd.h @@ -152,6 +152,7 @@ struct thread *kthread; bus_dma_tag_t tdmat; bus_dmamap_t tdmap; + caddr_t rscratch; /* DF-2474: scratch DMA vaddr for error cleanup */ uint64_t def_wwpn; uint64_t def_wwnn; uint32_t loop_down_time; diff --git a/sys/dev/disk/isp/isp_pci.c b/sys/dev/disk/isp/isp_pci.c --- a/sys/dev/disk/isp/isp_pci.c +++ b/sys/dev/disk/isp/isp_pci.c @@ -1615,6 +1615,7 @@ im.error = 0; bus_dmamap_load(isp->isp_osinfo.cdmat, isp->isp_osinfo.cdmap, base, len, imc, &im, 0); + caddr_t ctrl_base = base; /* DF-2474: save control-area base */ if (im.error) { isp_prt(isp, ISP_LOGERR, "error %d loading dma map for control areas", im.error); goto bad; @@ -1635,6 +1636,7 @@ im.vbase = base; im.error = 0; bus_dmamap_load(fc->tdmat, fc->tdmap, base, ISP_FC_SCRLEN, imc1, &im, 0); + fc->rscratch = base; /* DF-2474: save per-channel scratch base */ if (im.error) { bus_dmamem_free(fc->tdmat, base, fc->tdmap); bus_dma_tag_destroy(fc->tdmat); @@ -1667,10 +1669,10 @@ bad: while (--cmap >= 0) { struct isp_fc *fc = ISP_FC_PC(isp, cmap); - bus_dmamem_free(fc->tdmat, base, fc->tdmap); + bus_dmamem_free(fc->tdmat, fc->rscratch, fc->tdmap); bus_dma_tag_destroy(fc->tdmat); } - bus_dmamem_free(isp->isp_osinfo.cdmat, base, isp->isp_osinfo.cdmap); + bus_dmamem_free(isp->isp_osinfo.cdmat, ctrl_base, isp->isp_osinfo.cdmap); bus_dma_tag_destroy(isp->isp_osinfo.cdmat); kfree(isp->isp_xflist, M_DEVBUF); #ifdef ISP_TARGET_MODE