brcmfmac: have sdio return -EIO when device communication is not possible
authorArend van Spriel <arend@broadcom.com>
Wed, 10 Jun 2015 22:12:20 +0000 (00:12 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 15 Jun 2015 09:55:22 +0000 (12:55 +0300)
The bus interface functions txctl and rxctl may be used while the device
can not be accessed, eg. upon driver .remove() callback. This patch will
immediately return -EIO when this is the case which speeds up the module
unload.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/brcm80211/brcmfmac/sdio.c

index 71779b9..410a664 100644 (file)
@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
 
 static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
 {
+       sdiodev->state = BRCMF_SDIOD_DOWN;
        if (sdiodev->bus) {
                brcmf_sdio_remove(sdiodev->bus);
                sdiodev->bus = NULL;
index bf7a8b1..d36f5f3 100644 (file)
@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
+       if (sdiodev->state != BRCMF_SDIOD_DATA)
+               return -EIO;
 
        /* Add space for the header */
        skb_push(pkt, bus->tx_hdrlen);
@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
        int ret;
 
        brcmf_dbg(TRACE, "Enter\n");
+       if (sdiodev->state != BRCMF_SDIOD_DATA)
+               return -EIO;
 
        /* Send from dpc */
        bus->ctrl_frame_buf = msg;
@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter\n");
+       if (sdiodev->state != BRCMF_SDIOD_DATA)
+               return -EIO;
 
        /* Wait until control frame is available */
        timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending);