libertas: consolidate SDIO firmware wait code
authorDan Williams <dcbw@redhat.com>
Thu, 15 Apr 2010 20:27:44 +0000 (13:27 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Apr 2010 19:32:01 +0000 (15:32 -0400)
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>
drivers/net/wireless/libertas/if_sdio.c

index 33206a9..60dc9b6 100644 (file)
@@ -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)