diff options
author | Aaron Durbin <adurbin@chromium.org> | 2014-02-07 19:25:51 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-12 15:36:15 -0500 |
commit | 189b3299fe46c3d3f7555e1c80e8e8691e71faf1 (patch) | |
tree | 7266f6b4f4c21a3c7d2464982b82f3b2ecbbe611 | |
parent | dbccc92b5d543d1ead727f1416af9e113a3ccc4a (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.c | 14 |
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 | ||