From 37ac5780e08e4e3ce67e8355e52d71324e9c11cd Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Wed, 14 Nov 2012 18:46:18 -0800 Subject: brcmfmac: Handle mmc exceptions during init correct. when brcmf_sdbrcm_probe_attach results in error then cleanup will result in null pointer access. In brcmf_sdbrcm_release and in brcmf_ops_sdio_remove. This patch fixes order of init and de-init. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index e2351a7969a7..40a37ac04970 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3867,7 +3867,8 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) brcmf_sdio_intr_unregister(bus->sdiodev); cancel_work_sync(&bus->datawork); - destroy_workqueue(bus->brcmf_wq); + if (bus->brcmf_wq) + destroy_workqueue(bus->brcmf_wq); if (bus->sdiodev->bus_if->drvr) { brcmf_detach(bus->sdiodev->dev); @@ -3909,6 +3910,13 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->txminmax = BRCMF_TXMINMAX; bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; + INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); + bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); + if (bus->brcmf_wq == NULL) { + brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); + goto fail; + } + /* attempt to attach to the dongle */ if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); @@ -3920,13 +3928,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) init_waitqueue_head(&bus->ctrl_wait); init_waitqueue_head(&bus->dcmd_resp_wait); - bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); - if (bus->brcmf_wq == NULL) { - brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); - goto fail; - } - INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); - /* Set up the watchdog timer */ init_timer(&bus->timer); bus->timer.data = (unsigned long)bus; -- cgit v1.2.2