@@ -1372,28 +1372,16 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
if (resp && resp_len && *resp_len == 0)
return -EINVAL;
- treq = kmemdup(req, req_len, GFP_KERNEL);
- if (!treq)
- return -ENOMEM;
-
- req_paddr = dma_map_single(ar->dev, treq, req_len, DMA_TO_DEVICE);
- ret = dma_mapping_error(ar->dev, req_paddr);
- if (ret) {
+ treq = dma_alloc_coherent(ar->dev, req_len, &req_paddr, GFP_KERNEL);
+ if (!treq) {
ret = -EIO;
goto err_dma;
}
+ memcpy(treq, req, req_len);
if (resp && resp_len) {
- tresp = kzalloc(*resp_len, GFP_KERNEL);
+ tresp = dma_alloc_coherent(ar->dev, *resp_len, &resp_paddr, GFP_KERNEL);
if (!tresp) {
- ret = -ENOMEM;
- goto err_req;
- }
-
- resp_paddr = dma_map_single(ar->dev, tresp, *resp_len,
- DMA_FROM_DEVICE);
- ret = dma_mapping_error(ar->dev, resp_paddr);
- if (ret) {
ret = EIO;
goto err_req;
}
@@ -1422,23 +1410,19 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
}
err_resp:
+ if (ret == 0 && resp_len) {
+ *resp_len = min(*resp_len, xfer.resp_len);
+ memcpy(resp, tresp, xfer.resp_len);
+ }
if (resp) {
u32 unused_buffer;
ath10k_ce_revoke_recv_next(ce_rx, NULL, &unused_buffer);
- dma_unmap_single(ar->dev, resp_paddr,
- *resp_len, DMA_FROM_DEVICE);
+ dma_free_coherent(ar->dev, *resp_len, tresp, resp_paddr);
}
err_req:
- dma_unmap_single(ar->dev, req_paddr, req_len, DMA_TO_DEVICE);
-
- if (ret == 0 && resp_len) {
- *resp_len = min(*resp_len, xfer.resp_len);
- memcpy(resp, tresp, xfer.resp_len);
- }
+ dma_free_coherent(ar->dev, req_len, treq, req_paddr);
err_dma:
- kfree(treq);
- kfree(tresp);
return ret;
}
Update to convert the use of kmemdup to dma_alloc_coherent as dma_alloc_coherent will consider DMA region limits such as those seen with CONFIG_FSL_PCI && CONFIG_ZONE_DMA32 whereas kmemdup does not take those limitations into account. Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com> --- drivers/net/wireless/ath/ath10k/pci.c | 36 ++++++++++------------------------- 1 file changed, 10 insertions(+), 26 deletions(-)