diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2012-11-14 21:46:18 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-16 14:28:59 -0500 |
commit | 37ac5780e08e4e3ce67e8355e52d71324e9c11cd (patch) | |
tree | 1b361725247c8b053c3f6405283250f9c8fcb482 /drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |
parent | 1799ddf18597da5aa1319b089736aafd05481774 (diff) |
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 <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 17 |
1 files changed, 9 insertions, 8 deletions
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) | |||
3867 | brcmf_sdio_intr_unregister(bus->sdiodev); | 3867 | brcmf_sdio_intr_unregister(bus->sdiodev); |
3868 | 3868 | ||
3869 | cancel_work_sync(&bus->datawork); | 3869 | cancel_work_sync(&bus->datawork); |
3870 | destroy_workqueue(bus->brcmf_wq); | 3870 | if (bus->brcmf_wq) |
3871 | destroy_workqueue(bus->brcmf_wq); | ||
3871 | 3872 | ||
3872 | if (bus->sdiodev->bus_if->drvr) { | 3873 | if (bus->sdiodev->bus_if->drvr) { |
3873 | brcmf_detach(bus->sdiodev->dev); | 3874 | brcmf_detach(bus->sdiodev->dev); |
@@ -3909,6 +3910,13 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3909 | bus->txminmax = BRCMF_TXMINMAX; | 3910 | bus->txminmax = BRCMF_TXMINMAX; |
3910 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; | 3911 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; |
3911 | 3912 | ||
3913 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3914 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3915 | if (bus->brcmf_wq == NULL) { | ||
3916 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3917 | goto fail; | ||
3918 | } | ||
3919 | |||
3912 | /* attempt to attach to the dongle */ | 3920 | /* attempt to attach to the dongle */ |
3913 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { | 3921 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { |
3914 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); | 3922 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); |
@@ -3920,13 +3928,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3920 | init_waitqueue_head(&bus->ctrl_wait); | 3928 | init_waitqueue_head(&bus->ctrl_wait); |
3921 | init_waitqueue_head(&bus->dcmd_resp_wait); | 3929 | init_waitqueue_head(&bus->dcmd_resp_wait); |
3922 | 3930 | ||
3923 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3924 | if (bus->brcmf_wq == NULL) { | ||
3925 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3926 | goto fail; | ||
3927 | } | ||
3928 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3929 | |||
3930 | /* Set up the watchdog timer */ | 3931 | /* Set up the watchdog timer */ |
3931 | init_timer(&bus->timer); | 3932 | init_timer(&bus->timer); |
3932 | bus->timer.data = (unsigned long)bus; | 3933 | bus->timer.data = (unsigned long)bus; |