summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2020-11-18 03:43:03 +0000
committerAlexander Motin <mav@FreeBSD.org>2020-11-18 03:43:03 +0000
commitcf770ba3e98eefcb9476ab919d103f36ef5bdbb2 (patch)
tree7e084c7a2f49e85c83788e752841a46875225092
parent27a9392d543933f1aaa4e4ddae2a1585a72db1b2 (diff)
Notes
-rw-r--r--sys/dev/isp/isp_freebsd.c4
-rw-r--r--sys/dev/isp/isp_freebsd.h6
-rw-r--r--sys/dev/isp/isp_pci.c53
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);