Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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);
	}
+9 −8
Original line number Diff line number Diff line
@@ -3867,6 +3867,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
		brcmf_sdio_intr_unregister(bus->sdiodev);

		cancel_work_sync(&bus->datawork);
		if (bus->brcmf_wq)
			destroy_workqueue(bus->brcmf_wq);

		if (bus->sdiodev->bus_if->drvr) {
@@ -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;