diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-26 21:08:47 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-26 21:08:47 +0000 |
commit | 83eb479732879e9852064644942ca36a7fd986a9 (patch) | |
tree | af8f86de1c1829da8f13c6ca7f4dc963ca01c2b5 /firmware/target | |
parent | 3ca0614de9a3c4dc633e4c9f9ba459d89e44dd92 (diff) | |
download | rockbox-83eb479732879e9852064644942ca36a7fd986a9.tar.gz rockbox-83eb479732879e9852064644942ca36a7fd986a9.zip |
FS#10216 : Sansa AMS : Do not cross a bank boundary in a single transfer (Only for 8GB or more -if they exist- players)
Also add a few comments in the code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21096 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 03a6a8bd02..a0b9b13c0c 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -142,8 +142,8 @@ void INT_GPIOA(void) | |||
142 | GPIOA_IC = (1<<2); | 142 | GPIOA_IC = (1<<2); |
143 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); | 143 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); |
144 | } | 144 | } |
145 | #endif | 145 | #endif /* defined(SANSA_E200V2) || defined(SANSA_FUZE) */ |
146 | #endif | 146 | #endif /* HAVE_HOTSWAP */ |
147 | 147 | ||
148 | void INT_NAND(void) | 148 | void INT_NAND(void) |
149 | { | 149 | { |
@@ -211,7 +211,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, | |||
211 | { /* resp received */ | 211 | { /* resp received */ |
212 | if(flags & MCI_LONG_RESP) | 212 | if(flags & MCI_LONG_RESP) |
213 | { | 213 | { |
214 | /* store the response in little endian order for the words */ | 214 | /* store the response in reverse words order */ |
215 | response[0] = MCI_RESP3(drive); | 215 | response[0] = MCI_RESP3(drive); |
216 | response[1] = MCI_RESP2(drive); | 216 | response[1] = MCI_RESP2(drive); |
217 | response[2] = MCI_RESP1(drive); | 217 | response[2] = MCI_RESP1(drive); |
@@ -322,7 +322,7 @@ static int sd_init_card(const int drive) | |||
322 | 322 | ||
323 | card_info[drive].initialized = 1; | 323 | card_info[drive].initialized = 1; |
324 | 324 | ||
325 | MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed */ | 325 | MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed for controller clock */ |
326 | mci_delay(); | 326 | mci_delay(); |
327 | 327 | ||
328 | /* | 328 | /* |
@@ -626,7 +626,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
626 | const int drive = 0; | 626 | const int drive = 0; |
627 | #endif | 627 | #endif |
628 | int ret = 0; | 628 | int ret = 0; |
629 | int bank; | ||
630 | bool unaligned_transfer = (int)buf & 3; | 629 | bool unaligned_transfer = (int)buf & 3; |
631 | 630 | ||
632 | /* skip SanDisk OF */ | 631 | /* skip SanDisk OF */ |
@@ -647,29 +646,10 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
647 | 646 | ||
648 | last_disk_activity = current_tick; | 647 | last_disk_activity = current_tick; |
649 | 648 | ||
650 | /* Only switch banks for internal storage */ | ||
651 | if(drive == INTERNAL_AS3525) | ||
652 | { | ||
653 | bank = start / BLOCKS_PER_BANK; | ||
654 | |||
655 | if(card_info[INTERNAL_AS3525].current_bank != bank) | ||
656 | { | ||
657 | ret = sd_select_bank(bank); | ||
658 | if (ret < 0) | ||
659 | { | ||
660 | ret -= 20; | ||
661 | goto sd_transfer_error; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | start -= bank * BLOCKS_PER_BANK; | ||
666 | } | ||
667 | |||
668 | |||
669 | ret = sd_wait_for_state(drive, SD_TRAN); | 649 | ret = sd_wait_for_state(drive, SD_TRAN); |
670 | if (ret < 0) | 650 | if (ret < 0) |
671 | { | 651 | { |
672 | ret -= 2*20; | 652 | ret -= 20; |
673 | goto sd_transfer_error; | 653 | goto sd_transfer_error; |
674 | } | 654 | } |
675 | 655 | ||
@@ -683,13 +663,35 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
683 | void *dma_buf; | 663 | void *dma_buf; |
684 | const int cmd = | 664 | const int cmd = |
685 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | 665 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; |
686 | int arg = start; | 666 | unsigned long bank_start = start; |
687 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | ||
688 | arg *= BLOCK_SIZE; | ||
689 | 667 | ||
690 | /* Interrupt handler might set this to true during transfer */ | 668 | /* Interrupt handler might set this to true during transfer */ |
691 | retry = false; | 669 | retry = false; |
692 | 670 | ||
671 | /* Only switch banks for internal storage */ | ||
672 | if(drive == INTERNAL_AS3525) | ||
673 | { | ||
674 | int bank = start / BLOCKS_PER_BANK; /* Current bank */ | ||
675 | |||
676 | /* Switch bank if needed */ | ||
677 | if(card_info[INTERNAL_AS3525].current_bank != bank) | ||
678 | { | ||
679 | ret = sd_select_bank(bank); | ||
680 | if (ret < 0) | ||
681 | { | ||
682 | ret -= 2*20; | ||
683 | goto sd_transfer_error; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | /* Adjust start block in current bank */ | ||
688 | bank_start -= bank * BLOCKS_PER_BANK; | ||
689 | |||
690 | /* Do not cross a bank boundary in a single transfer loop */ | ||
691 | if((transfer + bank_start) >= BLOCKS_PER_BANK) | ||
692 | transfer = BLOCKS_PER_BANK - bank_start; | ||
693 | } | ||
694 | |||
693 | if(unaligned_transfer) | 695 | if(unaligned_transfer) |
694 | { | 696 | { |
695 | dma_buf = aligned_buffer; | 697 | dma_buf = aligned_buffer; |
@@ -698,10 +700,14 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
698 | if(write) | 700 | if(write) |
699 | memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE); | 701 | memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE); |
700 | } | 702 | } |
701 | else | 703 | else /* Aligned transfers are faster : no memcpy */ |
702 | dma_buf = buf; | 704 | dma_buf = buf; |
703 | 705 | ||
704 | if(!send_cmd(drive, cmd, arg, MCI_ARG, NULL)) | 706 | /* Set bank_start to the correct unit (blocks or bytes) */ |
707 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | ||
708 | bank_start *= BLOCK_SIZE; | ||
709 | |||
710 | if(!send_cmd(drive, cmd, bank_start, MCI_ARG, NULL)) | ||
705 | { | 711 | { |
706 | ret -= 3*20; | 712 | ret -= 3*20; |
707 | goto sd_transfer_error; | 713 | goto sd_transfer_error; |