Index: firmware/export/thread.h =================================================================== --- firmware/export/thread.h (revision 25449) +++ firmware/export/thread.h (working copy) @@ -58,6 +58,9 @@ #define NUM_PRIORITIES 32 #define PRIORITY_IDLE 32 /* Priority representative of no tasks */ +#define IO_PRIORITY_IMMEDIATE 0 +#define IO_PRIORITY_BACKGROUND 32 + #if CONFIG_CODEC == SWCODEC #ifdef HAVE_RECORDING @@ -294,6 +297,9 @@ struct corelock waiter_cl; /* Corelock for thread_wait */ struct corelock slot_cl; /* Corelock to lock thread slot */ #endif +#ifdef HAVE_IO_PRIORITY + unsigned char io_priority; +#endif }; /*** Macros for internal use ***/ @@ -539,6 +545,10 @@ int thread_set_priority(unsigned int thread_id, int priority); int thread_get_priority(unsigned int thread_id); #endif /* HAVE_PRIORITY_SCHEDULING */ +#ifdef HAVE_IO_PRIORITY +void thread_set_io_priority(unsigned int thread_id, int io_priority); +int thread_get_io_priority(unsigned int thread_id); +#endif /* HAVE_IO_PRIORITY */ #if NUM_CORES > 1 unsigned int switch_core(unsigned int new_core); #endif Index: firmware/export/config.h =================================================================== --- firmware/export/config.h (revision 25449) +++ firmware/export/config.h (working copy) @@ -921,4 +921,8 @@ #define HAVE_PLUGIN_CHECK_OPEN_CLOSE #endif +#ifdef HAVE_DIRCACHE +#define HAVE_IO_PRIORITY +#endif + #endif /* __CONFIG_H__ */ Index: firmware/export/storage.h =================================================================== --- firmware/export/storage.h (revision 25449) +++ firmware/export/storage.h (working copy) @@ -57,6 +57,7 @@ */ #define storage_num_drives() NUM_DRIVES #if (CONFIG_STORAGE & STORAGE_ATA) + #define STORAGE_FUNCTION(NAME) (ata_## NAME) #define storage_spindown ata_spindown #define storage_sleep ata_sleep #define storage_spin ata_spin @@ -67,8 +68,6 @@ #define storage_soft_reset() ata_soft_reset() #define storage_init() ata_init() #define storage_close() ata_close() - #define storage_read_sectors(drive, start, count, buf) ata_read_sectors(IF_MD2(drive,) start, count, buf) - #define storage_write_sectors(drive, start, count, buf) ata_write_sectors(IF_MD2(drive,) start, count, buf) #ifdef HAVE_STORAGE_FLUSH #define storage_flush() (void)0 #endif @@ -84,6 +83,7 @@ #define storage_present(drive) ata_present(IF_MD(drive)) #endif #elif (CONFIG_STORAGE & STORAGE_SD) + #define STORAGE_FUNCTION(NAME) (sd_## NAME) #define storage_spindown sd_spindown #define storage_sleep sd_sleep #define storage_spin sd_spin @@ -93,8 +93,6 @@ #define storage_disk_is_active() 0 #define storage_soft_reset() (void)0 #define storage_init() sd_init() - #define storage_read_sectors(drive, start, count, buf) sd_read_sectors(IF_MD2(drive,) start, count, buf) - #define storage_write_sectors(drive, start, count, buf) sd_write_sectors(IF_MD2(drive,) start, count, buf) #ifdef HAVE_STORAGE_FLUSH #define storage_flush() (void)0 #endif @@ -110,6 +108,7 @@ #define storage_present(drive) sd_present(IF_MD(drive)) #endif #elif (CONFIG_STORAGE & STORAGE_MMC) + #define STORAGE_FUNCTION(NAME) (mmc_## NAME) #define storage_spindown mmc_spindown #define storage_sleep mmc_sleep #define storage_spin mmc_spin @@ -119,8 +118,6 @@ #define storage_disk_is_active() mmc_disk_is_active() #define storage_soft_reset() (void)0 #define storage_init() mmc_init() - #define storage_read_sectors(drive, start, count, buf) mmc_read_sectors(IF_MD2(drive,) start, count, buf) - #define storage_write_sectors(drive, start, count, buf) mmc_write_sectors(IF_MD2(drive,) start, count, buf) #ifdef HAVE_STORAGE_FLUSH #define storage_flush() (void)0 #endif @@ -136,6 +133,7 @@ #define storage_present(drive) mmc_present(IF_MD(drive)) #endif #elif (CONFIG_STORAGE & STORAGE_NAND) + #define STORAGE_FUNCTION(NAME) (nand_## NAME) #define storage_spindown nand_spindown #define storage_sleep nand_sleep #define storage_spin nand_spin @@ -145,8 +143,6 @@ #define storage_disk_is_active() 0 #define storage_soft_reset() (void)0 #define storage_init() nand_init() - #define storage_read_sectors(drive, start, count, buf) nand_read_sectors(IF_MD2(drive,) start, count, buf) - #define storage_write_sectors(drive, start, count, buf) nand_write_sectors(IF_MD2(drive,) start, count, buf) #ifdef HAVE_STORAGE_FLUSH #define storage_flush() nand_flush() #endif @@ -162,6 +158,7 @@ #define storage_present(drive) nand_present(IF_MD(drive)) #endif #elif (CONFIG_STORAGE & STORAGE_RAMDISK) + #define STORAGE_FUNCTION(NAME) (ramdisk_## NAME) #define storage_spindown ramdisk_spindown #define storage_sleep ramdisk_sleep #define storage_spin ramdisk_spin @@ -171,8 +168,6 @@ #define storage_disk_is_active() 0 #define storage_soft_reset() (void)0 #define storage_init() ramdisk_init() - #define storage_read_sectors(drive, start, count, buf) ramdisk_read_sectors(IF_MD2(drive,) start, count, buf) - #define storage_write_sectors(drive, start, count, buf) ramdisk_write_sectors(IF_MD2(drive,) start, count, buf) #ifdef HAVE_STORAGE_FLUSH #define storage_flush() (void)0 #endif @@ -200,8 +195,6 @@ bool storage_disk_is_active(void); int storage_soft_reset(void); int storage_init(void); -int storage_read_sectors(int drive, unsigned long start, int count, void* buf); -int storage_write_sectors(int drive, unsigned long start, int count, const void* buf); int storage_flush(void); void storage_spin(void); void storage_spindown(int seconds); @@ -217,4 +210,7 @@ #endif #endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/ + +int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf); +int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf); #endif Index: firmware/usbstack/usb_storage.c =================================================================== --- firmware/usbstack/usb_storage.c (revision 25449) +++ firmware/usbstack/usb_storage.c (working copy) @@ -353,7 +353,7 @@ return true; #else unsigned char sector[SECTOR_SIZE]; - return storage_read_sectors(volume,0,1,sector) == 0; + return storage_read_sectors(IF_MD2(volume,)0,1,sector) == 0; #endif } @@ -537,7 +537,7 @@ cur_cmd.data[cur_cmd.data_select], MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); #else - int result = storage_write_sectors(cur_cmd.lun, + int result = storage_write_sectors(IF_MD2(cur_cmd.lun,) cur_cmd.sector, MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), cur_cmd.data[cur_cmd.data_select]); @@ -726,7 +726,7 @@ ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); #else - cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, + cur_cmd.last_result = storage_read_sectors(IF_MD2(cur_cmd.lun,) cur_cmd.sector, MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), cur_cmd.data[cur_cmd.data_select]); @@ -1070,7 +1070,7 @@ ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); #else - cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, + cur_cmd.last_result = storage_read_sectors(IF_MD2(cur_cmd.lun,) cur_cmd.sector, MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), cur_cmd.data[cur_cmd.data_select]); Index: firmware/SOURCES =================================================================== --- firmware/SOURCES (revision 25449) +++ firmware/SOURCES (working copy) @@ -152,9 +152,7 @@ #if (CONFIG_STORAGE & STORAGE_RAMDISK) drivers/ramdisk.c #endif -#ifdef CONFIG_STORAGE_MULTI storage.c -#endif drivers/fat.c #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD) hotswap.c Index: firmware/storage.c =================================================================== --- firmware/storage.c (revision 25449) +++ firmware/storage.c (working copy) @@ -19,7 +19,10 @@ * ****************************************************************************/ #include "storage.h" +#include "kernel.h" +#ifdef CONFIG_STORAGE_MULTI + #define DRIVER_MASK 0xff000000 #define DRIVER_OFFSET 24 #define DRIVE_MASK 0x00ff0000 @@ -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) +#ifdef HAVE_IO_PRIORITY + +/* Same for flash? */ +#define STORAGE_MINIMUM_IDLE_TIME (HZ/10) +#define STORAGE_DELAY_UNIT (HZ/20) + +unsigned int storage_last_thread[NUM_DRIVES]; +unsigned int storage_last_activity[NUM_DRIVES]; + +static bool storage_should_wait(int drive, int prio) { - 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=0) { - storage_drivers[num_drives++] = - (STORAGE_NAND<>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 @@ { #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; ipdist, priority); #endif +#ifdef HAVE_IO_PRIORITY + /* Default to high (foreground) priority */ + thread->io_priority = IO_PRIORITY_IMMEDIATE; +#endif + #if NUM_CORES > 1 thread->core = core; @@ -2918,6 +2923,20 @@ } #endif /* HAVE_PRIORITY_SCHEDULING */ +#ifdef HAVE_IO_PRIORITY +int thread_get_io_priority(unsigned int thread_id) +{ + struct thread_entry *thread = thread_id_entry(thread_id); + return thread->io_priority; +} + +void thread_set_io_priority(unsigned int thread_id,int io_priority) +{ + struct thread_entry *thread = thread_id_entry(thread_id); + thread->io_priority = io_priority; +} +#endif + /*--------------------------------------------------------------------------- * Starts a frozen thread - similar semantics to wakeup_thread except that * the thread is on no scheduler or wakeup queue at all. It exists simply by Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 25449) +++ firmware/drivers/fat.c (working copy) @@ -311,7 +311,7 @@ #endif /* Read the sector */ - rc = storage_read_sectors(drive, startsector,1,buf); + rc = storage_read_sectors(IF_MD2(drive,) startsector,1,buf); if(rc) { DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc); @@ -433,7 +433,7 @@ #endif /* #ifdef HAVE_FAT16SUPPORT */ { /* Read the fsinfo sector */ - rc = storage_read_sectors(drive, + rc = storage_read_sectors(IF_MD2(drive,) startsector + fat_bpb->bpb_fsinfo, 1, buf); if (rc < 0) { @@ -618,7 +618,7 @@ #endif /* Write to the first FAT */ - rc = storage_write_sectors(fce->fat_vol->drive, + rc = storage_write_sectors(IF_MD2(fce->fat_vol->drive,) secnum, 1, sectorbuf); if(rc < 0) @@ -639,7 +639,7 @@ #else secnum += fat_bpbs[0].fatsize; #endif - rc = storage_write_sectors(fce->fat_vol->drive, + rc = storage_write_sectors(IF_MD2(fce->fat_vol->drive,) secnum, 1, sectorbuf); if(rc < 0) { @@ -685,7 +685,7 @@ /* Load the sector if it is not cached */ if(!fce->inuse) { - rc = storage_read_sectors(fat_bpb->drive, + rc = storage_read_sectors(IF_MD2(fat_bpb->drive,) secnum + fat_bpb->startsector,1, sectorbuf); if(rc < 0) @@ -944,7 +944,7 @@ #endif /* #ifdef HAVE_FAT16SUPPORT */ /* update fsinfo */ - rc = storage_read_sectors(fat_bpb->drive, + rc = storage_read_sectors(IF_MD2(fat_bpb->drive,) fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); if (rc < 0) { @@ -957,7 +957,7 @@ intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]); *intptr = htole32(fat_bpb->fsinfo.nextfree); - rc = storage_write_sectors(fat_bpb->drive, + rc = storage_write_sectors(IF_MD2(fat_bpb->drive,) fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); if (rc < 0) { @@ -2110,11 +2110,11 @@ if (start + count > fat_bpb->totalsectors) panicf("Write %ld after data\n", start + count - fat_bpb->totalsectors); - rc = storage_write_sectors(fat_bpb->drive, + rc = storage_write_sectors(IF_MD2(fat_bpb->drive,) start + fat_bpb->startsector, count, buf); } else - rc = storage_read_sectors(fat_bpb->drive, + rc = storage_read_sectors(IF_MD2(fat_bpb->drive,) start + fat_bpb->startsector, count, buf); if (rc < 0) { DEBUGF( "transfer() - Couldn't %s sector %lx"