Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102689422
D42559.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D42559.diff
View Options
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
@@ -980,6 +980,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 */
@@ -1434,6 +1439,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 concern.
+ */
if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */
4, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
@@ -1668,6 +1679,22 @@
sc->max_host_ios = sc->facts.max_reqs -
(MPI3MR_INTERNALCMDS_RESVD + 1);
+ /*
+ * Set 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.
+ */
+ 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;
}
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,6 +273,16 @@
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 could retroactively 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 */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 16, 9:52 PM (21 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14664973
Default Alt Text
D42559.diff (2 KB)
Attached To
Mode
D42559: mpi3mr: Honor the dma mask from IOCFacts
Attached
Detach File
Event Timeline
Log In to Comment