diff options
Diffstat (limited to 'firmware/target/arm/imx31/ata-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/ata-imx31.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/ata-imx31.c b/firmware/target/arm/imx31/ata-imx31.c index 6ba49cada0..c3e3c51e63 100644 --- a/firmware/target/arm/imx31/ata-imx31.c +++ b/firmware/target/arm/imx31/ata-imx31.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "power.h" | 26 | #include "power.h" |
27 | #include "panic.h" | 27 | #include "panic.h" |
28 | #include "ata.h" | 28 | #include "ata.h" |
29 | #include "ata-defines.h" | ||
29 | #include "ata-target.h" | 30 | #include "ata-target.h" |
30 | #include "ccm-imx31.h" | 31 | #include "ccm-imx31.h" |
31 | #ifdef HAVE_ATA_DMA | 32 | #ifdef HAVE_ATA_DMA |
@@ -459,6 +460,7 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write) | |||
459 | * shouldn't be reached based upon size. Otherwise we simply didn't | 460 | * shouldn't be reached based upon size. Otherwise we simply didn't |
460 | * understand the DMA mode setup. Force PIO in both cases. */ | 461 | * understand the DMA mode setup. Force PIO in both cases. */ |
461 | ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST; | 462 | ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST; |
463 | yield(); | ||
462 | return false; | 464 | return false; |
463 | } | 465 | } |
464 | 466 | ||
@@ -645,6 +647,43 @@ bool ata_dma_finish(void) | |||
645 | } | 647 | } |
646 | #endif /* HAVE_ATA_DMA */ | 648 | #endif /* HAVE_ATA_DMA */ |
647 | 649 | ||
650 | static int ata_wait_status(unsigned status, unsigned mask, int timeout) | ||
651 | { | ||
652 | long busy_timeout = usec_timer() + 2; | ||
653 | long end_tick = current_tick + timeout; | ||
654 | |||
655 | while (1) | ||
656 | { | ||
657 | if ((ATA_DRIVE_STATUS & mask) == status) | ||
658 | return 1; | ||
659 | |||
660 | if (!TIME_AFTER(usec_timer(), busy_timeout)) | ||
661 | continue; | ||
662 | |||
663 | ata_keep_active(); | ||
664 | |||
665 | if (TIME_AFTER(current_tick, end_tick)) | ||
666 | break; | ||
667 | |||
668 | sleep(0); | ||
669 | busy_timeout = usec_timer() + 2; | ||
670 | } | ||
671 | |||
672 | return 0; /* timed out */ | ||
673 | } | ||
674 | |||
675 | int ata_wait_for_bsy(void) | ||
676 | { | ||
677 | /* BSY = 0 */ | ||
678 | return ata_wait_status(0, STATUS_BSY, 30*HZ); | ||
679 | } | ||
680 | |||
681 | int ata_wait_for_rdy(void) | ||
682 | { | ||
683 | /* RDY = 1 && BSY = 0 */ | ||
684 | return ata_wait_status(STATUS_RDY, STATUS_RDY | STATUS_BSY, 40*HZ); | ||
685 | } | ||
686 | |||
648 | void ata_device_init(void) | 687 | void ata_device_init(void) |
649 | { | 688 | { |
650 | /* Make sure we're not in reset mode */ | 689 | /* Make sure we're not in reset mode */ |