diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2010-04-03 22:02:09 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2010-04-03 22:02:09 +0000 |
commit | 376d8d577fe94a8dc8742deff5a7524aa1595e1c (patch) | |
tree | 4d76e5232d8b513a40f11588d0f6899d47336b49 /firmware | |
parent | ba7501513a87433043a217a813c9147d004314a5 (diff) | |
download | rockbox-376d8d577fe94a8dc8742deff5a7524aa1595e1c.tar.gz rockbox-376d8d577fe94a8dc8742deff5a7524aa1595e1c.zip |
Add IO priority handling. Currently all IO has equal priority, except the dircache scanning thread which is lower. This fixes the slow boot problem for me, with the added benefit that actual audio playback also starts faster.
Lots of the changes are due to changing storage_(read|write)sectors() from macros to wrapper functions. This means that they have to be called with IF_MD2(drive,) again.
Flyspray: FS#11167
Author: Frank Gevaerts
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25459 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/common/dircache.c | 8 | ||||
-rw-r--r-- | firmware/common/disk.c | 2 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 18 | ||||
-rw-r--r-- | firmware/export/config.h | 4 | ||||
-rw-r--r-- | firmware/export/storage.h | 20 | ||||
-rw-r--r-- | firmware/export/thread.h | 10 | ||||
-rw-r--r-- | firmware/storage.c | 223 | ||||
-rw-r--r-- | firmware/thread.c | 19 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 8 |
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) |
153 | drivers/ramdisk.c | 153 | drivers/ramdisk.c |
154 | #endif | 154 | #endif |
155 | #ifdef CONFIG_STORAGE_MULTI | ||
156 | storage.c | 155 | storage.c |
157 | #endif | ||
158 | drivers/fat.c | 156 | drivers/fat.c |
159 | #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD) | 157 | #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD) |
160 | hotswap.c | 158 | hotswap.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) | |||
760 | void dircache_init(void) | 761 | void 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, §or); | 85 | storage_read_sectors(IF_MD2(drive,) 0,1, §or); |
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); | |||
200 | bool storage_disk_is_active(void); | 195 | bool storage_disk_is_active(void); |
201 | int storage_soft_reset(void); | 196 | int storage_soft_reset(void); |
202 | int storage_init(void); | 197 | int storage_init(void); |
203 | int storage_read_sectors(int drive, unsigned long start, int count, void* buf); | ||
204 | int storage_write_sectors(int drive, unsigned long start, int count, const void* buf); | ||
205 | int storage_flush(void); | 198 | int storage_flush(void); |
206 | void storage_spin(void); | 199 | void storage_spin(void); |
207 | void storage_spindown(int seconds); | 200 | void 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 | |||
214 | int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf); | ||
215 | int 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); | |||
539 | int thread_set_priority(unsigned int thread_id, int priority); | 545 | int thread_set_priority(unsigned int thread_id, int priority); |
540 | int thread_get_priority(unsigned int thread_id); | 546 | int thread_get_priority(unsigned int thread_id); |
541 | #endif /* HAVE_PRIORITY_SCHEDULING */ | 547 | #endif /* HAVE_PRIORITY_SCHEDULING */ |
548 | #ifdef HAVE_IO_PRIORITY | ||
549 | void thread_set_io_priority(unsigned int thread_id, int io_priority); | ||
550 | int thread_get_io_priority(unsigned int thread_id); | ||
551 | #endif /* HAVE_IO_PRIORITY */ | ||
542 | #if NUM_CORES > 1 | 552 | #if NUM_CORES > 1 |
543 | unsigned int switch_core(unsigned int new_core); | 553 | unsigned 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 | ||
29 | static unsigned int storage_drivers[NUM_DRIVES]; | 32 | static unsigned int storage_drivers[NUM_DRIVES]; |
30 | static unsigned int num_drives; | 33 | static unsigned int num_drives; |
34 | #endif | ||
31 | 35 | ||
32 | int storage_num_drives(void) | ||
33 | { | ||
34 | return num_drives; | ||
35 | } | ||
36 | 36 | ||
37 | int 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) | 43 | unsigned int storage_last_thread[NUM_DRIVES]; |
66 | if ((rc=sd_init())) return rc; | 44 | unsigned int storage_last_activity[NUM_DRIVES]; |
67 | 45 | ||
68 | int sd_drives = sd_num_drives(num_drives); | 46 | static 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) | 69 | static 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 | ||
101 | int storage_read_sectors(int drive, unsigned long start, int count, | 86 | int 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 | ||
138 | int storage_write_sectors(int drive, unsigned long start, int count, | 132 | int 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 | |||
185 | static unsigned int storage_drivers[NUM_DRIVES]; | ||
186 | static unsigned int num_drives; | ||
187 | |||
188 | int storage_num_drives(void) | ||
189 | { | ||
190 | return num_drives; | ||
191 | } | ||
192 | |||
193 | int 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 | |||
175 | void storage_enable(bool on) | 258 | void 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 | ||
2927 | int 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 | |||
2933 | void 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]); |