diff options
author | Alexander Motin <mav@FreeBSD.org> | 2020-11-18 03:43:03 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2020-11-18 03:43:03 +0000 |
commit | cf770ba3e98eefcb9476ab919d103f36ef5bdbb2 (patch) | |
tree | 7e084c7a2f49e85c83788e752841a46875225092 | |
parent | 27a9392d543933f1aaa4e4ddae2a1585a72db1b2 (diff) |
Notes
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 4 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.h | 6 | ||||
-rw-r--r-- | sys/dev/isp/isp_pci.c | 53 |
3 files changed, 54 insertions, 9 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 29d93c6de36a..84780b6ae122 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -1320,6 +1320,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how) if (isp->isp_dblev & ISP_LOGTDEBUG1) { isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); } + bus_dmamap_sync(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, BUS_DMASYNC_PREWRITE); addr = isp->isp_osinfo.ecmd_dma; addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests, @@ -1469,6 +1470,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how) if (isp->isp_dblev & ISP_LOGTDEBUG1) { isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); } + bus_dmamap_sync(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, BUS_DMASYNC_PREWRITE); addr = isp->isp_osinfo.ecmd_dma; addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests, @@ -4309,6 +4311,7 @@ isp_timer(void *arg) callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp); } +#ifdef ISP_TARGET_MODE isp_ecmd_t * isp_get_ecmd(ispsoftc_t *isp) { @@ -4325,3 +4328,4 @@ isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd) ecmd->next = isp->isp_osinfo.ecmd_free; isp->isp_osinfo.ecmd_free = ecmd; } +#endif diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index a19c10e2b157..7d5da25d1ade 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -75,6 +75,7 @@ #define ISP_IFLAGS INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE +#ifdef ISP_TARGET_MODE #define N_XCMDS 64 #define XCMD_SIZE 512 struct ispsoftc; @@ -85,7 +86,6 @@ typedef union isp_ecmd { isp_ecmd_t * isp_get_ecmd(struct ispsoftc *); void isp_put_ecmd(struct ispsoftc *, isp_ecmd_t *); -#ifdef ISP_TARGET_MODE #define ATPDPSIZE 4096 #define ATPDPHASHSIZE 32 #define ATPDPHASH(x) ((((x) >> 24) ^ ((x) >> 16) ^ ((x) >> 8) ^ (x)) & \ @@ -305,9 +305,13 @@ struct isposinfo { int exec_throttle; int cont_max; +#ifdef ISP_TARGET_MODE + bus_dma_tag_t ecmd_dmat; + bus_dmamap_t ecmd_map; bus_addr_t ecmd_dma; isp_ecmd_t * ecmd_base; isp_ecmd_t * ecmd_free; +#endif /* * Per-type private storage... diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 1d0b2f178d27..381881d55bac 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1476,7 +1476,6 @@ isp_pci_mbxdma(ispsoftc_t *isp) bus_addr_t llim; /* low limit of unavailable dma */ bus_addr_t hlim; /* high limit of unavailable dma */ struct imush im; - isp_ecmd_t *ecmd; /* Already been here? If so, leave... */ if (isp->isp_xflist != NULL) @@ -1512,12 +1511,9 @@ isp_pci_mbxdma(ispsoftc_t *isp) } /* - * Allocate and map the request queue and a region for external - * DMA addressable command/status structures (22XX and later). + * Allocate and map the request queue. */ len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); - if (isp->isp_type >= ISP_HA_FC_2200) - len += (N_XCMDS * XCMD_SIZE); if (bus_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { @@ -1540,12 +1536,39 @@ isp_pci_mbxdma(ispsoftc_t *isp) isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx", (uintmax_t)im.maddr, (uintmax_t)len); isp->isp_rquest_dma = im.maddr; - base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); - im.maddr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); + +#ifdef ISP_TARGET_MODE + /* + * Allocate region for external DMA addressable command/status structures. + */ if (isp->isp_type >= ISP_HA_FC_2200) { + isp_ecmd_t *ecmd; + + len = N_XCMDS * XCMD_SIZE; + if (bus_dma_tag_create(isp->isp_osinfo.dmat, XCMD_SIZE, slim, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { + isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); + goto bad; + } + if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, + BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { + isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); + bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); + goto bad; + } + isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; + im.error = 0; + if (bus_dmamap_load(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, + base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { + isp_prt(isp, ISP_LOGERR, "error loading ECMD DMA map %d", im.error); + goto bad; + } + isp_prt(isp, ISP_LOGDEBUG0, "ecmd area @ 0x%jx/0x%jx", + (uintmax_t)im.maddr, (uintmax_t)len); + isp->isp_osinfo.ecmd_dma = im.maddr; isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)base; - isp->isp_osinfo.ecmd_base = isp->isp_osinfo.ecmd_free; for (ecmd = isp->isp_osinfo.ecmd_free; ecmd < &isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) { if (ecmd == &isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) @@ -1554,6 +1577,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) ecmd->next = ecmd + 1; } } +#endif /* * Allocate and map the result queue. @@ -1786,6 +1810,19 @@ isp_pci_mbxdmafree(ispsoftc_t *isp) bus_dma_tag_destroy(isp->isp_osinfo.respdmat); isp->isp_result = NULL; } +#ifdef ISP_TARGET_MODE + if (isp->isp_osinfo.ecmd_dma != 0) { + bus_dmamap_unload(isp->isp_osinfo.ecmd_dmat, + isp->isp_osinfo.ecmd_map); + isp->isp_osinfo.ecmd_dma = 0; + } + if (isp->isp_osinfo.ecmd_base != NULL) { + bus_dmamem_free(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_base, + isp->isp_osinfo.ecmd_map); + bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); + isp->isp_osinfo.ecmd_base = NULL; + } +#endif if (isp->isp_rquest_dma != 0) { bus_dmamap_unload(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap); |