summaryrefslogtreecommitdiff
path: root/firmware/drivers/ata.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-05-21 15:33:31 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-05-21 15:33:31 +0000
commitff25b3a20838241da597212a5faf9cb275420ab7 (patch)
tree37e52ccbf02f9fe136e724437e36a92fa16ce1cf /firmware/drivers/ata.c
parente24dd5ff98d63e81b4894b2ba06375f90105b373 (diff)
downloadrockbox-ff25b3a20838241da597212a5faf9cb275420ab7.tar.gz
rockbox-ff25b3a20838241da597212a5faf9cb275420ab7.zip
ata: do some threading-related corrections (some sync related where it matters). Make sure 'sleeping' is 'false' before the powerup sequence (throws-off powermgmt and it *is* about to woken again and powermgmt will need to compensate). Avoid looking at mutex flag directly; there's no tangible benefit I can discern and changes to the kernel that alter the meaning shouldn't be able to break anything. For that, in the jz sd driver, have sd_disk_is_active just return 'false' like all the other SD drivers do. If it *must* return this, it should implement it's own method but it seems to not matter.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26234 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r--firmware/drivers/ata.c43
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
818static int ata_perform_sleep(void) 817static 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
849void ata_sleepnow(void) 849void 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);