Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Nov 2020 03:43:04 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r367784 - head/sys/dev/isp
Message-ID:  <202011180343.0AI3h4tQ012508@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011180343.0AI3h4tQ012508>