* [PATCH v2 0/2] brcmfmac: fixes for some corner cases
@ 2016-05-11 22:06 Christian Daudt
2016-05-11 22:06 ` [PATCH v2 1/2] brcmfmac: Fix kernel oops in failed chip_attach Christian Daudt
2016-05-11 22:06 ` [PATCH v2 2/2] brcmfmac: Fix 'did not remove int handler' warning Christian Daudt
0 siblings, 2 replies; 4+ messages in thread
From: Christian Daudt @ 2016-05-11 22:06 UTC (permalink / raw)
To: linux-wireless
Cc: Christian Daudt, brcm80211-dev-list, Brett Rudley,
Arend van Spriel, Franky Lin, Hante Meuleman
A couple of patches against v4.6-rc6 which fix an oops when
handling buggy FW and clear int handler warnings on module unload
Changes from v1:
- combined the patches into a series since "Fix 'did not remove..."
depends on "Fix kernel oops..." patch
Christian Daudt (2):
brcmfmac: Fix kernel oops in failed chip_attach
brcmfmac: Fix 'did not remove int handler' warning
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 47 +++++++++++++---------
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 3 +-
2 files changed, 30 insertions(+), 20 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] brcmfmac: Fix kernel oops in failed chip_attach
2016-05-11 22:06 [PATCH v2 0/2] brcmfmac: fixes for some corner cases Christian Daudt
@ 2016-05-11 22:06 ` Christian Daudt
2016-06-04 14:59 ` [v2,1/2] " Kalle Valo
2016-05-11 22:06 ` [PATCH v2 2/2] brcmfmac: Fix 'did not remove int handler' warning Christian Daudt
1 sibling, 1 reply; 4+ messages in thread
From: Christian Daudt @ 2016-05-11 22:06 UTC (permalink / raw)
To: linux-wireless
Cc: Christian Daudt, brcm80211-dev-list, Brett Rudley,
Arend van Spriel, Franky Lin, Hante Meuleman
When chip attach fails, brcmf_sdiod_intr_unregister is being called
but that is too early as sdiodev->settings has not been set yet
nor has brcmf_sdiod_intr_register been called.
Change to use oob_irq_requested + newly created sd_irq_requested
to decide on what to unregister at intr_unregister time.
Steps to reproduce problem:
- modprobe brcmfmac using buggy FW
- rmmod brcmfmac
- modprobe brcmfmac again.
If done with a buggy firmware, brcm_chip_attach will fail on the
2nd modprobe triggering the call to intr_unregister and the
kernel oops when attempting to de-reference sdiodev->settings->bus.sdio
which has not yet been set.
Signed-off-by: Christian Daudt <csd@broadcom.com>
---
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 30 ++++++++++++----------
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 1 +
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index da0cdd3..09635a9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -166,6 +166,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
sdio_release_host(sdiodev->func[1]);
+ sdiodev->sd_irq_requested = true;
}
return 0;
@@ -173,27 +174,30 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
{
- struct brcmfmac_sdio_pd *pdata;
- brcmf_dbg(SDIO, "Entering\n");
+ brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
+ sdiodev->oob_irq_requested,
+ sdiodev->sd_irq_requested);
- pdata = &sdiodev->settings->bus.sdio;
- if (pdata->oob_irq_supported) {
+ if (sdiodev->oob_irq_requested) {
+ struct brcmfmac_sdio_pd *pdata;
+
+ pdata = &sdiodev->settings->bus.sdio;
sdio_claim_host(sdiodev->func[1]);
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
sdio_release_host(sdiodev->func[1]);
- if (sdiodev->oob_irq_requested) {
- sdiodev->oob_irq_requested = false;
- if (sdiodev->irq_wake) {
- disable_irq_wake(pdata->oob_irq_nr);
- sdiodev->irq_wake = false;
- }
- free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
- sdiodev->irq_en = false;
+ sdiodev->oob_irq_requested = false;
+ if (sdiodev->irq_wake) {
+ disable_irq_wake(pdata->oob_irq_nr);
+ sdiodev->irq_wake = false;
}
- } else {
+ free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
+ sdiodev->irq_en = false;
+ }
+
+ if (sdiodev->sd_irq_requested) {
sdio_claim_host(sdiodev->func[1]);
sdio_release_irq(sdiodev->func[2]);
sdio_release_irq(sdiodev->func[1]);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index dcf0ce8c..c07ad25 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -186,6 +186,7 @@ struct brcmf_sdio_dev {
struct brcmf_bus *bus_if;
struct brcmf_mp_device *settings;
bool oob_irq_requested;
+ bool sd_irq_requested;
bool irq_en; /* irq enable flags */
spinlock_t irq_en_lock;
bool irq_wake; /* irq wake enable flags */
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] brcmfmac: Fix 'did not remove int handler' warning
2016-05-11 22:06 [PATCH v2 0/2] brcmfmac: fixes for some corner cases Christian Daudt
2016-05-11 22:06 ` [PATCH v2 1/2] brcmfmac: Fix kernel oops in failed chip_attach Christian Daudt
@ 2016-05-11 22:06 ` Christian Daudt
1 sibling, 0 replies; 4+ messages in thread
From: Christian Daudt @ 2016-05-11 22:06 UTC (permalink / raw)
To: linux-wireless
Cc: Christian Daudt, brcm80211-dev-list, Brett Rudley,
Arend van Spriel, Franky Lin, Hante Meuleman
brcmf_sdiod_intr_unregister call that removes both func1 and
func2 interrupt handlers only called when brcmf_ops_sdio_remove
is called for func 1 (which is the 2nd call) but sdio is expecting
it to be removed at the end of each sdio_remove call.
This is causing 'rmmod bcmrfmac' on a 4356-sdio chip to complain
with:
WARNING: driver brcmfmac did not remove its interrupt handler!
The modification makes calling brcmf_sdiod_intr_unregister multiple
times harmless by clearing the variables that track if interrupt
handlers have been installed, and then calls it on every
brcmf_ops_sdio_remove call instead of just remove for func 1.
Signed-off-by: Christian Daudt <csd@broadcom.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 17 +++++++++++------
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 2 +-
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 09635a9..590cd41 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -172,7 +172,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
return 0;
}
-int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
+void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
{
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
@@ -195,6 +195,7 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
}
free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
sdiodev->irq_en = false;
+ sdiodev->oob_irq_requested = false;
}
if (sdiodev->sd_irq_requested) {
@@ -202,9 +203,8 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
sdio_release_irq(sdiodev->func[2]);
sdio_release_irq(sdiodev->func[1]);
sdio_release_host(sdiodev->func[1]);
+ sdiodev->sd_irq_requested = false;
}
-
- return 0;
}
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
@@ -1200,12 +1200,17 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
brcmf_dbg(SDIO, "Function: %d\n", func->num);
- if (func->num != 1)
- return;
-
bus_if = dev_get_drvdata(&func->dev);
if (bus_if) {
sdiodev = bus_if->bus_priv.sdio;
+
+ /* start by unregistering irqs */
+ brcmf_sdiod_intr_unregister(sdiodev);
+
+ if (func->num != 1)
+ return;
+
+ /* only proceed with rest of cleanup if func 1 */
brcmf_sdiod_remove(sdiodev);
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index c07ad25..f3da32f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -294,7 +294,7 @@ struct sdpcmd_regs {
/* Register/deregister interrupt handler. */
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
-int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
+void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
/* sdio device register access interface */
u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [v2,1/2] brcmfmac: Fix kernel oops in failed chip_attach
2016-05-11 22:06 ` [PATCH v2 1/2] brcmfmac: Fix kernel oops in failed chip_attach Christian Daudt
@ 2016-06-04 14:59 ` Kalle Valo
0 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2016-06-04 14:59 UTC (permalink / raw)
To: Christian Daudt
Cc: linux-wireless, Christian Daudt, brcm80211-dev-list, Brett Rudley,
Arend van Spriel, Franky Lin, Hante Meuleman
Christian Daudt <csd@broadcom.com> wrote:
> When chip attach fails, brcmf_sdiod_intr_unregister is being called
> but that is too early as sdiodev->settings has not been set yet
> nor has brcmf_sdiod_intr_register been called.
> Change to use oob_irq_requested + newly created sd_irq_requested
> to decide on what to unregister at intr_unregister time.
>
> Steps to reproduce problem:
> - modprobe brcmfmac using buggy FW
> - rmmod brcmfmac
> - modprobe brcmfmac again.
>
> If done with a buggy firmware, brcm_chip_attach will fail on the
> 2nd modprobe triggering the call to intr_unregister and the
> kernel oops when attempting to de-reference sdiodev->settings->bus.sdio
> which has not yet been set.
>
> Signed-off-by: Christian Daudt <csd@broadcom.com>
Thanks, 2 patches applied to wireless-drivers-next.git:
b88a2e80396b brcmfmac: Fix kernel oops in failed chip_attach
b746740147dc brcmfmac: Fix 'did not remove int handler' warning
--
Sent by pwcli
https://patchwork.kernel.org/patch/9075231/
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-06-04 14:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-11 22:06 [PATCH v2 0/2] brcmfmac: fixes for some corner cases Christian Daudt
2016-05-11 22:06 ` [PATCH v2 1/2] brcmfmac: Fix kernel oops in failed chip_attach Christian Daudt
2016-06-04 14:59 ` [v2,1/2] " Kalle Valo
2016-05-11 22:06 ` [PATCH v2 2/2] brcmfmac: Fix 'did not remove int handler' warning Christian Daudt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.