summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-11-01 16:14:28 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-11-01 16:14:28 +0000
commit2f8a0081c64534da23fc0fa9cc685eb7454fd9c9 (patch)
tree84dbdbd5326cb48f43d2ebd5a4c86e992c1d5288 /firmware/target
parent646cac0bde7b11fa7bcb670d1d76eec78e360485 (diff)
downloadrockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.tar.gz
rockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.zip
Apply FS#9500. This adds a storage_*() abstraction to replace ata_*(). To do that, it also introduces sd_*, nand_*, and mmc_*.
This should be a good first step to allow multi-driver targets, like the Elio (ATA/SD), or the D2 (NAND/SD). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18960 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/ata-nand-telechips.c93
-rw-r--r--firmware/target/arm/ata-sd-pp.c153
2 files changed, 97 insertions, 149 deletions
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index 1c135650f1..4276c10d64 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -18,7 +18,7 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "ata.h" 21#include "nand.h"
22#include "ata-nand-target.h" 22#include "ata-nand-target.h"
23#include "system.h" 23#include "system.h"
24#include <string.h> 24#include <string.h>
@@ -31,6 +31,7 @@
31#include "lcd.h" 31#include "lcd.h"
32#include "font.h" 32#include "font.h"
33#include "button.h" 33#include "button.h"
34#include "storage.h"
34#include <sprintf.h> 35#include <sprintf.h>
35 36
36#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
@@ -43,9 +44,6 @@ int ata_spinup_time = 0;
43 44
44long last_disk_activity = -1; 45long last_disk_activity = -1;
45 46
46/* as we aren't actually ata manually fill some fields */
47static unsigned short ata_identify[SECTOR_SIZE/2];
48
49/** static, private data **/ 47/** static, private data **/
50static bool initialized = false; 48static bool initialized = false;
51 49
@@ -662,7 +660,7 @@ static void read_write_cache_segment(int bank, int phys_segment)
662} 660}
663 661
664 662
665int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, 663int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
666 void* inbuf) 664 void* inbuf)
667{ 665{
668#ifdef HAVE_MULTIVOLUME 666#ifdef HAVE_MULTIVOLUME
@@ -702,7 +700,7 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
702 return 0; 700 return 0;
703} 701}
704 702
705int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, 703int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
706 const void* outbuf) 704 const void* outbuf)
707{ 705{
708#ifdef HAVE_MULTIVOLUME 706#ifdef HAVE_MULTIVOLUME
@@ -716,83 +714,21 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
716 return -1; 714 return -1;
717} 715}
718 716
719void ata_spindown(int seconds) 717void nand_get_info(struct storage_info *info)
720{
721 /* null */
722 (void)seconds;
723}
724
725bool ata_disk_is_active(void)
726{
727 /* null */
728 return 0;
729}
730
731void ata_sleep(void)
732{ 718{
733 /* null */
734}
735
736void ata_spin(void)
737{
738 /* null */
739}
740
741/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
742int ata_hard_reset(void)
743{
744 /* null */
745 return 0;
746}
747
748int ata_soft_reset(void)
749{
750 /* null */
751 return 0;
752}
753
754void ata_enable(bool on)
755{
756 /* null - flash controller is enabled/disabled as needed. */
757 (void)on;
758}
759
760static void fill_identify(void)
761{
762 char buf[80];
763 unsigned short *wbuf = (unsigned short *) buf;
764 unsigned long blocks;
765 int i;
766
767 memset(ata_identify, 0, sizeof(ata_identify));
768
769 /* firmware version */ 719 /* firmware version */
770 memset(buf, ' ', 8); 720 info->revision="0.00";
771 memcpy(buf, "0.00", 4);
772 721
773 for (i = 0; i < 4; i++) 722 info->vendor="Rockbox";
774 ata_identify[23 + i] = betoh16(wbuf[i]); 723 info->product="Internal Storage";
775
776 /* model field, need better name? */
777 memset(buf, ' ', 80);
778 memcpy(buf, "TNFL", 4);
779
780 for (i = 0; i < 40; i++)
781 ata_identify[27 + i] = betoh16(wbuf[i]);
782 724
783 /* blocks count */ 725 /* blocks count */
784 blocks = (pages_per_block * blocks_per_bank / SECTOR_SIZE) 726 info->num_sectors = (pages_per_block * blocks_per_bank / SECTOR_SIZE)
785 * page_size * total_banks; 727 * page_size * total_banks;
786 ata_identify[60] = blocks & 0xffff; 728 info->sector_size=SECTOR_SIZE;
787 ata_identify[61] = blocks >> 16;
788
789 /* TODO: discover where is s/n in TNFL */
790 for (i = 10; i < 20; i++) {
791 ata_identify[i] = 0;
792 }
793} 729}
794 730
795int ata_init(void) 731int nand_init(void)
796{ 732{
797 int i, bank, phys_segment; 733 int i, bank, phys_segment;
798 unsigned char spare_buf[16]; 734 unsigned char spare_buf[16];
@@ -909,13 +845,12 @@ int ata_init(void)
909 } 845 }
910#endif 846#endif
911 847
912 fill_identify();
913 initialized = true; 848 initialized = true;
914 849
915 return 0; 850 return 0;
916} 851}
917 852
918unsigned short* ata_get_identify(void) 853long nand_last_disk_activity(void)
919{ 854{
920 return ata_identify; 855 return last_disk_activity;
921} 856}
diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c
index b15b3634d8..a12aafc718 100644
--- a/firmware/target/arm/ata-sd-pp.c
+++ b/firmware/target/arm/ata-sd-pp.c
@@ -30,6 +30,8 @@
30#include "cpu.h" 30#include "cpu.h"
31#include "panic.h" 31#include "panic.h"
32#include "usb.h" 32#include "usb.h"
33#include "sd.h"
34#include "storage.h"
33 35
34#define BLOCK_SIZE 512 36#define BLOCK_SIZE 512
35#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
@@ -128,15 +130,13 @@
128 130
129/** global, exported variables **/ 131/** global, exported variables **/
130#ifdef HAVE_MULTIVOLUME 132#ifdef HAVE_MULTIVOLUME
131#define NUM_VOLUMES 2 133#define NUM_DRIVES 2
132#else 134#else
133#define NUM_VOLUMES 1 135#define NUM_DRIVES 1
134#endif 136#endif
135 137
136/* for compatibility */ 138/* for compatibility */
137int ata_spinup_time = 0; 139static long last_disk_activity = -1;
138
139long last_disk_activity = -1;
140 140
141/** static, private data **/ 141/** static, private data **/
142static bool initialized = false; 142static bool initialized = false;
@@ -153,7 +153,7 @@ struct sd_card_status
153 int retry_max; 153 int retry_max;
154}; 154};
155 155
156static struct sd_card_status sd_status[NUM_VOLUMES] = 156static struct sd_card_status sd_status[NUM_DRIVES] =
157{ 157{
158 { 0, 1 }, 158 { 0, 1 },
159#ifdef HAVE_MULTIVOLUME 159#ifdef HAVE_MULTIVOLUME
@@ -786,12 +786,12 @@ static void sd_select_device(int card_no)
786 786
787/* API Functions */ 787/* API Functions */
788 788
789static void ata_led(bool onoff) 789static void sd_led(bool onoff)
790{ 790{
791 led(onoff); 791 led(onoff);
792} 792}
793 793
794int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, 794int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
795 void* inbuf) 795 void* inbuf)
796{ 796{
797#ifndef HAVE_MULTIVOLUME 797#ifndef HAVE_MULTIVOLUME
@@ -805,14 +805,14 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
805 805
806 mutex_lock(&sd_mtx); 806 mutex_lock(&sd_mtx);
807 807
808 ata_led(true); 808 sd_led(true);
809 809
810ata_read_retry: 810sd_read_retry:
811 if (drive != 0 && !card_detect_target()) 811 if (drive != 0 && !card_detect_target())
812 { 812 {
813 /* no external sd-card inserted */ 813 /* no external sd-card inserted */
814 ret = -EC_NOCARD; 814 ret = -EC_NOCARD;
815 goto ata_read_error; 815 goto sd_read_error;
816 } 816 }
817 817
818 sd_select_device(drive); 818 sd_select_device(drive);
@@ -820,7 +820,7 @@ ata_read_retry:
820 if (currcard->initialized < 0) 820 if (currcard->initialized < 0)
821 { 821 {
822 ret = currcard->initialized; 822 ret = currcard->initialized;
823 goto ata_read_error; 823 goto sd_read_error;
824 } 824 }
825 825
826 last_disk_activity = current_tick; 826 last_disk_activity = current_tick;
@@ -834,7 +834,7 @@ ata_read_retry:
834 { 834 {
835 ret = sd_select_bank(bank); 835 ret = sd_select_bank(bank);
836 if (ret < 0) 836 if (ret < 0)
837 goto ata_read_error; 837 goto sd_read_error;
838 } 838 }
839 839
840 start -= bank * BLOCKS_PER_BANK; 840 start -= bank * BLOCKS_PER_BANK;
@@ -842,7 +842,7 @@ ata_read_retry:
842 842
843 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); 843 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY);
844 if (ret < 0) 844 if (ret < 0)
845 goto ata_read_error; 845 goto sd_read_error;
846 846
847 BLOCK_COUNT_REG = incount; 847 BLOCK_COUNT_REG = incount;
848 848
@@ -858,7 +858,7 @@ ata_read_retry:
858 ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); 858 ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25);
859 } 859 }
860 if (ret < 0) 860 if (ret < 0)
861 goto ata_read_error; 861 goto sd_read_error;
862 862
863 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ 863 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */
864 864
@@ -874,38 +874,38 @@ ata_read_retry:
874 } 874 }
875 875
876 ret = -EC_FIFO_READ_FULL; 876 ret = -EC_FIFO_READ_FULL;
877 goto ata_read_error; 877 goto sd_read_error;
878 } 878 }
879 879
880 last_disk_activity = current_tick; 880 last_disk_activity = current_tick;
881 881
882 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); 882 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
883 if (ret < 0) 883 if (ret < 0)
884 goto ata_read_error; 884 goto sd_read_error;
885 885
886 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT); 886 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT);
887 if (ret < 0) 887 if (ret < 0)
888 goto ata_read_error; 888 goto sd_read_error;
889 889
890 while (1) 890 while (1)
891 { 891 {
892 ata_led(false); 892 sd_led(false);
893 mutex_unlock(&sd_mtx); 893 mutex_unlock(&sd_mtx);
894 894
895 return ret; 895 return ret;
896 896
897ata_read_error: 897sd_read_error:
898 if (sd_status[drive].retry < sd_status[drive].retry_max 898 if (sd_status[drive].retry < sd_status[drive].retry_max
899 && ret != -EC_NOCARD) 899 && ret != -EC_NOCARD)
900 { 900 {
901 sd_status[drive].retry++; 901 sd_status[drive].retry++;
902 currcard->initialized = 0; 902 currcard->initialized = 0;
903 goto ata_read_retry; 903 goto sd_read_retry;
904 } 904 }
905 } 905 }
906} 906}
907 907
908int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, 908int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
909 const void* outbuf) 909 const void* outbuf)
910{ 910{
911/* Write support is not finished yet */ 911/* Write support is not finished yet */
@@ -920,14 +920,14 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
920 920
921 mutex_lock(&sd_mtx); 921 mutex_lock(&sd_mtx);
922 922
923 ata_led(true); 923 sd_led(true);
924 924
925ata_write_retry: 925sd_write_retry:
926 if (drive != 0 && !card_detect_target()) 926 if (drive != 0 && !card_detect_target())
927 { 927 {
928 /* no external sd-card inserted */ 928 /* no external sd-card inserted */
929 ret = -EC_NOCARD; 929 ret = -EC_NOCARD;
930 goto ata_write_error; 930 goto sd_write_error;
931 } 931 }
932 932
933 sd_select_device(drive); 933 sd_select_device(drive);
@@ -935,7 +935,7 @@ ata_write_retry:
935 if (currcard->initialized < 0) 935 if (currcard->initialized < 0)
936 { 936 {
937 ret = currcard->initialized; 937 ret = currcard->initialized;
938 goto ata_write_error; 938 goto sd_write_error;
939 } 939 }
940 940
941 /* Only switch banks with non-SDHC cards */ 941 /* Only switch banks with non-SDHC cards */
@@ -947,7 +947,7 @@ ata_write_retry:
947 { 947 {
948 ret = sd_select_bank(bank); 948 ret = sd_select_bank(bank);
949 if (ret < 0) 949 if (ret < 0)
950 goto ata_write_error; 950 goto sd_write_error;
951 } 951 }
952 952
953 start -= bank * BLOCKS_PER_BANK; 953 start -= bank * BLOCKS_PER_BANK;
@@ -957,7 +957,7 @@ ata_write_retry:
957 957
958 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY); 958 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY);
959 if (ret < 0) 959 if (ret < 0)
960 goto ata_write_error; 960 goto sd_write_error;
961 961
962 BLOCK_COUNT_REG = count; 962 BLOCK_COUNT_REG = count;
963 963
@@ -973,7 +973,7 @@ ata_write_retry:
973 ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); 973 ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d);
974 } 974 }
975 if (ret < 0) 975 if (ret < 0)
976 goto ata_write_error; 976 goto sd_write_error;
977 977
978 buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN; 978 buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN;
979 979
@@ -996,7 +996,7 @@ ata_write_retry:
996 } 996 }
997 997
998 ret = -EC_FIFO_WR_EMPTY; 998 ret = -EC_FIFO_WR_EMPTY;
999 goto ata_write_error; 999 goto sd_write_error;
1000 } 1000 }
1001 1001
1002 last_disk_activity = current_tick; 1002 last_disk_activity = current_tick;
@@ -1004,31 +1004,31 @@ ata_write_retry:
1004 if (!sd_poll_status(DATA_DONE, 0x80000)) 1004 if (!sd_poll_status(DATA_DONE, 0x80000))
1005 { 1005 {
1006 ret = -EC_FIFO_WR_DONE; 1006 ret = -EC_FIFO_WR_DONE;
1007 goto ata_write_error; 1007 goto sd_write_error;
1008 } 1008 }
1009 1009
1010 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); 1010 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
1011 if (ret < 0) 1011 if (ret < 0)
1012 goto ata_write_error; 1012 goto sd_write_error;
1013 1013
1014 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT); 1014 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT);
1015 if (ret < 0) 1015 if (ret < 0)
1016 goto ata_write_error; 1016 goto sd_write_error;
1017 1017
1018 while (1) 1018 while (1)
1019 { 1019 {
1020 ata_led(false); 1020 sd_led(false);
1021 mutex_unlock(&sd_mtx); 1021 mutex_unlock(&sd_mtx);
1022 1022
1023 return ret; 1023 return ret;
1024 1024
1025ata_write_error: 1025sd_write_error:
1026 if (sd_status[drive].retry < sd_status[drive].retry_max 1026 if (sd_status[drive].retry < sd_status[drive].retry_max
1027 && ret != -EC_NOCARD) 1027 && ret != -EC_NOCARD)
1028 { 1028 {
1029 sd_status[drive].retry++; 1029 sd_status[drive].retry++;
1030 currcard->initialized = 0; 1030 currcard->initialized = 0;
1031 goto ata_write_retry; 1031 goto sd_write_retry;
1032 } 1032 }
1033 } 1033 }
1034} 1034}
@@ -1088,7 +1088,7 @@ static void sd_thread(void)
1088 1088
1089 if (!idle_notified) 1089 if (!idle_notified)
1090 { 1090 {
1091 call_ata_idle_notifys(false); 1091 call_storage_idle_notifys(false);
1092 idle_notified = true; 1092 idle_notified = true;
1093 } 1093 }
1094 } 1094 }
@@ -1106,37 +1106,7 @@ static void sd_thread(void)
1106 } 1106 }
1107} 1107}
1108 1108
1109 1109void sd_enable(bool on)
1110void ata_spindown(int seconds)
1111{
1112 (void)seconds;
1113}
1114
1115bool ata_disk_is_active(void)
1116{
1117 return 0;
1118}
1119
1120void ata_sleep(void)
1121{
1122}
1123
1124void ata_spin(void)
1125{
1126}
1127
1128/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
1129int ata_hard_reset(void)
1130{
1131 return 0;
1132}
1133
1134int ata_soft_reset(void)
1135{
1136 return 0;
1137}
1138
1139void ata_enable(bool on)
1140{ 1110{
1141 if(on) 1111 if(on)
1142 { 1112 {
@@ -1170,7 +1140,7 @@ void card_enable_monitoring_target(bool on)
1170} 1140}
1171#endif 1141#endif
1172 1142
1173int ata_init(void) 1143int sd_init(void)
1174{ 1144{
1175 int ret = 0; 1145 int ret = 0;
1176 1146
@@ -1179,7 +1149,7 @@ int ata_init(void)
1179 1149
1180 mutex_lock(&sd_mtx); 1150 mutex_lock(&sd_mtx);
1181 1151
1182 ata_led(false); 1152 sd_led(false);
1183 1153
1184 if (!initialized) 1154 if (!initialized)
1185 { 1155 {
@@ -1324,3 +1294,46 @@ void microsd_int(void)
1324 1294
1325} 1295}
1326#endif /* HAVE_HOTSWAP */ 1296#endif /* HAVE_HOTSWAP */
1297
1298long sd_last_disk_activity(void)
1299{
1300 return last_disk_activity;
1301}
1302
1303void sd_get_info(IF_MV2(int drive,) struct storage_info *info)
1304{
1305#ifndef HAVE_MULTIVOLUME
1306 const int drive=0;
1307#endif
1308 info->sector_size=card_info[drive].block_size;
1309 info->num_sectors=card_info[drive].numblocks;
1310 info->vendor="Rockbox";
1311 if(drive==0)
1312 {
1313 info->product="Internal Storage";
1314 }
1315 else
1316 {
1317 info->product="SD Card Slot";
1318 }
1319 info->revision="0.00";
1320}
1321
1322#ifdef HAVE_HOTSWAP
1323bool sd_removable(IF_MV_NONVOID(int drive))
1324{
1325#ifndef HAVE_MULTIVOLUME
1326 const int drive=0;
1327#endif
1328 return (drive==1);
1329}
1330
1331bool sd_present(IF_MV_NONVOID(int drive))
1332{
1333#ifndef HAVE_MULTIVOLUME
1334 const int drive=0;
1335#endif
1336 return (card_info[drive].initialized && card_info[drive].numblocks > 0);
1337}
1338#endif
1339