diff options
author | Brian Norris <briannorris@chromium.org> | 2017-03-28 16:59:33 -0700 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2017-04-05 15:44:04 +0300 |
commit | 755b37c93a069ff0882411630a06e90b3193d092 (patch) | |
tree | 83d34d390fe620f70cb6ead4971c4486913da750 /drivers/net/wireless/marvell/mwifiex/sdio.c | |
parent | ce8fad9a1f09009ec3918a99685d9e3176f50ce3 (diff) | |
download | talos-obmc-linux-755b37c93a069ff0882411630a06e90b3193d092.tar.gz talos-obmc-linux-755b37c93a069ff0882411630a06e90b3193d092.zip |
mwifiex: catch mwifiex_fw_dpc() errors properly in reset
When resetting the device, we take a synchronous firmware-loading code
path, which borrows a lot from the asynchronous path used at probe time.
We don't catch errors correctly though, which means that in the PCIe
driver, we may try to dereference the 'adapter' struct after
mwifiex_fw_dpc() has freed it. See this (erronous) print in
mwifiex_pcie_reset_notify():
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
Let's instead refactor the synchronous (or "!req_fw_nowait") path so
that we propagate errors and handle them properly.
This fixes a use-after-free issue in the PCIe driver, as well as a
misleading debug message ("successful"). It looks like the SDIO driver
doesn't have these problems, since it doesn't do anything after
mwifiex_reinit_sw().
Fixes: 4c5dae59d2e9 ("mwifiex: add PCIe function level reset support")
Signed-off-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/sdio.c')
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/sdio.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 58d3da09cfbd..424532b81c2d 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -2196,6 +2196,7 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) { struct sdio_mmc_card *card = adapter->card; struct sdio_func *func = card->func; + int ret; mwifiex_shutdown_sw(adapter); @@ -2210,7 +2211,9 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - mwifiex_reinit_sw(adapter); + ret = mwifiex_reinit_sw(adapter); + if (ret) + dev_err(&func->dev, "reinit failed: %d\n", ret); } /* This function read/write firmware */ |