diff options
author | Dan Williams <dcbw@redhat.com> | 2010-04-15 13:27:44 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-16 15:32:01 -0400 |
commit | 96021f096e5178582af296a2fbb6df7dbd6b695c (patch) | |
tree | 7c09cb0ce44234ef1c0a7de19b38bbe1c9033f80 /drivers/net/wireless/libertas/if_sdio.c | |
parent | edbe056a5a70aac20127189ca99d042640fd3366 (diff) | |
download | op-kernel-dev-96021f096e5178582af296a2fbb6df7dbd6b695c.zip op-kernel-dev-96021f096e5178582af296a2fbb6df7dbd6b695c.tar.gz |
libertas: consolidate SDIO firmware wait code
Consolidate a bunch of C&P code that waits for the firmware to be ready.
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/if_sdio.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 98 |
1 files changed, 35 insertions, 63 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 33206a9..60dc9b6 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -314,12 +314,28 @@ out: return ret; } +static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) +{ + u8 status; + unsigned long timeout; + int ret = 0; + + timeout = jiffies + HZ; + while (1) { + status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); + if (ret || (status & condition)) + break; + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + mdelay(1); + } + return ret; +} + static int if_sdio_card_to_host(struct if_sdio_card *card) { int ret; - u8 status; u16 size, type, chunk; - unsigned long timeout; lbs_deb_enter(LBS_DEB_SDIO); @@ -334,19 +350,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) goto out; } - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto out; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto out; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); + if (ret) + goto out; /* * The transfer must be in one transaction or the firmware @@ -413,8 +419,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) { struct if_sdio_card *card; struct if_sdio_packet *packet; - unsigned long timeout; - u8 status; int ret; unsigned long flags; @@ -434,25 +438,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) sdio_claim_host(card->func); - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); + ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); + if (ret == 0) { + ret = sdio_writesb(card->func, card->ioport, + packet->buffer, packet->nb); } - ret = sdio_writesb(card->func, card->ioport, - packet->buffer, packet->nb); if (ret) - goto release; -release: + lbs_pr_err("error %d sending packet to firmware\n", ret); + sdio_release_host(card->func); kfree(packet); @@ -465,10 +459,11 @@ release: /* Firmware */ /********************************************************************/ +#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) + static int if_sdio_prog_helper(struct if_sdio_card *card) { int ret; - u8 status; const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; @@ -500,20 +495,9 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; chunk_size = min(size, (size_t)60); @@ -583,7 +567,6 @@ out: static int if_sdio_prog_real(struct if_sdio_card *card) { int ret; - u8 status; const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; @@ -615,20 +598,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card) size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); if (ret) |