Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149489285
D42559.1790251541.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D42559.1790251541.diff
View Options
diff --git a/sys/dev/mpi3mr/mpi3mr.h b/sys/dev/mpi3mr/mpi3mr.h
--- a/sys/dev/mpi3mr/mpi3mr.h
+++ b/sys/dev/mpi3mr/mpi3mr.h
@@ -544,7 +544,8 @@
char name[MPI3MR_NAME_LENGTH];
char driver_name[MPI3MR_NAME_LENGTH];
int bars;
- int dma_mask;
+ bus_addr_t dma_loaddr;
+ bus_addr_t dma_hiaddr;
u_int mpi3mr_debug;
struct mpi3mr_reset reset;
int max_msix_vectors;
diff --git a/sys/dev/mpi3mr/mpi3mr.c b/sys/dev/mpi3mr/mpi3mr.c
--- a/sys/dev/mpi3mr/mpi3mr.c
+++ b/sys/dev/mpi3mr/mpi3mr.c
@@ -604,8 +604,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
op_reply_q->qsz, /* maxsize */
1, /* nsegments */
@@ -619,7 +619,7 @@
if (bus_dmamem_alloc(op_reply_q->q_base_tag, (void **)&op_reply_q->q_base,
BUS_DMA_NOWAIT, &op_reply_q->q_base_dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
return (ENOMEM);
}
bzero(op_reply_q->q_base, op_reply_q->qsz);
@@ -750,8 +750,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
op_req_q->qsz, /* maxsize */
1, /* nsegments */
@@ -765,7 +765,7 @@
if (bus_dmamem_alloc(op_req_q->q_base_tag, (void **)&op_req_q->q_base,
BUS_DMA_NOWAIT, &op_req_q->q_base_dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
return (ENOMEM);
}
@@ -981,6 +981,11 @@
sc->admin_reply_ephase = 1;
if (!sc->admin_req) {
+ /*
+ * We need to create the tag for the admin queue to get the
+ * iofacts to see how many bits the controller decodes. Solve
+ * this chicken and egg problem by only doing lower 4GB dma.
+ */
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
@@ -998,7 +1003,7 @@
if (bus_dmamem_alloc(sc->admin_req_tag, (void **)&sc->admin_req,
BUS_DMA_NOWAIT, &sc->admin_req_dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
return (ENOMEM);
}
bzero(sc->admin_req, sc->admin_req_q_sz);
@@ -1036,7 +1041,7 @@
if (bus_dmamem_alloc(sc->admin_reply_tag, (void **)&sc->admin_reply,
BUS_DMA_NOWAIT, &sc->admin_reply_dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
return (ENOMEM);
}
bzero(sc->admin_reply, sc->admin_reply_q_sz);
@@ -1435,6 +1440,12 @@
MPI3_SGE_FLAGS_END_OF_LIST);
+ /*
+ * We can't use sc->dma_loaddr / hiaddr here. We set those only after we
+ * get the iocfacts. So allocate in the lower 4GB. The amount of data is
+ * tiny and we don't do this that often, so any bouncing we might have
+ * to do isn't a cause for concernt.
+ */
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
@@ -1669,6 +1680,23 @@
sc->max_host_ios = sc->facts.max_reqs -
(MPI3MR_INTERNALCMDS_RESVD + 1);
+ /*
+ * Setup the dma mask for the card. dma_mask is the number of bits that
+ * can have bits set in them. Translate this into bus_dma loaddr/hiaddr
+ * args. Add sanity for more bits than address space or other overflow
+ * situations. Assumes that BUS_SPACE_MAXADDR can fit into a bus_addr_t
+ * and is defined best for this platform.
+ */
+ if (sc->facts.dma_mask == 0 ||
+ (sc->facts.dma_mask >= sizeof(bus_addr_t) * 8))
+ sc->dma_loaddr = BUS_SPACE_MAXADDR;
+ else
+ sc->dma_loaddr = ~((1ull << sc->facts.dma_mask) - 1);
+ sc->dma_hiaddr = BUS_SPACE_MAXADDR;
+ mpi3mr_dprint(sc, MPI3MR_INFO,
+ "dma_mask bits: %d loaddr 0x%jx hiaddr 0x%jx\n",
+ sc->facts.dma_mask, sc->dma_loaddr, sc->dma_hiaddr);
+
return retval;
}
@@ -1704,8 +1732,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sz, /* maxsize */
1, /* nsegments */
@@ -1740,8 +1768,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
8, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sz, /* maxsize */
1, /* nsegments */
@@ -1774,8 +1802,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sz, /* maxsize */
1, /* nsegments */
@@ -1808,8 +1836,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
8, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sz, /* maxsize */
1, /* nsegments */
@@ -1945,8 +1973,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
fw_pkg_ver_len, /* maxsize */
1, /* nsegments */
@@ -2066,8 +2094,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
drvr_info_len, /* maxsize */
1, /* nsegments */
@@ -2482,8 +2510,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4096, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sz, /* maxsize */
1, /* nsegments */
@@ -2558,8 +2586,8 @@
sc->pel_seq_number_sz = sizeof(Mpi3PELSeq_t);
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
sc->pel_seq_number_sz, /* maxsize */
1, /* nsegments */
@@ -4906,8 +4934,8 @@
nsegs = MPI3MR_SG_DEPTH;
ret = bus_dma_tag_create( sc->mpi3mr_parent_dmat, /* parent */
1, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
MAXPHYS,/* maxsize */
nsegs, /* nsegments */
@@ -5080,8 +5108,8 @@
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
mem_desc->size, /* maxsize */
1, /* nsegments */
@@ -5095,7 +5123,7 @@
if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
goto out_failed;
}
bzero(mem_desc->addr, mem_desc->size);
@@ -5110,8 +5138,8 @@
mem_desc->size = MPI3MR_4K_PGSZ;
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
mem_desc->size, /* maxsize */
1, /* nsegments */
@@ -5125,7 +5153,7 @@
if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
- mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
goto out_failed;
}
bzero(mem_desc->addr, mem_desc->size);
@@ -5139,8 +5167,8 @@
mem_desc->size = MPI3MR_4K_PGSZ;
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
mem_desc->size, /* maxsize */
1, /* nsegments */
diff --git a/sys/dev/mpi3mr/mpi3mr_app.c b/sys/dev/mpi3mr/mpi3mr_app.c
--- a/sys/dev/mpi3mr/mpi3mr_app.c
+++ b/sys/dev/mpi3mr/mpi3mr_app.c
@@ -336,8 +336,8 @@
sc->nvme_encap_prp_sz = 0;
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
+ sc->dma_loaddr, /* lowaddr */
+ sc->dma_hiaddr, /* highaddr */
NULL, NULL, /* filter, filterarg */
dev_pgsz, /* maxsize */
1, /* nsegments */
diff --git a/sys/dev/mpi3mr/mpi3mr_pci.c b/sys/dev/mpi3mr/mpi3mr_pci.c
--- a/sys/dev/mpi3mr/mpi3mr_pci.c
+++ b/sys/dev/mpi3mr/mpi3mr_pci.c
@@ -273,10 +273,20 @@
sc->mpi3mr_btag = rman_get_bustag(sc->mpi3mr_regs_resource);
sc->mpi3mr_bhandle = rman_get_bushandle(sc->mpi3mr_regs_resource);
+ /*
+ * XXX perhaps we should move this to after we read iocfacts and use
+ * that to create the proper parent tag. However, to get the iocfacts we
+ * need to have a dmatag for both the admin queue and the iocfacts dma
+ * transfer. So for now, we just create a 'no restriction' tag and use
+ * sc->dma_loaddr for all the other tag_create calls to get the right
+ * value. It would be nice if one would retro-actively adjust a created
+ * tag. The Linux driver effectively does this by setting the dma_mask
+ * on the device.
+ */
/* Allocate the parent DMA tag */
if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
1, 0, /* algnmnt, boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
BUS_SPACE_MAXSIZE_32BIT,/* maxsize */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 24, 12:05 PM (15 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29901788
Default Alt Text
D42559.1790251541.diff (11 KB)
Attached To
Mode
D42559: mpi3mr: Honor the dma mask from IOCFacts
Attached
Detach File
Event Timeline
Log In to Comment