diff options
author | Dan Williams <dcbw@redhat.com> | 2010-04-15 16:27:44 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-16 15:32:01 -0400 |
commit | 96021f096e5178582af296a2fbb6df7dbd6b695c (patch) | |
tree | 7c09cb0ce44234ef1c0a7de19b38bbe1c9033f80 | |
parent | edbe056a5a70aac20127189ca99d042640fd3366 (diff) |
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>
-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 33206a98a572..60dc9b64381d 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -314,12 +314,28 @@ out: | |||
314 | return ret; | 314 | return ret; |
315 | } | 315 | } |
316 | 316 | ||
317 | static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) | ||
318 | { | ||
319 | u8 status; | ||
320 | unsigned long timeout; | ||
321 | int ret = 0; | ||
322 | |||
323 | timeout = jiffies + HZ; | ||
324 | while (1) { | ||
325 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | ||
326 | if (ret || (status & condition)) | ||
327 | break; | ||
328 | if (time_after(jiffies, timeout)) | ||
329 | return -ETIMEDOUT; | ||
330 | mdelay(1); | ||
331 | } | ||
332 | return ret; | ||
333 | } | ||
334 | |||
317 | static int if_sdio_card_to_host(struct if_sdio_card *card) | 335 | static int if_sdio_card_to_host(struct if_sdio_card *card) |
318 | { | 336 | { |
319 | int ret; | 337 | int ret; |
320 | u8 status; | ||
321 | u16 size, type, chunk; | 338 | u16 size, type, chunk; |
322 | unsigned long timeout; | ||
323 | 339 | ||
324 | lbs_deb_enter(LBS_DEB_SDIO); | 340 | lbs_deb_enter(LBS_DEB_SDIO); |
325 | 341 | ||
@@ -334,19 +350,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) | |||
334 | goto out; | 350 | goto out; |
335 | } | 351 | } |
336 | 352 | ||
337 | timeout = jiffies + HZ; | 353 | ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); |
338 | while (1) { | 354 | if (ret) |
339 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 355 | goto out; |
340 | if (ret) | ||
341 | goto out; | ||
342 | if (status & IF_SDIO_IO_RDY) | ||
343 | break; | ||
344 | if (time_after(jiffies, timeout)) { | ||
345 | ret = -ETIMEDOUT; | ||
346 | goto out; | ||
347 | } | ||
348 | mdelay(1); | ||
349 | } | ||
350 | 356 | ||
351 | /* | 357 | /* |
352 | * The transfer must be in one transaction or the firmware | 358 | * 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) | |||
413 | { | 419 | { |
414 | struct if_sdio_card *card; | 420 | struct if_sdio_card *card; |
415 | struct if_sdio_packet *packet; | 421 | struct if_sdio_packet *packet; |
416 | unsigned long timeout; | ||
417 | u8 status; | ||
418 | int ret; | 422 | int ret; |
419 | unsigned long flags; | 423 | unsigned long flags; |
420 | 424 | ||
@@ -434,25 +438,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) | |||
434 | 438 | ||
435 | sdio_claim_host(card->func); | 439 | sdio_claim_host(card->func); |
436 | 440 | ||
437 | timeout = jiffies + HZ; | 441 | ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); |
438 | while (1) { | 442 | if (ret == 0) { |
439 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 443 | ret = sdio_writesb(card->func, card->ioport, |
440 | if (ret) | 444 | packet->buffer, packet->nb); |
441 | goto release; | ||
442 | if (status & IF_SDIO_IO_RDY) | ||
443 | break; | ||
444 | if (time_after(jiffies, timeout)) { | ||
445 | ret = -ETIMEDOUT; | ||
446 | goto release; | ||
447 | } | ||
448 | mdelay(1); | ||
449 | } | 445 | } |
450 | 446 | ||
451 | ret = sdio_writesb(card->func, card->ioport, | ||
452 | packet->buffer, packet->nb); | ||
453 | if (ret) | 447 | if (ret) |
454 | goto release; | 448 | lbs_pr_err("error %d sending packet to firmware\n", ret); |
455 | release: | 449 | |
456 | sdio_release_host(card->func); | 450 | sdio_release_host(card->func); |
457 | 451 | ||
458 | kfree(packet); | 452 | kfree(packet); |
@@ -465,10 +459,11 @@ release: | |||
465 | /* Firmware */ | 459 | /* Firmware */ |
466 | /********************************************************************/ | 460 | /********************************************************************/ |
467 | 461 | ||
462 | #define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) | ||
463 | |||
468 | static int if_sdio_prog_helper(struct if_sdio_card *card) | 464 | static int if_sdio_prog_helper(struct if_sdio_card *card) |
469 | { | 465 | { |
470 | int ret; | 466 | int ret; |
471 | u8 status; | ||
472 | const struct firmware *fw; | 467 | const struct firmware *fw; |
473 | unsigned long timeout; | 468 | unsigned long timeout; |
474 | u8 *chunk_buffer; | 469 | u8 *chunk_buffer; |
@@ -500,20 +495,9 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) | |||
500 | size = fw->size; | 495 | size = fw->size; |
501 | 496 | ||
502 | while (size) { | 497 | while (size) { |
503 | timeout = jiffies + HZ; | 498 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); |
504 | while (1) { | 499 | if (ret) |
505 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 500 | goto release; |
506 | if (ret) | ||
507 | goto release; | ||
508 | if ((status & IF_SDIO_IO_RDY) && | ||
509 | (status & IF_SDIO_DL_RDY)) | ||
510 | break; | ||
511 | if (time_after(jiffies, timeout)) { | ||
512 | ret = -ETIMEDOUT; | ||
513 | goto release; | ||
514 | } | ||
515 | mdelay(1); | ||
516 | } | ||
517 | 501 | ||
518 | chunk_size = min(size, (size_t)60); | 502 | chunk_size = min(size, (size_t)60); |
519 | 503 | ||
@@ -583,7 +567,6 @@ out: | |||
583 | static int if_sdio_prog_real(struct if_sdio_card *card) | 567 | static int if_sdio_prog_real(struct if_sdio_card *card) |
584 | { | 568 | { |
585 | int ret; | 569 | int ret; |
586 | u8 status; | ||
587 | const struct firmware *fw; | 570 | const struct firmware *fw; |
588 | unsigned long timeout; | 571 | unsigned long timeout; |
589 | u8 *chunk_buffer; | 572 | u8 *chunk_buffer; |
@@ -615,20 +598,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card) | |||
615 | size = fw->size; | 598 | size = fw->size; |
616 | 599 | ||
617 | while (size) { | 600 | while (size) { |
618 | timeout = jiffies + HZ; | 601 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); |
619 | while (1) { | 602 | if (ret) |
620 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 603 | goto release; |
621 | if (ret) | ||
622 | goto release; | ||
623 | if ((status & IF_SDIO_IO_RDY) && | ||
624 | (status & IF_SDIO_DL_RDY)) | ||
625 | break; | ||
626 | if (time_after(jiffies, timeout)) { | ||
627 | ret = -ETIMEDOUT; | ||
628 | goto release; | ||
629 | } | ||
630 | mdelay(1); | ||
631 | } | ||
632 | 604 | ||
633 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); | 605 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); |
634 | if (ret) | 606 | if (ret) |