diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
commit | 3b51cc996e81d8a113416d8094fa4a88f8360a51 (patch) | |
tree | e75b98b228bb4e456c30673fcc4b56ffa1d09cf5 /drivers/net/wireless/libertas | |
parent | c68ed255265968c3948fa2678bf59d15c471b055 (diff) | |
parent | 672724403b42da1d276c6cf811e8e34d15efd964 (diff) |
Merge branch 'master' into for-davem
Conflicts:
drivers/net/wireless/ath/ath9k/phy.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 103 |
1 files changed, 40 insertions, 63 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index cd464a2589b9..13dfeda742bc 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -315,12 +315,28 @@ out: | |||
315 | return ret; | 315 | return ret; |
316 | } | 316 | } |
317 | 317 | ||
318 | static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) | ||
319 | { | ||
320 | u8 status; | ||
321 | unsigned long timeout; | ||
322 | int ret = 0; | ||
323 | |||
324 | timeout = jiffies + HZ; | ||
325 | while (1) { | ||
326 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | ||
327 | if (ret || (status & condition)) | ||
328 | break; | ||
329 | if (time_after(jiffies, timeout)) | ||
330 | return -ETIMEDOUT; | ||
331 | mdelay(1); | ||
332 | } | ||
333 | return ret; | ||
334 | } | ||
335 | |||
318 | static int if_sdio_card_to_host(struct if_sdio_card *card) | 336 | static int if_sdio_card_to_host(struct if_sdio_card *card) |
319 | { | 337 | { |
320 | int ret; | 338 | int ret; |
321 | u8 status; | ||
322 | u16 size, type, chunk; | 339 | u16 size, type, chunk; |
323 | unsigned long timeout; | ||
324 | 340 | ||
325 | lbs_deb_enter(LBS_DEB_SDIO); | 341 | lbs_deb_enter(LBS_DEB_SDIO); |
326 | 342 | ||
@@ -335,19 +351,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) | |||
335 | goto out; | 351 | goto out; |
336 | } | 352 | } |
337 | 353 | ||
338 | timeout = jiffies + HZ; | 354 | ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); |
339 | while (1) { | 355 | if (ret) |
340 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 356 | goto out; |
341 | if (ret) | ||
342 | goto out; | ||
343 | if (status & IF_SDIO_IO_RDY) | ||
344 | break; | ||
345 | if (time_after(jiffies, timeout)) { | ||
346 | ret = -ETIMEDOUT; | ||
347 | goto out; | ||
348 | } | ||
349 | mdelay(1); | ||
350 | } | ||
351 | 357 | ||
352 | /* | 358 | /* |
353 | * The transfer must be in one transaction or the firmware | 359 | * The transfer must be in one transaction or the firmware |
@@ -414,8 +420,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) | |||
414 | { | 420 | { |
415 | struct if_sdio_card *card; | 421 | struct if_sdio_card *card; |
416 | struct if_sdio_packet *packet; | 422 | struct if_sdio_packet *packet; |
417 | unsigned long timeout; | ||
418 | u8 status; | ||
419 | int ret; | 423 | int ret; |
420 | unsigned long flags; | 424 | unsigned long flags; |
421 | 425 | ||
@@ -435,25 +439,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) | |||
435 | 439 | ||
436 | sdio_claim_host(card->func); | 440 | sdio_claim_host(card->func); |
437 | 441 | ||
438 | timeout = jiffies + HZ; | 442 | ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); |
439 | while (1) { | 443 | if (ret == 0) { |
440 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 444 | ret = sdio_writesb(card->func, card->ioport, |
441 | if (ret) | 445 | packet->buffer, packet->nb); |
442 | goto release; | ||
443 | if (status & IF_SDIO_IO_RDY) | ||
444 | break; | ||
445 | if (time_after(jiffies, timeout)) { | ||
446 | ret = -ETIMEDOUT; | ||
447 | goto release; | ||
448 | } | ||
449 | mdelay(1); | ||
450 | } | 446 | } |
451 | 447 | ||
452 | ret = sdio_writesb(card->func, card->ioport, | ||
453 | packet->buffer, packet->nb); | ||
454 | if (ret) | 448 | if (ret) |
455 | goto release; | 449 | lbs_pr_err("error %d sending packet to firmware\n", ret); |
456 | release: | 450 | |
457 | sdio_release_host(card->func); | 451 | sdio_release_host(card->func); |
458 | 452 | ||
459 | kfree(packet); | 453 | kfree(packet); |
@@ -466,10 +460,11 @@ release: | |||
466 | /* Firmware */ | 460 | /* Firmware */ |
467 | /********************************************************************/ | 461 | /********************************************************************/ |
468 | 462 | ||
463 | #define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) | ||
464 | |||
469 | static int if_sdio_prog_helper(struct if_sdio_card *card) | 465 | static int if_sdio_prog_helper(struct if_sdio_card *card) |
470 | { | 466 | { |
471 | int ret; | 467 | int ret; |
472 | u8 status; | ||
473 | const struct firmware *fw; | 468 | const struct firmware *fw; |
474 | unsigned long timeout; | 469 | unsigned long timeout; |
475 | u8 *chunk_buffer; | 470 | u8 *chunk_buffer; |
@@ -501,20 +496,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) | |||
501 | size = fw->size; | 496 | size = fw->size; |
502 | 497 | ||
503 | while (size) { | 498 | while (size) { |
504 | timeout = jiffies + HZ; | 499 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); |
505 | while (1) { | 500 | if (ret) |
506 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 501 | goto release; |
507 | if (ret) | 502 | |
508 | goto release; | 503 | /* On some platforms (like Davinci) the chip needs more time |
509 | if ((status & IF_SDIO_IO_RDY) && | 504 | * between helper blocks. |
510 | (status & IF_SDIO_DL_RDY)) | 505 | */ |
511 | break; | 506 | mdelay(2); |
512 | if (time_after(jiffies, timeout)) { | ||
513 | ret = -ETIMEDOUT; | ||
514 | goto release; | ||
515 | } | ||
516 | mdelay(1); | ||
517 | } | ||
518 | 507 | ||
519 | chunk_size = min(size, (size_t)60); | 508 | chunk_size = min(size, (size_t)60); |
520 | 509 | ||
@@ -584,7 +573,6 @@ out: | |||
584 | static int if_sdio_prog_real(struct if_sdio_card *card) | 573 | static int if_sdio_prog_real(struct if_sdio_card *card) |
585 | { | 574 | { |
586 | int ret; | 575 | int ret; |
587 | u8 status; | ||
588 | const struct firmware *fw; | 576 | const struct firmware *fw; |
589 | unsigned long timeout; | 577 | unsigned long timeout; |
590 | u8 *chunk_buffer; | 578 | u8 *chunk_buffer; |
@@ -616,20 +604,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card) | |||
616 | size = fw->size; | 604 | size = fw->size; |
617 | 605 | ||
618 | while (size) { | 606 | while (size) { |
619 | timeout = jiffies + HZ; | 607 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); |
620 | while (1) { | 608 | if (ret) |
621 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 609 | goto release; |
622 | if (ret) | ||
623 | goto release; | ||
624 | if ((status & IF_SDIO_IO_RDY) && | ||
625 | (status & IF_SDIO_DL_RDY)) | ||
626 | break; | ||
627 | if (time_after(jiffies, timeout)) { | ||
628 | ret = -ETIMEDOUT; | ||
629 | goto release; | ||
630 | } | ||
631 | mdelay(1); | ||
632 | } | ||
633 | 610 | ||
634 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); | 611 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); |
635 | if (ret) | 612 | if (ret) |