Page MenuHomeFreeBSD

D42559.1790251541.diff
No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None

D42559.1790251541.diff

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

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)

Event Timeline