summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp_pci.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-04-12 14:19:19 +0000
committermav <mav@FreeBSD.org>2016-04-12 14:19:19 +0000
commitcbfc99fd680dc842757b8e5a0e1688f9fda6a75b (patch)
treeb462101073da292d02baa274f4499c7efb140cac /sys/dev/isp/isp_pci.c
parentf7d20d373434d068dcb6a6c509c1658cf683c026 (diff)
downloadFreeBSD-src-cbfc99fd680dc842757b8e5a0e1688f9fda6a75b.zip
FreeBSD-src-cbfc99fd680dc842757b8e5a0e1688f9fda6a75b.tar.gz
Allocate separate DMA area for synchronous IOCB execution.
Usually IOCBs should be put on queue for asynchronous processing and should not require additional DMA memory. But there are some cases like aborts and resets that for external reasons has to be synchronous. Give those cases separate 2*64 byte DMA area to decouple them from other DMA scratch area users, using it for asynchronous requests.
Diffstat (limited to 'sys/dev/isp/isp_pci.c')
-rw-r--r--sys/dev/isp/isp_pci.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 11386ee..0eefc16 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1730,9 +1730,23 @@ isp_pci_mbxdma(ispsoftc_t *isp)
if (IS_FC(isp)) {
if (isp_dma_tag_create(isp->isp_osinfo.dmat, 64, slim,
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
- ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, &isp->isp_osinfo.scdmat)) {
+ 2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, &isp->isp_osinfo.iocbdmat)) {
goto bad;
}
+ if (bus_dmamem_alloc(isp->isp_osinfo.iocbdmat,
+ (void **)&base, BUS_DMA_COHERENT, &isp->isp_osinfo.iocbmap) != 0)
+ goto bad;
+ isp->isp_iocb = base;
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap,
+ base, 2*QENTRY_LEN, imc, &im, 0) || im.error)
+ goto bad;
+ isp->isp_iocb_dma = im.maddr;
+
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, 64, slim,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, &isp->isp_osinfo.scdmat))
+ goto bad;
for (cmap = 0; cmap < isp->isp_nchan; cmap++) {
struct isp_fc *fc = ISP_FC_PC(isp, cmap);
if (bus_dmamem_alloc(isp->isp_osinfo.scdmat,
@@ -1791,7 +1805,8 @@ bad:
while (--cmap >= 0) {
struct isp_fc *fc = ISP_FC_PC(isp, cmap);
bus_dmamap_unload(isp->isp_osinfo.scdmat, fc->scmap);
- bus_dmamem_free(isp->isp_osinfo.scdmat, base, fc->scmap);
+ bus_dmamem_free(isp->isp_osinfo.scdmat,
+ FCPARAM(isp, cmap)->isp_scratch, fc->scmap);
while (fc->nexus_free_list) {
struct isp_nexus *n = fc->nexus_free_list;
fc->nexus_free_list = n->next;
@@ -1799,6 +1814,10 @@ bad:
}
}
bus_dma_tag_destroy(isp->isp_osinfo.scdmat);
+ bus_dmamap_unload(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap);
+ bus_dmamem_free(isp->isp_osinfo.iocbdmat, isp->isp_iocb,
+ isp->isp_osinfo.iocbmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat);
}
bad1:
if (isp->isp_rquest_dma != 0) {
OpenPOWER on IntegriCloud