summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/common/dircache.c8
-rw-r--r--firmware/common/disk.c2
-rw-r--r--firmware/drivers/fat.c18
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/export/storage.h20
-rw-r--r--firmware/export/thread.h10
-rw-r--r--firmware/storage.c223
-rw-r--r--firmware/thread.c19
-rw-r--r--firmware/usbstack/usb_storage.c8
10 files changed, 216 insertions, 98 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index e4bdca258e..fe97fe2253 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -152,9 +152,7 @@ drivers/sd.c
152#if (CONFIG_STORAGE & STORAGE_RAMDISK) 152#if (CONFIG_STORAGE & STORAGE_RAMDISK)
153drivers/ramdisk.c 153drivers/ramdisk.c
154#endif 154#endif
155#ifdef CONFIG_STORAGE_MULTI
156storage.c 155storage.c
157#endif
158drivers/fat.c 156drivers/fat.c
159#if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD) 157#if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
160hotswap.c 158hotswap.c
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 9f19ac3d24..8b9be78b35 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -40,6 +40,7 @@
40#include "file.h" 40#include "file.h"
41#include "buffer.h" 41#include "buffer.h"
42#include "dir.h" 42#include "dir.h"
43#include "storage.h"
43#if CONFIG_RTC 44#if CONFIG_RTC
44#include "time.h" 45#include "time.h"
45#include "timefuncs.h" 46#include "timefuncs.h"
@@ -760,6 +761,7 @@ void* dircache_steal_buffer(long *size)
760void dircache_init(void) 761void dircache_init(void)
761{ 762{
762 int i; 763 int i;
764 int thread_id;
763 765
764 dircache_initialized = false; 766 dircache_initialized = false;
765 dircache_initializing = false; 767 dircache_initializing = false;
@@ -771,10 +773,14 @@ void dircache_init(void)
771 } 773 }
772 774
773 queue_init(&dircache_queue, true); 775 queue_init(&dircache_queue, true);
774 create_thread(dircache_thread, dircache_stack, 776 thread_id = create_thread(dircache_thread, dircache_stack,
775 sizeof(dircache_stack), 0, dircache_thread_name 777 sizeof(dircache_stack), 0, dircache_thread_name
776 IF_PRIO(, PRIORITY_BACKGROUND) 778 IF_PRIO(, PRIORITY_BACKGROUND)
777 IF_COP(, CPU)); 779 IF_COP(, CPU));
780#ifdef HAVE_IO_PRIORITY
781 thread_set_io_priority(thread_id,IO_PRIORITY_BACKGROUND);
782#endif
783
778} 784}
779 785
780/** 786/**
diff --git a/firmware/common/disk.c b/firmware/common/disk.c
index c4553099ec..f8efe1c88b 100644
--- a/firmware/common/disk.c
+++ b/firmware/common/disk.c
@@ -82,7 +82,7 @@ struct partinfo* disk_init(IF_MD_NONVOID(int drive))
82 (void)drive; 82 (void)drive;
83#endif 83#endif
84 84
85 storage_read_sectors(drive, 0,1, &sector); 85 storage_read_sectors(IF_MD2(drive,) 0,1, &sector);
86 /* check that the boot sector is initialized */ 86 /* check that the boot sector is initialized */
87 if ( (sector[510] != 0x55) || 87 if ( (sector[510] != 0x55) ||
88 (sector[511] != 0xaa)) { 88 (sector[511] != 0xaa)) {
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index ff2bebce92..f93b32f832 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -311,7 +311,7 @@ int fat_mount(IF_MV2(int volume,) IF_MD2(int drive,) long startsector)
311#endif 311#endif
312 312
313 /* Read the sector */ 313 /* Read the sector */
314 rc = storage_read_sectors(drive, startsector,1,buf); 314 rc = storage_read_sectors(IF_MD2(drive,) startsector,1,buf);
315 if(rc) 315 if(rc)
316 { 316 {
317 DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc); 317 DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc);
@@ -433,7 +433,7 @@ int fat_mount(IF_MV2(int volume,) IF_MD2(int drive,) long startsector)
433#endif /* #ifdef HAVE_FAT16SUPPORT */ 433#endif /* #ifdef HAVE_FAT16SUPPORT */
434 { 434 {
435 /* Read the fsinfo sector */ 435 /* Read the fsinfo sector */
436 rc = storage_read_sectors(drive, 436 rc = storage_read_sectors(IF_MD2(drive,)
437 startsector + fat_bpb->bpb_fsinfo, 1, buf); 437 startsector + fat_bpb->bpb_fsinfo, 1, buf);
438 if (rc < 0) 438 if (rc < 0)
439 { 439 {
@@ -618,7 +618,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce,
618#endif 618#endif
619 619
620 /* Write to the first FAT */ 620 /* Write to the first FAT */
621 rc = storage_write_sectors(fce->fat_vol->drive, 621 rc = storage_write_sectors(IF_MD2(fce->fat_vol->drive,)
622 secnum, 1, 622 secnum, 1,
623 sectorbuf); 623 sectorbuf);
624 if(rc < 0) 624 if(rc < 0)
@@ -639,7 +639,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce,
639#else 639#else
640 secnum += fat_bpbs[0].fatsize; 640 secnum += fat_bpbs[0].fatsize;
641#endif 641#endif
642 rc = storage_write_sectors(fce->fat_vol->drive, 642 rc = storage_write_sectors(IF_MD2(fce->fat_vol->drive,)
643 secnum, 1, sectorbuf); 643 secnum, 1, sectorbuf);
644 if(rc < 0) 644 if(rc < 0)
645 { 645 {
@@ -685,7 +685,7 @@ static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,)
685 /* Load the sector if it is not cached */ 685 /* Load the sector if it is not cached */
686 if(!fce->inuse) 686 if(!fce->inuse)
687 { 687 {
688 rc = storage_read_sectors(fat_bpb->drive, 688 rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
689 secnum + fat_bpb->startsector,1, 689 secnum + fat_bpb->startsector,1,
690 sectorbuf); 690 sectorbuf);
691 if(rc < 0) 691 if(rc < 0)
@@ -944,7 +944,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
944#endif /* #ifdef HAVE_FAT16SUPPORT */ 944#endif /* #ifdef HAVE_FAT16SUPPORT */
945 945
946 /* update fsinfo */ 946 /* update fsinfo */
947 rc = storage_read_sectors(fat_bpb->drive, 947 rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
948 fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); 948 fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo);
949 if (rc < 0) 949 if (rc < 0)
950 { 950 {
@@ -957,7 +957,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
957 intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]); 957 intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]);
958 *intptr = htole32(fat_bpb->fsinfo.nextfree); 958 *intptr = htole32(fat_bpb->fsinfo.nextfree);
959 959
960 rc = storage_write_sectors(fat_bpb->drive, 960 rc = storage_write_sectors(IF_MD2(fat_bpb->drive,)
961 fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); 961 fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo);
962 if (rc < 0) 962 if (rc < 0)
963 { 963 {
@@ -2110,11 +2110,11 @@ static int transfer(IF_MV2(struct bpb* fat_bpb,)
2110 if (start + count > fat_bpb->totalsectors) 2110 if (start + count > fat_bpb->totalsectors)
2111 panicf("Write %ld after data\n", 2111 panicf("Write %ld after data\n",
2112 start + count - fat_bpb->totalsectors); 2112 start + count - fat_bpb->totalsectors);
2113 rc = storage_write_sectors(fat_bpb->drive, 2113 rc = storage_write_sectors(IF_MD2(fat_bpb->drive,)
2114 start + fat_bpb->startsector, count, buf); 2114 start + fat_bpb->startsector, count, buf);
2115 } 2115 }
2116 else 2116 else
2117 rc = storage_read_sectors(fat_bpb->drive, 2117 rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
2118 start + fat_bpb->startsector, count, buf); 2118 start + fat_bpb->startsector, count, buf);
2119 if (rc < 0) { 2119 if (rc < 0) {
2120 DEBUGF( "transfer() - Couldn't %s sector %lx" 2120 DEBUGF( "transfer() - Couldn't %s sector %lx"
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 9d8dc41111..858d9bf250 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -921,4 +921,8 @@ Lyre prototype 1 */
921#define HAVE_PLUGIN_CHECK_OPEN_CLOSE 921#define HAVE_PLUGIN_CHECK_OPEN_CLOSE
922#endif 922#endif
923 923
924#ifdef HAVE_DIRCACHE
925#define HAVE_IO_PRIORITY
926#endif
927
924#endif /* __CONFIG_H__ */ 928#endif /* __CONFIG_H__ */
diff --git a/firmware/export/storage.h b/firmware/export/storage.h
index 0096e87a8d..e62cf0d902 100644
--- a/firmware/export/storage.h
+++ b/firmware/export/storage.h
@@ -57,6 +57,7 @@ struct storage_info
57 */ 57 */
58 #define storage_num_drives() NUM_DRIVES 58 #define storage_num_drives() NUM_DRIVES
59 #if (CONFIG_STORAGE & STORAGE_ATA) 59 #if (CONFIG_STORAGE & STORAGE_ATA)
60 #define STORAGE_FUNCTION(NAME) (ata_## NAME)
60 #define storage_spindown ata_spindown 61 #define storage_spindown ata_spindown
61 #define storage_sleep ata_sleep 62 #define storage_sleep ata_sleep
62 #define storage_spin ata_spin 63 #define storage_spin ata_spin
@@ -67,8 +68,6 @@ struct storage_info
67 #define storage_soft_reset() ata_soft_reset() 68 #define storage_soft_reset() ata_soft_reset()
68 #define storage_init() ata_init() 69 #define storage_init() ata_init()
69 #define storage_close() ata_close() 70 #define storage_close() ata_close()
70 #define storage_read_sectors(drive, start, count, buf) ata_read_sectors(IF_MD2(drive,) start, count, buf)
71 #define storage_write_sectors(drive, start, count, buf) ata_write_sectors(IF_MD2(drive,) start, count, buf)
72 #ifdef HAVE_STORAGE_FLUSH 71 #ifdef HAVE_STORAGE_FLUSH
73 #define storage_flush() (void)0 72 #define storage_flush() (void)0
74 #endif 73 #endif
@@ -84,6 +83,7 @@ struct storage_info
84 #define storage_present(drive) ata_present(IF_MD(drive)) 83 #define storage_present(drive) ata_present(IF_MD(drive))
85 #endif 84 #endif
86 #elif (CONFIG_STORAGE & STORAGE_SD) 85 #elif (CONFIG_STORAGE & STORAGE_SD)
86 #define STORAGE_FUNCTION(NAME) (sd_## NAME)
87 #define storage_spindown sd_spindown 87 #define storage_spindown sd_spindown
88 #define storage_sleep sd_sleep 88 #define storage_sleep sd_sleep
89 #define storage_spin sd_spin 89 #define storage_spin sd_spin
@@ -93,8 +93,6 @@ struct storage_info
93 #define storage_disk_is_active() 0 93 #define storage_disk_is_active() 0
94 #define storage_soft_reset() (void)0 94 #define storage_soft_reset() (void)0
95 #define storage_init() sd_init() 95 #define storage_init() sd_init()
96 #define storage_read_sectors(drive, start, count, buf) sd_read_sectors(IF_MD2(drive,) start, count, buf)
97 #define storage_write_sectors(drive, start, count, buf) sd_write_sectors(IF_MD2(drive,) start, count, buf)
98 #ifdef HAVE_STORAGE_FLUSH 96 #ifdef HAVE_STORAGE_FLUSH
99 #define storage_flush() (void)0 97 #define storage_flush() (void)0
100 #endif 98 #endif
@@ -110,6 +108,7 @@ struct storage_info
110 #define storage_present(drive) sd_present(IF_MD(drive)) 108 #define storage_present(drive) sd_present(IF_MD(drive))
111 #endif 109 #endif
112 #elif (CONFIG_STORAGE & STORAGE_MMC) 110 #elif (CONFIG_STORAGE & STORAGE_MMC)
111 #define STORAGE_FUNCTION(NAME) (mmc_## NAME)
113 #define storage_spindown mmc_spindown 112 #define storage_spindown mmc_spindown
114 #define storage_sleep mmc_sleep 113 #define storage_sleep mmc_sleep
115 #define storage_spin mmc_spin 114 #define storage_spin mmc_spin
@@ -119,8 +118,6 @@ struct storage_info
119 #define storage_disk_is_active() mmc_disk_is_active() 118 #define storage_disk_is_active() mmc_disk_is_active()
120 #define storage_soft_reset() (void)0 119 #define storage_soft_reset() (void)0
121 #define storage_init() mmc_init() 120 #define storage_init() mmc_init()
122 #define storage_read_sectors(drive, start, count, buf) mmc_read_sectors(IF_MD2(drive,) start, count, buf)
123 #define storage_write_sectors(drive, start, count, buf) mmc_write_sectors(IF_MD2(drive,) start, count, buf)
124 #ifdef HAVE_STORAGE_FLUSH 121 #ifdef HAVE_STORAGE_FLUSH
125 #define storage_flush() (void)0 122 #define storage_flush() (void)0
126 #endif 123 #endif
@@ -136,6 +133,7 @@ struct storage_info
136 #define storage_present(drive) mmc_present(IF_MD(drive)) 133 #define storage_present(drive) mmc_present(IF_MD(drive))
137 #endif 134 #endif
138 #elif (CONFIG_STORAGE & STORAGE_NAND) 135 #elif (CONFIG_STORAGE & STORAGE_NAND)
136 #define STORAGE_FUNCTION(NAME) (nand_## NAME)
139 #define storage_spindown nand_spindown 137 #define storage_spindown nand_spindown
140 #define storage_sleep nand_sleep 138 #define storage_sleep nand_sleep
141 #define storage_spin nand_spin 139 #define storage_spin nand_spin
@@ -145,8 +143,6 @@ struct storage_info
145 #define storage_disk_is_active() 0 143 #define storage_disk_is_active() 0
146 #define storage_soft_reset() (void)0 144 #define storage_soft_reset() (void)0
147 #define storage_init() nand_init() 145 #define storage_init() nand_init()
148 #define storage_read_sectors(drive, start, count, buf) nand_read_sectors(IF_MD2(drive,) start, count, buf)
149 #define storage_write_sectors(drive, start, count, buf) nand_write_sectors(IF_MD2(drive,) start, count, buf)
150 #ifdef HAVE_STORAGE_FLUSH 146 #ifdef HAVE_STORAGE_FLUSH
151 #define storage_flush() nand_flush() 147 #define storage_flush() nand_flush()
152 #endif 148 #endif
@@ -162,6 +158,7 @@ struct storage_info
162 #define storage_present(drive) nand_present(IF_MD(drive)) 158 #define storage_present(drive) nand_present(IF_MD(drive))
163 #endif 159 #endif
164 #elif (CONFIG_STORAGE & STORAGE_RAMDISK) 160 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
161 #define STORAGE_FUNCTION(NAME) (ramdisk_## NAME)
165 #define storage_spindown ramdisk_spindown 162 #define storage_spindown ramdisk_spindown
166 #define storage_sleep ramdisk_sleep 163 #define storage_sleep ramdisk_sleep
167 #define storage_spin ramdisk_spin 164 #define storage_spin ramdisk_spin
@@ -171,8 +168,6 @@ struct storage_info
171 #define storage_disk_is_active() 0 168 #define storage_disk_is_active() 0
172 #define storage_soft_reset() (void)0 169 #define storage_soft_reset() (void)0
173 #define storage_init() ramdisk_init() 170 #define storage_init() ramdisk_init()
174 #define storage_read_sectors(drive, start, count, buf) ramdisk_read_sectors(IF_MD2(drive,) start, count, buf)
175 #define storage_write_sectors(drive, start, count, buf) ramdisk_write_sectors(IF_MD2(drive,) start, count, buf)
176 #ifdef HAVE_STORAGE_FLUSH 171 #ifdef HAVE_STORAGE_FLUSH
177 #define storage_flush() (void)0 172 #define storage_flush() (void)0
178 #endif 173 #endif
@@ -200,8 +195,6 @@ void storage_sleepnow(void);
200bool storage_disk_is_active(void); 195bool storage_disk_is_active(void);
201int storage_soft_reset(void); 196int storage_soft_reset(void);
202int storage_init(void); 197int storage_init(void);
203int storage_read_sectors(int drive, unsigned long start, int count, void* buf);
204int storage_write_sectors(int drive, unsigned long start, int count, const void* buf);
205int storage_flush(void); 198int storage_flush(void);
206void storage_spin(void); 199void storage_spin(void);
207void storage_spindown(int seconds); 200void storage_spindown(int seconds);
@@ -217,4 +210,7 @@ bool storage_present(int drive);
217#endif 210#endif
218 211
219#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/ 212#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/
213
214int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf);
215int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf);
220#endif 216#endif
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index 2a2a7a8619..a75981dcba 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -58,6 +58,9 @@
58#define NUM_PRIORITIES 32 58#define NUM_PRIORITIES 32
59#define PRIORITY_IDLE 32 /* Priority representative of no tasks */ 59#define PRIORITY_IDLE 32 /* Priority representative of no tasks */
60 60
61#define IO_PRIORITY_IMMEDIATE 0
62#define IO_PRIORITY_BACKGROUND 32
63
61#if CONFIG_CODEC == SWCODEC 64#if CONFIG_CODEC == SWCODEC
62 65
63#ifdef HAVE_RECORDING 66#ifdef HAVE_RECORDING
@@ -294,6 +297,9 @@ struct thread_entry
294 struct corelock waiter_cl; /* Corelock for thread_wait */ 297 struct corelock waiter_cl; /* Corelock for thread_wait */
295 struct corelock slot_cl; /* Corelock to lock thread slot */ 298 struct corelock slot_cl; /* Corelock to lock thread slot */
296#endif 299#endif
300#ifdef HAVE_IO_PRIORITY
301 unsigned char io_priority;
302#endif
297}; 303};
298 304
299/*** Macros for internal use ***/ 305/*** Macros for internal use ***/
@@ -539,6 +545,10 @@ unsigned int wakeup_thread(struct thread_entry **list);
539int thread_set_priority(unsigned int thread_id, int priority); 545int thread_set_priority(unsigned int thread_id, int priority);
540int thread_get_priority(unsigned int thread_id); 546int thread_get_priority(unsigned int thread_id);
541#endif /* HAVE_PRIORITY_SCHEDULING */ 547#endif /* HAVE_PRIORITY_SCHEDULING */
548#ifdef HAVE_IO_PRIORITY
549void thread_set_io_priority(unsigned int thread_id, int io_priority);
550int thread_get_io_priority(unsigned int thread_id);
551#endif /* HAVE_IO_PRIORITY */
542#if NUM_CORES > 1 552#if NUM_CORES > 1
543unsigned int switch_core(unsigned int new_core); 553unsigned int switch_core(unsigned int new_core);
544#endif 554#endif
diff --git a/firmware/storage.c b/firmware/storage.c
index d6700d1148..ceae98fa40 100644
--- a/firmware/storage.c
+++ b/firmware/storage.c
@@ -19,6 +19,9 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "storage.h" 21#include "storage.h"
22#include "kernel.h"
23
24#ifdef CONFIG_STORAGE_MULTI
22 25
23#define DRIVER_MASK 0xff000000 26#define DRIVER_MASK 0xff000000
24#define DRIVER_OFFSET 24 27#define DRIVER_OFFSET 24
@@ -28,116 +31,112 @@
28 31
29static unsigned int storage_drivers[NUM_DRIVES]; 32static unsigned int storage_drivers[NUM_DRIVES];
30static unsigned int num_drives; 33static unsigned int num_drives;
34#endif
31 35
32int storage_num_drives(void)
33{
34 return num_drives;
35}
36 36
37int storage_init(void) 37#ifdef HAVE_IO_PRIORITY
38{
39 int rc=0;
40 int i;
41 num_drives=0;
42
43#if (CONFIG_STORAGE & STORAGE_ATA)
44 if ((rc=ata_init())) return rc;
45
46 int ata_drives = ata_num_drives(num_drives);
47 for (i=0; i<ata_drives; i++)
48 {
49 storage_drivers[num_drives++] =
50 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
51 }
52#endif
53 38
54#if (CONFIG_STORAGE & STORAGE_MMC) 39/* Same for flash? */
55 if ((rc=mmc_init())) return rc; 40#define STORAGE_MINIMUM_IDLE_TIME (HZ/10)
56 41#define STORAGE_DELAY_UNIT (HZ/20)
57 int mmc_drives = mmc_num_drives(num_drives);
58 for (i=0; i<mmc_drives ;i++)
59 {
60 storage_drivers[num_drives++] =
61 (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
62 }
63#endif
64 42
65#if (CONFIG_STORAGE & STORAGE_SD) 43unsigned int storage_last_thread[NUM_DRIVES];
66 if ((rc=sd_init())) return rc; 44unsigned int storage_last_activity[NUM_DRIVES];
67 45
68 int sd_drives = sd_num_drives(num_drives); 46static bool storage_should_wait(int drive, int prio)
69 for (i=0; i<sd_drives; i++) 47{
48 int other_prio = thread_get_io_priority(storage_last_thread[drive]);
49 if(TIME_BEFORE(current_tick,storage_last_activity[drive]+STORAGE_MINIMUM_IDLE_TIME))
70 { 50 {
71 storage_drivers[num_drives++] = 51 if(prio<=other_prio)
72 (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET); 52 {
53 /* There is another active thread, but we have lower priority */
54 return false;
55 }
56 else
57 {
58 /* There is another active thread, but it has lower priority */
59 return true;
60 }
73 } 61 }
74#endif 62 else
75
76#if (CONFIG_STORAGE & STORAGE_NAND)
77 if ((rc=nand_init())) return rc;
78
79 int nand_drives = nand_num_drives(num_drives);
80 for (i=0; i<nand_drives; i++)
81 { 63 {
82 storage_drivers[num_drives++] = 64 /* There's nothing going on anyway */
83 (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET); 65 return false;
84 } 66 }
85#endif 67}
86 68
87#if (CONFIG_STORAGE & STORAGE_RAMDISK) 69static void storage_wait_turn(IF_MD_NONVOID(int drive))
88 if ((rc=ramdisk_init())) return rc; 70{
89 71#ifndef HAVE_MULTIDRIVE
90 int ramdisk_drives = ramdisk_num_drives(num_drives); 72 int drive=0;
91 for (i=0; i<ramdisk_drives; i++) 73#endif
74 int my_prio = thread_get_io_priority(thread_get_current());
75 int loops=my_prio;
76 while(storage_should_wait(drive, my_prio) && (loops--)>=0)
92 { 77 {
93 storage_drivers[num_drives++] = 78 sleep(STORAGE_DELAY_UNIT);
94 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
95 } 79 }
96#endif
97 80
98 return 0; 81 storage_last_thread[drive] = thread_get_current();
82 storage_last_activity[drive] = current_tick;
99} 83}
84#endif
100 85
101int storage_read_sectors(int drive, unsigned long start, int count, 86int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
102 void* buf) 87 void* buf)
103{ 88{
89#ifdef HAVE_IO_PRIORITY
90 storage_wait_turn(IF_MD(drive));
91#endif
92
93#ifdef CONFIG_STORAGE_MULTI
104 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 94 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
105 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 95 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
106 96
107 switch (driver) 97 switch (driver)
108 { 98 {
109#if (CONFIG_STORAGE & STORAGE_ATA) 99#if (CONFIG_STORAGE & STORAGE_ATA)
110 case STORAGE_ATA: 100 case STORAGE_ATA:
111 return ata_read_sectors(ldrive,start,count,buf); 101 return ata_read_sectors(IF_MD2(ldrive,) start,count,buf);
112#endif 102#endif
113 103
114#if (CONFIG_STORAGE & STORAGE_MMC) 104#if (CONFIG_STORAGE & STORAGE_MMC)
115 case STORAGE_MMC: 105 case STORAGE_MMC:
116 return mmc_read_sectors(ldrive,start,count,buf); 106 return mmc_read_sectors(IF_MD2(ldrive,) start,count,buf);
117#endif 107#endif
118 108
119#if (CONFIG_STORAGE & STORAGE_SD) 109#if (CONFIG_STORAGE & STORAGE_SD)
120 case STORAGE_SD: 110 case STORAGE_SD:
121 return sd_read_sectors(ldrive,start,count,buf); 111 return sd_read_sectors(IF_MD2(ldrive,) start,count,buf);
122#endif 112#endif
123 113
124#if (CONFIG_STORAGE & STORAGE_NAND) 114#if (CONFIG_STORAGE & STORAGE_NAND)
125 case STORAGE_NAND: 115 case STORAGE_NAND:
126 return nand_read_sectors(ldrive,start,count,buf); 116 return nand_read_sectors(IF_MD2(ldrive,) start,count,buf);
127#endif 117#endif
128 118
129#if (CONFIG_STORAGE & STORAGE_RAMDISK) 119#if (CONFIG_STORAGE & STORAGE_RAMDISK)
130 case STORAGE_RAMDISK: 120 case STORAGE_RAMDISK:
131 return ramdisk_read_sectors(ldrive,start,count,buf); 121 return ramdisk_read_sectors(IF_MD2(ldrive,) start,count,buf);
132#endif 122#endif
133 } 123 }
134 124
135 return -1; 125 return -1;
126#else /* CONFIG_STORAGE_MULTI */
127 return STORAGE_FUNCTION(read_sectors)(IF_MD2(drive,)start,count,buf);
128#endif /* CONFIG_STORAGE_MULTI */
129
136} 130}
137 131
138int storage_write_sectors(int drive, unsigned long start, int count, 132int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
139 const void* buf) 133 const void* buf)
140{ 134{
135#ifdef HAVE_IO_PRIORITY
136 storage_wait_turn(IF_MD(drive));
137#endif
138
139#ifdef CONFIG_STORAGE_MULTI
141 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 140 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
142 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 141 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
143 142
@@ -145,33 +144,117 @@ int storage_write_sectors(int drive, unsigned long start, int count,
145 { 144 {
146#if (CONFIG_STORAGE & STORAGE_ATA) 145#if (CONFIG_STORAGE & STORAGE_ATA)
147 case STORAGE_ATA: 146 case STORAGE_ATA:
148 return ata_write_sectors(ldrive,start,count,buf); 147 return ata_write_sectors(IF_MD2(ldrive,)start,count,buf);
149#endif 148#endif
150 149
151#if (CONFIG_STORAGE & STORAGE_MMC) 150#if (CONFIG_STORAGE & STORAGE_MMC)
152 case STORAGE_MMC: 151 case STORAGE_MMC:
153 return mmc_write_sectors(ldrive,start,count,buf); 152 return mmc_write_sectors(IF_MD2(ldrive,)start,count,buf);
154#endif 153#endif
155 154
156#if (CONFIG_STORAGE & STORAGE_SD) 155#if (CONFIG_STORAGE & STORAGE_SD)
157 case STORAGE_SD: 156 case STORAGE_SD:
158 return sd_write_sectors(ldrive,start,count,buf); 157 return sd_write_sectors(IF_MD2(ldrive,)start,count,buf);
159#endif 158#endif
160 159
161#if (CONFIG_STORAGE & STORAGE_NAND) 160#if (CONFIG_STORAGE & STORAGE_NAND)
162 case STORAGE_NAND: 161 case STORAGE_NAND:
163 return nand_write_sectors(ldrive,start,count,buf); 162 return nand_write_sectors(IF_MD2(ldrive,)start,count,buf);
164#endif 163#endif
165 164
166#if (CONFIG_STORAGE & STORAGE_RAMDISK) 165#if (CONFIG_STORAGE & STORAGE_RAMDISK)
167 case STORAGE_RAMDISK: 166 case STORAGE_RAMDISK:
168 return ramdisk_write_sectors(ldrive,start,count,buf); 167 return ramdisk_write_sectors(IF_MD2(ldrive,)start,count,buf);
169#endif 168#endif
170 } 169 }
171 170
172 return -1; 171 return -1;
172#else /* CONFIG_STORAGE_MULTI */
173 return STORAGE_FUNCTION(write_sectors)(IF_MD2(drive,)start,count,buf);
174#endif /* CONFIG_STORAGE_MULTI */
175}
176
177#ifdef CONFIG_STORAGE_MULTI
178
179#define DRIVER_MASK 0xff000000
180#define DRIVER_OFFSET 24
181#define DRIVE_MASK 0x00ff0000
182#define DRIVE_OFFSET 16
183#define PARTITION_MASK 0x0000ff00
184
185static unsigned int storage_drivers[NUM_DRIVES];
186static unsigned int num_drives;
187
188int storage_num_drives(void)
189{
190 return num_drives;
191}
192
193int storage_init(void)
194{
195 int rc=0;
196 int i;
197 num_drives=0;
198
199#if (CONFIG_STORAGE & STORAGE_ATA)
200 if ((rc=ata_init())) return rc;
201
202 int ata_drives = ata_num_drives(num_drives);
203 for (i=0; i<ata_drives; i++)
204 {
205 storage_drivers[num_drives++] =
206 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
207 }
208#endif
209
210#if (CONFIG_STORAGE & STORAGE_MMC)
211 if ((rc=mmc_init())) return rc;
212
213 int mmc_drives = mmc_num_drives(num_drives);
214 for (i=0; i<mmc_drives ;i++)
215 {
216 storage_drivers[num_drives++] =
217 (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
218 }
219#endif
220
221#if (CONFIG_STORAGE & STORAGE_SD)
222 if ((rc=sd_init())) return rc;
223
224 int sd_drives = sd_num_drives(num_drives);
225 for (i=0; i<sd_drives; i++)
226 {
227 storage_drivers[num_drives++] =
228 (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
229 }
230#endif
231
232#if (CONFIG_STORAGE & STORAGE_NAND)
233 if ((rc=nand_init())) return rc;
234
235 int nand_drives = nand_num_drives(num_drives);
236 for (i=0; i<nand_drives; i++)
237 {
238 storage_drivers[num_drives++] =
239 (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
240 }
241#endif
242
243#if (CONFIG_STORAGE & STORAGE_RAMDISK)
244 if ((rc=ramdisk_init())) return rc;
245
246 int ramdisk_drives = ramdisk_num_drives(num_drives);
247 for (i=0; i<ramdisk_drives; i++)
248 {
249 storage_drivers[num_drives++] =
250 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
251 }
252#endif
253
254 return 0;
173} 255}
174 256
257
175void storage_enable(bool on) 258void storage_enable(bool on)
176{ 259{
177#if (CONFIG_STORAGE & STORAGE_ATA) 260#if (CONFIG_STORAGE & STORAGE_ATA)
@@ -572,3 +655,5 @@ bool storage_present(int drive)
572 return ret; 655 return ret;
573} 656}
574#endif 657#endif
658
659#endif /*CONFIG_STORAGE_MULTI*/
diff --git a/firmware/thread.c b/firmware/thread.c
index 38933f623e..81ef42a6b0 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -2413,6 +2413,11 @@ unsigned int create_thread(void (*function)(void),
2413 prio_add_entry(&thread->pdist, priority); 2413 prio_add_entry(&thread->pdist, priority);
2414#endif 2414#endif
2415 2415
2416#ifdef HAVE_IO_PRIORITY
2417 /* Default to high (foreground) priority */
2418 thread->io_priority = IO_PRIORITY_IMMEDIATE;
2419#endif
2420
2416#if NUM_CORES > 1 2421#if NUM_CORES > 1
2417 thread->core = core; 2422 thread->core = core;
2418 2423
@@ -2918,6 +2923,20 @@ int thread_get_priority(unsigned int thread_id)
2918} 2923}
2919#endif /* HAVE_PRIORITY_SCHEDULING */ 2924#endif /* HAVE_PRIORITY_SCHEDULING */
2920 2925
2926#ifdef HAVE_IO_PRIORITY
2927int thread_get_io_priority(unsigned int thread_id)
2928{
2929 struct thread_entry *thread = thread_id_entry(thread_id);
2930 return thread->io_priority;
2931}
2932
2933void thread_set_io_priority(unsigned int thread_id,int io_priority)
2934{
2935 struct thread_entry *thread = thread_id_entry(thread_id);
2936 thread->io_priority = io_priority;
2937}
2938#endif
2939
2921/*--------------------------------------------------------------------------- 2940/*---------------------------------------------------------------------------
2922 * Starts a frozen thread - similar semantics to wakeup_thread except that 2941 * Starts a frozen thread - similar semantics to wakeup_thread except that
2923 * the thread is on no scheduler or wakeup queue at all. It exists simply by 2942 * the thread is on no scheduler or wakeup queue at all. It exists simply by
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 4a8f2dc397..647fbd8e5b 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -353,7 +353,7 @@ static bool check_disk_present(IF_MD_NONVOID(int volume))
353 return true; 353 return true;
354#else 354#else
355 unsigned char sector[SECTOR_SIZE]; 355 unsigned char sector[SECTOR_SIZE];
356 return storage_read_sectors(volume,0,1,sector) == 0; 356 return storage_read_sectors(IF_MD2(volume,)0,1,sector) == 0;
357#endif 357#endif
358} 358}
359 359
@@ -537,7 +537,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
537 cur_cmd.data[cur_cmd.data_select], 537 cur_cmd.data[cur_cmd.data_select],
538 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 538 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
539#else 539#else
540 int result = storage_write_sectors(cur_cmd.lun, 540 int result = storage_write_sectors(IF_MD2(cur_cmd.lun,)
541 cur_cmd.sector, 541 cur_cmd.sector,
542 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 542 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
543 cur_cmd.data[cur_cmd.data_select]); 543 cur_cmd.data[cur_cmd.data_select]);
@@ -726,7 +726,7 @@ static void send_and_read_next(void)
726 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 726 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
727 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 727 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
728#else 728#else
729 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, 729 cur_cmd.last_result = storage_read_sectors(IF_MD2(cur_cmd.lun,)
730 cur_cmd.sector, 730 cur_cmd.sector,
731 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 731 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
732 cur_cmd.data[cur_cmd.data_select]); 732 cur_cmd.data[cur_cmd.data_select]);
@@ -1070,7 +1070,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1070 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 1070 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
1071 MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); 1071 MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE);
1072#else 1072#else
1073 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, 1073 cur_cmd.last_result = storage_read_sectors(IF_MD2(cur_cmd.lun,)
1074 cur_cmd.sector, 1074 cur_cmd.sector,
1075 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 1075 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
1076 cur_cmd.data[cur_cmd.data_select]); 1076 cur_cmd.data[cur_cmd.data_select]);