Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132641503
D6824.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D6824.diff
View Options
Index: head/sys/dev/iwm/if_iwm.c
===================================================================
--- head/sys/dev/iwm/if_iwm.c
+++ head/sys/dev/iwm/if_iwm.c
@@ -956,6 +956,8 @@
{
bus_addr_t paddr;
bus_size_t size;
+ size_t maxsize;
+ int nsegments;
int i, error;
ring->qid = qid;
@@ -988,9 +990,18 @@
}
ring->cmd = ring->cmd_dma.vaddr;
+ /* FW commands may require more mapped space than packets. */
+ if (qid == IWM_MVM_CMD_QUEUE) {
+ maxsize = IWM_RBUF_SIZE;
+ nsegments = 1;
+ } else {
+ maxsize = MCLBYTES;
+ nsegments = IWM_MAX_SCATTER - 2;
+ }
+
error = bus_dma_tag_create(sc->sc_dmat, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
- IWM_MAX_SCATTER - 2, MCLBYTES, 0, NULL, NULL, &ring->data_dmat);
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, maxsize,
+ nsegments, maxsize, 0, NULL, NULL, &ring->data_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "could not create TX buf DMA tag\n");
goto fail;
Index: head/sys/dev/iwm/if_iwm_util.c
===================================================================
--- head/sys/dev/iwm/if_iwm_util.c
+++ head/sys/dev/iwm/if_iwm_util.c
@@ -157,19 +157,6 @@
#include <dev/iwm/if_iwm_util.h>
#include <dev/iwm/if_iwm_pcie_trans.h>
-static void
-iwm_dma_map_mem(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
- if (error != 0)
- return;
- KASSERT(nsegs <= 2, ("too many DMA segments, %d should be <= 2",
- nsegs));
- if (nsegs > 1)
- KASSERT(segs[1].ds_addr == segs[0].ds_addr + segs[0].ds_len,
- ("fragmented DMA memory"));
- *(bus_addr_t *)arg = segs[0].ds_addr;
-}
-
/*
* Send a command to the firmware. We try to implement the Linux
* driver interface for the routine.
@@ -183,12 +170,15 @@
struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE];
struct iwm_tfd *desc;
struct iwm_tx_data *data;
- struct iwm_device_cmd *cmd = NULL;
+ struct iwm_device_cmd *cmd;
+ struct mbuf *m;
+ bus_dma_segment_t seg;
bus_addr_t paddr;
uint32_t addr_lo;
int error = 0, i, paylen, off;
int code;
int async, wantresp;
+ int nsegs;
code = hcmd->id;
async = hcmd->flags & IWM_CMD_ASYNC;
@@ -231,15 +221,24 @@
error = EINVAL;
goto out;
}
- error = bus_dmamem_alloc(ring->data_dmat, (void **)&cmd,
- BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &data->map);
- if (error != 0)
+ m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWM_RBUF_SIZE);
+ if (m == NULL) {
+ error = ENOBUFS;
goto out;
- error = bus_dmamap_load(ring->data_dmat, data->map,
- cmd, paylen + sizeof(cmd->hdr), iwm_dma_map_mem,
- &paddr, BUS_DMA_NOWAIT);
- if (error != 0)
+ }
+
+ m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
+ error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
+ data->map, m, &seg, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: can't map mbuf, error %d\n", __func__, error);
+ m_freem(m);
goto out;
+ }
+ data->m = m; /* mbuf will be freed in iwm_cmd_done() */
+ cmd = mtod(m, struct iwm_device_cmd *);
+ paddr = seg.ds_addr;
} else {
cmd = &ring->cmd[ring->cur];
paddr = data->cmd_paddr;
@@ -319,8 +318,6 @@
}
}
out:
- if (cmd && paylen > sizeof(cmd->data))
- bus_dmamem_free(ring->data_dmat, cmd, data->map);
if (wantresp && error != 0) {
iwm_free_resp(sc, hcmd);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 19, 4:37 PM (1 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23932824
Default Alt Text
D6824.diff (3 KB)
Attached To
Mode
D6824: [iwm] Use mbuf for large firmware commands, like OpenBSD does.
Attached
Detach File
Event Timeline
Log In to Comment