Commit 2f47150a authored by Brian Norris's avatar Brian Norris Committed by Kalle Valo

mwifiex: pcie: disable device DMA before unmapping/freeing buffers

In testing the mwifiex reset code path, I've noticed KASAN complaining
about some "overwritten poison values" in our RX buffer descriptors.
Because KASAN didn't notice this at the time of a CPU write, this seems
to suggest that the device is writing to this memory.

This makes a little sense, because when resetting, we don't necessarily
expect the device to be responsive, so we don't have a chance to disable
everything cleanly.

We can at least take the precaution of disabling DMA for the device
though, and in my testing that seems to clear up this particular issue.

This patch reorders the removal path so that we disable the device
*before* releasing our last PCIe buffers, and it clears/sets the bus
master feature from the PCI device when resetting.

Along the way, remove the insufficient (and confusing) error path in
mwifiex_pcie_up_dev() (it doesn't unwind things well enough, and it
doesn't propagate its errors upward anyway).
Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 37680819
...@@ -2971,15 +2971,17 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) ...@@ -2971,15 +2971,17 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
"Failed to write driver not-ready signature\n"); "Failed to write driver not-ready signature\n");
} }
mwifiex_pcie_free_buffers(adapter);
if (pdev) { if (pdev) {
pci_disable_device(pdev);
pci_iounmap(pdev, card->pci_mmap); pci_iounmap(pdev, card->pci_mmap);
pci_iounmap(pdev, card->pci_mmap1); pci_iounmap(pdev, card->pci_mmap1);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_release_region(pdev, 2); pci_release_region(pdev, 2);
pci_release_region(pdev, 0); pci_release_region(pdev, 0);
} }
mwifiex_pcie_free_buffers(adapter);
} }
static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter) static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
...@@ -3155,7 +3157,6 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) ...@@ -3155,7 +3157,6 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter) static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
int ret;
struct pci_dev *pdev = card->dev; struct pci_dev *pdev = card->dev;
/* tx_buf_size might be changed to 3584 by firmware during /* tx_buf_size might be changed to 3584 by firmware during
...@@ -3163,11 +3164,9 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter) ...@@ -3163,11 +3164,9 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
*/ */
adapter->tx_buf_size = card->pcie.tx_buf_size; adapter->tx_buf_size = card->pcie.tx_buf_size;
ret = mwifiex_pcie_alloc_buffers(adapter); mwifiex_pcie_alloc_buffers(adapter);
if (!ret)
return;
pci_iounmap(pdev, card->pci_mmap1); pci_set_master(pdev);
} }
/* This function cleans up the PCI-E host memory space. */ /* This function cleans up the PCI-E host memory space. */
...@@ -3175,10 +3174,13 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter) ...@@ -3175,10 +3174,13 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
struct pci_dev *pdev = card->dev;
if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000)) if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n"); mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n");
pci_clear_master(pdev);
adapter->seq_num = 0; adapter->seq_num = 0;
mwifiex_pcie_free_buffers(adapter); mwifiex_pcie_free_buffers(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment