summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c493
-rw-r--r--firmware/drivers/ramdisk.c5
-rw-r--r--firmware/export/ata.h4
-rw-r--r--firmware/export/ata_mmc.h2
-rw-r--r--firmware/export/sd.h2
-rw-r--r--firmware/export/storage.h78
-rw-r--r--firmware/storage.c383
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c276
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c188
-rw-r--r--firmware/target/arm/ata-nand-telechips.c6
-rw-r--r--firmware/target/arm/imx233/ata-target.h4
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c190
-rw-r--r--firmware/target/arm/imx31/ata-target.h4
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c274
-rw-r--r--firmware/target/arm/pp/ata-target.h4
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c187
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h4
-rw-r--r--firmware/target/arm/s3c2440/sd-s3c2440.c100
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c1
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c76
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c69
-rw-r--r--firmware/target/arm/tcc780x/sd-tcc780x.c129
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c139
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c96
-rw-r--r--firmware/target/sh/archos/ondio/ata_mmc.c139
25 files changed, 1279 insertions, 1574 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index b574117620..373078d8f9 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -20,18 +20,13 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdbool.h> 21#include <stdbool.h>
22#include <inttypes.h> 22#include <inttypes.h>
23#include "ata.h"
24#include "kernel.h"
25#include "thread.h"
26#include "led.h" 23#include "led.h"
27#include "cpu.h" 24#include "cpu.h"
28#include "system.h" 25#include "system.h"
29#include "debug.h" 26#include "debug.h"
30#include "panic.h" 27#include "panic.h"
31#include "usb.h"
32#include "power.h" 28#include "power.h"
33#include "string.h" 29#include "string.h"
34#include "ata_idle_notify.h"
35#include "ata-driver.h" 30#include "ata-driver.h"
36#include "ata-defines.h" 31#include "ata-defines.h"
37#include "fs_defines.h" 32#include "fs_defines.h"
@@ -64,24 +59,28 @@
64#define CMD_WRITE_DMA_EXT 0x35 59#define CMD_WRITE_DMA_EXT 0x35
65#endif 60#endif
66 61
67/* Should all be < 0x100 (which are reserved for control messages) */
68#define Q_SLEEP 0
69#define Q_CLOSE 1
70
71#define READWRITE_TIMEOUT 5*HZ 62#define READWRITE_TIMEOUT 5*HZ
72 63
73#ifdef HAVE_ATA_POWER_OFF 64#ifdef HAVE_ATA_POWER_OFF
74#define ATA_POWER_OFF_TIMEOUT 2*HZ 65#define ATA_POWER_OFF_TIMEOUT 2*HZ
75#endif 66#endif
76 67
77#ifdef ATA_DRIVER_CLOSE
78static unsigned int ata_thread_id = 0;
79#endif
80
81#if defined(HAVE_USBSTACK) 68#if defined(HAVE_USBSTACK)
82#define ALLOW_USB_SPINDOWN 69#define ATA_ACTIVE_IN_USB 1
70#else
71#define ATA_ACTIVE_IN_USB 0
83#endif 72#endif
84 73
74enum {
75 ATA_BOOT = -1,
76 ATA_OFF,
77 ATA_SLEEPING,
78 ATA_SPINUP,
79 ATA_ON,
80};
81
82static int ata_state = ATA_BOOT;
83
85static struct mutex ata_mtx SHAREDBSS_ATTR; 84static struct mutex ata_mtx SHAREDBSS_ATTR;
86static int ata_device; /* device 0 (master) or 1 (slave) */ 85static int ata_device; /* device 0 (master) or 1 (slave) */
87 86
@@ -90,22 +89,16 @@ static int spinup_time = 0;
90static bool ata_led_enabled = true; 89static bool ata_led_enabled = true;
91static bool ata_led_on = false; 90static bool ata_led_on = false;
92#endif 91#endif
93static bool spinup = false; 92
94static bool sleeping = true;
95#ifdef HAVE_ATA_POWER_OFF
96static bool poweroff = false;
97#endif
98static long sleep_timeout = 5*HZ; 93static long sleep_timeout = 5*HZ;
99#ifdef HAVE_LBA48 94#ifdef HAVE_LBA48
100static bool lba48 = false; /* set for 48 bit addressing */ 95static bool lba48 = false; /* set for 48 bit addressing */
101#endif 96#endif
102static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)];
103static const char ata_thread_name[] = "ata";
104static struct event_queue ata_queue SHAREDBSS_ATTR;
105static bool initialized = false;
106 97
107static long last_user_activity = -1;
108static long last_disk_activity = -1; 98static long last_disk_activity = -1;
99#ifdef HAVE_ATA_POWER_OFF
100static long power_off_tick;
101#endif
109 102
110static unsigned long total_sectors; 103static unsigned long total_sectors;
111static int multisectors; /* number of supported multisectors */ 104static int multisectors; /* number of supported multisectors */
@@ -135,6 +128,38 @@ static int perform_soft_reset(void);
135static int set_multiple_mode(int sectors); 128static int set_multiple_mode(int sectors);
136static int set_features(void); 129static int set_features(void);
137 130
131static inline void keep_ata_active(void)
132{
133 last_disk_activity = current_tick;
134}
135
136static inline void schedule_ata_sleep(long from_now)
137{
138 last_disk_activity = current_tick - sleep_timeout + from_now;
139}
140
141static inline bool ata_sleep_timed_out(void)
142{
143 return sleep_timeout &&
144 TIME_AFTER(current_tick, last_disk_activity + sleep_timeout);
145}
146
147static inline void schedule_ata_power_off(void)
148{
149#ifdef HAVE_ATA_POWER_OFF
150 power_off_tick = current_tick + ATA_POWER_OFF_TIMEOUT;
151#endif
152}
153
154static inline bool ata_power_off_timed_out(void)
155{
156#ifdef HAVE_ATA_POWER_OFF
157 return TIME_AFTER(current_tick, power_off_tick);
158#else
159 return false;
160#endif
161}
162
138#ifndef ATA_TARGET_POLLING 163#ifndef ATA_TARGET_POLLING
139static ICODE_ATTR int wait_for_bsy(void) 164static ICODE_ATTR int wait_for_bsy(void)
140{ 165{
@@ -144,7 +169,7 @@ static ICODE_ATTR int wait_for_bsy(void)
144 { 169 {
145 if (!(ATA_IN8(ATA_STATUS) & STATUS_BSY)) 170 if (!(ATA_IN8(ATA_STATUS) & STATUS_BSY))
146 return 1; 171 return 1;
147 last_disk_activity = current_tick; 172 keep_ata_active();
148 yield(); 173 yield();
149 } while (TIME_BEFORE(current_tick, timeout)); 174 } while (TIME_BEFORE(current_tick, timeout));
150 175
@@ -164,7 +189,7 @@ static ICODE_ATTR int wait_for_rdy(void)
164 { 189 {
165 if (ATA_IN8(ATA_ALT_STATUS) & STATUS_RDY) 190 if (ATA_IN8(ATA_ALT_STATUS) & STATUS_RDY)
166 return 1; 191 return 1;
167 last_disk_activity = current_tick; 192 keep_ata_active();
168 yield(); 193 yield();
169 } while (TIME_BEFORE(current_tick, timeout)); 194 } while (TIME_BEFORE(current_tick, timeout));
170 195
@@ -175,6 +200,44 @@ static ICODE_ATTR int wait_for_rdy(void)
175#define wait_for_rdy ata_wait_for_rdy 200#define wait_for_rdy ata_wait_for_rdy
176#endif 201#endif
177 202
203static int ata_perform_wakeup(int state)
204{
205 if (state > ATA_OFF) {
206 if (perform_soft_reset()) {
207 return -1;
208 }
209 }
210#ifdef HAVE_ATA_POWER_OFF
211 else {
212 if (ata_power_on()) {
213 return -2;
214 }
215 }
216#endif
217
218 return 0;
219}
220
221static int ata_perform_sleep(void)
222{
223 ATA_OUT8(ATA_SELECT, ata_device);
224
225 if(!wait_for_rdy()) {
226 DEBUGF("ata_perform_sleep() - not RDY\n");
227 return -1;
228 }
229
230 ATA_OUT8(ATA_COMMAND, CMD_SLEEP);
231
232 if (!wait_for_rdy())
233 {
234 DEBUGF("ata_perform_sleep() - CMD failed\n");
235 return -2;
236 }
237
238 return 0;
239}
240
178static ICODE_ATTR int wait_for_start_of_transfer(void) 241static ICODE_ATTR int wait_for_start_of_transfer(void)
179{ 242{
180 if (!wait_for_bsy()) 243 if (!wait_for_bsy())
@@ -278,42 +341,27 @@ static int ata_transfer_sectors(unsigned long start,
278 long timeout; 341 long timeout;
279 int count; 342 int count;
280 void* buf; 343 void* buf;
281 long spinup_start; 344 long spinup_start = spinup_start;
282#ifdef HAVE_ATA_DMA 345#ifdef HAVE_ATA_DMA
283 bool usedma = false; 346 bool usedma = false;
284#endif 347#endif
285 348
286#ifndef MAX_PHYS_SECTOR_SIZE
287 mutex_lock(&ata_mtx);
288#endif
289
290 if (start + incount > total_sectors) { 349 if (start + incount > total_sectors) {
291 ret = -1; 350 ret = -1;
292 goto error; 351 goto error;
293 } 352 }
294 353
295 last_disk_activity = current_tick; 354 keep_ata_active();
296 spinup_start = current_tick;
297 355
298 ata_led(true); 356 ata_led(true);
299 357
300 if ( sleeping ) { 358 if (ata_state < ATA_ON) {
301 sleeping = false; /* set this now since it'll be on */ 359 spinup_start = current_tick;
302 spinup = true; 360 int state = ata_state;
303#ifdef HAVE_ATA_POWER_OFF 361 ata_state = ATA_SPINUP;
304 if (poweroff) { 362 if (ata_perform_wakeup(state)) {
305 if (ata_power_on()) { 363 ret = -2;
306 ret = -2; 364 goto error;
307 goto error;
308 }
309 }
310 else
311#endif
312 {
313 if (perform_soft_reset()) {
314 ret = -2;
315 goto error;
316 }
317 } 365 }
318 } 366 }
319 367
@@ -331,7 +379,7 @@ static int ata_transfer_sectors(unsigned long start,
331 count = incount; 379 count = incount;
332 while (TIME_BEFORE(current_tick, timeout)) { 380 while (TIME_BEFORE(current_tick, timeout)) {
333 ret = 0; 381 ret = 0;
334 last_disk_activity = current_tick; 382 keep_ata_active();
335 383
336#ifdef HAVE_ATA_DMA 384#ifdef HAVE_ATA_DMA
337 /* If DMA is supported and parameters are ok for DMA, use it */ 385 /* If DMA is supported and parameters are ok for DMA, use it */
@@ -395,12 +443,9 @@ static int ata_transfer_sectors(unsigned long start,
395 goto retry; 443 goto retry;
396 } 444 }
397 445
398 if (spinup) { 446 if (ata_state == ATA_SPINUP) {
447 ata_state = ATA_ON;
399 spinup_time = current_tick - spinup_start; 448 spinup_time = current_tick - spinup_start;
400 spinup = false;
401#ifdef HAVE_ATA_POWER_OFF
402 poweroff = false;
403#endif
404 } 449 }
405 } 450 }
406 else 451 else
@@ -426,12 +471,9 @@ static int ata_transfer_sectors(unsigned long start,
426 goto retry; 471 goto retry;
427 } 472 }
428 473
429 if (spinup) { 474 if (ata_state == ATA_SPINUP) {
475 ata_state = ATA_ON;
430 spinup_time = current_tick - spinup_start; 476 spinup_time = current_tick - spinup_start;
431 spinup = false;
432#ifdef HAVE_ATA_POWER_OFF
433 poweroff = false;
434#endif
435 } 477 }
436 478
437 /* read the status register exactly once per loop */ 479 /* read the status register exactly once per loop */
@@ -470,7 +512,7 @@ static int ata_transfer_sectors(unsigned long start,
470 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */ 512 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */
471 count -= sectors; 513 count -= sectors;
472 514
473 last_disk_activity = current_tick; 515 keep_ata_active();
474 } 516 }
475 } 517 }
476 518
@@ -490,9 +532,11 @@ static int ata_transfer_sectors(unsigned long start,
490 532
491 error: 533 error:
492 ata_led(false); 534 ata_led(false);
493#ifndef MAX_PHYS_SECTOR_SIZE 535
494 mutex_unlock(&ata_mtx); 536 if (ret < 0 && ata_state == ATA_SPINUP) {
495#endif 537 /* bailed out before updating */
538 ata_state = ATA_ON;
539 }
496 540
497 return ret; 541 return ret;
498} 542}
@@ -507,11 +551,12 @@ int ata_read_sectors(IF_MD(int drive,)
507 (void)drive; /* unused for now */ 551 (void)drive; /* unused for now */
508#endif 552#endif
509 553
510 return ata_transfer_sectors(start, incount, inbuf, false); 554 mutex_lock(&ata_mtx);
555 int rc = ata_transfer_sectors(start, incount, inbuf, false);
556 mutex_unlock(&ata_mtx);
557 return rc;
511} 558}
512#endif
513 559
514#ifndef MAX_PHYS_SECTOR_SIZE
515int ata_write_sectors(IF_MD(int drive,) 560int ata_write_sectors(IF_MD(int drive,)
516 unsigned long start, 561 unsigned long start,
517 int count, 562 int count,
@@ -521,9 +566,12 @@ int ata_write_sectors(IF_MD(int drive,)
521 (void)drive; /* unused for now */ 566 (void)drive; /* unused for now */
522#endif 567#endif
523 568
524 return ata_transfer_sectors(start, count, (void*)buf, true); 569 mutex_lock(&ata_mtx);
570 int rc = ata_transfer_sectors(start, count, (void*)buf, true);
571 mutex_unlock(&ata_mtx);
572 return rc;
525} 573}
526#endif 574#endif /* ndef MAX_PHYS_SECTOR_SIZE */
527 575
528#ifdef MAX_PHYS_SECTOR_SIZE 576#ifdef MAX_PHYS_SECTOR_SIZE
529static int cache_sector(unsigned long sector) 577static int cache_sector(unsigned long sector)
@@ -748,178 +796,26 @@ void ata_spindown(int seconds)
748 796
749bool ata_disk_is_active(void) 797bool ata_disk_is_active(void)
750{ 798{
751 return !sleeping; 799 return ata_state >= ATA_SPINUP;
752}
753
754static int ata_perform_sleep(void)
755{
756 /* guard against calls made with checks of these variables outside
757 the mutex that may not be on the ata thread; status may have changed. */
758 if (spinup || sleeping) {
759 return 0;
760 }
761
762 ATA_OUT8(ATA_SELECT, ata_device);
763
764 if(!wait_for_rdy()) {
765 DEBUGF("ata_perform_sleep() - not RDY\n");
766 return -1;
767 }
768
769 ATA_OUT8(ATA_COMMAND, CMD_SLEEP);
770
771 if (!wait_for_rdy())
772 {
773 DEBUGF("ata_perform_sleep() - CMD failed\n");
774 return -2;
775 }
776
777 sleeping = true;
778 return 0;
779}
780
781void ata_sleep(void)
782{
783 queue_post(&ata_queue, Q_SLEEP, 0);
784} 800}
785 801
786void ata_sleepnow(void) 802void ata_sleepnow(void)
787{ 803{
788 if (!spinup && !sleeping && initialized) 804 if (ata_state >= ATA_SPINUP) {
789 {
790 call_storage_idle_notifys(false);
791 mutex_lock(&ata_mtx); 805 mutex_lock(&ata_mtx);
792 ata_perform_sleep(); 806 if (ata_state == ATA_ON) {
807 if (!ata_perform_sleep()) {
808 ata_state = ATA_SLEEPING;
809 schedule_ata_power_off();
810 }
811 }
793 mutex_unlock(&ata_mtx); 812 mutex_unlock(&ata_mtx);
794 } 813 }
795} 814}
796 815
797void ata_spin(void) 816void ata_spin(void)
798{ 817{
799 last_user_activity = current_tick; 818 keep_ata_active();
800}
801
802static void ata_thread(void)
803{
804#ifdef HAVE_ATA_POWER_OFF
805 static long last_sleep = 0;
806#endif
807 struct queue_event ev;
808#ifdef ALLOW_USB_SPINDOWN
809 static bool usb_mode = false;
810#endif
811
812 while (1) {
813 queue_wait_w_tmo(&ata_queue, &ev, HZ/2);
814
815 switch ( ev.id ) {
816 case SYS_TIMEOUT:
817 if (!spinup && !sleeping)
818 {
819 if (TIME_AFTER( current_tick,
820 last_disk_activity + (HZ*2) ) )
821 {
822#ifdef ALLOW_USB_SPINDOWN
823 if(!usb_mode)
824#endif
825 {
826 call_storage_idle_notifys(false);
827 }
828 }
829
830 if ( sleep_timeout &&
831 TIME_AFTER( current_tick,
832 last_user_activity + sleep_timeout ) &&
833 TIME_AFTER( current_tick,
834 last_disk_activity + sleep_timeout ) )
835 {
836#ifdef ALLOW_USB_SPINDOWN
837 if(!usb_mode)
838#endif
839 {
840 call_storage_idle_notifys(true);
841 }
842 mutex_lock(&ata_mtx);
843 ata_perform_sleep();
844#ifdef HAVE_ATA_POWER_OFF
845 last_sleep = current_tick;
846#endif
847 mutex_unlock(&ata_mtx);
848 }
849 }
850
851#ifdef HAVE_ATA_POWER_OFF
852 if ( !spinup && sleeping && !poweroff &&
853 TIME_AFTER( current_tick, last_sleep + ATA_POWER_OFF_TIMEOUT ))
854 {
855 mutex_lock(&ata_mtx);
856 ide_power_enable(false);
857 poweroff = true;
858 mutex_unlock(&ata_mtx);
859 }
860#endif
861 break;
862
863#ifndef USB_NONE
864 case SYS_USB_CONNECTED:
865 /* Tell the USB thread that we are safe */
866 DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
867#ifdef ALLOW_USB_SPINDOWN
868 usb_mode = true;
869 usb_acknowledge(SYS_USB_CONNECTED_ACK);
870 /* There is no need to force ATA power on */
871#else
872 mutex_lock(&ata_mtx);
873 if (sleeping) {
874 ata_led(true);
875 sleeping = false; /* set this now since it'll be on */
876
877#ifdef HAVE_ATA_POWER_OFF
878 if (poweroff) {
879 ata_power_on();
880 poweroff = false;
881 }
882 else
883#endif
884 {
885 perform_soft_reset();
886 }
887
888 ata_led(false);
889 }
890 mutex_unlock(&ata_mtx);
891
892 /* Wait until the USB cable is extracted again */
893 usb_acknowledge(SYS_USB_CONNECTED_ACK);
894 usb_wait_for_disconnect(&ata_queue);
895#endif
896 break;
897
898#ifdef ALLOW_USB_SPINDOWN
899 case SYS_USB_DISCONNECTED:
900 /* Tell the USB thread that we are ready again */
901 DEBUGF("ata_thread got SYS_USB_DISCONNECTED\n");
902 usb_mode = false;
903 break;
904#endif
905#endif /* USB_NONE */
906
907 case Q_SLEEP:
908#ifdef ALLOW_USB_SPINDOWN
909 if(!usb_mode)
910#endif
911 {
912 call_storage_idle_notifys(false);
913 }
914 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
915 break;
916
917#ifdef ATA_DRIVER_CLOSE
918 case Q_CLOSE:
919 return;
920#endif
921 }
922 }
923} 819}
924 820
925/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ 821/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
@@ -1025,11 +921,13 @@ static int perform_soft_reset(void)
1025 921
1026int ata_soft_reset(void) 922int ata_soft_reset(void)
1027{ 923{
1028 int ret; 924 int ret = -6;
1029 925
1030 mutex_lock(&ata_mtx); 926 mutex_lock(&ata_mtx);
1031 927
1032 ret = perform_soft_reset(); 928 if (ata_state > ATA_OFF) {
929 ret = perform_soft_reset();
930 }
1033 931
1034 mutex_unlock(&ata_mtx); 932 mutex_unlock(&ata_mtx);
1035 return ret; 933 return ret;
@@ -1068,7 +966,7 @@ static int ata_power_on(void)
1068 966
1069 return 0; 967 return 0;
1070} 968}
1071#endif 969#endif /* HAVE_ATA_POWER_OFF */
1072 970
1073static int STORAGE_INIT_ATTR master_slave_detect(void) 971static int STORAGE_INIT_ATTR master_slave_detect(void)
1074{ 972{
@@ -1250,9 +1148,8 @@ int STORAGE_INIT_ATTR ata_init(void)
1250 int rc = 0; 1148 int rc = 0;
1251 bool coldstart; 1149 bool coldstart;
1252 1150
1253 if ( !initialized ) { 1151 if (ata_state == ATA_BOOT) {
1254 mutex_init(&ata_mtx); 1152 mutex_init(&ata_mtx);
1255 queue_init(&ata_queue, true);
1256 } 1153 }
1257 1154
1258 mutex_lock(&ata_mtx); 1155 mutex_lock(&ata_mtx);
@@ -1261,16 +1158,13 @@ int STORAGE_INIT_ATTR ata_init(void)
1261 coldstart = ata_is_coldstart(); 1158 coldstart = ata_is_coldstart();
1262 ata_led(false); 1159 ata_led(false);
1263 ata_device_init(); 1160 ata_device_init();
1264 sleeping = false;
1265 ata_enable(true); 1161 ata_enable(true);
1266#ifdef MAX_PHYS_SECTOR_SIZE 1162#ifdef MAX_PHYS_SECTOR_SIZE
1267 memset(&sector_cache, 0, sizeof(sector_cache)); 1163 memset(&sector_cache, 0, sizeof(sector_cache));
1268#endif 1164#endif
1269 1165
1270 if ( !initialized ) { 1166 if (ata_state == ATA_BOOT) {
1271 /* First call won't have multiple thread contention - this 1167 ata_state = ATA_OFF;
1272 * may return at any point without having to unlock */
1273 mutex_unlock(&ata_mtx);
1274 1168
1275 if (!ide_powered()) /* somebody has switched it off */ 1169 if (!ide_powered()) /* somebody has switched it off */
1276 { 1170 {
@@ -1290,14 +1184,17 @@ int STORAGE_INIT_ATTR ata_init(void)
1290 { /* failed? -> second try, always with hard reset */ 1184 { /* failed? -> second try, always with hard reset */
1291 DEBUGF("ata: init failed, retrying...\n"); 1185 DEBUGF("ata: init failed, retrying...\n");
1292 rc = init_and_check(true); 1186 rc = init_and_check(true);
1293 if (rc) 1187 if (rc) {
1294 return rc; 1188 goto error;
1189 }
1295 } 1190 }
1296 1191
1297 rc = identify(); 1192 rc = identify();
1298 1193
1299 if (rc) 1194 if (rc) {
1300 return -40 + rc; 1195 rc = -40 + rc;
1196 goto error;
1197 }
1301 1198
1302 multisectors = identify_info[47] & 0xff; 1199 multisectors = identify_info[47] & 0xff;
1303 if (multisectors == 0) /* Invalid multisector info, try with 16 */ 1200 if (multisectors == 0) /* Invalid multisector info, try with 16 */
@@ -1317,15 +1214,20 @@ int STORAGE_INIT_ATTR ata_init(void)
1317 total_sectors = identify_info[100] | (identify_info[101] << 16); 1214 total_sectors = identify_info[100] | (identify_info[101] << 16);
1318 lba48 = true; /* use BigLBA */ 1215 lba48 = true; /* use BigLBA */
1319 } 1216 }
1320#endif 1217#endif /* HAVE_LBA48 */
1218
1321 rc = freeze_lock(); 1219 rc = freeze_lock();
1322 1220
1323 if (rc) 1221 if (rc) {
1324 return -50 + rc; 1222 rc = -50 + rc;
1223 goto error;
1224 }
1325 1225
1326 rc = set_features(); 1226 rc = set_features();
1327 if (rc) 1227 if (rc) {
1328 return -60 + rc; 1228 rc = -60 + rc;
1229 goto error;
1230 }
1329 1231
1330#ifdef MAX_PHYS_SECTOR_SIZE 1232#ifdef MAX_PHYS_SECTOR_SIZE
1331 /* Find out the physical sector size */ 1233 /* Find out the physical sector size */
@@ -1351,44 +1253,20 @@ int STORAGE_INIT_ATTR ata_init(void)
1351 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE)) 1253 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
1352 panicf("Unsupported physical sector size: %d", 1254 panicf("Unsupported physical sector size: %d",
1353 phys_sector_mult * SECTOR_SIZE); 1255 phys_sector_mult * SECTOR_SIZE);
1354#endif 1256#endif /* MAX_PHYS_SECTOR_SIZE */
1355
1356 mutex_lock(&ata_mtx); /* Balance unlock below */
1357
1358 last_disk_activity = current_tick;
1359#ifdef ATA_DRIVER_CLOSE
1360 ata_thread_id =
1361#endif
1362 create_thread(ata_thread, ata_stack,
1363 sizeof(ata_stack), 0, ata_thread_name
1364 IF_PRIO(, PRIORITY_USER_INTERFACE)
1365 IF_COP(, CPU));
1366 initialized = true;
1367 1257
1258 ata_state = ATA_ON;
1259 keep_ata_active();
1368 } 1260 }
1369 rc = set_multiple_mode(multisectors); 1261 rc = set_multiple_mode(multisectors);
1370 if (rc) 1262 if (rc)
1371 rc = -70 + rc; 1263 rc = -70 + rc;
1372 1264
1265error:
1373 mutex_unlock(&ata_mtx); 1266 mutex_unlock(&ata_mtx);
1374 return rc; 1267 return rc;
1375} 1268}
1376 1269
1377#ifdef ATA_DRIVER_CLOSE
1378void ata_close(void)
1379{
1380 unsigned int thread_id = ata_thread_id;
1381
1382 if (thread_id == 0)
1383 return;
1384
1385 ata_thread_id = 0;
1386
1387 queue_post(&ata_queue, Q_CLOSE, 0);
1388 thread_wait(thread_id);
1389}
1390#endif /* ATA_DRIVER_CLOSE */
1391
1392#if (CONFIG_LED == LED_REAL) 1270#if (CONFIG_LED == LED_REAL)
1393void ata_set_led_enabled(bool enabled) 1271void ata_set_led_enabled(bool enabled)
1394{ 1272{
@@ -1453,9 +1331,7 @@ int ata_get_dma_mode(void)
1453 1331
1454/* Needed to allow updating while waiting for DMA to complete */ 1332/* Needed to allow updating while waiting for DMA to complete */
1455void ata_keep_active(void) 1333void ata_keep_active(void)
1456{ 1334 __attribute__((alias("ata_spin")));
1457 last_disk_activity = current_tick;
1458}
1459#endif 1335#endif
1460 1336
1461#ifdef CONFIG_STORAGE_MULTI 1337#ifdef CONFIG_STORAGE_MULTI
@@ -1467,3 +1343,58 @@ int ata_num_drives(int first_drive)
1467 return 1; 1343 return 1;
1468} 1344}
1469#endif 1345#endif
1346
1347int ata_event(long id, intptr_t data)
1348{
1349 int rc = 0;
1350
1351 /* GCC does a lousy job culling unreachable cases in the default handler
1352 if statements are in a switch statement, so we'll do it this way. Only
1353 the first case is frequently hit anyway. */
1354 if (LIKELY(id == Q_STORAGE_TICK)) {
1355 /* won't see ATA_BOOT in here */
1356 int state = ata_state;
1357 if (state != ATA_ON || !ata_sleep_timed_out()) {
1358 if (state == ATA_SLEEPING && ata_power_off_timed_out()) {
1359 mutex_lock(&ata_mtx);
1360 if (ata_state == ATA_SLEEPING) {
1361 ide_power_enable(false);
1362 ata_state = ATA_OFF;
1363 }
1364 mutex_unlock(&ata_mtx);
1365 }
1366 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1367 }
1368 }
1369 else if (id == Q_STORAGE_SLEEPNOW) {
1370 ata_sleepnow();
1371 }
1372 else if (id == Q_STORAGE_SLEEP) {
1373 schedule_ata_sleep(HZ/5);
1374 }
1375#ifndef USB_NONE
1376 else if (id == SYS_USB_CONNECTED) {
1377 if (ATA_ACTIVE_IN_USB) {
1378 /* There is no need to force ATA power on */
1379 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1380 }
1381 else {
1382 mutex_lock(&ata_mtx);
1383 if (ata_state < ATA_ON) {
1384 ata_led(true);
1385 if (!(rc = ata_perform_wakeup(ata_state))) {
1386 ata_state = ATA_ON;
1387 }
1388 ata_led(false);
1389 }
1390 mutex_unlock(&ata_mtx);
1391 }
1392 }
1393#endif /* ndef USB_NONE */
1394 else {
1395 rc = storage_event_default_handler(id, data, last_disk_activity,
1396 STORAGE_ATA);
1397 }
1398
1399 return rc;
1400}
diff --git a/firmware/drivers/ramdisk.c b/firmware/drivers/ramdisk.c
index 44235c4575..9f73b6b5c3 100644
--- a/firmware/drivers/ramdisk.c
+++ b/firmware/drivers/ramdisk.c
@@ -159,3 +159,8 @@ bool ramdisk_present(IF_MD(int drive))
159} 159}
160#endif 160#endif
161 161
162int ramdisk_event(long id, intptr_t data)
163{
164 return storage_event_default_handler(id, data, last_disk_activity,
165 STORAGE_RAMDISK);
166}
diff --git a/firmware/export/ata.h b/firmware/export/ata.h
index a1b7ab6372..e6ca9422ea 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -175,4 +175,8 @@ int ata_get_dma_mode(void);
175int ata_read_smart(struct ata_smart_values*); 175int ata_read_smart(struct ata_smart_values*);
176#endif 176#endif
177 177
178#ifdef BOOTLOADER
179#define STORAGE_CLOSE
180#endif
181
178#endif /* __ATA_H__ */ 182#endif /* __ATA_H__ */
diff --git a/firmware/export/ata_mmc.h b/firmware/export/ata_mmc.h
index 2f8011cf8f..cde1fc7ad1 100644
--- a/firmware/export/ata_mmc.h
+++ b/firmware/export/ata_mmc.h
@@ -21,6 +21,8 @@
21#ifndef __ATA_MMC_H__ 21#ifndef __ATA_MMC_H__
22#define __ATA_MMC_H__ 22#define __ATA_MMC_H__
23 23
24#include <stdbool.h>
25
24void mmc_enable_int_flash_clock(bool on); 26void mmc_enable_int_flash_clock(bool on);
25bool mmc_detect(void); 27bool mmc_detect(void);
26bool mmc_touched(void); 28bool mmc_touched(void);
diff --git a/firmware/export/sd.h b/firmware/export/sd.h
index 9ae3313ffd..c657f8a545 100644
--- a/firmware/export/sd.h
+++ b/firmware/export/sd.h
@@ -27,7 +27,7 @@
27#include "mv.h" /* for HAVE_MULTIDRIVE or not */ 27#include "mv.h" /* for HAVE_MULTIDRIVE or not */
28 28
29#ifdef HAVE_BOOTLOADER_USB_MODE 29#ifdef HAVE_BOOTLOADER_USB_MODE
30#define SD_DRIVER_CLOSE 30#define STORAGE_CLOSE
31#endif 31#endif
32 32
33#define SD_BLOCK_SIZE 512 /* XXX : support other sizes ? */ 33#define SD_BLOCK_SIZE 512 /* XXX : support other sizes ? */
diff --git a/firmware/export/storage.h b/firmware/export/storage.h
index 14cba09b35..8a4c95c05b 100644
--- a/firmware/export/storage.h
+++ b/firmware/export/storage.h
@@ -25,6 +25,7 @@
25#include <stdbool.h> 25#include <stdbool.h>
26#include "config.h" /* for HAVE_MULTIDRIVE or not */ 26#include "config.h" /* for HAVE_MULTIDRIVE or not */
27#include "mv.h" 27#include "mv.h"
28#include <kernel.h>
28 29
29#if (CONFIG_STORAGE & STORAGE_HOSTFS) || defined(SIMULATOR) 30#if (CONFIG_STORAGE & STORAGE_HOSTFS) || defined(SIMULATOR)
30#define HAVE_HOSTFS 31#define HAVE_HOSTFS
@@ -46,6 +47,57 @@
46#include "ramdisk.h" 47#include "ramdisk.h"
47#endif 48#endif
48 49
50enum
51{
52 Q_STORAGE_TICK = 1,
53 Q_STORAGE_SLEEP,
54 Q_STORAGE_SLEEPNOW,
55#ifdef STORAGE_CLOSE
56 Q_STORAGE_CLOSE,
57#endif
58};
59
60#define STG_EVENT_ASSERT_ACTIVE(type) \
61 ({ intptr_t __data = (data); \
62 *((unsigned int *)(__data)) |= (type); })
63
64static FORCE_INLINE int storage_event_default_handler(long id,
65 intptr_t data,
66 long last_activity,
67 unsigned int type)
68{
69 /* fake sleep in order to trigger storage idle sequence */
70 static long slept_at = -1;
71
72 if (id == Q_STORAGE_TICK) {
73 if (last_activity == slept_at ||
74 TIME_BEFORE(current_tick, last_activity + 3*HZ)) {
75 STG_EVENT_ASSERT_ACTIVE(type);
76 }
77 }
78 else if (id == Q_STORAGE_SLEEPNOW) {
79 slept_at = last_activity;
80 }
81
82 return 0;
83}
84
85#if (CONFIG_STORAGE & STORAGE_SD)
86int sd_event(long id, intptr_t data);
87#endif
88#if (CONFIG_STORAGE & STORAGE_MMC)
89int mmc_event(long id, intptr_t data);
90#endif
91#if (CONFIG_STORAGE & STORAGE_ATA)
92int ata_event(long id, intptr_t data);
93#endif
94#if (CONFIG_STORAGE & STORAGE_NAND)
95int nand_event(long id, intptr_t data);
96#endif
97#if (CONFIG_STORAGE & STORAGE_RAMDISK)
98int ramdisk_event(long id, intptr_t data);
99#endif
100
49struct storage_info 101struct storage_info
50{ 102{
51 unsigned int sector_size; 103 unsigned int sector_size;
@@ -55,13 +107,24 @@ struct storage_info
55 char *revision; 107 char *revision;
56}; 108};
57 109
110int storage_init(void) STORAGE_INIT_ATTR;
111void storage_close(void);
112
58#ifdef HAVE_HOSTFS 113#ifdef HAVE_HOSTFS
59#include "hostfs.h" 114#include "hostfs.h"
60/* stubs for the plugin api */ 115/* stubs for the plugin api */
61static inline void stub_storage_sleep(void) {} 116static inline void stub_storage_sleep(void) {}
62static inline void stub_storage_spin(void) {} 117static inline void stub_storage_spin(void) {}
63static inline void stub_storage_spindown(int timeout) { (void)timeout; } 118static inline void stub_storage_spindown(int timeout) { (void)timeout; }
119static inline int stub_storage_event(long id, intptr_t data)
120 { return 0; (void)id; (void)data; }
121#else /* ndef HAVE_HOSTFS */
122#if (CONFIG_STORAGE & STORAGE_ATA)
123void storage_sleep(void);
124#else
125static inline void storage_sleep(void) {}
64#endif 126#endif
127#endif /* HAVE_HOSTFS */
65 128
66#if !defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOSTFS) 129#if !defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOSTFS)
67/* storage_spindown, storage_sleep and storage_spin are passed as 130/* storage_spindown, storage_sleep and storage_spin are passed as
@@ -70,6 +133,7 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
70 #define storage_num_drives() NUM_DRIVES 133 #define storage_num_drives() NUM_DRIVES
71 #if defined(HAVE_HOSTFS) 134 #if defined(HAVE_HOSTFS)
72 #define STORAGE_FUNCTION(NAME) (stub_## NAME) 135 #define STORAGE_FUNCTION(NAME) (stub_## NAME)
136 #define storage_event stub_storage_event
73 #define storage_spindown stub_storage_spindown 137 #define storage_spindown stub_storage_spindown
74 #define storage_sleep stub_storage_sleep 138 #define storage_sleep stub_storage_sleep
75 #define storage_spin stub_storage_spin 139 #define storage_spin stub_storage_spin
@@ -97,15 +161,12 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
97 #elif (CONFIG_STORAGE & STORAGE_ATA) 161 #elif (CONFIG_STORAGE & STORAGE_ATA)
98 #define STORAGE_FUNCTION(NAME) (ata_## NAME) 162 #define STORAGE_FUNCTION(NAME) (ata_## NAME)
99 #define storage_spindown ata_spindown 163 #define storage_spindown ata_spindown
100 #define storage_sleep ata_sleep
101 #define storage_spin ata_spin 164 #define storage_spin ata_spin
102 165
103 #define storage_enable(on) ata_enable(on) 166 #define storage_enable(on) ata_enable(on)
104 #define storage_sleepnow() ata_sleepnow() 167 #define storage_sleepnow() ata_sleepnow()
105 #define storage_disk_is_active() ata_disk_is_active() 168 #define storage_disk_is_active() ata_disk_is_active()
106 #define storage_soft_reset() ata_soft_reset() 169 #define storage_soft_reset() ata_soft_reset()
107 #define storage_init() ata_init()
108 #define storage_close() ata_close()
109 #ifdef HAVE_STORAGE_FLUSH 170 #ifdef HAVE_STORAGE_FLUSH
110 #define storage_flush() (void)0 171 #define storage_flush() (void)0
111 #endif 172 #endif
@@ -124,15 +185,12 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
124 #elif (CONFIG_STORAGE & STORAGE_SD) 185 #elif (CONFIG_STORAGE & STORAGE_SD)
125 #define STORAGE_FUNCTION(NAME) (sd_## NAME) 186 #define STORAGE_FUNCTION(NAME) (sd_## NAME)
126 #define storage_spindown sd_spindown 187 #define storage_spindown sd_spindown
127 #define storage_sleep sd_sleep
128 #define storage_spin sd_spin 188 #define storage_spin sd_spin
129 189
130 #define storage_enable(on) sd_enable(on) 190 #define storage_enable(on) sd_enable(on)
131 #define storage_sleepnow() sd_sleepnow() 191 #define storage_sleepnow() sd_sleepnow()
132 #define storage_disk_is_active() 0 192 #define storage_disk_is_active() 0
133 #define storage_soft_reset() (void)0 193 #define storage_soft_reset() (void)0
134 #define storage_init() sd_init()
135 #define storage_close() sd_close()
136 #ifdef HAVE_STORAGE_FLUSH 194 #ifdef HAVE_STORAGE_FLUSH
137 #define storage_flush() (void)0 195 #define storage_flush() (void)0
138 #endif 196 #endif
@@ -151,14 +209,12 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
151 #elif (CONFIG_STORAGE & STORAGE_MMC) 209 #elif (CONFIG_STORAGE & STORAGE_MMC)
152 #define STORAGE_FUNCTION(NAME) (mmc_## NAME) 210 #define STORAGE_FUNCTION(NAME) (mmc_## NAME)
153 #define storage_spindown mmc_spindown 211 #define storage_spindown mmc_spindown
154 #define storage_sleep mmc_sleep
155 #define storage_spin mmc_spin 212 #define storage_spin mmc_spin
156 213
157 #define storage_enable(on) mmc_enable(on) 214 #define storage_enable(on) mmc_enable(on)
158 #define storage_sleepnow() mmc_sleepnow() 215 #define storage_sleepnow() mmc_sleepnow()
159 #define storage_disk_is_active() mmc_disk_is_active() 216 #define storage_disk_is_active() mmc_disk_is_active()
160 #define storage_soft_reset() (void)0 217 #define storage_soft_reset() (void)0
161 #define storage_init() mmc_init()
162 #ifdef HAVE_STORAGE_FLUSH 218 #ifdef HAVE_STORAGE_FLUSH
163 #define storage_flush() (void)0 219 #define storage_flush() (void)0
164 #endif 220 #endif
@@ -177,14 +233,12 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
177 #elif (CONFIG_STORAGE & STORAGE_NAND) 233 #elif (CONFIG_STORAGE & STORAGE_NAND)
178 #define STORAGE_FUNCTION(NAME) (nand_## NAME) 234 #define STORAGE_FUNCTION(NAME) (nand_## NAME)
179 #define storage_spindown nand_spindown 235 #define storage_spindown nand_spindown
180 #define storage_sleep nand_sleep
181 #define storage_spin nand_spin 236 #define storage_spin nand_spin
182 237
183 #define storage_enable(on) (void)0 238 #define storage_enable(on) (void)0
184 #define storage_sleepnow() nand_sleepnow() 239 #define storage_sleepnow() nand_sleepnow()
185 #define storage_disk_is_active() 0 240 #define storage_disk_is_active() 0
186 #define storage_soft_reset() (void)0 241 #define storage_soft_reset() (void)0
187 #define storage_init() nand_init()
188 #ifdef HAVE_STORAGE_FLUSH 242 #ifdef HAVE_STORAGE_FLUSH
189 #define storage_flush() nand_flush() 243 #define storage_flush() nand_flush()
190 #endif 244 #endif
@@ -203,14 +257,12 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
203 #elif (CONFIG_STORAGE & STORAGE_RAMDISK) 257 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
204 #define STORAGE_FUNCTION(NAME) (ramdisk_## NAME) 258 #define STORAGE_FUNCTION(NAME) (ramdisk_## NAME)
205 #define storage_spindown ramdisk_spindown 259 #define storage_spindown ramdisk_spindown
206 #define storage_sleep ramdisk_sleep
207 #define storage_spin ramdisk_spin 260 #define storage_spin ramdisk_spin
208 261
209 #define storage_enable(on) (void)0 262 #define storage_enable(on) (void)0
210 #define storage_sleepnow() ramdisk_sleepnow() 263 #define storage_sleepnow() ramdisk_sleepnow()
211 #define storage_disk_is_active() 0 264 #define storage_disk_is_active() 0
212 #define storage_soft_reset() (void)0 265 #define storage_soft_reset() (void)0
213 #define storage_init() ramdisk_init()
214 #ifdef HAVE_STORAGE_FLUSH 266 #ifdef HAVE_STORAGE_FLUSH
215 #define storage_flush() (void)0 267 #define storage_flush() (void)0
216 #endif 268 #endif
@@ -234,11 +286,9 @@ static inline void stub_storage_spindown(int timeout) { (void)timeout; }
234/* Multi-driver use normal functions */ 286/* Multi-driver use normal functions */
235 287
236void storage_enable(bool on); 288void storage_enable(bool on);
237void storage_sleep(void);
238void storage_sleepnow(void); 289void storage_sleepnow(void);
239bool storage_disk_is_active(void); 290bool storage_disk_is_active(void);
240int storage_soft_reset(void); 291int storage_soft_reset(void);
241int storage_init(void) STORAGE_INIT_ATTR;
242int storage_flush(void); 292int storage_flush(void);
243void storage_spin(void); 293void storage_spin(void);
244void storage_spindown(int seconds); 294void storage_spindown(int seconds);
diff --git a/firmware/storage.c b/firmware/storage.c
index e9a3396f30..790cddcd1a 100644
--- a/firmware/storage.c
+++ b/firmware/storage.c
@@ -20,6 +20,9 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "storage.h" 21#include "storage.h"
22#include "kernel.h" 22#include "kernel.h"
23#include "ata_idle_notify.h"
24#include "usb.h"
25#include "disk.h"
23 26
24#ifdef CONFIG_STORAGE_MULTI 27#ifdef CONFIG_STORAGE_MULTI
25 28
@@ -31,118 +34,243 @@
31 34
32static unsigned int storage_drivers[NUM_DRIVES]; 35static unsigned int storage_drivers[NUM_DRIVES];
33static unsigned int num_drives; 36static unsigned int num_drives;
37#endif /* CONFIG_STORAGE_MULTI */
38
39/* defaults: override elsewhere target-wise if they must be different */
40#if (CONFIG_STORAGE & STORAGE_ATA)
41 #ifndef ATA_THREAD_STACK_SIZE
42 #define ATA_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
43 #endif
44#endif
45#if (CONFIG_STORAGE & STORAGE_MMC)
46 #ifndef MMC_THREAD_STACK_SIZE
47 #define MMC_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
48 #endif
49#endif
50#if (CONFIG_STORAGE & STORAGE_SD)
51 #ifndef SD_THREAD_STACK_SIZE
52 #define SD_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
53 #endif
54#endif
55#if (CONFIG_STORAGE & STORAGE_NAND)
56 #ifndef NAND_THREAD_STACK_SIZE
57 #define NAND_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
58 #endif
59#endif
60#if (CONFIG_STORAGE & STORAGE_RAMDISK)
61 #ifndef RAMDISK_THREAD_STACK_SIZE
62 #define RAMDISK_THREAD_STACK_SIZE (0) /* not used on its own */
63 #endif
34#endif 64#endif
35 65
36int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count, 66static struct event_queue storage_queue SHAREDBSS_ATTR;
37 void* buf) 67static unsigned int storage_thread_id = 0;
38{
39#ifdef CONFIG_STORAGE_MULTI
40 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
41 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
42 68
43 switch (driver) 69static union {
44 {
45#if (CONFIG_STORAGE & STORAGE_ATA) 70#if (CONFIG_STORAGE & STORAGE_ATA)
46 case STORAGE_ATA: 71 long stk_ata[ATA_THREAD_STACK_SIZE / sizeof (long)];
47 return ata_read_sectors(IF_MD(ldrive,) start,count,buf);
48#endif 72#endif
49
50#if (CONFIG_STORAGE & STORAGE_MMC) 73#if (CONFIG_STORAGE & STORAGE_MMC)
51 case STORAGE_MMC: 74 long stk_mmc[MMC_THREAD_STACK_SIZE / sizeof (long)];
52 return mmc_read_sectors(IF_MD(ldrive,) start,count,buf);
53#endif 75#endif
54
55#if (CONFIG_STORAGE & STORAGE_SD) 76#if (CONFIG_STORAGE & STORAGE_SD)
56 case STORAGE_SD: 77 long stk_sd[SD_THREAD_STACK_SIZE / sizeof (long)];
57 return sd_read_sectors(IF_MD(ldrive,) start,count,buf);
58#endif 78#endif
59
60#if (CONFIG_STORAGE & STORAGE_NAND) 79#if (CONFIG_STORAGE & STORAGE_NAND)
61 case STORAGE_NAND: 80 long stk_nand[NAND_THREAD_STACK_SIZE / sizeof (long)];
62 return nand_read_sectors(IF_MD(ldrive,) start,count,buf); 81#endif
82#if (CONFIG_STORAGE & STORAGE_RAMDISK)
83 long stk_ramdisk[RAMDISK_THREAD_STACK_SIZE / sizeof (long)];
63#endif 84#endif
85} storage_thread_stack;
64 86
87static const char storage_thread_name[] =
88#if (CONFIG_STORAGE & STORAGE_ATA)
89 "/ata"
90#endif
91#if (CONFIG_STORAGE & STORAGE_MMC)
92 "/mmc"
93#endif
94#if (CONFIG_STORAGE & STORAGE_SD)
95 "/sd"
96#endif
97#if (CONFIG_STORAGE & STORAGE_NAND)
98 "/nand"
99#endif
65#if (CONFIG_STORAGE & STORAGE_RAMDISK) 100#if (CONFIG_STORAGE & STORAGE_RAMDISK)
66 case STORAGE_RAMDISK: 101 "/ramdisk"
67 return ramdisk_read_sectors(IF_MD(ldrive,) start,count,buf);
68#endif 102#endif
69 } 103 ;
70
71 return -1;
72#else /* CONFIG_STORAGE_MULTI */
73 return STORAGE_FUNCTION(read_sectors)(IF_MD(drive,)start,count,buf);
74#endif /* CONFIG_STORAGE_MULTI */
75 104
76} 105/* event is targeted to a specific drive */
106#define DRIVE_EVT (1 << STORAGE_NUM_TYPES)
77 107
78int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count,
79 const void* buf)
80{
81#ifdef CONFIG_STORAGE_MULTI 108#ifdef CONFIG_STORAGE_MULTI
82 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 109static int storage_event_send(unsigned int route, long id, intptr_t data)
83 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 110{
84 111 /* most events go to everyone */
85 switch (driver) 112 if (UNLIKELY(route == DRIVE_EVT)) {
86 { 113 route = (storage_drivers[data] & DRIVER_MASK) >> DRIVER_OFFSET;
114 data = (storage_drivers[data] & DRIVE_MASK) >> DRIVE_OFFSET;
115 }
116
117 int rc = 0;
118
87#if (CONFIG_STORAGE & STORAGE_ATA) 119#if (CONFIG_STORAGE & STORAGE_ATA)
88 case STORAGE_ATA: 120 if (route & STORAGE_ATA) {
89 return ata_write_sectors(IF_MD(ldrive,)start,count,buf); 121 rc = ata_event(id, data);
122 }
90#endif 123#endif
91
92#if (CONFIG_STORAGE & STORAGE_MMC) 124#if (CONFIG_STORAGE & STORAGE_MMC)
93 case STORAGE_MMC: 125 if (route & STORAGE_MMC) {
94 return mmc_write_sectors(IF_MD(ldrive,)start,count,buf); 126 rc = mmc_event(id, data);
127 }
95#endif 128#endif
96
97#if (CONFIG_STORAGE & STORAGE_SD) 129#if (CONFIG_STORAGE & STORAGE_SD)
98 case STORAGE_SD: 130 if (route & STORAGE_SD) {
99 return sd_write_sectors(IF_MD(ldrive,)start,count,buf); 131 rc = sd_event(id, data);
132 }
100#endif 133#endif
101
102#if (CONFIG_STORAGE & STORAGE_NAND) 134#if (CONFIG_STORAGE & STORAGE_NAND)
103 case STORAGE_NAND: 135 if (route & STORAGE_NAND) {
104 return nand_write_sectors(IF_MD(ldrive,)start,count,buf); 136 rc = nand_event(id, data);
137 }
105#endif 138#endif
106
107#if (CONFIG_STORAGE & STORAGE_RAMDISK) 139#if (CONFIG_STORAGE & STORAGE_RAMDISK)
108 case STORAGE_RAMDISK: 140 if (route & STORAGE_RAMDISK) {
109 return ramdisk_write_sectors(IF_MD(ldrive,)start,count,buf); 141 rc = ramdisk_event(id, data);
110#endif
111 } 142 }
112 143#endif
113 return -1; 144
114#else /* CONFIG_STORAGE_MULTI */ 145 return rc;
115 return STORAGE_FUNCTION(write_sectors)(IF_MD(drive,)start,count,buf); 146}
116#endif /* CONFIG_STORAGE_MULTI */ 147#endif /* CONFIG_STORAGE_MULTI */
148
149#ifndef CONFIG_STORAGE_MULTI
150static FORCE_INLINE int storage_event_send(unsigned int route, long id,
151 intptr_t data)
152{
153 return route ? STORAGE_FUNCTION(event)(id, data) : 0;
117} 154}
155#endif /* ndef CONFIG_STORAGE_MULTI */
118 156
119#ifdef CONFIG_STORAGE_MULTI 157static void NORETURN_ATTR storage_thread(void)
158{
159 unsigned int bdcast = CONFIG_STORAGE;
160 bool usb_mode = false;
161 struct queue_event ev;
120 162
121#define DRIVER_MASK 0xff000000 163 while (1)
122#define DRIVER_OFFSET 24 164 {
123#define DRIVE_MASK 0x00ff0000 165 queue_wait_w_tmo(&storage_queue, &ev, HZ/2);
124#define DRIVE_OFFSET 16 166
125#define PARTITION_MASK 0x0000ff00 167 switch (ev.id)
168 {
169 case SYS_TIMEOUT:;
170 /* drivers hold their bit low when they want to
171 sleep and keep it high otherwise */
172 unsigned int trig = 0;
173 storage_event_send(bdcast, Q_STORAGE_TICK, (intptr_t)&trig);
174 trig = bdcast & ~trig;
175 if (trig) {
176 if (!usb_mode) {
177 call_storage_idle_notifys(false);
178 }
179 storage_event_send(trig, Q_STORAGE_SLEEPNOW, 0);
180 }
181 break;
126 182
127static unsigned int storage_drivers[NUM_DRIVES]; 183#if (CONFIG_STORAGE & STORAGE_ATA)
128static unsigned int num_drives; 184 case Q_STORAGE_SLEEP:
185 storage_event_send(bdcast, ev.id, 0);
186 break;
187#endif
129 188
130int storage_num_drives(void) 189#ifdef STORAGE_CLOSE
190 case Q_STORAGE_CLOSE:
191 storage_event_send(CONFIG_STORAGE, ev.id, 0);
192 thread_exit();
193#endif /* STORAGE_CLOSE */
194
195#ifdef HAVE_HOTSWAP
196 case SYS_HOTSWAP_INSERTED:
197 case SYS_HOTSWAP_EXTRACTED:
198 if (!usb_mode) {
199 int drive = IF_MD_DRV(ev.data);
200 if (!CHECK_DRV(drive)) {
201 break;
202 }
203
204 int umnt = disk_unmount(drive);
205 int mnt = 0;
206 int rci = storage_event_send(DRIVE_EVT, ev.id, drive);
207
208 if (ev.id == SYS_HOTSWAP_INSERTED && !rci) {
209 mnt = disk_mount(drive);
210 }
211
212 if (umnt > 0 || mnt > 0) {
213 /* something was unmounted and/or mounted */
214 queue_broadcast(SYS_FS_CHANGED, drive);
215 }
216 }
217 break;
218#endif /* HAVE_HOTSWAP */
219
220#ifndef USB_NONE
221 case SYS_USB_CONNECTED:
222 case SYS_USB_DISCONNECTED:
223 bdcast = 0;
224 storage_event_send(CONFIG_STORAGE, ev.id, (intptr_t)&bdcast);
225 usb_mode = ev.id == SYS_USB_CONNECTED;
226 if (usb_mode) {
227 usb_acknowledge(SYS_USB_CONNECTED_ACK);
228 }
229 else {
230 bdcast = CONFIG_STORAGE;
231 }
232 break;
233#endif /* ndef USB_NONE */
234 }
235 }
236}
237
238#if (CONFIG_STORAGE & STORAGE_ATA)
239void storage_sleep(void)
131{ 240{
132 return num_drives; 241 if (storage_thread_id) {
242 queue_post(&storage_queue, Q_STORAGE_SLEEP, 0);
243 }
133} 244}
245#endif /* (CONFIG_STORAGE & STORAGE_ATA) */
134 246
135int storage_driver_type(int drive) 247#ifdef STORAGE_CLOSE
248void storage_close(void)
136{ 249{
137 if ((unsigned int)drive >= num_drives) 250 if (storage_thread_id) {
138 return -1; 251 queue_post(&storage_queue, Q_STORAGE_CLOSE, 0);
252 thread_wait(storage_thread_id);
253 }
254}
255#endif /* STORAGE_CLOSE */
139 256
140 unsigned int bit = (storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 257static inline void storage_thread_init(void)
141 return bit ? find_first_set_bit(bit) : -1; 258{
259 if (storage_thread_id) {
260 return;
261 }
262
263 queue_init(&storage_queue, true);
264 storage_thread_id = create_thread(storage_thread, &storage_thread_stack,
265 sizeof (storage_thread_stack),
266 0, &storage_thread_name[1]
267 IF_PRIO(, PRIORITY_USER_INTERFACE)
268 IF_COP(, CPU));
142} 269}
143 270
144int storage_init(void) 271int storage_init(void)
145{ 272{
273#ifdef CONFIG_STORAGE_MULTI
146 int rc=0; 274 int rc=0;
147 int i; 275 int i;
148 num_drives=0; 276 num_drives=0;
@@ -201,54 +329,142 @@ int storage_init(void)
201 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET); 329 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
202 } 330 }
203#endif 331#endif
332#else /* ndef CONFIG_STORAGE_MULTI */
333 STORAGE_FUNCTION(init)();
334#endif /* CONFIG_STORAGE_MULTI */
204 335
336 storage_thread_init();
205 return 0; 337 return 0;
206} 338}
207 339
340int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count,
341 void* buf)
342{
343#ifdef CONFIG_STORAGE_MULTI
344 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
345 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
208 346
209void storage_enable(bool on) 347 switch (driver)
348 {
349#if (CONFIG_STORAGE & STORAGE_ATA)
350 case STORAGE_ATA:
351 return ata_read_sectors(IF_MD(ldrive,) start,count,buf);
352#endif
353
354#if (CONFIG_STORAGE & STORAGE_MMC)
355 case STORAGE_MMC:
356 return mmc_read_sectors(IF_MD(ldrive,) start,count,buf);
357#endif
358
359#if (CONFIG_STORAGE & STORAGE_SD)
360 case STORAGE_SD:
361 return sd_read_sectors(IF_MD(ldrive,) start,count,buf);
362#endif
363
364#if (CONFIG_STORAGE & STORAGE_NAND)
365 case STORAGE_NAND:
366 return nand_read_sectors(IF_MD(ldrive,) start,count,buf);
367#endif
368
369#if (CONFIG_STORAGE & STORAGE_RAMDISK)
370 case STORAGE_RAMDISK:
371 return ramdisk_read_sectors(IF_MD(ldrive,) start,count,buf);
372#endif
373 }
374
375 return -1;
376#else /* CONFIG_STORAGE_MULTI */
377 return STORAGE_FUNCTION(read_sectors)(IF_MD(drive,)start,count,buf);
378#endif /* CONFIG_STORAGE_MULTI */
379
380}
381
382int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count,
383 const void* buf)
210{ 384{
385#ifdef CONFIG_STORAGE_MULTI
386 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
387 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
388
389 switch (driver)
390 {
211#if (CONFIG_STORAGE & STORAGE_ATA) 391#if (CONFIG_STORAGE & STORAGE_ATA)
212 ata_enable(on); 392 case STORAGE_ATA:
393 return ata_write_sectors(IF_MD(ldrive,)start,count,buf);
213#endif 394#endif
214 395
215#if (CONFIG_STORAGE & STORAGE_MMC) 396#if (CONFIG_STORAGE & STORAGE_MMC)
216 mmc_enable(on); 397 case STORAGE_MMC:
398 return mmc_write_sectors(IF_MD(ldrive,)start,count,buf);
217#endif 399#endif
218 400
219#if (CONFIG_STORAGE & STORAGE_SD) 401#if (CONFIG_STORAGE & STORAGE_SD)
220 sd_enable(on); 402 case STORAGE_SD:
403 return sd_write_sectors(IF_MD(ldrive,)start,count,buf);
221#endif 404#endif
222 405
223#if (CONFIG_STORAGE & STORAGE_NAND) 406#if (CONFIG_STORAGE & STORAGE_NAND)
224 nand_enable(on); 407 case STORAGE_NAND:
408 return nand_write_sectors(IF_MD(ldrive,)start,count,buf);
225#endif 409#endif
226 410
227#if (CONFIG_STORAGE & STORAGE_RAMDISK) 411#if (CONFIG_STORAGE & STORAGE_RAMDISK)
228 ramdisk_enable(on); 412 case STORAGE_RAMDISK:
413 return ramdisk_write_sectors(IF_MD(ldrive,)start,count,buf);
229#endif 414#endif
415 }
416
417 return -1;
418#else /* CONFIG_STORAGE_MULTI */
419 return STORAGE_FUNCTION(write_sectors)(IF_MD(drive,)start,count,buf);
420#endif /* CONFIG_STORAGE_MULTI */
230} 421}
231 422
232void storage_sleep(void) 423#ifdef CONFIG_STORAGE_MULTI
424
425#define DRIVER_MASK 0xff000000
426#define DRIVER_OFFSET 24
427#define DRIVE_MASK 0x00ff0000
428#define DRIVE_OFFSET 16
429#define PARTITION_MASK 0x0000ff00
430
431static unsigned int storage_drivers[NUM_DRIVES];
432static unsigned int num_drives;
433
434int storage_num_drives(void)
435{
436 return num_drives;
437}
438
439int storage_driver_type(int drive)
440{
441 if ((unsigned int)drive >= num_drives)
442 return -1;
443
444 unsigned int bit = (storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
445 return bit ? find_first_set_bit(bit) : -1;
446}
447
448void storage_enable(bool on)
233{ 449{
234#if (CONFIG_STORAGE & STORAGE_ATA) 450#if (CONFIG_STORAGE & STORAGE_ATA)
235 ata_sleep(); 451 ata_enable(on);
236#endif 452#endif
237 453
238#if (CONFIG_STORAGE & STORAGE_MMC) 454#if (CONFIG_STORAGE & STORAGE_MMC)
239 mmc_sleep(); 455 mmc_enable(on);
240#endif 456#endif
241 457
242#if (CONFIG_STORAGE & STORAGE_SD) 458#if (CONFIG_STORAGE & STORAGE_SD)
243 sd_sleep(); 459 sd_enable(on);
244#endif 460#endif
245 461
246#if (CONFIG_STORAGE & STORAGE_NAND) 462#if (CONFIG_STORAGE & STORAGE_NAND)
247 nand_sleep(); 463 nand_enable(on);
248#endif 464#endif
249 465
250#if (CONFIG_STORAGE & STORAGE_RAMDISK) 466#if (CONFIG_STORAGE & STORAGE_RAMDISK)
251 ramdisk_sleep(); 467 ramdisk_enable(on);
252#endif 468#endif
253} 469}
254 470
@@ -603,6 +819,5 @@ bool storage_present(int drive)
603 return false; 819 return false;
604 } 820 }
605} 821}
606#endif 822#endif /* HAVE_HOTSWAP */
607
608#endif /*CONFIG_STORAGE_MULTI*/ 823#endif /*CONFIG_STORAGE_MULTI*/
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index e65a7525b6..d6c6654319 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -24,7 +24,6 @@
24 24
25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */ 25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */
26#include "fs_defines.h" 26#include "fs_defines.h"
27#include "thread.h"
28#include "led.h" 27#include "led.h"
29#include "sdmmc.h" 28#include "sdmmc.h"
30#include "system.h" 29#include "system.h"
@@ -39,20 +38,15 @@
39#include "dma-target.h" /* DMA request lines */ 38#include "dma-target.h" /* DMA request lines */
40#include "clock-target.h" 39#include "clock-target.h"
41#include "panic.h" 40#include "panic.h"
41#include "storage.h"
42
42#ifdef HAVE_BUTTON_LIGHT 43#ifdef HAVE_BUTTON_LIGHT
43#include "backlight-target.h" 44#include "backlight-target.h"
44#endif 45#endif
45#include "stdbool.h" 46
46#include "ata_idle_notify.h"
47#include "sd.h"
48#include "usb.h"
49/*#define LOGF_ENABLE*/ 47/*#define LOGF_ENABLE*/
50#include "logf.h" 48#include "logf.h"
51 49
52#ifdef HAVE_HOTSWAP
53#include "disk.h"
54#endif
55
56//#define VERIFY_WRITE 1 50//#define VERIFY_WRITE 1
57 51
58/* command flags */ 52/* command flags */
@@ -119,16 +113,19 @@ static tCardInfo card_info[NUM_DRIVES];
119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ 113#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */
120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ 114#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */
121 115
116#ifdef CONFIG_STORAGE_MULTI
117static int sd_first_drive = 0;
118#else
119#define sd_first_drive 0
120#endif
121
122/* for compatibility */ 122/* for compatibility */
123static long last_disk_activity = -1; 123static long last_disk_activity = -1;
124 124
125#define MIN_YIELD_PERIOD 5 /* ticks */ 125#define MIN_YIELD_PERIOD 5 /* ticks */
126static long next_yield = 0; 126static long next_yield = 0;
127 127
128static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 128static struct mutex sd_mtx;
129static const char sd_thread_name[] = "ata/sd";
130static struct mutex sd_mtx;
131static struct event_queue sd_queue;
132bool sd_enabled = false; 129bool sd_enabled = false;
133 130
134#if defined(HAVE_MULTIDRIVE) 131#if defined(HAVE_MULTIDRIVE)
@@ -147,6 +144,59 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
147 144
148static inline void mci_delay(void) { udelay(1000) ; } 145static inline void mci_delay(void) { udelay(1000) ; }
149 146
147static void enable_controller(bool on)
148{
149
150#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
151 extern int buttonlight_is_on;
152#endif
153
154#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
155 static bool cpu_boosted = false;
156#endif
157
158 if (sd_enabled == on)
159 return; /* nothing to do */
160
161 sd_enabled = on;
162
163 if(on)
164 {
165#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
166 /* buttonlight AMSes need a bit of special handling for the buttonlight
167 * here due to the dual mapping of GPIOD and XPD */
168 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
169 if (buttonlight_is_on)
170 GPIOD_DIR &= ~(1<<7);
171 else
172 buttonlight_hw_off();
173#endif
174
175#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
176 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
177 {
178 cpu_boosted = true;
179 cpu_boost(true);
180 }
181#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
182 }
183 else
184 {
185#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
186 if(cpu_boosted)
187 {
188 cpu_boost(false);
189 cpu_boosted = false;
190 }
191#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
192
193#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
194 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
195 if (buttonlight_is_on)
196 buttonlight_hw_on();
197#endif
198 }
199}
150 200
151static inline bool card_detect_target(void) 201static inline bool card_detect_target(void)
152{ 202{
@@ -161,18 +211,13 @@ static inline bool card_detect_target(void)
161#ifdef HAVE_HOTSWAP 211#ifdef HAVE_HOTSWAP
162static int sd1_oneshot_callback(struct timeout *tmo) 212static int sd1_oneshot_callback(struct timeout *tmo)
163{ 213{
164 (void)tmo;
165
166 /* This is called only if the state was stable for 300ms - check state 214 /* This is called only if the state was stable for 300ms - check state
167 * and post appropriate event. */ 215 * and post appropriate event. */
168 if (card_detect_target()) 216 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
169 { 217 SYS_HOTSWAP_EXTRACTED,
170 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 218 sd_first_drive + SD_SLOT_AS3525);
171 }
172 else
173 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
174
175 return 0; 219 return 0;
220 (void)tmo;
176} 221}
177 222
178void sd_gpioa_isr(void) 223void sd_gpioa_isr(void)
@@ -435,87 +480,6 @@ static int sd_init_card(const int drive)
435 return 0; 480 return 0;
436} 481}
437 482
438static void sd_thread(void) NORETURN_ATTR;
439static void sd_thread(void)
440{
441 struct queue_event ev;
442 bool idle_notified = false;
443
444 while (1)
445 {
446 queue_wait_w_tmo(&sd_queue, &ev, HZ);
447
448 switch ( ev.id )
449 {
450#ifdef HAVE_HOTSWAP
451 case SYS_HOTSWAP_INSERTED:
452 case SYS_HOTSWAP_EXTRACTED:;
453 int success = 1;
454
455 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
456
457 mutex_lock(&sd_mtx); /* lock-out card activity */
458
459 /* Force card init for new card, re-init for re-inserted one or
460 * clear if the last attempt to init failed with an error. */
461 card_info[SD_SLOT_AS3525].initialized = 0;
462
463 if (ev.id == SYS_HOTSWAP_INSERTED)
464 {
465 success = 0;
466 sd_enable(true);
467 init_pl180_controller(SD_SLOT_AS3525);
468 int rc = sd_init_card(SD_SLOT_AS3525);
469 sd_enable(false);
470 if (rc >= 0)
471 success = 2;
472 else /* initialisation failed */
473 panicf("microSD init failed : %d", rc);
474 }
475
476 mutex_unlock(&sd_mtx);
477
478 if (success > 1)
479 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
480
481 /*
482 * Mount succeeded, or this was an EXTRACTED event,
483 * in both cases notify the system about the changed filesystems
484 */
485 if (success)
486 queue_broadcast(SYS_FS_CHANGED, 0);
487
488 break;
489#endif /* HAVE_HOTSWAP */
490
491 case SYS_TIMEOUT:
492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
493 {
494 idle_notified = false;
495 }
496 else
497 {
498 /* never let a timer wrap confuse us */
499 next_yield = current_tick;
500
501 if (!idle_notified)
502 {
503 call_storage_idle_notifys(false);
504 idle_notified = true;
505 }
506 }
507 break;
508
509 case SYS_USB_CONNECTED:
510 usb_acknowledge(SYS_USB_CONNECTED_ACK);
511 /* Wait until the USB cable is extracted again */
512 usb_wait_for_disconnect(&sd_queue);
513
514 break;
515 }
516 }
517}
518
519static void init_pl180_controller(const int drive) 483static void init_pl180_controller(const int drive)
520{ 484{
521 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 485 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
@@ -576,12 +540,8 @@ int sd_init(void)
576 /* init mutex */ 540 /* init mutex */
577 mutex_init(&sd_mtx); 541 mutex_init(&sd_mtx);
578 542
579 queue_init(&sd_queue, true); 543 sd_enabled = true; /* force action on next call */
580 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 544 enable_controller(false);
581 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
582
583 sd_enabled = true;
584 sd_enable(false);
585 545
586 return 0; 546 return 0;
587} 547}
@@ -698,7 +658,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
698 unsigned long response; 658 unsigned long response;
699 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 659 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
700 660
701 sd_enable(true); 661 enable_controller(true);
702 led(true); 662 led(true);
703 663
704 if (card_info[drive].initialized <= 0) 664 if (card_info[drive].initialized <= 0)
@@ -873,7 +833,7 @@ sd_transfer_error:
873sd_transfer_error_nodma: 833sd_transfer_error_nodma:
874 834
875 led(false); 835 led(false);
876 sd_enable(false); 836 enable_controller(false);
877 837
878 if (ret) /* error */ 838 if (ret) /* error */
879 card_info[drive].initialized = 0; 839 card_info[drive].initialized = 0;
@@ -947,55 +907,9 @@ long sd_last_disk_activity(void)
947 907
948void sd_enable(bool on) 908void sd_enable(bool on)
949{ 909{
950#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) 910 mutex_lock(&sd_mtx);
951 extern int buttonlight_is_on; 911 enable_controller(on);
952#endif 912 mutex_unlock(&sd_mtx);
953
954#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
955 static bool cpu_boosted = false;
956#endif
957
958 if (sd_enabled == on)
959 return; /* nothing to do */
960
961 sd_enabled = on;
962
963 if(on)
964 {
965#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
966 /* buttonlight AMSes need a bit of special handling for the buttonlight
967 * here due to the dual mapping of GPIOD and XPD */
968 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
969 if (buttonlight_is_on)
970 GPIOD_DIR &= ~(1<<7);
971 else
972 buttonlight_hw_off();
973#endif
974
975#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
976 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
977 {
978 cpu_boosted = true;
979 cpu_boost(true);
980 }
981#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
982 }
983 else
984 {
985#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
986 if(cpu_boosted)
987 {
988 cpu_boost(false);
989 cpu_boosted = false;
990 }
991#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
992
993#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
994 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
995 if (buttonlight_is_on)
996 buttonlight_hw_on();
997#endif
998 }
999} 913}
1000 914
1001tCardInfo *card_get_info_target(int card_no) 915tCardInfo *card_get_info_target(int card_no)
@@ -1006,9 +920,45 @@ tCardInfo *card_get_info_target(int card_no)
1006#ifdef CONFIG_STORAGE_MULTI 920#ifdef CONFIG_STORAGE_MULTI
1007int sd_num_drives(int first_drive) 921int sd_num_drives(int first_drive)
1008{ 922{
1009 /* We don't care which logical drive number(s) we have been assigned */ 923 sd_first_drive = first_drive;
1010 (void)first_drive;
1011
1012 return NUM_DRIVES; 924 return NUM_DRIVES;
1013} 925}
1014#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
927
928int sd_event(long id, intptr_t data)
929{
930 int rc = 0;
931
932 switch (id)
933 {
934#ifdef HAVE_HOTSWAP
935 case SYS_HOTSWAP_INSERTED:
936 case SYS_HOTSWAP_EXTRACTED:
937 mutex_lock(&sd_mtx); /* lock-out card activity */
938
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942
943 if (id == SYS_HOTSWAP_INSERTED)
944 {
945 enable_controller(true);
946 init_pl180_controller(data);
947 rc = sd_init_card(data);
948 enable_controller(false);
949 }
950
951 mutex_unlock(&sd_mtx);
952 break;
953#endif /* HAVE_HOTSWAP */
954 case Q_STORAGE_TICK:
955 /* never let a timer wrap confuse us */
956 next_yield = current_tick;
957 default:
958 rc = storage_event_default_handler(id, data, last_disk_activity,
959 STORAGE_SD);
960 break;
961 }
962
963 return rc;
964}
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 3f39629e0b..f78345577c 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -22,7 +22,6 @@
22 22
23#include "config.h" /* for HAVE_MULTIVOLUME */ 23#include "config.h" /* for HAVE_MULTIVOLUME */
24#include "fs_defines.h" 24#include "fs_defines.h"
25#include "thread.h"
26#include "gcc_extensions.h" 25#include "gcc_extensions.h"
27#include "led.h" 26#include "led.h"
28#include "sdmmc.h" 27#include "sdmmc.h"
@@ -36,19 +35,7 @@
36#include "pl081.h" /* DMA controller */ 35#include "pl081.h" /* DMA controller */
37#include "dma-target.h" /* DMA request lines */ 36#include "dma-target.h" /* DMA request lines */
38#include "clock-target.h" 37#include "clock-target.h"
39#include "panic.h" 38#include "storage.h"
40#include "stdbool.h"
41#include "ata_idle_notify.h"
42#include "sd.h"
43#include "usb.h"
44
45#ifdef HAVE_HOTSWAP
46#include "disk.h"
47#endif
48
49#include "lcd.h"
50#include <stdarg.h>
51#include "sysfont.h"
52 39
53#define INTERNAL_AS3525 0 /* embedded SD card */ 40#define INTERNAL_AS3525 0 /* embedded SD card */
54#define SD_SLOT_AS3525 1 /* SD slot if present */ 41#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -327,13 +314,15 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
327 314
328static tCardInfo card_info[NUM_DRIVES]; 315static tCardInfo card_info[NUM_DRIVES];
329 316
317#ifdef CONFIG_STORAGE_MULTI
318static int sd_first_drive = 0;
319#else
320#define sd_first_drive 0
321#endif
322
330/* for compatibility */ 323/* for compatibility */
331static long last_disk_activity = -1; 324static long last_disk_activity = -1;
332
333static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
334static const char sd_thread_name[] = "ata/sd";
335static struct mutex sd_mtx SHAREDBSS_ATTR; 325static struct mutex sd_mtx SHAREDBSS_ATTR;
336static struct event_queue sd_queue;
337#ifndef BOOTLOADER 326#ifndef BOOTLOADER
338bool sd_enabled = false; 327bool sd_enabled = false;
339#endif 328#endif
@@ -371,6 +360,22 @@ void INT_NAND(void)
371 MCI_CTRL |= INT_ENABLE; 360 MCI_CTRL |= INT_ENABLE;
372} 361}
373 362
363#ifndef BOOTLOADER
364static void enable_controller(bool on)
365{
366 if (on)
367 {
368 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
369 CGU_SDSLOT |= (1<<7); /* interface enable */
370 }
371 else
372 {
373 CGU_SDSLOT &= ~(1<<7); /* interface enable */
374 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
375 }
376}
377#endif /* BOOTLOADER */
378
374static inline bool card_detect_target(void) 379static inline bool card_detect_target(void)
375{ 380{
376#if defined(HAVE_MULTIDRIVE) 381#if defined(HAVE_MULTIDRIVE)
@@ -577,75 +582,6 @@ static int sd_init_card(const int drive)
577 return 0; 582 return 0;
578} 583}
579 584
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589
590 switch ( ev.id )
591 {
592#ifdef HAVE_HOTSWAP
593 case SYS_HOTSWAP_INSERTED:
594 case SYS_HOTSWAP_EXTRACTED:;
595 int success = 1;
596
597 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
598
599 mutex_lock(&sd_mtx); /* lock-out card activity */
600
601 /* Force card init for new card, re-init for re-inserted one or
602 * clear if the last attempt to init failed with an error. */
603 card_info[SD_SLOT_AS3525].initialized = 0;
604
605 if (ev.id == SYS_HOTSWAP_INSERTED)
606 {
607 sd_enable(true);
608 success = sd_init_card(SD_SLOT_AS3525) == 0 ? 2 : 0;
609 sd_enable(false);
610 }
611
612 mutex_unlock(&sd_mtx);
613
614 if (success > 1)
615 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
616
617 /*
618 * Mount succeeded, or this was an EXTRACTED event,
619 * in both cases notify the system about the changed filesystems
620 */
621 if (success)
622 queue_broadcast(SYS_FS_CHANGED, 0);
623
624 break;
625#endif /* HAVE_HOTSWAP */
626
627 case SYS_TIMEOUT:
628 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
629 {
630 idle_notified = false;
631 }
632 else if (!idle_notified)
633 {
634 call_storage_idle_notifys(false);
635 idle_notified = true;
636 }
637 break;
638
639 case SYS_USB_CONNECTED:
640 usb_acknowledge(SYS_USB_CONNECTED_ACK);
641 /* Wait until the USB cable is extracted again */
642 usb_wait_for_disconnect(&sd_queue);
643
644 break;
645 }
646 }
647}
648
649static void init_controller(void) 585static void init_controller(void)
650{ 586{
651 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1; 587 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
@@ -706,6 +642,7 @@ int sd_init(void)
706 | (AS3525_SDSLOT_DIV << 2) 642 | (AS3525_SDSLOT_DIV << 2)
707 | 1; /* clock source = PLLA */ 643 | 1; /* clock source = PLLA */
708 644
645 mutex_init(&sd_mtx);
709 semaphore_init(&transfer_completion_signal, 1, 0); 646 semaphore_init(&transfer_completion_signal, 1, 0);
710 semaphore_init(&command_completion_signal, 1, 0); 647 semaphore_init(&command_completion_signal, 1, 0);
711 648
@@ -737,16 +674,9 @@ int sd_init(void)
737 if(ret < 0) 674 if(ret < 0)
738 return ret; 675 return ret;
739 676
740 /* init mutex */
741 mutex_init(&sd_mtx);
742
743 queue_init(&sd_queue, true);
744 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
745 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
746
747#ifndef BOOTLOADER 677#ifndef BOOTLOADER
748 sd_enabled = true; 678 sd_enabled = true;
749 sd_enable(false); 679 enable_controller(false);
750#endif 680#endif
751 return 0; 681 return 0;
752} 682}
@@ -767,7 +697,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
767 697
768 mutex_lock(&sd_mtx); 698 mutex_lock(&sd_mtx);
769#ifndef BOOTLOADER 699#ifndef BOOTLOADER
770 sd_enable(true); 700 enable_controller(true);
771 led(true); 701 led(true);
772#endif 702#endif
773 703
@@ -925,7 +855,7 @@ retry_with_reinit:
925 855
926exit: 856exit:
927#ifndef BOOTLOADER 857#ifndef BOOTLOADER
928 sd_enable(false); 858 enable_controller(false);
929 led(false); 859 led(false);
930#endif 860#endif
931 mutex_unlock(&sd_mtx); 861 mutex_unlock(&sd_mtx);
@@ -952,16 +882,9 @@ long sd_last_disk_activity(void)
952 882
953void sd_enable(bool on) 883void sd_enable(bool on)
954{ 884{
955 if (on) 885 mutex_lock(&sd_mtx);
956 { 886 enable_controller(on);
957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 887 mutex_unlock(&sd_mtx);
958 CGU_SDSLOT |= (1<<7); /* interface enable */
959 }
960 else
961 {
962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
964 }
965} 888}
966#endif /* BOOTLOADER */ 889#endif /* BOOTLOADER */
967 890
@@ -983,18 +906,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
983 906
984static int sd1_oneshot_callback(struct timeout *tmo) 907static int sd1_oneshot_callback(struct timeout *tmo)
985{ 908{
986 (void)tmo;
987
988 /* This is called only if the state was stable for 300ms - check state 909 /* This is called only if the state was stable for 300ms - check state
989 * and post appropriate event. */ 910 * and post appropriate event. */
990 if (card_detect_target()) 911 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
991 { 912 SYS_HOTSWAP_EXTRACTED,
992 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 913 sd_first_drive + SD_SLOT_AS3525);
993 }
994 else
995 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
996
997 return 0; 914 return 0;
915 (void)tmo;
998} 916}
999 917
1000void sd_gpioa_isr(void) 918void sd_gpioa_isr(void)
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void)
1012#ifdef CONFIG_STORAGE_MULTI 930#ifdef CONFIG_STORAGE_MULTI
1013int sd_num_drives(int first_drive) 931int sd_num_drives(int first_drive)
1014{ 932{
1015 /* We don't care which logical drive number(s) we have been assigned */ 933 sd_first_drive = first_drive;
1016 (void)first_drive;
1017
1018 return NUM_DRIVES; 934 return NUM_DRIVES;
1019} 935}
1020#endif /* CONFIG_STORAGE_MULTI */ 936#endif /* CONFIG_STORAGE_MULTI */
937
938int sd_event(long id, intptr_t data)
939{
940 int rc = 0;
941
942 switch (id)
943 {
944#ifdef HAVE_HOTSWAP
945 case SYS_HOTSWAP_INSERTED:
946 case SYS_HOTSWAP_EXTRACTED:
947 mutex_lock(&sd_mtx); /* lock-out card activity */
948
949 /* Force card init for new card, re-init for re-inserted one or
950 * clear if the last attempt to init failed with an error. */
951 card_info[data].initialized = 0;
952
953 if (id == SYS_HOTSWAP_INSERTED)
954 {
955 enable_controller(true);
956 rc = sd_init_card(data);
957 enable_controller(false);
958 }
959
960 mutex_unlock(&sd_mtx);
961 break;
962#endif /* HAVE_HOTSWAP */
963 default:
964 rc = storage_event_default_handler(id, data, last_disk_activity,
965 STORAGE_SD);
966 break;
967 }
968
969 return rc;
970}
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index 869a53c1ef..73d92a5215 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -1065,3 +1065,9 @@ void nand_enable(bool onoff)
1065} 1065}
1066 1066
1067#endif /* CONFIG_STORAGE_MULTI */ 1067#endif /* CONFIG_STORAGE_MULTI */
1068
1069int nand_event(long id, intptr_t data)
1070{
1071 return storage_event_default_handler(id, data, last_disk_activity,
1072 STORAGE_NAND);
1073}
diff --git a/firmware/target/arm/imx233/ata-target.h b/firmware/target/arm/imx233/ata-target.h
index a95ea03247..2c553ebbff 100644
--- a/firmware/target/arm/imx233/ata-target.h
+++ b/firmware/target/arm/imx233/ata-target.h
@@ -23,10 +23,6 @@
23 23
24#include "config.h" 24#include "config.h"
25 25
26#ifdef BOOTLOADER
27#define ATA_DRIVER_CLOSE
28#endif
29
30#ifdef HAVE_ATA_DMA 26#ifdef HAVE_ATA_DMA
31/* FIXME does this chips does MWDMA ? */ 27/* FIXME does this chips does MWDMA ? */
32#define ATA_MAX_MWDMA 2 28#define ATA_MAX_MWDMA 2
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index d3dabafecb..af090e8a07 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -217,9 +217,6 @@ static struct sdmmc_status_t sdmmc_status[SDMMC_NUM_DRIVES];
217#define SDMMC_STATUS(drive) sdmmc_status[drive] 217#define SDMMC_STATUS(drive) sdmmc_status[drive]
218 218
219/* sd only */ 219/* sd only */
220static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
221static const char sdmmc_thread_name[] = "sdmmc";
222static struct event_queue sdmmc_queue;
223#if CONFIG_STORAGE & STORAGE_SD 220#if CONFIG_STORAGE & STORAGE_SD
224static int sd_first_drive; 221static int sd_first_drive;
225static unsigned _sd_num_drives; 222static unsigned _sd_num_drives;
@@ -260,10 +257,38 @@ static void sdmmc_detect_callback(int ssp)
260{ 257{
261 /* This is called only if the state was stable for 300ms - check state 258 /* This is called only if the state was stable for 300ms - check state
262 * and post appropriate event. */ 259 * and post appropriate event. */
263 if(imx233_ssp_sdmmc_detect(ssp)) 260 long evid = imx233_ssp_sdmmc_detect(ssp) ?
264 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 261 SYS_HOTSWAP_INSERTED : SYS_HOTSWAP_EXTRACTED;
265 else 262
266 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 263 /* Have to reverse lookup the ssp */
264 for (unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
265 {
266 if (SDMMC_SSP(drive) != ssp)
267 continue;
268
269 int first_drive, *map;
270 switch (SDMMC_MODE(drive))
271 {
272#if (CONFIG_STORAGE & STORAGE_MMC)
273 case MMC_MODE:
274 first_drive = mmc_first_drive;
275 map = mmc_map;
276 break;
277#endif
278#if (CONFIG_STORAGE & STORAGE_SD)
279 case SD_MODE:
280 first_drive = sd_first_drive;
281 map = sd_map;
282 break;
283#endif
284 default:
285 continue;
286 }
287
288 /* message requires logical drive number as data */
289 queue_broadcast(evid, first_drive + map[drive]);
290 }
291
267 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false, 292 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false,
268 imx233_ssp_sdmmc_is_detect_inverted(ssp)); 293 imx233_ssp_sdmmc_is_detect_inverted(ssp));
269} 294}
@@ -483,7 +508,48 @@ static int init_sd_card(int drive)
483 508
484 return 0; 509 return 0;
485} 510}
486#endif 511
512int sd_event(long id, intptr_t data)
513{
514 int rc = 0;
515
516 switch (id)
517 {
518#ifdef HAVE_HOTSWAP
519 case SYS_HOTSWAP_INSERTED:
520 case SYS_HOTSWAP_EXTRACTED:;
521 const int drive = sd_map[data];
522
523 /* Skip non-removable drivers */
524 if(!sdmmc_removable(drive))
525 {
526 rc = -1;
527 break;
528 }
529
530 mutex_lock(&mutex[drive]); /* lock-out card activity */
531
532 /* Force card init for new card, re-init for re-inserted one or
533 * clear if the last attempt to init failed with an error. */
534 SDMMC_INFO(drive).initialized = 0;
535
536 if(id == SYS_HOTSWAP_INSERTED)
537 rc = init_drive(drive);
538
539 /* unlock card */
540 mutex_unlock(&mutex[drive]);
541 /* Access is now safe */
542 break;
543#endif /* HAVE_HOTSWAP */
544 default:
545 rc = storage_event_default_handler(id, data, sd_last_disk_activity(),
546 STORAGE_SD);
547 break;
548 }
549
550 return rc;
551}
552#endif /* CONFIG_STORAGE & STORAGE_SD */
487 553
488#if CONFIG_STORAGE & STORAGE_MMC 554#if CONFIG_STORAGE & STORAGE_MMC
489static int init_mmc_drive(int drive) 555static int init_mmc_drive(int drive)
@@ -573,7 +639,13 @@ static int init_mmc_drive(int drive)
573 639
574 return 0; 640 return 0;
575} 641}
576#endif 642
643int mmc_event(long id, intptr_t data)
644{
645 return storage_event_default_handler(id, data, mmc_last_disk_activity(),
646 STORAGE_MMC);
647}
648#endif /* CONFIG_STORAGE & STORAGE_MMC */
577 649
578/* low-level function, don't call directly! */ 650/* low-level function, don't call directly! */
579static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 651static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read)
@@ -770,98 +842,6 @@ static int init_drive(int drive)
770 return 0; 842 return 0;
771} 843}
772 844
773static void sdmmc_thread(void) NORETURN_ATTR;
774static void sdmmc_thread(void)
775{
776 struct queue_event ev;
777 bool idle_notified = false;
778 int timeout = 0;
779
780 while (1)
781 {
782 queue_wait_w_tmo(&sdmmc_queue, &ev, HZ);
783
784 switch(ev.id)
785 {
786#if CONFIG_STORAGE & STORAGE_SD
787 case SYS_HOTSWAP_INSERTED:
788 case SYS_HOTSWAP_EXTRACTED:
789 {
790 int microsd_init = ev.id == SYS_HOTSWAP_INSERTED ? 0 : 1;
791
792 /* We now have exclusive control of fat cache and sd.
793 * Release "by force", ensure file
794 * descriptors aren't leaked and any busy
795 * ones are invalid if mounting. */
796 for(unsigned sd_drive = 0; sd_drive < _sd_num_drives; sd_drive++)
797 {
798 int drive = sd_map[sd_drive];
799 /* Skip non-removable drivers */
800 if(!sdmmc_removable(drive))
801 continue;
802
803 disk_unmount(sd_first_drive + sd_drive);
804
805 mutex_lock(&mutex[drive]); /* lock-out card activity */
806
807 /* Force card init for new card, re-init for re-inserted one or
808 * clear if the last attempt to init failed with an error. */
809 SDMMC_INFO(sd_map[sd_drive]).initialized = 0;
810
811 int rc = -1;
812 if(ev.id == SYS_HOTSWAP_INSERTED)
813 {
814 rc = init_drive(drive);
815 if(rc < 0) /* initialisation failed */
816 panicf("%s init failed : %d", SDMMC_CONF(sd_map[sd_drive]).name, rc);
817 }
818
819 /* unlock card */
820 mutex_unlock(&mutex[drive]);
821
822 if (rc >= 0)
823 microsd_init += disk_mount(sd_first_drive + sd_drive); /* 0 if fail */
824 }
825 /* Access is now safe */
826 /*
827 * One or more mounts succeeded, or this was an EXTRACTED event,
828 * in both cases notify the system about the changed filesystems
829 */
830 if(microsd_init)
831 queue_broadcast(SYS_FS_CHANGED, 0);
832
833 break;
834 }
835#endif
836 case SYS_TIMEOUT:
837#if CONFIG_STORAGE & STORAGE_SD
838 timeout = MAX(timeout, sd_last_disk_activity()+(3*HZ));
839#endif
840#if CONFIG_STORAGE & STORAGE_MMC
841 timeout = MAX(timeout, mmc_last_disk_activity()+(3*HZ));
842#endif
843 if(TIME_BEFORE(current_tick, timeout))
844 {
845 idle_notified = false;
846 }
847 else
848 {
849 if(!idle_notified)
850 {
851 call_storage_idle_notifys(false);
852 idle_notified = true;
853 }
854 }
855 break;
856 case SYS_USB_CONNECTED:
857 usb_acknowledge(SYS_USB_CONNECTED_ACK);
858 /* Wait until the USB cable is extracted again */
859 usb_wait_for_disconnect(&sdmmc_queue);
860 break;
861 }
862 }
863}
864
865static int sdmmc_init(void) 845static int sdmmc_init(void)
866{ 846{
867 static int is_initialized = false; 847 static int is_initialized = false;
@@ -871,10 +851,6 @@ static int sdmmc_init(void)
871 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 851 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
872 mutex_init(&mutex[drive]); 852 mutex_init(&mutex[drive]);
873 853
874 queue_init(&sdmmc_queue, true);
875 create_thread(sdmmc_thread, sdmmc_stack, sizeof(sdmmc_stack), 0,
876 sdmmc_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
877
878 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 854 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
879 { 855 {
880 if(sdmmc_removable(drive)) 856 if(sdmmc_removable(drive))
@@ -1024,10 +1000,6 @@ void mmc_enable(bool on)
1024 (void) on; 1000 (void) on;
1025} 1001}
1026 1002
1027void mmc_sleep(void)
1028{
1029}
1030
1031void mmc_sleepnow(void) 1003void mmc_sleepnow(void)
1032{ 1004{
1033} 1005}
diff --git a/firmware/target/arm/imx31/ata-target.h b/firmware/target/arm/imx31/ata-target.h
index 6893e83198..9363a8579c 100644
--- a/firmware/target/arm/imx31/ata-target.h
+++ b/firmware/target/arm/imx31/ata-target.h
@@ -23,10 +23,6 @@
23 23
24#include "config.h" 24#include "config.h"
25 25
26#ifdef BOOTLOADER
27#define ATA_DRIVER_CLOSE
28#endif
29
30/* Plain C read & write loops */ 26/* Plain C read & write loops */
31/* They likely won't be used anyway since DMA potentially works for any 27/* They likely won't be used anyway since DMA potentially works for any
32 * sector number and alignment. */ 28 * sector number and alignment. */
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index edb806ab96..fb0a9e150e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -24,16 +24,10 @@
24#ifdef HAVE_HOTSWAP 24#ifdef HAVE_HOTSWAP
25#include "sd-pp-target.h" 25#include "sd-pp-target.h"
26#endif 26#endif
27#include "ata_idle_notify.h"
28#include "system.h" 27#include "system.h"
29#include <string.h> 28#include <string.h>
30#include "thread.h"
31#include "led.h" 29#include "led.h"
32#include "disk.h"
33#include "cpu.h" 30#include "cpu.h"
34#include "panic.h"
35#include "usb.h"
36#include "sd.h"
37#include "storage.h" 31#include "storage.h"
38#include "fs_defines.h" 32#include "fs_defines.h"
39 33
@@ -151,12 +145,6 @@
151/* for compatibility */ 145/* for compatibility */
152static long last_disk_activity = -1; 146static long last_disk_activity = -1;
153 147
154/** static, private data **/
155static bool initialized = false;
156static unsigned int sd_thread_id = 0;
157
158#define Q_CLOSE 1
159
160static long next_yield = 0; 148static long next_yield = 0;
161#define MIN_YIELD_PERIOD 1000 149#define MIN_YIELD_PERIOD 1000
162 150
@@ -177,30 +165,28 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
177#endif 165#endif
178}; 166};
179 167
180/* Shoot for around 75% usage */ 168static struct mutex sd_mtx SHAREDBSS_ATTR;
181static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
182static const char sd_thread_name[] = "ata/sd";
183static struct mutex sd_mtx SHAREDBSS_ATTR;
184static struct event_queue sd_queue SHAREDBSS_ATTR;
185 169
186#ifdef HAVE_HOTSWAP 170#ifdef HAVE_HOTSWAP
187static int sd_first_drive = 0; 171static int sd_first_drive = 0;
188#endif 172#endif
189 173
190/* Posted when card plugged status has changed */
191#define SD_HOTSWAP 1
192/* Actions taken by sd_thread when card status has changed */
193enum sd_thread_actions
194{
195 SDA_NONE = 0x0,
196 SDA_UNMOUNTED = 0x1,
197 SDA_MOUNTED = 0x2
198};
199
200/* Private Functions */ 174/* Private Functions */
201 175
202static unsigned int check_time[NUM_EC]; 176static unsigned int check_time[NUM_EC];
203 177
178static inline void enable_controller(bool on)
179{
180 if(on)
181 {
182 DEV_EN |= DEV_ATA; /* Enable controller */
183 }
184 else
185 {
186 DEV_EN &= ~DEV_ATA; /* Disable controller */
187 }
188}
189
204static inline bool sd_check_timeout(long timeout, int id) 190static inline bool sd_check_timeout(long timeout, int id)
205{ 191{
206 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout); 192 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
@@ -876,7 +862,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
876 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
877 863
878 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
879 sd_enable(true); 865 enable_controller(true);
880 led(true); 866 led(true);
881 867
882sd_read_retry: 868sd_read_retry:
@@ -964,7 +950,7 @@ sd_read_retry:
964 while (1) 950 while (1)
965 { 951 {
966 led(false); 952 led(false);
967 sd_enable(false); 953 enable_controller(false);
968 mutex_unlock(&sd_mtx); 954 mutex_unlock(&sd_mtx);
969 955
970 return ret; 956 return ret;
@@ -994,7 +980,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
994 unsigned int bank; 980 unsigned int bank;
995 981
996 mutex_lock(&sd_mtx); 982 mutex_lock(&sd_mtx);
997 sd_enable(true); 983 enable_controller(true);
998 led(true); 984 led(true);
999 985
1000sd_write_retry: 986sd_write_retry:
@@ -1092,7 +1078,7 @@ sd_write_retry:
1092 while (1) 1078 while (1)
1093 { 1079 {
1094 led(false); 1080 led(false);
1095 sd_enable(false); 1081 enable_controller(false);
1096 mutex_unlock(&sd_mtx); 1082 mutex_unlock(&sd_mtx);
1097 1083
1098 return ret; 1084 return ret;
@@ -1108,182 +1094,79 @@ sd_write_error:
1108 } 1094 }
1109} 1095}
1110 1096
1111#ifndef SD_DRIVER_CLOSE
1112static void sd_thread(void) NORETURN_ATTR;
1113#endif
1114static void sd_thread(void)
1115{
1116 struct queue_event ev;
1117 bool idle_notified = false;
1118
1119 while (1)
1120 {
1121 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1122
1123 switch ( ev.id )
1124 {
1125#ifdef HAVE_HOTSWAP
1126 case SYS_HOTSWAP_INSERTED:
1127 case SYS_HOTSWAP_EXTRACTED:;
1128 int success = 1;
1129
1130 disk_unmount(sd_first_drive+1); /* release "by force" */
1131
1132 mutex_lock(&sd_mtx); /* lock-out card activity */
1133
1134 /* Force card init for new card, re-init for re-inserted one or
1135 * clear if the last attempt to init failed with an error. */
1136 card_info[1].initialized = 0;
1137 sd_status[1].retry = 0;
1138
1139 /* Access is now safe */
1140 mutex_unlock(&sd_mtx);
1141
1142 if (ev.id == SYS_HOTSWAP_INSERTED)
1143 success = disk_mount(sd_first_drive+1); /* 0 if fail */
1144
1145 if (success)
1146 queue_broadcast(SYS_FS_CHANGED, 0);
1147 break;
1148#endif /* HAVE_HOTSWAP */
1149 case SYS_TIMEOUT:
1150 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1151 {
1152 idle_notified = false;
1153 }
1154 else
1155 {
1156 /* never let a timer wrap confuse us */
1157 next_yield = USEC_TIMER;
1158
1159 if (!idle_notified)
1160 {
1161 call_storage_idle_notifys(false);
1162 idle_notified = true;
1163 }
1164 }
1165 break;
1166 case SYS_USB_CONNECTED:
1167 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1168 /* Wait until the USB cable is extracted again */
1169 usb_wait_for_disconnect(&sd_queue);
1170 break;
1171
1172#ifdef SD_DRIVER_CLOSE
1173 case Q_CLOSE:
1174 return;
1175#endif
1176 }
1177 }
1178}
1179
1180#ifdef SD_DRIVER_CLOSE
1181void sd_close(void)
1182{
1183 unsigned int thread_id = sd_thread_id;
1184
1185 if (thread_id == 0)
1186 return;
1187
1188 sd_thread_id = 0;
1189
1190 queue_post(&sd_queue, Q_CLOSE, 0);
1191 thread_wait(thread_id);
1192}
1193#endif /* SD_DRIVER_CLOSE */
1194
1195void sd_enable(bool on) 1097void sd_enable(bool on)
1196{ 1098{
1197 if(on) 1099 mutex_lock(&sd_mtx);
1198 { 1100 enable_controller(on);
1199 DEV_EN |= DEV_ATA; /* Enable controller */ 1101 mutex_unlock(&sd_mtx);
1200 }
1201 else
1202 {
1203 DEV_EN &= ~DEV_ATA; /* Disable controller */
1204 }
1205} 1102}
1206 1103
1207
1208int sd_init(void) 1104int sd_init(void)
1209{ 1105{
1210 int ret = 0; 1106 int ret = 0;
1211 1107
1212 if (!initialized) 1108 mutex_init(&sd_mtx);
1213 mutex_init(&sd_mtx);
1214
1215 mutex_lock(&sd_mtx);
1216 1109
1217 led(false); 1110 led(false);
1218 1111
1219 if (!initialized) 1112 /* init controller */
1220 {
1221 initialized = true;
1222
1223 /* init controller */
1224#if defined(PHILIPS_SA9200) 1113#if defined(PHILIPS_SA9200)
1225 GPIOA_ENABLE = 0x00; 1114 GPIOA_ENABLE = 0x00;
1226 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01); 1115 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
1227#else 1116#else
1228 outl(inl(0x70000088) & ~(0x4), 0x70000088); 1117 outl(inl(0x70000088) & ~(0x4), 0x70000088);
1229 outl(inl(0x7000008c) & ~(0x4), 0x7000008c); 1118 outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
1230 GPO32_ENABLE |= 0x4; 1119 GPO32_ENABLE |= 0x4;
1231 1120
1232 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5)); 1121 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
1233 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5)); 1122 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
1234 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5)); 1123 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
1235#endif 1124#endif
1236 1125
1237#ifdef HAVE_HOTSWAP 1126#ifdef HAVE_HOTSWAP
1238 /* enable card detection port - mask interrupt first */ 1127 /* enable card detection port - mask interrupt first */
1239#ifdef SANSA_E200 1128#ifdef SANSA_E200
1240 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80); 1129 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1241 1130
1242 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80); 1131 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
1243 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80); 1132 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
1244#elif defined SANSA_C200 1133#elif defined SANSA_C200
1245 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08); 1134 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1246 1135
1247 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08); 1136 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
1248 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08); 1137 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
1249#endif 1138#endif
1250#endif 1139#endif
1251 sd_select_device(0); 1140 sd_select_device(0);
1252
1253 if (currcard->initialized < 0)
1254 ret = currcard->initialized;
1255 1141
1256 queue_init(&sd_queue, true); 1142 if (currcard->initialized < 0)
1257 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack), 1143 ret = currcard->initialized;
1258 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1259 IF_COP(, CPU));
1260 1144
1261 /* enable interupt for the mSD card */ 1145 /* enable interupt for the mSD card */
1262 sleep(HZ/10); 1146 sleep(HZ/10);
1263#ifdef HAVE_HOTSWAP 1147#ifdef HAVE_HOTSWAP
1264#ifdef SANSA_E200 1148#ifdef SANSA_E200
1265 CPU_INT_EN = HI_MASK; 1149 CPU_INT_EN = HI_MASK;
1266 CPU_HI_INT_EN = GPIO0_MASK; 1150 CPU_HI_INT_EN = GPIO0_MASK;
1267 1151
1268 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80); 1152 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1269 1153
1270 GPIOA_INT_CLR = 0x80; 1154 GPIOA_INT_CLR = 0x80;
1271 1155
1272 /* enable the card detect interrupt */ 1156 /* enable the card detect interrupt */
1273 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); 1157 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1274#elif defined SANSA_C200 1158#elif defined SANSA_C200
1275 CPU_INT_EN = HI_MASK; 1159 CPU_INT_EN = HI_MASK;
1276 CPU_HI_INT_EN = GPIO2_MASK; 1160 CPU_HI_INT_EN = GPIO2_MASK;
1277 1161
1278 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08); 1162 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1279 1163
1280 GPIOL_INT_CLR = 0x08; 1164 GPIOL_INT_CLR = 0x08;
1281 1165
1282 /* enable the card detect interrupt */ 1166 /* enable the card detect interrupt */
1283 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); 1167 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1284#endif
1285#endif 1168#endif
1286 } 1169#endif /* HAVE_HOTSWAP */
1287 1170
1288 mutex_unlock(&sd_mtx); 1171 mutex_unlock(&sd_mtx);
1289 1172
@@ -1294,19 +1177,17 @@ tCardInfo *card_get_info_target(int card_no)
1294{ 1177{
1295 return &card_info[card_no]; 1178 return &card_info[card_no];
1296} 1179}
1180
1297#ifdef HAVE_HOTSWAP 1181#ifdef HAVE_HOTSWAP
1298static int sd1_oneshot_callback(struct timeout *tmo) 1182static int sd1_oneshot_callback(struct timeout *tmo)
1299{ 1183{
1300 (void)tmo;
1301
1302 /* This is called only if the state was stable for 300ms - check state 1184 /* This is called only if the state was stable for 300ms - check state
1303 * and post appropriate event. */ 1185 * and post appropriate event. */
1304 if (card_detect_target()) 1186 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
1305 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1187 SYS_HOTSWAP_EXTRACTED,
1306 else 1188 sd_first_drive+1);
1307 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1308
1309 return 0; 1189 return 0;
1190 (void)tmo;
1310} 1191}
1311 1192
1312/* called on insertion/removal interrupt */ 1193/* called on insertion/removal interrupt */
@@ -1377,3 +1258,36 @@ int sd_num_drives(int first_drive)
1377#endif 1258#endif
1378} 1259}
1379#endif 1260#endif
1261
1262int sd_event(long id, intptr_t data)
1263{
1264 int rc = 0;
1265
1266 switch (id)
1267 {
1268#ifdef HAVE_HOTSWAP
1269 case SYS_HOTSWAP_INSERTED:
1270 case SYS_HOTSWAP_EXTRACTED:
1271 mutex_lock(&sd_mtx); /* lock-out card activity */
1272
1273 /* Force card init for new card, re-init for re-inserted one or
1274 * clear if the last attempt to init failed with an error. */
1275 card_info[data].initialized = 0;
1276 sd_status[data].retry = 0;
1277
1278 /* Access is now safe */
1279 mutex_unlock(&sd_mtx);
1280 break;
1281#endif /* HAVE_HOTSWAP */
1282
1283 case Q_STORAGE_TICK:
1284 /* never let a timer wrap confuse us */
1285 next_yield = USEC_TIMER;
1286 default:
1287 rc = storage_event_default_handler(id, data, last_disk_activity,
1288 STORAGE_SD);
1289 break;
1290 }
1291
1292 return rc;
1293}
diff --git a/firmware/target/arm/pp/ata-target.h b/firmware/target/arm/pp/ata-target.h
index b888f85b88..a11aeda36d 100644
--- a/firmware/target/arm/pp/ata-target.h
+++ b/firmware/target/arm/pp/ata-target.h
@@ -24,10 +24,6 @@
24 24
25#include "config.h" 25#include "config.h"
26 26
27#ifdef HAVE_BOOTLOADER_USB_MODE
28#define ATA_DRIVER_CLOSE
29#endif
30
31/* primary channel */ 27/* primary channel */
32#define ATA_DATA (*((volatile unsigned short*)(IDE_BASE + 0x1e0))) 28#define ATA_DATA (*((volatile unsigned short*)(IDE_BASE + 0x1e0)))
33#define ATA_ERROR (*((volatile unsigned char*)(IDE_BASE + 0x1e4))) 29#define ATA_ERROR (*((volatile unsigned char*)(IDE_BASE + 0x1e4)))
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 6eeff7bae5..2ddfd0cf0a 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -34,13 +34,7 @@
34#include <string.h> 34#include <string.h>
35#include "panic.h" 35#include "panic.h"
36#include "stdbool.h" 36#include "stdbool.h"
37#include "ata_idle_notify.h" 37#include "storage.h"
38#include "sd.h"
39#include "usb.h"
40
41#ifdef HAVE_HOTSWAP
42#include "disk.h"
43#endif
44 38
45#include "lcd.h" 39#include "lcd.h"
46#include <stdarg.h> 40#include <stdarg.h>
@@ -57,21 +51,39 @@ static tCardInfo card_info;
57/* for compatibility */ 51/* for compatibility */
58static long last_disk_activity = -1; 52static long last_disk_activity = -1;
59 53
60static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
61static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR; 54static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR;
62 55
63static const char sd_thread_name[] = "ata/sd";
64static struct mutex sd_mtx SHAREDBSS_ATTR; 56static struct mutex sd_mtx SHAREDBSS_ATTR;
65static struct event_queue sd_queue;
66#ifndef BOOTLOADER 57#ifndef BOOTLOADER
67bool sd_enabled = false; 58bool sd_enabled = false;
68#endif 59#endif
69 60
61#ifdef CONFIG_STORAGE_MULTI
62static int sd_first_drive = 0;
63#else
64#define sd_first_drive 0
65#endif
66
70static struct semaphore transfer_completion_signal; 67static struct semaphore transfer_completion_signal;
71static struct semaphore command_completion_signal; 68static struct semaphore command_completion_signal;
72static volatile bool retry; 69static volatile bool retry;
73static volatile int cmd_error; 70static volatile int cmd_error;
74 71
72static void enable_controller(bool on)
73{
74 /* enable or disable clock signal for SD module */
75 if (on)
76 {
77 SCU_CLKCFG &= ~CLKCFG_SD;
78 led(true);
79 }
80 else
81 {
82 SCU_CLKCFG |= CLKCFG_SD;
83 led(false);
84 }
85}
86
75/* interrupt handler for SD */ 87/* interrupt handler for SD */
76void INT_SD(void) 88void INT_SD(void)
77{ 89{
@@ -318,81 +330,6 @@ static int sd_init_card(void)
318 return 0; 330 return 0;
319} 331}
320 332
321static void sd_thread(void) NORETURN_ATTR;
322static void sd_thread(void)
323{
324 struct queue_event ev;
325 bool idle_notified = false;
326
327 while (1)
328 {
329 queue_wait_w_tmo(&sd_queue, &ev, HZ);
330
331 switch ( ev.id )
332 {
333#ifdef HAVE_HOTSWAP
334 case SYS_HOTSWAP_INSERTED:
335 case SYS_HOTSWAP_EXTRACTED:;
336 int success = 1;
337
338 disk_unmount(sd_first_drive); /* release "by force" */
339
340 mutex_lock(&sd_mtx); /* lock-out card activity */
341
342 /* Force card init for new card, re-init for re-inserted one or
343 * clear if the last attempt to init failed with an error. */
344 card_info.initialized = 0;
345
346 if (ev.id == SYS_HOTSWAP_INSERTED)
347 {
348 success = 0;
349 sd_enable(true);
350 int rc = sd_init_card(sd_first_drive);
351 sd_enable(false);
352 if (rc >= 0)
353 success = 2;
354 else /* initialisation failed */
355 panicf("microSD init failed : %d", rc);
356 }
357
358 /* Access is now safe */
359 mutex_unlock(&sd_mtx);
360
361 if (success > 1)
362 success = disk_mount(sd_first_drive); /* 0 if fail */
363
364 /*
365 * Mount succeeded, or this was an EXTRACTED event,
366 * in both cases notify the system about the changed filesystems
367 */
368 if (success)
369 queue_broadcast(SYS_FS_CHANGED, 0);
370
371 break;
372#endif /* HAVE_HOTSWAP */
373
374 case SYS_TIMEOUT:
375 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
376 {
377 idle_notified = false;
378 }
379 else if (!idle_notified)
380 {
381 call_storage_idle_notifys(false);
382 idle_notified = true;
383 }
384 break;
385
386 case SYS_USB_CONNECTED:
387 usb_acknowledge(SYS_USB_CONNECTED_ACK);
388 /* Wait until the USB cable is extracted again */
389 usb_wait_for_disconnect(&sd_queue);
390
391 break;
392 }
393 }
394}
395
396static void init_controller(void) 333static void init_controller(void)
397{ 334{
398 /* reset SD module */ 335 /* reset SD module */
@@ -441,6 +378,7 @@ int sd_init(void)
441{ 378{
442 int ret; 379 int ret;
443 380
381 mutex_init(&sd_mtx);
444 semaphore_init(&transfer_completion_signal, 1, 0); 382 semaphore_init(&transfer_completion_signal, 1, 0);
445 semaphore_init(&command_completion_signal, 1, 0); 383 semaphore_init(&command_completion_signal, 1, 0);
446 384
@@ -450,13 +388,6 @@ int sd_init(void)
450 if(ret < 0) 388 if(ret < 0)
451 return ret; 389 return ret;
452 390
453 /* init mutex */
454 mutex_init(&sd_mtx);
455
456 queue_init(&sd_queue, true);
457 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
458 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
459
460 return 0; 391 return 0;
461} 392}
462 393
@@ -523,7 +454,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
523 unsigned char *dst; 454 unsigned char *dst;
524 455
525 mutex_lock(&sd_mtx); 456 mutex_lock(&sd_mtx);
526 sd_enable(true); 457 enable_controller(true);
527 458
528 if (count <= 0 || start + count > card_info.numblocks) 459 if (count <= 0 || start + count > card_info.numblocks)
529 return -1; 460 return -1;
@@ -627,7 +558,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
627 558
628 } /* while (retry_cnt++ < 20) */ 559 } /* while (retry_cnt++ < 20) */
629 560
630 sd_enable(false); 561 enable_controller(false);
631 mutex_unlock(&sd_mtx); 562 mutex_unlock(&sd_mtx);
632 563
633 return ret; 564 return ret;
@@ -659,7 +590,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
659 /* bool card_selected = false; */ 590 /* bool card_selected = false; */
660 591
661 mutex_lock(&sd_mtx); 592 mutex_lock(&sd_mtx);
662 sd_enable(true); 593 enable_controller(true);
663 594
664 if (count <= 0 || start + count > card_info.numblocks) 595 if (count <= 0 || start + count > card_info.numblocks)
665 return -1; 596 return -1;
@@ -731,7 +662,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
731 break; 662 break;
732 } 663 }
733 664
734 sd_enable(false); 665 enable_controller(false);
735 mutex_unlock(&sd_mtx); 666 mutex_unlock(&sd_mtx);
736 667
737#ifdef RK27XX_SD_DEBUG 668#ifdef RK27XX_SD_DEBUG
@@ -746,17 +677,9 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
746 677
747void sd_enable(bool on) 678void sd_enable(bool on)
748{ 679{
749 /* enable or disable clock signal for SD module */ 680 mutex_lock(&sd_mtx);
750 if (on) 681 enable_controller(on);
751 { 682 mutex_unlock(&sd_mtx);
752 SCU_CLKCFG &= ~CLKCFG_SD;
753 led(true);
754 }
755 else
756 {
757 SCU_CLKCFG |= CLKCFG_SD;
758 led(false);
759 }
760} 683}
761 684
762#ifndef BOOTLOADER 685#ifndef BOOTLOADER
@@ -788,18 +711,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
788 711
789static int sd_oneshot_callback(struct timeout *tmo) 712static int sd_oneshot_callback(struct timeout *tmo)
790{ 713{
791 (void)tmo;
792
793 /* This is called only if the state was stable for 300ms - check state 714 /* This is called only if the state was stable for 300ms - check state
794 * and post appropriate event. */ 715 * and post appropriate event. */
795 if (card_detect_target()) 716 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
796 { 717 SYS_HOTSWAP_EXTRACTED,
797 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 718 sd_first_drive);
798 }
799 else
800 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
801
802 return 0; 719 return 0;
720 (void)tmo;
803} 721}
804 722
805/* interrupt handler for SD detect */ 723/* interrupt handler for SD detect */
@@ -809,9 +727,42 @@ static int sd_oneshot_callback(struct timeout *tmo)
809#ifdef CONFIG_STORAGE_MULTI 727#ifdef CONFIG_STORAGE_MULTI
810int sd_num_drives(int first_drive) 728int sd_num_drives(int first_drive)
811{ 729{
812 (void)first_drive;
813
814 /* we have only one SD drive */ 730 /* we have only one SD drive */
731 sd_first_drive = first_drive;
815 return 1; 732 return 1;
816} 733}
817#endif /* CONFIG_STORAGE_MULTI */ 734#endif /* CONFIG_STORAGE_MULTI */
735
736int sd_event(long id, intptr_t data)
737{
738 int rc = 0;
739
740 switch (id)
741 {
742#ifdef HAVE_HOTSWAP
743 case SYS_HOTSWAP_INSERTED:
744 case SYS_HOTSWAP_EXTRACTED:
745 mutex_lock(&sd_mtx); /* lock-out card activity */
746
747 /* Force card init for new card, re-init for re-inserted one or
748 * clear if the last attempt to init failed with an error. */
749 card_info.initialized = 0;
750
751 if (id == SYS_HOTSWAP_INSERTED)
752 {
753 enable_controller(true);
754 rc = sd_init_card();
755 enable_controller(false);
756 }
757
758 mutex_unlock(&sd_mtx);
759 break;
760#endif /* HAVE_HOTSWAP */
761 default:
762 rc = storage_event_default_handler(id, data, last_disk_activity,
763 STORAGE_SD);
764 break;
765 }
766
767 return rc;
768}
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
index 7ca7d77c4f..5403b2418a 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
@@ -21,10 +21,6 @@
21#ifndef ATA_TARGET_H 21#ifndef ATA_TARGET_H
22#define ATA_TARGET_H 22#define ATA_TARGET_H
23 23
24#ifdef BOOTLOADER
25#define ATA_DRIVER_CLOSE
26#endif
27
28/* Plain C read & write loops */ 24/* Plain C read & write loops */
29#define PREFER_C_READING 25#define PREFER_C_READING
30#define PREFER_C_WRITING 26#define PREFER_C_WRITING
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index e8de3ac78d..2ff68aa4ee 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -21,11 +21,9 @@
21 21
22//#define SD_DEBUG 22//#define SD_DEBUG
23 23
24#include "sd.h"
25#include "system.h" 24#include "system.h"
26#include <string.h> 25#include <string.h>
27#include "gcc_extensions.h" 26#include "gcc_extensions.h"
28#include "thread.h"
29#include "panic.h" 27#include "panic.h"
30 28
31#ifdef SD_DEBUG 29#ifdef SD_DEBUG
@@ -33,8 +31,8 @@
33#endif 31#endif
34#ifdef HAVE_HOTSWAP 32#ifdef HAVE_HOTSWAP
35#include "sdmmc.h" 33#include "sdmmc.h"
36#include "disk.h"
37#endif 34#endif
35#include "storage.h"
38#include "dma-target.h" 36#include "dma-target.h"
39#include "system-target.h" 37#include "system-target.h"
40#include "led-mini2440.h" 38#include "led-mini2440.h"
@@ -90,6 +88,12 @@ struct sd_card_status
90/* for compatibility */ 88/* for compatibility */
91static long last_disk_activity = -1; 89static long last_disk_activity = -1;
92 90
91#ifdef CONFIG_STORAGE_MULTI
92static int sd_first_drive = 0;
93#else
94#define sd_first_drive 0
95#endif
96
93static bool initialized = false; 97static bool initialized = false;
94static bool sd_enabled = false; 98static bool sd_enabled = false;
95static long next_yield = 0; 99static long next_yield = 0;
@@ -109,11 +113,7 @@ static struct sd_card_status sd_status[NUM_CARDS] =
109#endif 113#endif
110#endif 114#endif
111 115
112/* Shoot for around 75% usage */
113static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
114static const char sd_thread_name[] = "sd";
115static struct mutex sd_mtx SHAREDBSS_ATTR; 116static struct mutex sd_mtx SHAREDBSS_ATTR;
116static struct event_queue sd_queue;
117static struct semaphore transfer_completion_signal; 117static struct semaphore transfer_completion_signal;
118static volatile unsigned int transfer_error[NUM_DRIVES]; 118static volatile unsigned int transfer_error[NUM_DRIVES];
119/* align on cache line size */ 119/* align on cache line size */
@@ -511,17 +511,13 @@ static inline bool card_detect_target(void)
511 511
512static int sd1_oneshot_callback(struct timeout *tmo) 512static int sd1_oneshot_callback(struct timeout *tmo)
513{ 513{
514 (void)tmo;
515
516 /* This is called only if the state was stable for 300ms - check state 514 /* This is called only if the state was stable for 300ms - check state
517 * and post appropriate event. */ 515 * and post appropriate event. */
518 if (card_detect_target()) 516 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
519 { 517 SYS_HOTSWAP_EXTRACTED,
520 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 518 sd_first_drive + CARD_NUM_SLOT);
521 }
522 else
523 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
524 return 0; 519 return 0;
520 (void)tmo;
525} 521}
526 522
527void EINT8_23(void) 523void EINT8_23(void)
@@ -571,46 +567,6 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
571#endif /* HAVE_HOTSWAP */ 567#endif /* HAVE_HOTSWAP */
572/*****************************************************************************/ 568/*****************************************************************************/
573 569
574static void sd_thread(void) NORETURN_ATTR;
575static void sd_thread(void)
576{
577 struct queue_event ev;
578
579 /* TODO */
580 while (1)
581 {
582 queue_wait_w_tmo(&sd_queue, &ev, HZ);
583 switch ( ev.id )
584 {
585#ifdef HAVE_HOTSWAP
586 case SYS_HOTSWAP_INSERTED:
587 case SYS_HOTSWAP_EXTRACTED:;
588 int success = 1;
589
590 disk_unmount(0); /* release "by force" */
591
592 mutex_lock(&sd_mtx); /* lock-out card activity */
593
594 /* Force card init for new card, re-init for re-inserted one or
595 * clear if the last attempt to init failed with an error. */
596 card_info[0].initialized = 0;
597
598 /* Access is now safe */
599 mutex_unlock(&sd_mtx);
600
601 if (ev.id == SYS_HOTSWAP_INSERTED)
602 success = disk_mount(0); /* 0 if fail */
603
604 /* notify the system about the changed filesystems
605 */
606 if (success)
607 queue_broadcast(SYS_FS_CHANGED, 0);
608 break;
609#endif /* HAVE_HOTSWAP */
610 }
611 }
612}
613
614static int sd_wait_for_state(const int card_no, unsigned int state) 570static int sd_wait_for_state(const int card_no, unsigned int state)
615{ 571{
616 unsigned long response = 0; 572 unsigned long response = 0;
@@ -907,9 +863,6 @@ int sd_init(void)
907 semaphore_init(&transfer_completion_signal, 1, 0); 863 semaphore_init(&transfer_completion_signal, 1, 0);
908 /* init mutex */ 864 /* init mutex */
909 mutex_init(&sd_mtx); 865 mutex_init(&sd_mtx);
910 queue_init(&sd_queue, true);
911 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
912 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
913 866
914 uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]); 867 uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
915 868
@@ -950,18 +903,11 @@ tCardInfo *card_get_info_target(int card_no)
950int sd_num_drives(int first_drive) 903int sd_num_drives(int first_drive)
951{ 904{
952 dbgprintf ("sd_num_drv"); 905 dbgprintf ("sd_num_drv");
953#if 0
954 /* Store which logical drive number(s) we have been assigned */ 906 /* Store which logical drive number(s) we have been assigned */
955 sd_first_drive = first_drive; 907 sd_first_drive = first_drive;
956#endif
957
958 return NUM_CARDS; 908 return NUM_CARDS;
959} 909}
960 910
961void sd_sleepnow(void)
962{
963}
964
965bool sd_disk_is_active(void) 911bool sd_disk_is_active(void)
966{ 912{
967 return false; 913 return false;
@@ -980,3 +926,27 @@ int sd_spinup_time(void)
980#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
981/*****************************************************************************/ 927/*****************************************************************************/
982 928
929int sd_event(long id, intptr_t data)
930{
931 int rc = 0;
932
933 switch (id)
934 {
935#ifdef HAVE_HOTSWAP
936 case SYS_HOTSWAP_INSERTED:
937 case SYS_HOTSWAP_EXTRACTED:
938 mutex_lock(&sd_mtx);
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942 mutex_unlock(&sd_mtx);
943 break;
944#endif /* HAVE_HOTSWAP */
945 default:
946 rc = storage_event_default_handler(id, data, last_disk_activity,
947 STORAGE_SD);
948 break;
949 }
950
951 return rc;
952}
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 227f6b703b..7f68b82a0d 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -52,7 +52,6 @@ void nand_spindown(int seconds)
52 52
53void nand_sleep(void) 53void nand_sleep(void)
54{ 54{
55 nand_power_down();
56} 55}
57 56
58void nand_sleepnow(void) 57void nand_sleepnow(void)
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
index 1698dc2b9b..4b74405c1c 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
@@ -31,8 +31,7 @@
31#include <mmu-arm.h> 31#include <mmu-arm.h>
32#include <string.h> 32#include <string.h>
33#include "led.h" 33#include "led.h"
34#include "ata_idle_notify.h" 34#include "storage.h"
35
36 35
37#define NAND_CMD_READ 0x00 36#define NAND_CMD_READ 0x00
38#define NAND_CMD_PROGCNFRM 0x10 37#define NAND_CMD_PROGCNFRM 0x10
@@ -91,7 +90,6 @@ static int nand_powered = 0;
91static int nand_interleaved = 0; 90static int nand_interleaved = 0;
92static int nand_cached = 0; 91static int nand_cached = 0;
93static long nand_last_activity_value = -1; 92static long nand_last_activity_value = -1;
94static long nand_stack[DEFAULT_STACK_SIZE];
95 93
96static struct mutex nand_mtx; 94static struct mutex nand_mtx;
97static struct semaphore nand_complete; 95static struct semaphore nand_complete;
@@ -359,20 +357,22 @@ void nand_power_up(void)
359 357
360void nand_power_down(void) 358void nand_power_down(void)
361{ 359{
362 if (!nand_powered) return;
363 mutex_lock(&nand_mtx); 360 mutex_lock(&nand_mtx);
364 pmu_ldo_power_off(4); 361 if (nand_powered)
365 PCON2 = 0x11111111; 362 {
366 PDAT2 = 0; 363 pmu_ldo_power_off(4);
367 PCON3 = 0x11111111; 364 PCON2 = 0x11111111;
368 PDAT3 = 0; 365 PDAT2 = 0;
369 PCON4 = 0x11111111; 366 PCON3 = 0x11111111;
370 PDAT4 = 0; 367 PDAT3 = 0;
371 PCON5 = (PCON5 & ~0xF) | 1; 368 PCON4 = 0x11111111;
372 PUNK5 = 1; 369 PDAT4 = 0;
373 PWRCONEXT |= 0x40; 370 PCON5 = (PCON5 & ~0xF) | 1;
374 PWRCON |= 0x100000; 371 PUNK5 = 1;
375 nand_powered = 0; 372 PWRCONEXT |= 0x40;
373 PWRCON |= 0x100000;
374 nand_powered = 0;
375 }
376 mutex_unlock(&nand_mtx); 376 mutex_unlock(&nand_mtx);
377} 377}
378 378
@@ -714,20 +714,6 @@ const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
714 return &nand_deviceinfotable[nand_type[bank]]; 714 return &nand_deviceinfotable[nand_type[bank]];
715} 715}
716 716
717static void nand_thread(void)
718{
719 while (1)
720 {
721 if (TIME_AFTER(current_tick, nand_last_activity_value + HZ / 5)
722 && nand_powered)
723 {
724 call_storage_idle_notifys(false);
725 nand_power_down();
726 }
727 sleep(HZ / 10);
728 }
729}
730
731int nand_device_init(void) 717int nand_device_init(void)
732{ 718{
733 mutex_init(&nand_mtx); 719 mutex_init(&nand_mtx);
@@ -776,10 +762,30 @@ int nand_device_init(void)
776 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1); 762 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1);
777 763
778 nand_last_activity_value = current_tick; 764 nand_last_activity_value = current_tick;
779 create_thread(nand_thread, nand_stack,
780 sizeof(nand_stack), 0, "nand"
781 IF_PRIO(, PRIORITY_USER_INTERFACE)
782 IF_COP(, CPU));
783
784 return 0; 765 return 0;
785} 766}
767
768int nand_event(long id, intptr_t data)
769{
770 int rc = 0;
771
772 if (LIKELY(id == Q_STORAGE_TICK))
773 {
774 if (!nand_powered ||
775 TIME_BEFORE(current_tick, nand_last_activity_value + HZ / 5))
776 {
777 STG_EVENT_ASSERT_ACTIVE(STORAGE_NAND);
778 }
779 }
780 else if (id == Q_STORAGE_SLEEPNOW)
781 {
782 nand_power_down();
783 }
784 else
785 {
786 rc = storage_event_default_handler(id, data, nand_last_activity_value,
787 STORAGE_NAND);
788 }
789
790 return rc;
791}
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index ef39a5cabb..36d119aff3 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -19,8 +19,6 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "thread.h"
23#include "disk.h"
24#include "storage.h" 22#include "storage.h"
25#include "timer.h" 23#include "timer.h"
26#include "kernel.h" 24#include "kernel.h"
@@ -31,8 +29,6 @@
31#include "mmcdefs-target.h" 29#include "mmcdefs-target.h"
32#include "s5l8702.h" 30#include "s5l8702.h"
33#include "led.h" 31#include "led.h"
34#include "ata_idle_notify.h"
35#include "disk_cache.h"
36 32
37 33
38#ifndef ATA_RETRIES 34#ifndef ATA_RETRIES
@@ -58,7 +54,6 @@ static struct semaphore ata_wakeup;
58static uint32_t ata_dma_flags; 54static uint32_t ata_dma_flags;
59static long ata_last_activity_value = -1; 55static long ata_last_activity_value = -1;
60static long ata_sleep_timeout = 20 * HZ; 56static long ata_sleep_timeout = 20 * HZ;
61static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
62static bool ata_powered; 57static bool ata_powered;
63static const int ata_retries = ATA_RETRIES; 58static const int ata_retries = ATA_RETRIES;
64static const bool ata_error_srst = true; 59static const bool ata_error_srst = true;
@@ -889,21 +884,6 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr
889 return 0; 884 return 0;
890} 885}
891 886
892static void ata_thread(void)
893{
894 while (true)
895 {
896 mutex_lock(&ata_mutex);
897 if (TIME_AFTER(current_tick, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
898 {
899 call_storage_idle_notifys(false);
900 ata_power_down();
901 }
902 mutex_unlock(&ata_mutex);
903 sleep(HZ / 2);
904 }
905}
906
907/* API Functions */ 887/* API Functions */
908int ata_soft_reset(void) 888int ata_soft_reset(void)
909{ 889{
@@ -982,11 +962,6 @@ void ata_spindown(int seconds)
982 ata_sleep_timeout = seconds * HZ; 962 ata_sleep_timeout = seconds * HZ;
983} 963}
984 964
985void ata_sleep(void)
986{
987 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
988}
989
990void ata_sleepnow(void) 965void ata_sleepnow(void)
991{ 966{
992 mutex_lock(&ata_mutex); 967 mutex_lock(&ata_mutex);
@@ -994,11 +969,6 @@ void ata_sleepnow(void)
994 mutex_unlock(&ata_mutex); 969 mutex_unlock(&ata_mutex);
995} 970}
996 971
997void ata_close(void)
998{
999 ata_sleepnow();
1000}
1001
1002void ata_spin(void) 972void ata_spin(void)
1003{ 973{
1004 ata_set_active(); 974 ata_set_active();
@@ -1034,10 +1004,6 @@ int ata_init(void)
1034 mutex_unlock(&ata_mutex); 1004 mutex_unlock(&ata_mutex);
1035 if (IS_ERR(rc)) return rc; 1005 if (IS_ERR(rc)) return rc;
1036 1006
1037 create_thread(ata_thread, ata_stack,
1038 sizeof(ata_stack), 0, "ATA idle monitor"
1039 IF_PRIO(, PRIORITY_USER_INTERFACE)
1040 IF_COP(, CPU));
1041 return 0; 1007 return 0;
1042} 1008}
1043 1009
@@ -1129,3 +1095,38 @@ void INT_MMC(void)
1129 SDCI_IRQ = irq; 1095 SDCI_IRQ = irq;
1130} 1096}
1131 1097
1098int ata_event(long id, intptr_t data)
1099{
1100 int rc = 0;
1101
1102 /* GCC does a lousy job culling unreachable cases in the default handler
1103 if statements are in a switch statement, so we'll do it this way. Only
1104 the first case is frequently hit anyway. */
1105 if (LIKELY(id == Q_STORAGE_TICK))
1106 {
1107 if (!ata_powered ||
1108 TIME_BEFORE(current_tick, ata_last_activity_value + ata_sleep_timeout))
1109 {
1110 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1111 }
1112 }
1113 else if (id == Q_STORAGE_SLEEPNOW)
1114 {
1115 ata_sleepnow();
1116 }
1117 else if (id == Q_STORAGE_SLEEP)
1118 {
1119 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
1120 }
1121 else if (id == SYS_USB_CONNECTED)
1122 {
1123 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1124 }
1125 else
1126 {
1127 rc = storage_event_default_handler(id, data, ata_last_activity_value,
1128 STORAGE_ATA);
1129 }
1130
1131 return rc;
1132}
diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c
index ba98539157..c80c3b746f 100644
--- a/firmware/target/arm/tcc780x/sd-tcc780x.c
+++ b/firmware/target/arm/tcc780x/sd-tcc780x.c
@@ -19,17 +19,13 @@
19 * KIND, either express or implied. 19 * KIND, either express or implied.
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22#include "sd.h" 22#include "config.h"
23#include "system.h" 23#include "system.h"
24#include <string.h> 24#include <string.h>
25#include "gcc_extensions.h" 25#include "gcc_extensions.h"
26#include "sdmmc.h" 26#include "sdmmc.h"
27#include "storage.h" 27#include "storage.h"
28#include "led.h" 28#include "led.h"
29#include "thread.h"
30#include "disk.h"
31#include "ata_idle_notify.h"
32#include "usb.h"
33 29
34#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) 30#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
35#define CARD_NUM_INTERNAL 0 31#define CARD_NUM_INTERNAL 0
@@ -55,9 +51,6 @@
55/* for compatibility */ 51/* for compatibility */
56static long last_disk_activity = -1; 52static long last_disk_activity = -1;
57 53
58/** static, private data **/
59static bool initialized = false;
60
61static long next_yield = 0; 54static long next_yield = 0;
62#define MIN_YIELD_PERIOD 1000 55#define MIN_YIELD_PERIOD 1000
63 56
@@ -80,14 +73,13 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
80#endif 73#endif
81}; 74};
82 75
83/* Shoot for around 75% usage */
84static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
85static const char sd_thread_name[] = "sd";
86static struct mutex sd_mtx SHAREDBSS_ATTR; 76static struct mutex sd_mtx SHAREDBSS_ATTR;
87static struct event_queue sd_queue;
88 77
78#ifdef CONFIG_STORAGE_MULTI
89static int sd_first_drive = 0; 79static int sd_first_drive = 0;
90 80#else
81#define sd_first_drive 0
82#endif
91 83
92static bool sd_poll_status(unsigned int trigger, long timeout) 84static bool sd_poll_status(unsigned int trigger, long timeout)
93{ 85{
@@ -216,16 +208,13 @@ static inline bool card_detect_target(void)
216 208
217static int sd1_oneshot_callback(struct timeout *tmo) 209static int sd1_oneshot_callback(struct timeout *tmo)
218{ 210{
219 (void)tmo;
220
221 /* This is called only if the state was stable for 300ms - check state 211 /* This is called only if the state was stable for 300ms - check state
222 * and post appropriate event. */ 212 * and post appropriate event. */
223 if (card_detect_target()) 213 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
224 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 214 SYS_HOTSWAP_EXTRACTED,
225 else 215 sd_first_drive + CARD_NUM_SLOT);
226 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
227
228 return 0; 216 return 0;
217 (void)tmo;
229} 218}
230 219
231void EXT0(void) 220void EXT0(void)
@@ -642,71 +631,6 @@ sd_write_error:
642 } 631 }
643} 632}
644 633
645static void sd_thread(void) NORETURN_ATTR;
646static void sd_thread(void)
647{
648 struct queue_event ev;
649 bool idle_notified = false;
650
651 while (1)
652 {
653 queue_wait_w_tmo(&sd_queue, &ev, HZ);
654
655 switch ( ev.id )
656 {
657#ifdef HAVE_HOTSWAP
658 case SYS_HOTSWAP_INSERTED:
659 case SYS_HOTSWAP_EXTRACTED:;
660 int success = 1;
661
662 /* Release "by force" */
663 disk_unmount(sd_first_drive + CARD_NUM_SLOT);
664
665 mutex_lock(&sd_mtx); /* lock-out card activity */
666
667 /* Force card init for new card, re-init for re-inserted one or
668 * clear if the last attempt to init failed with an error. */
669 card_info[CARD_NUM_SLOT].initialized = 0;
670 sd_status[CARD_NUM_SLOT].retry = 0;
671
672 mutex_unlock(&sd_mtx);
673
674 if (ev.id == SYS_HOTSWAP_INSERTED)
675 success = disk_mount(sd_first_drive + CARD_NUM_SLOT);
676
677 if (success)
678 queue_broadcast(SYS_FS_CHANGED, 0);
679
680 break;
681#endif /* HAVE_HOTSWAP */
682
683 case SYS_TIMEOUT:
684 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
685 {
686 idle_notified = false;
687 }
688 else
689 {
690 /* never let a timer wrap confuse us */
691 next_yield = USEC_TIMER;
692
693 if (!idle_notified)
694 {
695 call_storage_idle_notifys(false);
696 idle_notified = true;
697 }
698 }
699 break;
700
701 case SYS_USB_CONNECTED:
702 usb_acknowledge(SYS_USB_CONNECTED_ACK);
703 /* Wait until the USB cable is extracted again */
704 usb_wait_for_disconnect(&sd_queue);
705 break;
706 }
707 }
708}
709
710void sd_enable(bool on) 634void sd_enable(bool on)
711{ 635{
712 if(on) 636 if(on)
@@ -725,6 +649,7 @@ void sd_enable(bool on)
725 649
726int sd_init(void) 650int sd_init(void)
727{ 651{
652 static bool initialized = false;
728 int ret = 0; 653 int ret = 0;
729 654
730 if (!initialized) 655 if (!initialized)
@@ -752,11 +677,6 @@ int sd_init(void)
752 /* Configure card power(?) GPIO as output */ 677 /* Configure card power(?) GPIO as output */
753 GPIOC_DIR |= (1<<24); 678 GPIOC_DIR |= (1<<24);
754 679
755 queue_init(&sd_queue, true);
756 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
757 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
758 IF_COP(, CPU));
759
760 sleep(HZ/10); 680 sleep(HZ/10);
761 681
762#ifdef HAVE_HOTSWAP 682#ifdef HAVE_HOTSWAP
@@ -794,10 +714,6 @@ int sd_num_drives(int first_drive)
794#endif 714#endif
795} 715}
796 716
797void sd_sleepnow(void)
798{
799}
800
801bool sd_disk_is_active(void) 717bool sd_disk_is_active(void)
802{ 718{
803 return false; 719 return false;
@@ -814,3 +730,28 @@ int sd_spinup_time(void)
814} 730}
815 731
816#endif /* CONFIG_STORAGE_MULTI */ 732#endif /* CONFIG_STORAGE_MULTI */
733
734int sd_event(long id, intptr_t data)
735{
736 int rc = 0;
737
738 switch (id)
739 {
740#ifdef HAVE_HOTSWAP
741 case SYS_HOTSWAP_INSERTED:
742 case SYS_HOTSWAP_EXTRACTED:
743 mutex_lock(&sd_mtx);
744 /* Force card init for new card, re-init for re-inserted one or
745 * clear if the last attempt to init failed with an error. */
746 card_info[data].initialized = 0;
747 sd_status[data].retry = 0;
748 mutex_unlock(&sd_mtx);
749 break;
750#endif /* HAVE_HOTSWAP */
751 default:
752 rc = storage_event_default_handler(id, data, last_disk_activity, STORAGE_SD);
753 break;
754 }
755
756 return rc;
757}
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
index a6e261bcfa..8818d645d8 100644
--- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -19,13 +19,10 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "sd.h"
23#include "system.h" 22#include "system.h"
24#include <string.h> 23#include <string.h>
25#include "gcc_extensions.h" 24#include "gcc_extensions.h"
26#include "thread.h"
27#include "panic.h" 25#include "panic.h"
28#include "kernel.h"
29#include "dma-target.h" 26#include "dma-target.h"
30#include "ata_idle_notify.h" 27#include "ata_idle_notify.h"
31 28
@@ -42,8 +39,8 @@
42#endif 39#endif
43#endif 40#endif
44#include "sdmmc.h" 41#include "sdmmc.h"
45#include "disk.h"
46#include "system-target.h" 42#include "system-target.h"
43#include "storage.h"
47 44
48/* The configuration method is not very flexible. */ 45/* The configuration method is not very flexible. */
49#define CARD_NUM_SLOT 1 46#define CARD_NUM_SLOT 1
@@ -105,7 +102,6 @@ struct sd_card_status
105static long last_disk_activity = -1; 102static long last_disk_activity = -1;
106 103
107static bool initialized = false; 104static bool initialized = false;
108static unsigned int sd_thread_id = 0;
109 105
110static bool sd_enabled = false; 106static bool sd_enabled = false;
111static long next_yield = 0; 107static long next_yield = 0;
@@ -122,10 +118,7 @@ static struct sd_card_status sd_status[NUM_CARDS] =
122}; 118};
123 119
124/* Shoot for around 75% usage */ 120/* Shoot for around 75% usage */
125static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
126static const char sd_thread_name[] = "sd";
127static struct mutex sd_mtx SHAREDBSS_ATTR; 121static struct mutex sd_mtx SHAREDBSS_ATTR;
128static struct event_queue sd_queue;
129static volatile unsigned int transfer_error[NUM_DRIVES]; 122static volatile unsigned int transfer_error[NUM_DRIVES];
130/* align on cache line size */ 123/* align on cache line size */
131static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 124static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
@@ -154,20 +147,16 @@ static void sd_card_mux(int card_no)
154#endif 147#endif
155} 148}
156 149
150static inline void enable_controller(bool on)
151{
152 sd_enabled = on;
153}
157 154
158void sd_enable(bool on) 155void sd_enable(bool on)
159{ 156{
160 if (sd_enabled == on) 157 mutex_lock(&sd_mtx);
161 return; /* nothing to do */ 158 enable_controller(on);
162 159 mutex_unlock(&sd_mtx);
163 if (on)
164 {
165 sd_enabled = true;
166 }
167 else
168 {
169 sd_enabled = false;
170 }
171} 160}
172 161
173/* sets clock rate just like OF does */ 162/* sets clock rate just like OF does */
@@ -514,17 +503,13 @@ static inline bool card_detect_target(void)
514 503
515static int sd1_oneshot_callback(struct timeout *tmo) 504static int sd1_oneshot_callback(struct timeout *tmo)
516{ 505{
517 (void)tmo;
518
519 /* This is called only if the state was stable for 300ms - check state 506 /* This is called only if the state was stable for 300ms - check state
520 * and post appropriate event. */ 507 * and post appropriate event. */
521 if (card_detect_target()) 508 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
522 { 509 SYS_HOTSWAP_EXTRACTED,
523 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 510 CARD_NUM_SLOT);
524 }
525 else
526 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
527 return 0; 511 return 0;
512 (void)tmo;
528} 513}
529 514
530#ifdef SANSA_CONNECT 515#ifdef SANSA_CONNECT
@@ -577,57 +562,6 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
577 562
578#endif /* HAVE_HOTSWAP */ 563#endif /* HAVE_HOTSWAP */
579 564
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589 switch ( ev.id )
590 {
591#ifdef HAVE_HOTSWAP
592 case SYS_HOTSWAP_INSERTED:
593 case SYS_HOTSWAP_EXTRACTED:;
594 int success = 1;
595
596 disk_unmount(0); /* release "by force" */
597
598 mutex_lock(&sd_mtx); /* lock-out card activity */
599
600 /* Force card init for new card, re-init for re-inserted one or
601 * clear if the last attempt to init failed with an error. */
602 card_info[0].initialized = 0;
603
604 mutex_unlock(&sd_mtx);
605
606 if (ev.id == SYS_HOTSWAP_INSERTED)
607 success = disk_mount(0); /* 0 if fail */
608
609 /* notify the system about the changed filesystems */
610 if (success)
611 queue_broadcast(SYS_FS_CHANGED, 0);
612
613 break;
614#endif /* HAVE_HOTSWAP */
615
616 case SYS_TIMEOUT:
617 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
618 {
619 idle_notified = false;
620 }
621 else if (!idle_notified)
622 {
623 call_storage_idle_notifys(false);
624 idle_notified = true;
625 }
626 break;
627 }
628 }
629}
630
631static int sd_wait_for_state(unsigned int state) 565static int sd_wait_for_state(unsigned int state)
632{ 566{
633 unsigned long response = 0; 567 unsigned long response = 0;
@@ -671,7 +605,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
671 605
672 dbgprintf("transfer %d %d %d", card_no, start, count); 606 dbgprintf("transfer %d %d %d", card_no, start, count);
673 mutex_lock(&sd_mtx); 607 mutex_lock(&sd_mtx);
674 sd_enable(true); 608 enable_controller(true);
675 609
676sd_transfer_retry: 610sd_transfer_retry:
677 if (card_no == CARD_NUM_SLOT && !card_detect_target()) 611 if (card_no == CARD_NUM_SLOT && !card_detect_target())
@@ -812,7 +746,7 @@ sd_transfer_retry:
812 746
813 while (1) 747 while (1)
814 { 748 {
815 sd_enable(false); 749 enable_controller(false);
816 mutex_unlock(&sd_mtx); 750 mutex_unlock(&sd_mtx);
817 751
818 return ret; 752 return ret;
@@ -860,14 +794,17 @@ int sd_init(void)
860{ 794{
861 int ret = EC_OK; 795 int ret = EC_OK;
862 796
863#ifndef BOOTLOADER 797 if (!initialized)
864 sd_enabled = true; 798 {
865 sd_enable(false); 799 mutex_init(&sd_mtx);
866#endif 800 initialized = true;
867 mutex_init(&sd_mtx); 801 }
868 802
869 mutex_lock(&sd_mtx); 803 mutex_lock(&sd_mtx);
870 initialized = true; 804
805#ifndef BOOTLOADER
806 enable_controller(false);
807#endif
871 808
872 /* based on linux/drivers/mmc/dm320mmc.c 809 /* based on linux/drivers/mmc/dm320mmc.c
873 Copyright (C) 2006 ZSI, All Rights Reserved. 810 Copyright (C) 2006 ZSI, All Rights Reserved.
@@ -919,12 +856,6 @@ int sd_init(void)
919 856
920 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */ 857 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */
921 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); 858 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8));
922
923 queue_init(&sd_queue, true);
924 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
925 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
926 IF_COP(, CPU));
927
928 mutex_unlock(&sd_mtx); 859 mutex_unlock(&sd_mtx);
929 860
930 return ret; 861 return ret;
@@ -940,7 +871,27 @@ tCardInfo *card_get_info_target(int card_no)
940 return &card_info[card_no]; 871 return &card_info[card_no];
941} 872}
942 873
943void sd_sleepnow(void) 874int sd_event(long id, intptr_t data)
944{ 875{
945} 876 int rc = 0;
946 877
878 switch (id)
879 {
880#ifdef HAVE_HOTSWAP
881 case SYS_HOTSWAP_INSERTED:
882 case SYS_HOTSWAP_EXTRACTED:
883 mutex_lock(&sd_mtx); /* lock-out card activity */
884 /* Force card init for new card, re-init for re-inserted one or
885 * clear if the last attempt to init failed with an error. */
886 card_info[data].initialized = 0;
887 mutex_unlock(&sd_mtx);
888 break;
889#endif /* HAVE_HOTSWAP */
890 default:
891 rc = storage_event_default_handler(id, data, last_disk_activity,
892 STORAGE_SD);
893 break;
894 }
895
896 return rc;
897}
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 0e74444cf3..3ddbff0510 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -22,32 +22,23 @@
22#include "config.h" 22#include "config.h"
23#include "gcc_extensions.h" 23#include "gcc_extensions.h"
24#include "jz4740.h" 24#include "jz4740.h"
25#include "ata.h"
26#include "ata_idle_notify.h"
27#include "ata-sd-target.h" 25#include "ata-sd-target.h"
28#include "disk.h"
29#include "led.h" 26#include "led.h"
30#include "sdmmc.h" 27#include "sdmmc.h"
31#include "logf.h" 28#include "logf.h"
32#include "sd.h"
33#include "system.h"
34#include "kernel.h"
35#include "storage.h" 29#include "storage.h"
36#include "string.h" 30#include "string.h"
37#include "usb.h"
38 31
39static long last_disk_activity = -1; 32static long last_disk_activity = -1;
40#if defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOTSWAP) 33#if defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOTSWAP)
41static int sd_drive_nr = 0; 34static int sd_drive_nr = 0;
35#else
36#define sd_drive_nr 0
42#endif 37#endif
43static tCardInfo card; 38static tCardInfo card;
44 39
45static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
46static const char sd_thread_name[] = "ata/sd";
47static struct event_queue sd_queue;
48static struct mutex sd_mtx; 40static struct mutex sd_mtx;
49static struct semaphore sd_wakeup; 41static struct semaphore sd_wakeup;
50static void sd_thread(void) NORETURN_ATTR;
51 42
52static int use_4bit; 43static int use_4bit;
53static int num_6; 44static int num_6;
@@ -1229,11 +1220,6 @@ int sd_init(void)
1229 { 1220 {
1230 semaphore_init(&sd_wakeup, 1, 0); 1221 semaphore_init(&sd_wakeup, 1, 0);
1231 mutex_init(&sd_mtx); 1222 mutex_init(&sd_mtx);
1232 queue_init(&sd_queue, true);
1233 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
1234 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1235 IF_COP(, CPU));
1236
1237 inited = true; 1223 inited = true;
1238 } 1224 }
1239 1225
@@ -1265,7 +1251,7 @@ static inline void sd_stop_transfer(void)
1265 mutex_unlock(&sd_mtx); 1251 mutex_unlock(&sd_mtx);
1266} 1252}
1267 1253
1268int sd_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 1254int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1269{ 1255{
1270#ifdef HAVE_MULTIVOLUME 1256#ifdef HAVE_MULTIVOLUME
1271 (void)drive; 1257 (void)drive;
@@ -1404,7 +1390,7 @@ int sd_soft_reset(void)
1404} 1390}
1405 1391
1406#ifdef HAVE_HOTSWAP 1392#ifdef HAVE_HOTSWAP
1407bool sd_removable(IF_MV_NONVOID(int drive)) 1393bool sd_removable(IF_MD_NONVOID(int drive))
1408{ 1394{
1409#ifdef HAVE_MULTIVOLUME 1395#ifdef HAVE_MULTIVOLUME
1410 (void)drive; 1396 (void)drive;
@@ -1414,19 +1400,16 @@ bool sd_removable(IF_MV_NONVOID(int drive))
1414 1400
1415static int sd_oneshot_callback(struct timeout *tmo) 1401static int sd_oneshot_callback(struct timeout *tmo)
1416{ 1402{
1417 (void)tmo;
1418 int state = card_detect_target(); 1403 int state = card_detect_target();
1419 1404
1420 /* This is called only if the state was stable for 300ms - check state 1405 /* This is called only if the state was stable for 300ms - check state
1421 * and post appropriate event. */ 1406 * and post appropriate event. */
1422 if (state) 1407 queue_broadcast(state ? SYS_HOTSWAP_INSERTED : SYS_HOTSWAP_EXTRACTED,
1423 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1408 sd_drive_nr);
1424 else
1425 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1426 1409
1427 sd_gpio_setup_irq(state); 1410 sd_gpio_setup_irq(state);
1428
1429 return 0; 1411 return 0;
1412 (void)tmo;
1430} 1413}
1431 1414
1432/* called on insertion/removal interrupt */ 1415/* called on insertion/removal interrupt */
@@ -1453,58 +1436,27 @@ int sd_num_drives(int first_drive)
1453} 1436}
1454#endif 1437#endif
1455 1438
1456static void sd_thread(void) 1439int sd_event(long id, intptr_t data)
1457{ 1440{
1458 struct queue_event ev; 1441 int rc = 0;
1459 bool idle_notified = false;
1460 1442
1461 while (1) 1443 switch (id)
1462 { 1444 {
1463 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1464
1465 switch (ev.id)
1466 {
1467#ifdef HAVE_HOTSWAP 1445#ifdef HAVE_HOTSWAP
1468 case SYS_HOTSWAP_INSERTED: 1446 case SYS_HOTSWAP_INSERTED:
1469 case SYS_HOTSWAP_EXTRACTED:; 1447 case SYS_HOTSWAP_EXTRACTED:
1470 int success = 1; 1448 mutex_lock(&sd_mtx); /* lock-out card activity */
1471 1449 /* Force card init for new card, re-init for re-inserted one or
1472 disk_unmount(sd_drive_nr); /* release "by force" */ 1450 * clear if the last attempt to init failed with an error. */
1473 1451 card.initialized = 0;
1474 mutex_lock(&sd_mtx); /* lock-out card activity */ 1452 mutex_unlock(&sd_mtx);
1475 1453 break;
1476 /* Force card init for new card, re-init for re-inserted one or
1477 * clear if the last attempt to init failed with an error. */
1478 card.initialized = 0;
1479
1480 mutex_unlock(&sd_mtx);
1481
1482 if(ev.id == SYS_HOTSWAP_INSERTED)
1483 success = disk_mount(sd_drive_nr); /* 0 if fail */
1484
1485 if(success)
1486 queue_broadcast(SYS_FS_CHANGED, 0);
1487
1488 break;
1489#endif /* HAVE_HOTSWAP */ 1454#endif /* HAVE_HOTSWAP */
1490 1455 default:
1491 case SYS_TIMEOUT: 1456 rc = storage_event_default_handler(id, data, last_disk_activity,
1492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) 1457 STORAGE_SD);
1493 idle_notified = false; 1458 break;
1494 else
1495 {
1496 if (!idle_notified)
1497 {
1498 call_storage_idle_notifys(false);
1499 idle_notified = true;
1500 }
1501 }
1502 break;
1503 case SYS_USB_CONNECTED:
1504 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1505 /* Wait until the USB cable is extracted again */
1506 usb_wait_for_disconnect(&sd_queue);
1507 break;
1508 }
1509 } 1459 }
1460
1461 return rc;
1510} 1462}
diff --git a/firmware/target/sh/archos/ondio/ata_mmc.c b/firmware/target/sh/archos/ondio/ata_mmc.c
index 5d95a0e789..f252e1c4ce 100644
--- a/firmware/target/sh/archos/ondio/ata_mmc.c
+++ b/firmware/target/sh/archos/ondio/ata_mmc.c
@@ -18,27 +18,29 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdbool.h> 21#include "config.h"
22#include "mmc.h"
23#include "ata_mmc.h" 22#include "ata_mmc.h"
24#include "sdmmc.h" 23#include "sdmmc.h"
25#include "ata_idle_notify.h"
26#include "kernel.h" 24#include "kernel.h"
27#include "thread.h"
28#include "led.h" 25#include "led.h"
29#include "sh7034.h" 26#include "sh7034.h"
30#include "system.h" 27#include "system.h"
31#include "debug.h" 28#include "debug.h"
32#include "panic.h" 29#include "panic.h"
33#include "usb.h"
34#include "power.h" 30#include "power.h"
35#include "string.h" 31#include "string.h"
36#include "hwcompat.h" 32#include "hwcompat.h"
37#include "adc.h" 33#include "adc.h"
38#include "bitswap.h" 34#include "bitswap.h"
39#include "disk.h" /* for mount/unmount */
40#include "storage.h" 35#include "storage.h"
41 36
37
38#ifdef HAVE_MULTIDRIVE
39#define MMC_NUM_DRIVES 2
40#else
41#define MMC_NUM_DRIVES 1
42#endif
43
42#define BLOCK_SIZE 512 /* fixed */ 44#define BLOCK_SIZE 512 /* fixed */
43 45
44/* Command definitions */ 46/* Command definitions */
@@ -90,15 +92,14 @@ static long last_disk_activity = -1;
90 92
91/* private variables */ 93/* private variables */
92 94
93static struct mutex mmc_mutex SHAREDBSS_ATTR; 95#ifdef CONFIG_STORAGE_MULTI
94 96static int mmc_first_drive = 0;
95#ifdef HAVE_HOTSWAP
96static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)];
97#else 97#else
98static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)]; 98#define mmc_first_drive 0
99#endif 99#endif
100static const char mmc_thread_name[] = "mmc"; 100
101static struct event_queue mmc_queue SHAREDBSS_ATTR; 101static struct mutex mmc_mutex SHAREDBSS_ATTR;
102
102static bool initialized = false; 103static bool initialized = false;
103static bool new_mmc_circuit; 104static bool new_mmc_circuit;
104 105
@@ -158,6 +159,21 @@ static void mmc_tick(void);
158 159
159/* implementation */ 160/* implementation */
160 161
162static void enable_controller(bool on)
163{
164 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
165 * if not modified below */
166 if (on)
167 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
168
169 and_b(~0x80, &PADRL); /* assert flash reset */
170 sleep(HZ/100);
171 or_b(0x80, &PADRL); /* de-assert flash reset */
172 sleep(HZ/100);
173 card_info[0].initialized = false;
174 card_info[1].initialized = false;
175}
176
161void mmc_enable_int_flash_clock(bool on) 177void mmc_enable_int_flash_clock(bool on)
162{ 178{
163 /* Internal flash clock is enabled by setting PA12 high with the new 179 /* Internal flash clock is enabled by setting PA12 high with the new
@@ -763,51 +779,6 @@ bool mmc_disk_is_active(void)
763 return mutex_test(&mmc_mutex); 779 return mutex_test(&mmc_mutex);
764} 780}
765 781
766static void mmc_thread(void)
767{
768 struct queue_event ev;
769 bool idle_notified = false;
770
771 while (1) {
772 queue_wait_w_tmo(&mmc_queue, &ev, HZ);
773 switch ( ev.id )
774 {
775 case SYS_USB_CONNECTED:
776 usb_acknowledge(SYS_USB_CONNECTED_ACK);
777 /* Wait until the USB cable is extracted again */
778 usb_wait_for_disconnect(&mmc_queue);
779 break;
780
781#ifdef HAVE_HOTSWAP
782 case SYS_HOTSWAP_INSERTED:
783 disk_mount(1); /* mount MMC */
784 queue_broadcast(SYS_FS_CHANGED, 0);
785 break;
786
787 case SYS_HOTSWAP_EXTRACTED:
788 disk_unmount(1); /* release "by force" */
789 queue_broadcast(SYS_FS_CHANGED, 0);
790 break;
791#endif
792
793 default:
794 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
795 {
796 idle_notified = false;
797 }
798 else
799 {
800 if (!idle_notified)
801 {
802 call_storage_idle_notifys(false);
803 idle_notified = true;
804 }
805 }
806 break;
807 }
808 }
809}
810
811bool mmc_detect(void) 782bool mmc_detect(void)
812{ 783{
813 return (adc_read(ADC_MMC_SWITCH) < 0x200); 784 return (adc_read(ADC_MMC_SWITCH) < 0x200);
@@ -868,11 +839,11 @@ static void mmc_tick(void)
868 { 839 {
869 if (current_status) 840 if (current_status)
870 { 841 {
871 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 842 queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1);
872 } 843 }
873 else 844 else
874 { 845 {
875 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 846 queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1);
876 mmc_status = MMC_UNTOUCHED; 847 mmc_status = MMC_UNTOUCHED;
877 card_info[1].initialized = false; 848 card_info[1].initialized = false;
878 } 849 }
@@ -882,17 +853,9 @@ static void mmc_tick(void)
882 853
883void mmc_enable(bool on) 854void mmc_enable(bool on)
884{ 855{
885 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, 856 mutex_lock(&mmc_mutex);
886 * if not modified below */ 857 enable_controller(on);
887 if (on) 858 mutex_unlock(&mmc_mutex);
888 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
889
890 and_b(~0x80, &PADRL); /* assert flash reset */
891 sleep(HZ/100);
892 or_b(0x80, &PADRL); /* de-assert flash reset */
893 sleep(HZ/100);
894 card_info[0].initialized = false;
895 card_info[1].initialized = false;
896} 859}
897 860
898int mmc_init(void) 861int mmc_init(void)
@@ -900,10 +863,8 @@ int mmc_init(void)
900 int rc = 0; 863 int rc = 0;
901 864
902 if (!initialized) 865 if (!initialized)
903 {
904 mutex_init(&mmc_mutex); 866 mutex_init(&mmc_mutex);
905 queue_init(&mmc_queue, true); 867
906 }
907 mutex_lock(&mmc_mutex); 868 mutex_lock(&mmc_mutex);
908 led(false); 869 led(false);
909 870
@@ -933,15 +894,10 @@ int mmc_init(void)
933 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ 894 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
934 895
935 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); 896 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
936
937 create_thread(mmc_thread, mmc_stack,
938 sizeof(mmc_stack), 0, mmc_thread_name
939 IF_PRIO(, PRIORITY_SYSTEM)
940 IF_COP(, CPU));
941 tick_add_task(mmc_tick); 897 tick_add_task(mmc_tick);
942 initialized = true; 898 initialized = true;
943 } 899 }
944 mmc_enable(true); 900 enable_controller(true);
945 901
946 mutex_unlock(&mmc_mutex); 902 mutex_unlock(&mmc_mutex);
947 return rc; 903 return rc;
@@ -998,11 +954,6 @@ bool mmc_present(IF_MD_NONVOID(int drive))
998} 954}
999#endif 955#endif
1000 956
1001
1002void mmc_sleep(void)
1003{
1004}
1005
1006void mmc_spin(void) 957void mmc_spin(void)
1007{ 958{
1008} 959}
@@ -1015,13 +966,13 @@ void mmc_spindown(int seconds)
1015#ifdef CONFIG_STORAGE_MULTI 966#ifdef CONFIG_STORAGE_MULTI
1016int mmc_num_drives(int first_drive) 967int mmc_num_drives(int first_drive)
1017{ 968{
1018 /* We don't care which logical drive number(s) we have been assigned */ 969 mmc_first_drive = first_drive;
1019 (void)first_drive; 970 return MMC_NUM_DRIVES;
1020 971}
1021#ifdef HAVE_MULTIDRIVE 972#endif /* CONFIG_STORAGE_MULTI */
1022 return 2; 973
1023#else 974int mmc_event(long id, intptr_t data)
1024 return 1; 975{
1025#endif 976 return storage_event_default_handler(id, data, last_disk_activity,
977 STORAGE_MMC);
1026} 978}
1027#endif