summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-29 16:54:36 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-29 16:54:36 +0000
commite9749d1b93f23b3bc36305ad1d39ca5e5c0cb3a8 (patch)
treea997eee450ed119bfb2b1c17a23759f1e72ccde2
parent7436e7ab4112bbda3bd4e534fd6fc49a9286904e (diff)
downloadrockbox-e9749d1b93f23b3bc36305ad1d39ca5e5c0cb3a8.tar.gz
rockbox-e9749d1b93f23b3bc36305ad1d39ca5e5c0cb3a8.zip
AMSv2 SD: Fix card insert lockups in USB mode. First, get rid of infinite loops and retry those a limited number of times-- no explaination for their dubious existence was offered in the source. Second, SD thread was no longer monitoring inserts (and it wouldn't really matter if it were). Thus, .initialized was reported as '1' despite the new card needing reinit.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29169 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 929a036935..70d7c8fda1 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -334,9 +334,6 @@ static tCardInfo card_info[NUM_DRIVES];
334/* for compatibility */ 334/* for compatibility */
335static long last_disk_activity = -1; 335static long last_disk_activity = -1;
336 336
337#define MIN_YIELD_PERIOD 5 /* ticks */
338static long next_yield = 0;
339
340static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 337static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
341static const char sd_thread_name[] = "ata/sd"; 338static const char sd_thread_name[] = "ata/sd";
342static struct mutex sd_mtx SHAREDBSS_ATTR; 339static struct mutex sd_mtx SHAREDBSS_ATTR;
@@ -470,10 +467,18 @@ static int sd_wait_for_tran_state(const int drive)
470{ 467{
471 unsigned long response; 468 unsigned long response;
472 unsigned int timeout = current_tick + 5*HZ; 469 unsigned int timeout = current_tick + 5*HZ;
470 int cmd_retry = 10;
473 471
474 while (1) 472 while (1)
475 { 473 {
476 while(!(send_cmd(drive, SD_SEND_STATUS, card_info[drive].rca, MCI_RESP, &response))); 474 while (!send_cmd(drive, SD_SEND_STATUS, card_info[drive].rca, MCI_RESP,
475 &response) && cmd_retry > 0)
476 {
477 cmd_retry--;
478 }
479
480 if (cmd_retry <= 0)
481 return -1;
477 482
478 if (((response >> 9) & 0xf) == SD_TRAN) 483 if (((response >> 9) & 0xf) == SD_TRAN)
479 return 0; 484 return 0;
@@ -481,11 +486,7 @@ static int sd_wait_for_tran_state(const int drive)
481 if(TIME_AFTER(current_tick, timeout)) 486 if(TIME_AFTER(current_tick, timeout))
482 return -10 * ((response >> 9) & 0xf); 487 return -10 * ((response >> 9) & 0xf);
483 488
484 if (TIME_AFTER(current_tick, next_yield)) 489 last_disk_activity = current_tick;
485 {
486 yield();
487 next_yield = current_tick + MIN_YIELD_PERIOD;
488 }
489 } 490 }
490} 491}
491 492
@@ -669,11 +670,13 @@ static void sd_thread(void)
669 */ 670 */
670 if (microsd_init) 671 if (microsd_init)
671 queue_broadcast(SYS_FS_CHANGED, 0); 672 queue_broadcast(SYS_FS_CHANGED, 0);
673
674 sd_enable(false);
675
672 /* Access is now safe */ 676 /* Access is now safe */
673 mutex_unlock(&sd_mtx); 677 mutex_unlock(&sd_mtx);
674 fat_unlock(); 678 fat_unlock();
675 sd_enable(false); 679 }
676 }
677 break; 680 break;
678#endif 681#endif
679 case SYS_TIMEOUT: 682 case SYS_TIMEOUT:
@@ -681,16 +684,10 @@ static void sd_thread(void)
681 { 684 {
682 idle_notified = false; 685 idle_notified = false;
683 } 686 }
684 else 687 else if (!idle_notified)
685 { 688 {
686 /* never let a timer wrap confuse us */ 689 call_storage_idle_notifys(false);
687 next_yield = current_tick; 690 idle_notified = true;
688
689 if (!idle_notified)
690 {
691 call_storage_idle_notifys(false);
692 idle_notified = true;
693 }
694 } 691 }
695 break; 692 break;
696 693
@@ -825,7 +822,10 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
825 const int drive = 0; 822 const int drive = 0;
826#endif 823#endif
827 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 824 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
828 825 int const retry_all_max = 1;
826 int retry_all = 0;
827 int const retry_data_max = 100; /* Generous, methinks */
828 int retry_data;
829 829
830 mutex_lock(&sd_mtx); 830 mutex_lock(&sd_mtx);
831#ifndef BOOTLOADER 831#ifndef BOOTLOADER
@@ -833,6 +833,21 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
833 led(true); 833 led(true);
834#endif 834#endif
835 835
836 if(count < 0) /* XXX: why is it signed ? */
837 {
838 ret = -18;
839 goto sd_transfer_error_no_dma;
840 }
841
842 /* skip SanDisk OF */
843 if (drive == INTERNAL_AS3525)
844 start += AMS_OF_SIZE;
845
846 /* no need for complete retry on main, just SD */
847 if (drive == SD_SLOT_AS3525)
848 retry_all = retry_all_max;
849
850sd_transfer_retry_with_reinit:
836 if (card_info[drive].initialized <= 0) 851 if (card_info[drive].initialized <= 0)
837 { 852 {
838 ret = sd_init_card(drive); 853 ret = sd_init_card(drive);
@@ -840,21 +855,12 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
840 goto sd_transfer_error_no_dma; 855 goto sd_transfer_error_no_dma;
841 } 856 }
842 857
843 if(count < 0) /* XXX: why is it signed ? */
844 {
845 ret = -18;
846 goto sd_transfer_error_no_dma;
847 }
848 if((start+count) > card_info[drive].numblocks) 858 if((start+count) > card_info[drive].numblocks)
849 { 859 {
850 ret = -19; 860 ret = -19;
851 goto sd_transfer_error_no_dma; 861 goto sd_transfer_error_no_dma;
852 } 862 }
853 863
854 /* skip SanDisk OF */
855 if (drive == INTERNAL_AS3525)
856 start += AMS_OF_SIZE;
857
858 /* CMD7 w/rca: Select card to put it in TRAN state */ 864 /* CMD7 w/rca: Select card to put it in TRAN state */
859 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL)) 865 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL))
860 { 866 {
@@ -862,7 +868,6 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
862 goto sd_transfer_error_no_dma; 868 goto sd_transfer_error_no_dma;
863 } 869 }
864 870
865 last_disk_activity = current_tick;
866 dma_retain(); 871 dma_retain();
867 872
868 if(aligned) 873 if(aligned)
@@ -874,12 +879,15 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
874 } 879 }
875 880
876 const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; 881 const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
882 retry_data = retry_data_max;
877 883
878 do 884 while (1)
879 { 885 {
880 void *dma_buf; 886 void *dma_buf;
881 unsigned int transfer = count; 887 unsigned int transfer = count;
882 888
889 last_disk_activity = current_tick;
890
883 if(aligned) 891 if(aligned)
884 { 892 {
885 dma_buf = AS3525_PHYSICAL_ADDR(buf); 893 dma_buf = AS3525_PHYSICAL_ADDR(buf);
@@ -947,15 +955,21 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
947 buf += transfer * SD_BLOCK_SIZE; 955 buf += transfer * SD_BLOCK_SIZE;
948 start += transfer; 956 start += transfer;
949 count -= transfer; 957 count -= transfer;
958
959 if (count > 0)
960 continue;
950 } 961 }
951 else /* reset controller if we had an error */ 962 else /* reset controller if we had an error */
952 { 963 {
953 MCI_CTRL |= (FIFO_RESET|DMA_RESET); 964 MCI_CTRL |= (FIFO_RESET|DMA_RESET);
954 while(MCI_CTRL & (FIFO_RESET|DMA_RESET)) 965 while(MCI_CTRL & (FIFO_RESET|DMA_RESET))
955 ; 966 ;
967 if (--retry_data >= 0)
968 continue;
956 } 969 }
957 970
958 } while(retry || count); 971 break;
972 }
959 973
960 dma_release(); 974 dma_release();
961 975
@@ -967,22 +981,29 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
967 goto sd_transfer_error; 981 goto sd_transfer_error;
968 } 982 }
969 983
984 while (1)
985 {
970#ifndef BOOTLOADER 986#ifndef BOOTLOADER
971 sd_enable(false); 987 sd_enable(false);
972 led(false); 988 led(false);
973#endif 989#endif
974 mutex_unlock(&sd_mtx); 990 mutex_unlock(&sd_mtx);
975 return 0; 991 return ret;
976 992
977sd_transfer_error: 993sd_transfer_error:
978 994 dma_release();
979 dma_release();
980 995
981sd_transfer_error_no_dma: 996sd_transfer_error_no_dma:
997 card_info[drive].initialized = 0;
982 998
983 card_info[drive].initialized = 0; 999 /* .initialized might have been >= 0 but now stale if the ata sd thread
984 mutex_unlock(&sd_mtx); 1000 * isn't handling an insert because of USB */
985 return ret; 1001 if (--retry_all >= 0)
1002 {
1003 ret = 0;
1004 goto sd_transfer_retry_with_reinit;
1005 }
1006 }
986} 1007}
987 1008
988int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, 1009int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,