diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index ff463e52d1..1d738f5bc2 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -371,6 +371,7 @@ static int ata_transfer_sectors(unsigned long start, | |||
371 | ata_led(true); | 371 | ata_led(true); |
372 | 372 | ||
373 | if ( sleeping ) { | 373 | if ( sleeping ) { |
374 | sleeping = false; /* set this now since it'll be on */ | ||
374 | spinup = true; | 375 | spinup = true; |
375 | if (poweroff) { | 376 | if (poweroff) { |
376 | if (ata_power_on()) { | 377 | if (ata_power_on()) { |
@@ -467,7 +468,6 @@ static int ata_transfer_sectors(unsigned long start, | |||
467 | if (spinup) { | 468 | if (spinup) { |
468 | spinup_time = current_tick - spinup_start; | 469 | spinup_time = current_tick - spinup_start; |
469 | spinup = false; | 470 | spinup = false; |
470 | sleeping = false; | ||
471 | poweroff = false; | 471 | poweroff = false; |
472 | } | 472 | } |
473 | } | 473 | } |
@@ -497,7 +497,6 @@ static int ata_transfer_sectors(unsigned long start, | |||
497 | if (spinup) { | 497 | if (spinup) { |
498 | spinup_time = current_tick - spinup_start; | 498 | spinup_time = current_tick - spinup_start; |
499 | spinup = false; | 499 | spinup = false; |
500 | sleeping = false; | ||
501 | poweroff = false; | 500 | poweroff = false; |
502 | } | 501 | } |
503 | 502 | ||
@@ -817,13 +816,16 @@ bool ata_disk_is_active(void) | |||
817 | 816 | ||
818 | static int ata_perform_sleep(void) | 817 | static int ata_perform_sleep(void) |
819 | { | 818 | { |
820 | mutex_lock(&ata_mtx); | 819 | /* guard against calls made with checks of these variables outside |
820 | the mutex that may not be on the ata thread; status may have changed. */ | ||
821 | if (spinup || sleeping) { | ||
822 | return 0; | ||
823 | } | ||
821 | 824 | ||
822 | SET_REG(ATA_SELECT, ata_device); | 825 | SET_REG(ATA_SELECT, ata_device); |
823 | 826 | ||
824 | if(!wait_for_rdy()) { | 827 | if(!wait_for_rdy()) { |
825 | DEBUGF("ata_perform_sleep() - not RDY\n"); | 828 | DEBUGF("ata_perform_sleep() - not RDY\n"); |
826 | mutex_unlock(&ata_mtx); | ||
827 | return -1; | 829 | return -1; |
828 | } | 830 | } |
829 | 831 | ||
@@ -832,12 +834,10 @@ static int ata_perform_sleep(void) | |||
832 | if (!wait_for_rdy()) | 834 | if (!wait_for_rdy()) |
833 | { | 835 | { |
834 | DEBUGF("ata_perform_sleep() - CMD failed\n"); | 836 | DEBUGF("ata_perform_sleep() - CMD failed\n"); |
835 | mutex_unlock(&ata_mtx); | ||
836 | return -2; | 837 | return -2; |
837 | } | 838 | } |
838 | 839 | ||
839 | sleeping = true; | 840 | sleeping = true; |
840 | mutex_unlock(&ata_mtx); | ||
841 | return 0; | 841 | return 0; |
842 | } | 842 | } |
843 | 843 | ||
@@ -848,10 +848,12 @@ void ata_sleep(void) | |||
848 | 848 | ||
849 | void ata_sleepnow(void) | 849 | void ata_sleepnow(void) |
850 | { | 850 | { |
851 | if (!spinup && !sleeping && !ata_mtx.locked && initialized) | 851 | if (!spinup && !sleeping && initialized) |
852 | { | 852 | { |
853 | call_storage_idle_notifys(false); | 853 | call_storage_idle_notifys(false); |
854 | mutex_lock(&ata_mtx); | ||
854 | ata_perform_sleep(); | 855 | ata_perform_sleep(); |
856 | mutex_unlock(&ata_mtx); | ||
855 | } | 857 | } |
856 | } | 858 | } |
857 | 859 | ||
@@ -864,7 +866,6 @@ static void ata_thread(void) | |||
864 | { | 866 | { |
865 | static long last_sleep = 0; | 867 | static long last_sleep = 0; |
866 | struct queue_event ev; | 868 | struct queue_event ev; |
867 | static long last_seen_mtx_unlock = 0; | ||
868 | #ifdef ALLOW_USB_SPINDOWN | 869 | #ifdef ALLOW_USB_SPINDOWN |
869 | static bool usb_mode = false; | 870 | static bool usb_mode = false; |
870 | #endif | 871 | #endif |
@@ -876,21 +877,17 @@ static void ata_thread(void) | |||
876 | case SYS_TIMEOUT: | 877 | case SYS_TIMEOUT: |
877 | if (!spinup && !sleeping) | 878 | if (!spinup && !sleeping) |
878 | { | 879 | { |
879 | if (!ata_mtx.locked) | 880 | if (TIME_AFTER( current_tick, |
881 | last_disk_activity + (HZ*2) ) ) | ||
880 | { | 882 | { |
881 | if (!last_seen_mtx_unlock) | ||
882 | last_seen_mtx_unlock = current_tick; | ||
883 | if (TIME_AFTER(current_tick, last_seen_mtx_unlock+(HZ*2))) | ||
884 | { | ||
885 | #ifdef ALLOW_USB_SPINDOWN | 883 | #ifdef ALLOW_USB_SPINDOWN |
886 | if(!usb_mode) | 884 | if(!usb_mode) |
887 | #endif | 885 | #endif |
888 | { | 886 | { |
889 | call_storage_idle_notifys(false); | 887 | call_storage_idle_notifys(false); |
890 | } | ||
891 | last_seen_mtx_unlock = 0; | ||
892 | } | 888 | } |
893 | } | 889 | } |
890 | |||
894 | if ( sleep_timeout && | 891 | if ( sleep_timeout && |
895 | TIME_AFTER( current_tick, | 892 | TIME_AFTER( current_tick, |
896 | last_user_activity + sleep_timeout ) && | 893 | last_user_activity + sleep_timeout ) && |
@@ -903,8 +900,10 @@ static void ata_thread(void) | |||
903 | { | 900 | { |
904 | call_storage_idle_notifys(true); | 901 | call_storage_idle_notifys(true); |
905 | } | 902 | } |
903 | mutex_lock(&ata_mtx); | ||
906 | ata_perform_sleep(); | 904 | ata_perform_sleep(); |
907 | last_sleep = current_tick; | 905 | last_sleep = current_tick; |
906 | mutex_unlock(&ata_mtx); | ||
908 | } | 907 | } |
909 | } | 908 | } |
910 | 909 | ||
@@ -929,9 +928,11 @@ static void ata_thread(void) | |||
929 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 928 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
930 | /* There is no need to force ATA power on */ | 929 | /* There is no need to force ATA power on */ |
931 | #else | 930 | #else |
931 | mutex_lock(&ata_mtx); | ||
932 | if (sleeping) { | 932 | if (sleeping) { |
933 | mutex_lock(&ata_mtx); | ||
934 | ata_led(true); | 933 | ata_led(true); |
934 | sleeping = false; /* set this now since it'll be on */ | ||
935 | |||
935 | if (poweroff) { | 936 | if (poweroff) { |
936 | ata_power_on(); | 937 | ata_power_on(); |
937 | poweroff = false; | 938 | poweroff = false; |
@@ -939,10 +940,10 @@ static void ata_thread(void) | |||
939 | else { | 940 | else { |
940 | perform_soft_reset(); | 941 | perform_soft_reset(); |
941 | } | 942 | } |
942 | sleeping = false; | 943 | |
943 | ata_led(false); | 944 | ata_led(false); |
944 | mutex_unlock(&ata_mtx); | ||
945 | } | 945 | } |
946 | mutex_unlock(&ata_mtx); | ||
946 | 947 | ||
947 | /* Wait until the USB cable is extracted again */ | 948 | /* Wait until the USB cable is extracted again */ |
948 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 949 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |