Commit 37ac5780 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville

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: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1799ddf1
......@@ -512,6 +512,8 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
ret = brcmf_sdio_probe(sdiodev);
if (ret)
dev_set_drvdata(&func->dev, NULL);
}
return ret;
......@@ -532,8 +534,12 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
brcmf_sdio_remove(sdiodev);
dev_set_drvdata(&func->card->dev, NULL);
dev_set_drvdata(&func->dev, NULL);
}
if (func->num == 1) {
sdiodev = dev_get_drvdata(&func->card->dev);
bus_if = sdiodev->bus_if;
dev_set_drvdata(&func->card->dev, NULL);
kfree(bus_if);
kfree(sdiodev);
}
......
......@@ -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;
......
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