diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 7bb492c39d..119297ff02 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -90,7 +90,7 @@ enum { | |||
90 | 90 | ||
91 | static int ata_state = ATA_BOOT; | 91 | static int ata_state = ATA_BOOT; |
92 | 92 | ||
93 | static struct mutex ata_mtx SHAREDBSS_ATTR; | 93 | static struct mutex ata_mutex SHAREDBSS_ATTR; |
94 | static int ata_device; /* device 0 (master) or 1 (slave) */ | 94 | static int ata_device; /* device 0 (master) or 1 (slave) */ |
95 | 95 | ||
96 | static int spinup_time = 0; | 96 | static int spinup_time = 0; |
@@ -101,7 +101,7 @@ static bool ata_led_on = false; | |||
101 | 101 | ||
102 | static long sleep_timeout = 5*HZ; | 102 | static long sleep_timeout = 5*HZ; |
103 | #ifdef HAVE_LBA48 | 103 | #ifdef HAVE_LBA48 |
104 | static bool lba48 = false; /* set for 48 bit addressing */ | 104 | static bool ata_lba48 = false; /* set for 48 bit addressing */ |
105 | #endif | 105 | #endif |
106 | static bool canflush = true; | 106 | static bool canflush = true; |
107 | 107 | ||
@@ -112,17 +112,17 @@ static long power_off_tick = 0; | |||
112 | 112 | ||
113 | static sector_t total_sectors; | 113 | static sector_t total_sectors; |
114 | static int multisectors; /* number of supported multisectors */ | 114 | static int multisectors; /* number of supported multisectors */ |
115 | static unsigned short identify_info[ATA_IDENTIFY_WORDS]; | 115 | |
116 | static unsigned short identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR; | ||
116 | 117 | ||
117 | #ifdef MAX_PHYS_SECTOR_SIZE | 118 | #ifdef MAX_PHYS_SECTOR_SIZE |
118 | struct sector_cache_entry { | 119 | struct sector_cache_entry { |
119 | bool inuse; | ||
120 | sector_t sectornum; /* logical sector */ | ||
121 | unsigned char data[MAX_PHYS_SECTOR_SIZE]; | 120 | unsigned char data[MAX_PHYS_SECTOR_SIZE]; |
121 | sector_t sectornum; /* logical sector */ | ||
122 | bool inuse; | ||
122 | }; | 123 | }; |
123 | /* buffer for reading and writing large physical sectors */ | 124 | /* buffer for reading and writing large physical sectors */ |
124 | #define NUMCACHES 2 | 125 | static struct sector_cache_entry sector_cache STORAGE_ALIGN_ATTR; |
125 | static struct sector_cache_entry sector_cache; | ||
126 | static int phys_sector_mult = 1; | 126 | static int phys_sector_mult = 1; |
127 | #endif | 127 | #endif |
128 | 128 | ||
@@ -255,7 +255,7 @@ static int ata_perform_flush_cache(void) | |||
255 | 255 | ||
256 | if (!canflush) { | 256 | if (!canflush) { |
257 | return 0; | 257 | return 0; |
258 | } else if (lba48 && identify_info[83] & (1 << 13)) { | 258 | } else if (ata_lba48 && identify_info[83] & (1 << 13)) { |
259 | cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices */ | 259 | cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices */ |
260 | } else if (identify_info[83] & (1 << 12)) { | 260 | } else if (identify_info[83] & (1 << 12)) { |
261 | cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */ | 261 | cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */ |
@@ -290,9 +290,9 @@ static int ata_perform_flush_cache(void) | |||
290 | int ata_flush(void) | 290 | int ata_flush(void) |
291 | { | 291 | { |
292 | if (ata_state >= ATA_SPINUP) { | 292 | if (ata_state >= ATA_SPINUP) { |
293 | mutex_lock(&ata_mtx); | 293 | mutex_lock(&ata_mutex); |
294 | ata_perform_flush_cache(); | 294 | ata_perform_flush_cache(); |
295 | mutex_unlock(&ata_mtx); | 295 | mutex_unlock(&ata_mutex); |
296 | } | 296 | } |
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
@@ -447,7 +447,7 @@ static int ata_transfer_sectors(uint64_t start, | |||
447 | #endif | 447 | #endif |
448 | 448 | ||
449 | #ifdef HAVE_LBA48 | 449 | #ifdef HAVE_LBA48 |
450 | if (lba48) | 450 | if (ata_lba48) |
451 | { | 451 | { |
452 | ATA_OUT8(ATA_NSECTOR, count >> 8); | 452 | ATA_OUT8(ATA_NSECTOR, count >> 8); |
453 | ATA_OUT8(ATA_NSECTOR, count & 0xff); | 453 | ATA_OUT8(ATA_NSECTOR, count & 0xff); |
@@ -474,7 +474,7 @@ static int ata_transfer_sectors(uint64_t start, | |||
474 | ATA_OUT8(ATA_SECTOR, start & 0xff); | 474 | ATA_OUT8(ATA_SECTOR, start & 0xff); |
475 | ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); | 475 | ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); |
476 | ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); | 476 | ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); |
477 | ATA_OUT8(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device); | 477 | ATA_OUT8(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device); /* LBA28, mask off upper 4 bits of 32-bit sector address */ |
478 | #ifdef HAVE_ATA_DMA | 478 | #ifdef HAVE_ATA_DMA |
479 | if (write) | 479 | if (write) |
480 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_WRITE_DMA : CMD_WRITE_MULTIPLE); | 480 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_WRITE_DMA : CMD_WRITE_MULTIPLE); |
@@ -610,9 +610,9 @@ int ata_read_sectors(IF_MD(int drive,) | |||
610 | (void)drive; /* unused for now */ | 610 | (void)drive; /* unused for now */ |
611 | #endif | 611 | #endif |
612 | 612 | ||
613 | mutex_lock(&ata_mtx); | 613 | mutex_lock(&ata_mutex); |
614 | int rc = ata_transfer_sectors(start, incount, inbuf, false); | 614 | int rc = ata_transfer_sectors(start, incount, inbuf, false); |
615 | mutex_unlock(&ata_mtx); | 615 | mutex_unlock(&ata_mutex); |
616 | return rc; | 616 | return rc; |
617 | } | 617 | } |
618 | 618 | ||
@@ -625,9 +625,9 @@ int ata_write_sectors(IF_MD(int drive,) | |||
625 | (void)drive; /* unused for now */ | 625 | (void)drive; /* unused for now */ |
626 | #endif | 626 | #endif |
627 | 627 | ||
628 | mutex_lock(&ata_mtx); | 628 | mutex_lock(&ata_mutex); |
629 | int rc = ata_transfer_sectors(start, count, (void*)buf, true); | 629 | int rc = ata_transfer_sectors(start, count, (void*)buf, true); |
630 | mutex_unlock(&ata_mtx); | 630 | mutex_unlock(&ata_mutex); |
631 | return rc; | 631 | return rc; |
632 | } | 632 | } |
633 | #endif /* ndef MAX_PHYS_SECTOR_SIZE */ | 633 | #endif /* ndef MAX_PHYS_SECTOR_SIZE */ |
@@ -637,8 +637,8 @@ static int cache_sector(sector_t sector) | |||
637 | { | 637 | { |
638 | int rc; | 638 | int rc; |
639 | 639 | ||
640 | /* round down to physical sector boundary */ | ||
640 | sector &= ~(phys_sector_mult - 1); | 641 | sector &= ~(phys_sector_mult - 1); |
641 | /* round down to physical sector boundary */ | ||
642 | 642 | ||
643 | /* check whether the sector is already cached */ | 643 | /* check whether the sector is already cached */ |
644 | if (sector_cache.inuse && (sector_cache.sectornum == sector)) | 644 | if (sector_cache.inuse && (sector_cache.sectornum == sector)) |
@@ -672,7 +672,7 @@ int ata_read_sectors(IF_MD(int drive,) | |||
672 | #ifdef HAVE_MULTIDRIVE | 672 | #ifdef HAVE_MULTIDRIVE |
673 | (void)drive; /* unused for now */ | 673 | (void)drive; /* unused for now */ |
674 | #endif | 674 | #endif |
675 | mutex_lock(&ata_mtx); | 675 | mutex_lock(&ata_mutex); |
676 | 676 | ||
677 | offset = start & (phys_sector_mult - 1); | 677 | offset = start & (phys_sector_mult - 1); |
678 | 678 | ||
@@ -722,7 +722,7 @@ int ata_read_sectors(IF_MD(int drive,) | |||
722 | } | 722 | } |
723 | 723 | ||
724 | error: | 724 | error: |
725 | mutex_unlock(&ata_mtx); | 725 | mutex_unlock(&ata_mutex); |
726 | 726 | ||
727 | return rc; | 727 | return rc; |
728 | } | 728 | } |
@@ -738,7 +738,7 @@ int ata_write_sectors(IF_MD(int drive,) | |||
738 | #ifdef HAVE_MULTIDRIVE | 738 | #ifdef HAVE_MULTIDRIVE |
739 | (void)drive; /* unused for now */ | 739 | (void)drive; /* unused for now */ |
740 | #endif | 740 | #endif |
741 | mutex_lock(&ata_mtx); | 741 | mutex_lock(&ata_mutex); |
742 | 742 | ||
743 | offset = start & (phys_sector_mult - 1); | 743 | offset = start & (phys_sector_mult - 1); |
744 | 744 | ||
@@ -799,7 +799,7 @@ int ata_write_sectors(IF_MD(int drive,) | |||
799 | } | 799 | } |
800 | 800 | ||
801 | error: | 801 | error: |
802 | mutex_unlock(&ata_mtx); | 802 | mutex_unlock(&ata_mutex); |
803 | 803 | ||
804 | return rc; | 804 | return rc; |
805 | } | 805 | } |
@@ -862,7 +862,7 @@ void ata_sleepnow(void) | |||
862 | { | 862 | { |
863 | if (ata_state >= ATA_SPINUP) { | 863 | if (ata_state >= ATA_SPINUP) { |
864 | logf("ata SLEEPNOW %ld", current_tick); | 864 | logf("ata SLEEPNOW %ld", current_tick); |
865 | mutex_lock(&ata_mtx); | 865 | mutex_lock(&ata_mutex); |
866 | if (ata_state == ATA_ON) { | 866 | if (ata_state == ATA_ON) { |
867 | if (!ata_perform_flush_cache() && !ata_perform_sleep()) { | 867 | if (!ata_perform_flush_cache() && !ata_perform_sleep()) { |
868 | ata_state = ATA_SLEEPING; | 868 | ata_state = ATA_SLEEPING; |
@@ -873,7 +873,7 @@ void ata_sleepnow(void) | |||
873 | #endif | 873 | #endif |
874 | } | 874 | } |
875 | } | 875 | } |
876 | mutex_unlock(&ata_mtx); | 876 | mutex_unlock(&ata_mutex); |
877 | } | 877 | } |
878 | } | 878 | } |
879 | 879 | ||
@@ -891,7 +891,7 @@ static int STORAGE_INIT_ATTR ata_hard_reset(void) | |||
891 | { | 891 | { |
892 | int ret; | 892 | int ret; |
893 | 893 | ||
894 | mutex_lock(&ata_mtx); | 894 | mutex_lock(&ata_mutex); |
895 | 895 | ||
896 | ata_reset(); | 896 | ata_reset(); |
897 | 897 | ||
@@ -902,7 +902,7 @@ static int STORAGE_INIT_ATTR ata_hard_reset(void) | |||
902 | /* Massage the return code so it is 0 on success and -1 on failure */ | 902 | /* Massage the return code so it is 0 on success and -1 on failure */ |
903 | ret = ret?0:-1; | 903 | ret = ret?0:-1; |
904 | 904 | ||
905 | mutex_unlock(&ata_mtx); | 905 | mutex_unlock(&ata_mutex); |
906 | 906 | ||
907 | return ret; | 907 | return ret; |
908 | } | 908 | } |
@@ -992,13 +992,13 @@ int ata_soft_reset(void) | |||
992 | { | 992 | { |
993 | int ret = -6; | 993 | int ret = -6; |
994 | 994 | ||
995 | mutex_lock(&ata_mtx); | 995 | mutex_lock(&ata_mutex); |
996 | 996 | ||
997 | if (ata_state > ATA_OFF) { | 997 | if (ata_state > ATA_OFF) { |
998 | ret = perform_soft_reset(); | 998 | ret = perform_soft_reset(); |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | mutex_unlock(&ata_mtx); | 1001 | mutex_unlock(&ata_mutex); |
1002 | return ret; | 1002 | return ret; |
1003 | } | 1003 | } |
1004 | 1004 | ||
@@ -1232,10 +1232,10 @@ int STORAGE_INIT_ATTR ata_init(void) | |||
1232 | bool coldstart; | 1232 | bool coldstart; |
1233 | 1233 | ||
1234 | if (ata_state == ATA_BOOT) { | 1234 | if (ata_state == ATA_BOOT) { |
1235 | mutex_init(&ata_mtx); | 1235 | mutex_init(&ata_mutex); |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | mutex_lock(&ata_mtx); | 1238 | mutex_lock(&ata_mutex); |
1239 | 1239 | ||
1240 | /* must be called before ata_device_init() */ | 1240 | /* must be called before ata_device_init() */ |
1241 | coldstart = ata_is_coldstart(); | 1241 | coldstart = ata_is_coldstart(); |
@@ -1292,7 +1292,7 @@ int STORAGE_INIT_ATTR ata_init(void) | |||
1292 | ((uint64_t)identify_info[102] << 32) | | 1292 | ((uint64_t)identify_info[102] << 32) | |
1293 | ((uint64_t)identify_info[101] << 16) | | 1293 | ((uint64_t)identify_info[101] << 16) | |
1294 | identify_info[100]; | 1294 | identify_info[100]; |
1295 | lba48 = true; /* use BigLBA */ | 1295 | ata_lba48 = true; /* use BigLBA */ |
1296 | } | 1296 | } |
1297 | #endif /* HAVE_LBA48 */ | 1297 | #endif /* HAVE_LBA48 */ |
1298 | 1298 | ||
@@ -1320,8 +1320,8 @@ int STORAGE_INIT_ATTR ata_init(void) | |||
1320 | if (phys_sector_mult > 1) | 1320 | if (phys_sector_mult > 1) |
1321 | { | 1321 | { |
1322 | /* Check if drive really needs emulation - if we can access | 1322 | /* Check if drive really needs emulation - if we can access |
1323 | * sector 1 then assume the drive will handle it better than | 1323 | sector 1 then assume the drive supports "512e" and will handle |
1324 | * us, and ignore the large physical sectors. | 1324 | it better than us, so ignore the large physical sectors. |
1325 | */ | 1325 | */ |
1326 | char throwaway[SECTOR_SIZE]; | 1326 | char throwaway[SECTOR_SIZE]; |
1327 | rc = ata_transfer_sectors(1, 1, &throwaway, false); | 1327 | rc = ata_transfer_sectors(1, 1, &throwaway, false); |
@@ -1348,7 +1348,7 @@ int STORAGE_INIT_ATTR ata_init(void) | |||
1348 | } | 1348 | } |
1349 | 1349 | ||
1350 | error: | 1350 | error: |
1351 | mutex_unlock(&ata_mtx); | 1351 | mutex_unlock(&ata_mutex); |
1352 | return rc; | 1352 | return rc; |
1353 | } | 1353 | } |
1354 | 1354 | ||
@@ -1448,11 +1448,11 @@ int ata_event(long id, intptr_t data) | |||
1448 | #ifdef HAVE_ATA_POWER_OFF | 1448 | #ifdef HAVE_ATA_POWER_OFF |
1449 | if (ata_state == ATA_SLEEPING && ata_power_off_timed_out()) { | 1449 | if (ata_state == ATA_SLEEPING && ata_power_off_timed_out()) { |
1450 | power_off_tick = 0; | 1450 | power_off_tick = 0; |
1451 | mutex_lock(&ata_mtx); | 1451 | mutex_lock(&ata_mutex); |
1452 | logf("ata OFF %ld", current_tick); | 1452 | logf("ata OFF %ld", current_tick); |
1453 | ide_power_enable(false); | 1453 | ide_power_enable(false); |
1454 | ata_state = ATA_OFF; | 1454 | ata_state = ATA_OFF; |
1455 | mutex_unlock(&ata_mtx); | 1455 | mutex_unlock(&ata_mutex); |
1456 | } | 1456 | } |
1457 | #endif | 1457 | #endif |
1458 | STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA); | 1458 | STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA); |
@@ -1472,7 +1472,7 @@ int ata_event(long id, intptr_t data) | |||
1472 | STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA); | 1472 | STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA); |
1473 | } | 1473 | } |
1474 | else { | 1474 | else { |
1475 | mutex_lock(&ata_mtx); | 1475 | mutex_lock(&ata_mutex); |
1476 | if (ata_state < ATA_ON) { | 1476 | if (ata_state < ATA_ON) { |
1477 | ata_led(true); | 1477 | ata_led(true); |
1478 | if (!(rc = ata_perform_wakeup(ata_state))) { | 1478 | if (!(rc = ata_perform_wakeup(ata_state))) { |
@@ -1480,7 +1480,7 @@ int ata_event(long id, intptr_t data) | |||
1480 | } | 1480 | } |
1481 | ata_led(false); | 1481 | ata_led(false); |
1482 | } | 1482 | } |
1483 | mutex_unlock(&ata_mtx); | 1483 | mutex_unlock(&ata_mutex); |
1484 | } | 1484 | } |
1485 | } | 1485 | } |
1486 | #endif /* ndef USB_NONE */ | 1486 | #endif /* ndef USB_NONE */ |