Author: mav Date: Wed Nov 18 03:43:03 2020 New Revision: 367784 URL: https://svnweb.freebsd.org/changeset/base/367784
Log: Move ecmd memory allocation itto separate DMA tag. Ecmd memory is not directly related to the request queue, only referenced from it sometimes in target mode. Separate allocation should be easier in case of fragmented memory and can be skipped when target is not built. MFC after: 1 month Modified: head/sys/dev/isp/isp_freebsd.c head/sys/dev/isp/isp_freebsd.h head/sys/dev/isp/isp_pci.c Modified: head/sys/dev/isp/isp_freebsd.c ============================================================================== --- head/sys/dev/isp/isp_freebsd.c Wed Nov 18 03:30:31 2020 (r367783) +++ head/sys/dev/isp/isp_freebsd.c Wed Nov 18 03:43:03 2020 (r367784) @@ -1320,6 +1320,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, 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, 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 Modified: head/sys/dev/isp/isp_freebsd.h ============================================================================== --- head/sys/dev/isp/isp_freebsd.h Wed Nov 18 03:30:31 2020 (r367783) +++ head/sys/dev/isp/isp_freebsd.h Wed Nov 18 03:43:03 2020 (r367784) @@ -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... Modified: head/sys/dev/isp/isp_pci.c ============================================================================== --- head/sys/dev/isp/isp_pci.c Wed Nov 18 03:30:31 2020 (r367783) +++ head/sys/dev/isp/isp_pci.c Wed Nov 18 03:43:03 2020 (r367784) @@ -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); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"