diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 34c993dd0602..fa35b23bbaa7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -287,6 +287,9 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
287 | s32 retry = 0; | 287 | s32 retry = 0; |
288 | int ret; | 288 | int ret; |
289 | 289 | ||
290 | if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) | ||
291 | return -ENOMEDIUM; | ||
292 | |||
290 | /* | 293 | /* |
291 | * figure out how to read the register based on address range | 294 | * figure out how to read the register based on address range |
292 | * 0x00 ~ 0x7FF: function 0 CCCR and FBR | 295 | * 0x00 ~ 0x7FF: function 0 CCCR and FBR |
@@ -306,9 +309,12 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
306 | usleep_range(1000, 2000); | 309 | usleep_range(1000, 2000); |
307 | ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, | 310 | ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, |
308 | data, write); | 311 | data, write); |
309 | } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | 312 | } while (ret != 0 && ret != -ENOMEDIUM && |
313 | retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | ||
310 | 314 | ||
311 | if (ret != 0) | 315 | if (ret == -ENOMEDIUM) |
316 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); | ||
317 | else if (ret != 0) | ||
312 | brcmf_err("failed with %d\n", ret); | 318 | brcmf_err("failed with %d\n", ret); |
313 | 319 | ||
314 | return ret; | 320 | return ret; |
@@ -320,6 +326,9 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | |||
320 | int err = 0, i; | 326 | int err = 0, i; |
321 | u8 addr[3]; | 327 | u8 addr[3]; |
322 | 328 | ||
329 | if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) | ||
330 | return -ENOMEDIUM; | ||
331 | |||
323 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; | 332 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; |
324 | addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; | 333 | addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; |
325 | addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; | 334 | addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; |
@@ -429,6 +438,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
429 | bool write, u32 addr, struct sk_buff *pkt) | 438 | bool write, u32 addr, struct sk_buff *pkt) |
430 | { | 439 | { |
431 | unsigned int req_sz; | 440 | unsigned int req_sz; |
441 | int err; | ||
432 | 442 | ||
433 | brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); | 443 | brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); |
434 | if (brcmf_sdiod_pm_resume_error(sdiodev)) | 444 | if (brcmf_sdiod_pm_resume_error(sdiodev)) |
@@ -439,18 +449,18 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
439 | req_sz &= (uint)~3; | 449 | req_sz &= (uint)~3; |
440 | 450 | ||
441 | if (write) | 451 | if (write) |
442 | return sdio_memcpy_toio(sdiodev->func[fn], addr, | 452 | err = sdio_memcpy_toio(sdiodev->func[fn], addr, |
443 | ((u8 *)(pkt->data)), | 453 | ((u8 *)(pkt->data)), req_sz); |
444 | req_sz); | ||
445 | else if (fn == 1) | 454 | else if (fn == 1) |
446 | return sdio_memcpy_fromio(sdiodev->func[fn], | 455 | err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)), |
447 | ((u8 *)(pkt->data)), | 456 | addr, req_sz); |
448 | addr, req_sz); | ||
449 | else | 457 | else |
450 | /* function 2 read is FIFO operation */ | 458 | /* function 2 read is FIFO operation */ |
451 | return sdio_readsb(sdiodev->func[fn], | 459 | err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, |
452 | ((u8 *)(pkt->data)), addr, | 460 | req_sz); |
453 | req_sz); | 461 | if (err == -ENOMEDIUM) |
462 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); | ||
463 | return err; | ||
454 | } | 464 | } |
455 | 465 | ||
456 | /** | 466 | /** |
@@ -593,7 +603,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
593 | mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); | 603 | mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); |
594 | 604 | ||
595 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; | 605 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; |
596 | if (ret != 0) { | 606 | if (ret == -ENOMEDIUM) { |
607 | brcmf_bus_change_state(sdiodev->bus_if, | ||
608 | BRCMF_BUS_NOMEDIUM); | ||
609 | break; | ||
610 | } else if (ret != 0) { | ||
597 | brcmf_err("CMD53 sg block %s failed %d\n", | 611 | brcmf_err("CMD53 sg block %s failed %d\n", |
598 | write ? "write" : "read", ret); | 612 | write ? "write" : "read", ret); |
599 | ret = -EIO; | 613 | ret = -EIO; |
@@ -852,8 +866,6 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) | |||
852 | 866 | ||
853 | static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) | 867 | static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) |
854 | { | 868 | { |
855 | sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
856 | |||
857 | if (sdiodev->bus) { | 869 | if (sdiodev->bus) { |
858 | brcmf_sdio_remove(sdiodev->bus); | 870 | brcmf_sdio_remove(sdiodev->bus); |
859 | sdiodev->bus = NULL; | 871 | sdiodev->bus = NULL; |