summaryrefslogtreecommitdiffstats
path: root/firmware/storage.c
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2010-04-03 22:02:09 +0000
committerFrank Gevaerts <frank@gevaerts.be>2010-04-03 22:02:09 +0000
commit376d8d577fe94a8dc8742deff5a7524aa1595e1c (patch)
tree4d76e5232d8b513a40f11588d0f6899d47336b49 /firmware/storage.c
parentba7501513a87433043a217a813c9147d004314a5 (diff)
downloadrockbox-376d8d577fe94a8dc8742deff5a7524aa1595e1c.tar.gz
rockbox-376d8d577fe94a8dc8742deff5a7524aa1595e1c.tar.bz2
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/storage.c')
-rw-r--r--firmware/storage.c223
1 files changed, 154 insertions, 69 deletions
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 @@
*
****************************************************************************/
#include "storage.h"
+#include "kernel.h"
+
+#ifdef CONFIG_STORAGE_MULTI
#define DRIVER_MASK 0xff000000
#define DRIVER_OFFSET 24
@@ -28,116 +31,112 @@
static unsigned int storage_drivers[NUM_DRIVES];
static unsigned int num_drives;
+#endif
-int storage_num_drives(void)
-{
- return num_drives;
-}
-int storage_init(void)
-{
- int rc=0;
- int i;
- num_drives=0;
-
-#if (CONFIG_STORAGE & STORAGE_ATA)
- if ((rc=ata_init())) return rc;
-
- int ata_drives = ata_num_drives(num_drives);
- for (i=0; i<ata_drives; i++)
- {
- storage_drivers[num_drives++] =
- (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
- }
-#endif
+#ifdef HAVE_IO_PRIORITY
-#if (CONFIG_STORAGE & STORAGE_MMC)
- if ((rc=mmc_init())) return rc;
-
- int mmc_drives = mmc_num_drives(num_drives);
- for (i=0; i<mmc_drives ;i++)
- {
- storage_drivers[num_drives++] =
- (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
- }
-#endif
+/* Same for flash? */
+#define STORAGE_MINIMUM_IDLE_TIME (HZ/10)
+#define STORAGE_DELAY_UNIT (HZ/20)
-#if (CONFIG_STORAGE & STORAGE_SD)
- if ((rc=sd_init())) return rc;
-
- int sd_drives = sd_num_drives(num_drives);
- for (i=0; i<sd_drives; i++)
+unsigned int storage_last_thread[NUM_DRIVES];
+unsigned int storage_last_activity[NUM_DRIVES];
+
+static bool storage_should_wait(int drive, int prio)
+{
+ int other_prio = thread_get_io_priority(storage_last_thread[drive]);
+ if(TIME_BEFORE(current_tick,storage_last_activity[drive]+STORAGE_MINIMUM_IDLE_TIME))
{
- storage_drivers[num_drives++] =
- (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ if(prio<=other_prio)
+ {
+ /* There is another active thread, but we have lower priority */
+ return false;
+ }
+ else
+ {
+ /* There is another active thread, but it has lower priority */
+ return true;
+ }
}
-#endif
-
-#if (CONFIG_STORAGE & STORAGE_NAND)
- if ((rc=nand_init())) return rc;
-
- int nand_drives = nand_num_drives(num_drives);
- for (i=0; i<nand_drives; i++)
+ else
{
- storage_drivers[num_drives++] =
- (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ /* There's nothing going on anyway */
+ return false;
}
-#endif
+}
-#if (CONFIG_STORAGE & STORAGE_RAMDISK)
- if ((rc=ramdisk_init())) return rc;
-
- int ramdisk_drives = ramdisk_num_drives(num_drives);
- for (i=0; i<ramdisk_drives; i++)
+static void storage_wait_turn(IF_MD_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIDRIVE
+ int drive=0;
+#endif
+ int my_prio = thread_get_io_priority(thread_get_current());
+ int loops=my_prio;
+ while(storage_should_wait(drive, my_prio) && (loops--)>=0)
{
- storage_drivers[num_drives++] =
- (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ sleep(STORAGE_DELAY_UNIT);
}
-#endif
- return 0;
+ storage_last_thread[drive] = thread_get_current();
+ storage_last_activity[drive] = current_tick;
}
+#endif
-int storage_read_sectors(int drive, unsigned long start, int count,
+int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
void* buf)
{
+#ifdef HAVE_IO_PRIORITY
+ storage_wait_turn(IF_MD(drive));
+#endif
+
+#ifdef CONFIG_STORAGE_MULTI
int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
-
+
switch (driver)
{
#if (CONFIG_STORAGE & STORAGE_ATA)
case STORAGE_ATA:
- return ata_read_sectors(ldrive,start,count,buf);
+ return ata_read_sectors(IF_MD2(ldrive,) start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_MMC)
case STORAGE_MMC:
- return mmc_read_sectors(ldrive,start,count,buf);
+ return mmc_read_sectors(IF_MD2(ldrive,) start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_SD)
case STORAGE_SD:
- return sd_read_sectors(ldrive,start,count,buf);
+ return sd_read_sectors(IF_MD2(ldrive,) start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_NAND)
case STORAGE_NAND:
- return nand_read_sectors(ldrive,start,count,buf);
+ return nand_read_sectors(IF_MD2(ldrive,) start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
case STORAGE_RAMDISK:
- return ramdisk_read_sectors(ldrive,start,count,buf);
+ return ramdisk_read_sectors(IF_MD2(ldrive,) start,count,buf);
#endif
}
return -1;
+#else /* CONFIG_STORAGE_MULTI */
+ return STORAGE_FUNCTION(read_sectors)(IF_MD2(drive,)start,count,buf);
+#endif /* CONFIG_STORAGE_MULTI */
+
}
-int storage_write_sectors(int drive, unsigned long start, int count,
+int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
const void* buf)
{
+#ifdef HAVE_IO_PRIORITY
+ storage_wait_turn(IF_MD(drive));
+#endif
+
+#ifdef CONFIG_STORAGE_MULTI
int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
@@ -145,33 +144,117 @@ int storage_write_sectors(int drive, unsigned long start, int count,
{
#if (CONFIG_STORAGE & STORAGE_ATA)
case STORAGE_ATA:
- return ata_write_sectors(ldrive,start,count,buf);
+ return ata_write_sectors(IF_MD2(ldrive,)start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_MMC)
case STORAGE_MMC:
- return mmc_write_sectors(ldrive,start,count,buf);
+ return mmc_write_sectors(IF_MD2(ldrive,)start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_SD)
case STORAGE_SD:
- return sd_write_sectors(ldrive,start,count,buf);
+ return sd_write_sectors(IF_MD2(ldrive,)start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_NAND)
case STORAGE_NAND:
- return nand_write_sectors(ldrive,start,count,buf);
+ return nand_write_sectors(IF_MD2(ldrive,)start,count,buf);
#endif
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
case STORAGE_RAMDISK:
- return ramdisk_write_sectors(ldrive,start,count,buf);
+ return ramdisk_write_sectors(IF_MD2(ldrive,)start,count,buf);
#endif
}
return -1;
+#else /* CONFIG_STORAGE_MULTI */
+ return STORAGE_FUNCTION(write_sectors)(IF_MD2(drive,)start,count,buf);
+#endif /* CONFIG_STORAGE_MULTI */
+}
+
+#ifdef CONFIG_STORAGE_MULTI
+
+#define DRIVER_MASK 0xff000000
+#define DRIVER_OFFSET 24
+#define DRIVE_MASK 0x00ff0000
+#define DRIVE_OFFSET 16
+#define PARTITION_MASK 0x0000ff00
+
+static unsigned int storage_drivers[NUM_DRIVES];
+static unsigned int num_drives;
+
+int storage_num_drives(void)
+{
+ return num_drives;
+}
+
+int storage_init(void)
+{
+ int rc=0;
+ int i;
+ num_drives=0;
+
+#if (CONFIG_STORAGE & STORAGE_ATA)
+ if ((rc=ata_init())) return rc;
+
+ int ata_drives = ata_num_drives(num_drives);
+ for (i=0; i<ata_drives; i++)
+ {
+ storage_drivers[num_drives++] =
+ (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ }
+#endif
+
+#if (CONFIG_STORAGE & STORAGE_MMC)
+ if ((rc=mmc_init())) return rc;
+
+ int mmc_drives = mmc_num_drives(num_drives);
+ for (i=0; i<mmc_drives ;i++)
+ {
+ storage_drivers[num_drives++] =
+ (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ }
+#endif
+
+#if (CONFIG_STORAGE & STORAGE_SD)
+ if ((rc=sd_init())) return rc;
+
+ int sd_drives = sd_num_drives(num_drives);
+ for (i=0; i<sd_drives; i++)
+ {
+ storage_drivers[num_drives++] =
+ (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ }
+#endif
+
+#if (CONFIG_STORAGE & STORAGE_NAND)
+ if ((rc=nand_init())) return rc;
+
+ int nand_drives = nand_num_drives(num_drives);
+ for (i=0; i<nand_drives; i++)
+ {
+ storage_drivers[num_drives++] =
+ (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ }
+#endif
+
+#if (CONFIG_STORAGE & STORAGE_RAMDISK)
+ if ((rc=ramdisk_init())) return rc;
+
+ int ramdisk_drives = ramdisk_num_drives(num_drives);
+ for (i=0; i<ramdisk_drives; i++)
+ {
+ storage_drivers[num_drives++] =
+ (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
+ }
+#endif
+
+ return 0;
}
+
void storage_enable(bool on)
{
#if (CONFIG_STORAGE & STORAGE_ATA)
@@ -572,3 +655,5 @@ bool storage_present(int drive)
return ret;
}
#endif
+
+#endif /*CONFIG_STORAGE_MULTI*/