aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-02-07 19:25:51 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-12 15:36:15 -0500
commit189b3299fe46c3d3f7555e1c80e8e8691e71faf1 (patch)
tree7266f6b4f4c21a3c7d2464982b82f3b2ecbbe611
parentdbccc92b5d543d1ead727f1416af9e113a3ccc4a (diff)
mwifiex: don't leak DMA command skbuffs
The current mwifiex pcie driver assumed that it would get its cmdrsp_complete() callback called before another command was sent to unmap the command's skbuff. However, that is not true. The mwifiex_check_ps_cond() will send a sleep command to the card without having adapter->curr_cmd set. Within the workqueue's state machine the adapter's state would be set to allow commands (curr_cmd = NULL && cmd_sent = false) after having receieved the response from the sleep command. The card->cmd_buf would then be overridden with the new command but the first command's skbuff was not unmapped. This leaks mapped skbuffs when a bounce buffer is employed. To rectify this unmap the card->cmd_buf when the response is received from the card instead of waiting for the cmdrsp_complete() callback. Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Paul Stewart <pstew@chromium.org> Reviewed-by: Avinash Patil <patila@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4e1c6b268f99..d11d4acf0890 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1513,6 +1513,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1513 1513
1514 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); 1514 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
1515 1515
1516 /* Unmap the command as a response has been received. */
1517 if (card->cmd_buf) {
1518 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1519 PCI_DMA_TODEVICE);
1520 card->cmd_buf = NULL;
1521 }
1522
1516 pkt_len = *((__le16 *)skb->data); 1523 pkt_len = *((__le16 *)skb->data);
1517 rx_len = le16_to_cpu(pkt_len); 1524 rx_len = le16_to_cpu(pkt_len);
1518 skb_trim(skb, rx_len); 1525 skb_trim(skb, rx_len);
@@ -1569,7 +1576,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1569 struct sk_buff *skb) 1576 struct sk_buff *skb)
1570{ 1577{
1571 struct pcie_service_card *card = adapter->card; 1578 struct pcie_service_card *card = adapter->card;
1572 struct sk_buff *skb_tmp;
1573 1579
1574 if (skb) { 1580 if (skb) {
1575 card->cmdrsp_buf = skb; 1581 card->cmdrsp_buf = skb;
@@ -1579,12 +1585,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1579 return -1; 1585 return -1;
1580 } 1586 }
1581 1587
1582 skb_tmp = card->cmd_buf;
1583 if (skb_tmp) {
1584 mwifiex_unmap_pci_memory(adapter, skb_tmp, PCI_DMA_FROMDEVICE);
1585 card->cmd_buf = NULL;
1586 }
1587
1588 return 0; 1588 return 0;
1589} 1589}
1590 1590