diff options
Diffstat (limited to 'firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c index 2952c36324..dbf0ce9dd4 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include "s5l8702.h" | 32 | #include "s5l8702.h" |
33 | #include "led.h" | 33 | #include "led.h" |
34 | #include "ata_idle_notify.h" | 34 | #include "ata_idle_notify.h" |
35 | #include "fat.h" | ||
36 | #include "splash.h" | ||
35 | 37 | ||
36 | 38 | ||
37 | #ifndef ATA_RETRIES | 39 | #ifndef ATA_RETRIES |
@@ -49,6 +51,7 @@ | |||
49 | static uint8_t ceata_taskfile[16] __attribute__((aligned(16))); | 51 | static uint8_t ceata_taskfile[16] __attribute__((aligned(16))); |
50 | static uint16_t ata_identify_data[0x100] __attribute__((aligned(16))); | 52 | static uint16_t ata_identify_data[0x100] __attribute__((aligned(16))); |
51 | static bool ceata; | 53 | static bool ceata; |
54 | static bool ata_swap; | ||
52 | static bool ata_lba48; | 55 | static bool ata_lba48; |
53 | static bool ata_dma; | 56 | static bool ata_dma; |
54 | static uint64_t ata_total_sectors; | 57 | static uint64_t ata_total_sectors; |
@@ -512,15 +515,14 @@ static int ata_identify(uint16_t* buf) | |||
512 | } | 515 | } |
513 | else | 516 | else |
514 | { | 517 | { |
518 | uint32_t old = ATA_CFG; | ||
519 | ATA_CFG |= BIT(6); | ||
515 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); | 520 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); |
516 | ata_write_cbr(&ATA_PIO_DVR, 0); | 521 | ata_write_cbr(&ATA_PIO_DVR, 0); |
517 | ata_write_cbr(&ATA_PIO_CSD, 0xec); | 522 | ata_write_cbr(&ATA_PIO_CSD, 0xec); |
518 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); | 523 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); |
519 | for (i = 0; i < 0x100; i++) | 524 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); |
520 | { | 525 | ATA_CFG = old; |
521 | uint16_t word = ata_read_cbr(&ATA_PIO_DTR); | ||
522 | buf[i] = (word >> 8) | (word << 8); | ||
523 | } | ||
524 | } | 526 | } |
525 | return 0; | 527 | return 0; |
526 | } | 528 | } |
@@ -586,6 +588,7 @@ static int ata_power_up(void) | |||
586 | sleep(HZ / 5); | 588 | sleep(HZ / 5); |
587 | ATA_PIO_TIME = 0x191f7; | 589 | ATA_PIO_TIME = 0x191f7; |
588 | ATA_PIO_LHR = 0; | 590 | ATA_PIO_LHR = 0; |
591 | if (!ata_swap) ATA_CFG = BIT(6); | ||
589 | while (!(ATA_PIO_READY & BIT(1))) yield(); | 592 | while (!(ATA_PIO_READY & BIT(1))) yield(); |
590 | PASS_RC(ata_identify(ata_identify_data), 2, 0); | 593 | PASS_RC(ata_identify(ata_identify_data), 2, 0); |
591 | uint32_t piotime = 0x11f3; | 594 | uint32_t piotime = 0x11f3; |
@@ -1095,12 +1098,35 @@ int ata_init(void) | |||
1095 | PCON(9) = 0x44444444; | 1098 | PCON(9) = 0x44444444; |
1096 | PCON(10) = (PCON(10) & ~0xffff) | 0x4444; | 1099 | PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
1097 | } | 1100 | } |
1101 | ata_swap = false; | ||
1098 | ata_powered = false; | 1102 | ata_powered = false; |
1099 | ata_total_sectors = 0; | 1103 | ata_total_sectors = 0; |
1100 | ata_power_up(); | 1104 | ata_power_up(); |
1101 | #ifdef ATA_HAVE_BBT | 1105 | #ifdef ATA_HAVE_BBT |
1102 | ata_bbt_reload(); | 1106 | ata_bbt_reload(); |
1103 | #endif | 1107 | #endif |
1108 | |||
1109 | /* HDD data endianness check: | ||
1110 | During the transition period Rockbox needs to detect the HDD data | ||
1111 | endianness automatically and support both. We're now using the correct | ||
1112 | endianness by default and only switching back to swapped bytes if we | ||
1113 | find a reversed MBR signature. | ||
1114 | To make this warning go away, update your emCORE version. The HDD will | ||
1115 | be reformatted with the correct endianness during the process. | ||
1116 | Once most users have switched over, this code may be removed again. | ||
1117 | -- Michael Sparmann (theseven), 2011-10-22 */ | ||
1118 | if (!ceata) | ||
1119 | { | ||
1120 | unsigned char* sector = fat_get_sector_buffer(); | ||
1121 | ata_rw_sectors(0, 1, sector, false); | ||
1122 | if (sector[510] == 0xaa && sector[511] == 0x55) | ||
1123 | { | ||
1124 | ata_swap = true; | ||
1125 | splashf(5000, "Wrong HDD endianness, please update your emCORE version!"); | ||
1126 | } | ||
1127 | fat_release_sector_buffer(); | ||
1128 | } | ||
1129 | |||
1104 | create_thread(ata_thread, ata_stack, | 1130 | create_thread(ata_thread, ata_stack, |
1105 | sizeof(ata_stack), 0, "ATA idle monitor" | 1131 | sizeof(ata_stack), 0, "ATA idle monitor" |
1106 | IF_PRIO(, PRIORITY_USER_INTERFACE) | 1132 | IF_PRIO(, PRIORITY_USER_INTERFACE) |