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"

Reply via email to