From 2f8a0081c64534da23fc0fa9cc685eb7454fd9c9 Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Sat, 1 Nov 2008 16:14:28 +0000 Subject: Apply FS#9500. This adds a storage_*() abstraction to replace ata_*(). To do that, it also introduces sd_*, nand_*, and mmc_*. This should be a good first step to allow multi-driver targets, like the Elio (ATA/SD), or the D2 (NAND/SD). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18960 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 1 + firmware/ata_idle_notify.c | 10 +- firmware/common/disk.c | 4 +- firmware/drivers/ata.c | 57 ++++++++++-- firmware/drivers/ata_flash.c | 89 ++++++------------ firmware/drivers/ata_mmc.c | 80 ++++++++++------ firmware/drivers/fat.c | 20 ++-- firmware/export/ata.h | 55 ++++++----- firmware/export/ata_idle_notify.h | 24 ++--- firmware/export/disk.h | 2 +- firmware/export/fat.h | 2 +- firmware/export/nand_id.h | 2 +- firmware/powermgmt.c | 18 ++-- firmware/target/arm/ata-nand-telechips.c | 93 +++---------------- firmware/target/arm/ata-sd-pp.c | 153 +++++++++++++++++-------------- firmware/usb.c | 32 +++---- firmware/usbstack/usb_core.c | 6 +- firmware/usbstack/usb_storage.c | 125 ++++++++++--------------- 18 files changed, 365 insertions(+), 408 deletions(-) (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index 724f0920cf..3bdf089585 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -108,6 +108,7 @@ drivers/serial.c /* Storage */ +storage.c #ifndef SIMULATOR #if (CONFIG_STORAGE & STORAGE_MMC) drivers/ata_mmc.c diff --git a/firmware/ata_idle_notify.c b/firmware/ata_idle_notify.c index 3dde52f391..99b1d4d786 100644 --- a/firmware/ata_idle_notify.c +++ b/firmware/ata_idle_notify.c @@ -25,9 +25,9 @@ #include "kernel.h" #include "string.h" -void register_ata_idle_func(ata_idle_notify function) +void register_storage_idle_func(storage_idle_notify function) { -#if USING_ATA_CALLBACK +#if USING_STORAGE_CALLBACK add_event(DISK_EVENT_SPINUP, true, function); #else function(); /* just call the function now */ @@ -37,8 +37,8 @@ void register_ata_idle_func(ata_idle_notify function) #endif } -#if USING_ATA_CALLBACK -void unregister_ata_idle_func(ata_idle_notify func, bool run) +#if USING_STORAGE_CALLBACK +void unregister_storage_idle_func(storage_idle_notify func, bool run) { remove_event(DISK_EVENT_SPINUP, func); @@ -46,7 +46,7 @@ void unregister_ata_idle_func(ata_idle_notify func, bool run) func(); } -bool call_ata_idle_notifys(bool force) +bool call_storage_idle_notifys(bool force) { static int lock_until = 0; diff --git a/firmware/common/disk.c b/firmware/common/disk.c index 4add5b99df..32b15b8857 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -19,7 +19,7 @@ * ****************************************************************************/ #include -#include "ata.h" +#include "storage.h" #include "debug.h" #include "fat.h" #ifdef HAVE_HOTSWAP @@ -80,7 +80,7 @@ struct partinfo* disk_init(IF_MV_NONVOID(int drive)) struct partinfo* pinfo = part; #endif - ata_read_sectors(IF_MV2(drive,) 0,1, §or); + storage_read_sectors(IF_MV2(drive,) 0,1, §or); /* check that the boot sector is initialized */ if ( (sector[510] != 0x55) || (sector[511] != 0xaa)) { diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index b80f615eb3..c2882a5b74 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -32,6 +32,7 @@ #include "string.h" #include "ata_idle_notify.h" #include "ata-target.h" +#include "storage.h" #define SECTOR_SIZE (512) @@ -148,7 +149,7 @@ static void ata_lock_unlock(struct ata_lock *l) static struct mutex ata_mtx SHAREDBSS_ATTR; static int ata_device; /* device 0 (master) or 1 (slave) */ -int ata_spinup_time = 0; +static int spinup_time = 0; #if (CONFIG_LED == LED_REAL) static bool ata_led_enabled = true; static bool ata_led_on = false; @@ -166,7 +167,7 @@ static struct event_queue ata_queue; static bool initialized = false; static long last_user_activity = -1; -long last_disk_activity = -1; +static long last_disk_activity = -1; static unsigned long total_sectors; static int multisectors; /* number of supported multisectors */ @@ -407,7 +408,7 @@ int ata_read_sectors(IF_MV2(int drive,) } if (spinup) { - ata_spinup_time = current_tick - spinup_start; + spinup_time = current_tick - spinup_start; spinup = false; sleeping = false; poweroff = false; @@ -584,7 +585,7 @@ int ata_write_sectors(IF_MV2(int drive,) } if (spinup) { - ata_spinup_time = current_tick - spinup_start; + spinup_time = current_tick - spinup_start; spinup = false; sleeping = false; poweroff = false; @@ -873,7 +874,7 @@ void ata_sleepnow(void) { if (!spinup && !sleeping && !ata_mtx.locked && initialized) { - call_ata_idle_notifys(false); + call_storage_idle_notifys(false); ata_perform_sleep(); } } @@ -908,7 +909,7 @@ static void ata_thread(void) #ifdef ALLOW_USB_SPINDOWN if(!usb_mode) #endif - call_ata_idle_notifys(false); + call_storage_idle_notifys(false); last_seen_mtx_unlock = 0; } } @@ -921,7 +922,7 @@ static void ata_thread(void) #ifdef ALLOW_USB_SPINDOWN if(!usb_mode) #endif - call_ata_idle_notifys(true); + call_storage_idle_notifys(true); ata_perform_sleep(); last_sleep = current_tick; } @@ -974,7 +975,7 @@ static void ata_thread(void) #ifdef ALLOW_USB_SPINDOWN if(!usb_mode) #endif - call_ata_idle_notifys(false); + call_storage_idle_notifys(false); last_disk_activity = current_tick - sleep_timeout + (HZ/2); break; @@ -1391,3 +1392,43 @@ void ata_set_led_enabled(bool enabled) led(false); } #endif + +long ata_last_disk_activity(void) +{ + return last_disk_activity; +} + +int ata_spinup_time(void) +{ + return spinup_time; +} + +void ata_get_info(struct storage_info *info) +{ + unsigned short *src,*dest; + static char vendor[8]; + static char product[16]; + static char revision[4]; + int i; + info->sector_size = SECTOR_SIZE; + info->num_sectors= ((unsigned long)identify_info[61] << 16 | \ + (unsigned long)identify_info[60]); + + src = (unsigned short*)&identify_info[27]; + dest = (unsigned short*)vendor; + for (i=0;i<4;i++) + dest[i] = htobe16(src[i]); + info->vendor=vendor; + + src = (unsigned short*)&identify_info[31]; + dest = (unsigned short*)product; + for (i=0;i<8;i++) + dest[i] = htobe16(src[i]); + info->product=product; + + src = (unsigned short*)&identify_info[23]; + dest = (unsigned short*)revision; + for (i=0;i<2;i++) + dest[i] = htobe16(src[i]); + info->revision=revision; +} diff --git a/firmware/drivers/ata_flash.c b/firmware/drivers/ata_flash.c index d77e05647b..9b1b64145d 100644 --- a/firmware/drivers/ata_flash.c +++ b/firmware/drivers/ata_flash.c @@ -19,7 +19,7 @@ * ****************************************************************************/ -#include "ata.h" +#include "storage.h" #include #include @@ -42,8 +42,6 @@ #define SECTOR_SIZE (512) -static unsigned short identify_info[SECTOR_SIZE]; -int ata_spinup_time = 0; long last_disk_activity = -1; #if CONFIG_FLASH == FLASH_IFP7XX @@ -386,7 +384,7 @@ int flash_disk_read_sectors(unsigned long start, return done; } -int ata_read_sectors(IF_MV2(int drive,) +int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) @@ -403,7 +401,7 @@ int ata_read_sectors(IF_MV2(int drive,) return 0; } -int ata_write_sectors(IF_MV2(int drive,) +int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) @@ -414,60 +412,7 @@ int ata_write_sectors(IF_MV2(int drive,) return -1; } -/* schedule a single sector write, executed with the the next spinup - (volume 0 only, used for config sector) */ -extern void ata_delayed_write(unsigned long sector, const void* buf) -{ - (void)sector; - (void)buf; -} - -/* write the delayed sector to volume 0 */ -extern void ata_flush(void) -{ - -} - -void ata_spindown(int seconds) -{ - (void)seconds; -} - -bool ata_disk_is_active(void) -{ - return 0; -} - -void ata_sleep(void) -{ -} - -void ata_spin(void) -{ -} - -/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ -int ata_hard_reset(void) -{ - return 0; -} - -int ata_soft_reset(void) -{ - return 0; -} - -void ata_enable(bool on) -{ - (void)on; -} - -unsigned short* ata_get_identify(void) -{ - return identify_info; -} - -int ata_init(void) +int nand_init(void) { int i, id, id2; @@ -499,3 +444,29 @@ int ata_init(void) return 0; } + +long nand_last_disk_activity(void) +{ + return last_disk_activity; +} + +void nand_get_info(struct storage_info *info) +{ + unsigned long blocks; + int i; + + /* firmware version */ + info->revision="0.00"; + + /* vendor field, need better name? */ + info->vendor="Rockbox"; + /* model field, need better name? */ + info->product="TNFL"; + + /* blocks count */ + info->num_sectors = 0; + info->sector_size=SECTOR_SIZE; + + info->serial=0; +} + diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index 1040ab067f..953bb90bbc 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c @@ -19,7 +19,7 @@ * ****************************************************************************/ #include -#include "ata.h" +#include "mmc.h" #include "ata_mmc.h" #include "ata_idle_notify.h" #include "kernel.h" @@ -36,6 +36,7 @@ #include "adc.h" #include "bitswap.h" #include "disk.h" /* for mount/unmount */ +#include "storage.h" #define BLOCK_SIZE 512 /* fixed */ @@ -84,8 +85,7 @@ #define DT_STOP_TRAN 0xfd /* for compatibility */ -int ata_spinup_time = 0; -long last_disk_activity = -1; +static long last_disk_activity = -1; /* private variables */ @@ -601,7 +601,7 @@ static int send_block_send(unsigned char start_token, long timeout, return rc; } -int ata_read_sectors(IF_MV2(int drive,) +int mmc_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) @@ -687,7 +687,7 @@ int ata_read_sectors(IF_MV2(int drive,) return rc; } -int ata_write_sectors(IF_MV2(int drive,) +int mmc_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) @@ -755,25 +755,12 @@ int ata_write_sectors(IF_MV2(int drive,) return rc; } -void ata_spindown(int seconds) -{ - (void)seconds; -} - -bool ata_disk_is_active(void) +bool mmc_disk_is_active(void) { /* this is correct unless early return from write gets implemented */ return mmc_mutex.locked; } -void ata_sleep(void) -{ -} - -void ata_spin(void) -{ -} - static void mmc_thread(void) { struct queue_event ev; @@ -810,7 +797,7 @@ static void mmc_thread(void) { if (!idle_notified) { - call_ata_idle_notifys(false); + call_storage_idle_notifys(false); idle_notified = true; } } @@ -904,12 +891,7 @@ static void mmc_tick(void) } } -int ata_soft_reset(void) -{ - return 0; -} - -void ata_enable(bool on) +void mmc_enable(bool on) { PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, * if not modified below */ @@ -924,7 +906,7 @@ void ata_enable(bool on) card_info[1].initialized = false; } -int ata_init(void) +int mmc_init(void) { int rc = 0; @@ -970,9 +952,51 @@ int ata_init(void) tick_add_task(mmc_tick); initialized = true; } - ata_enable(true); + mmc_enable(true); mutex_unlock(&mmc_mutex); return rc; } +long mmc_last_disk_activity(void) +{ + return last_disk_activity; +} + +void mmc_get_info(IF_MV2(int drive,) struct storage_info *info) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + info->sector_size=card_info[drive].blocksize; + info->num_sectors=card_info[drive].numblocks; + info->vendor="Rockbox"; + if(drive==0) + { + info->product="Internal Storage"; + } + else + { + info->product="MMC Card Slot"; + } + info->revision="0.00"; +} + +#ifdef HAVE_HOTSWAP +bool mmc_removable(IF_MV_NONVOID(int drive)) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + return (drive==1); +} + +bool mmc_present(IF_MV_NONVOID(int drive)) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + return (card_info[drive].initialized && card_info[drive].numblocks > 0); +} +#endif + diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 90be93f4f4..4317b70766 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -24,7 +24,7 @@ #include #include #include "fat.h" -#include "ata.h" +#include "storage.h" #include "debug.h" #include "panic.h" #include "system.h" @@ -300,7 +300,7 @@ int fat_mount(IF_MV2(int volume,) IF_MV2(int drive,) long startsector) #endif /* Read the sector */ - rc = ata_read_sectors(IF_MV2(drive,) startsector,1,buf); + rc = storage_read_sectors(IF_MV2(drive,) startsector,1,buf); if(rc) { DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc); @@ -422,7 +422,7 @@ int fat_mount(IF_MV2(int volume,) IF_MV2(int drive,) long startsector) #endif /* #ifdef HAVE_FAT16SUPPORT */ { /* Read the fsinfo sector */ - rc = ata_read_sectors(IF_MV2(drive,) + rc = storage_read_sectors(IF_MV2(drive,) startsector + fat_bpb->bpb_fsinfo, 1, buf); if (rc < 0) { @@ -597,7 +597,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce, #endif /* Write to the first FAT */ - rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) + rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,) secnum, 1, sectorbuf); if(rc < 0) @@ -618,7 +618,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce, #else secnum += fat_bpbs[0].fatsize; #endif - rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) + rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,) secnum, 1, sectorbuf); if(rc < 0) { @@ -664,7 +664,7 @@ static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,) /* Load the sector if it is not cached */ if(!fce->inuse) { - rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + rc = storage_read_sectors(IF_MV2(fat_bpb->drive,) secnum + fat_bpb->startsector,1, sectorbuf); if(rc < 0) @@ -923,7 +923,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb)) #endif /* #ifdef HAVE_FAT16SUPPORT */ /* update fsinfo */ - rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + rc = storage_read_sectors(IF_MV2(fat_bpb->drive,) fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); if (rc < 0) { @@ -936,7 +936,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb)) intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]); *intptr = htole32(fat_bpb->fsinfo.nextfree); - rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) + rc = storage_write_sectors(IF_MV2(fat_bpb->drive,) fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); if (rc < 0) { @@ -2077,11 +2077,11 @@ static int transfer(IF_MV2(struct bpb* fat_bpb,) if (start + count > fat_bpb->totalsectors) panicf("Write %ld after data\n", start + count - fat_bpb->totalsectors); - rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) + rc = storage_write_sectors(IF_MV2(fat_bpb->drive,) start + fat_bpb->startsector, count, buf); } else - rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + rc = storage_read_sectors(IF_MV2(fat_bpb->drive,) start + fat_bpb->startsector, count, buf); if (rc < 0) { DEBUGF( "transfer() - Couldn't %s sector %lx" diff --git a/firmware/export/ata.h b/firmware/export/ata.h index 164261a40a..f09a4630d3 100644 --- a/firmware/export/ata.h +++ b/firmware/export/ata.h @@ -23,43 +23,40 @@ #include #include "config.h" /* for HAVE_MULTIVOLUME or not */ +#include "mv.h" /* for IF_MV() and friends */ -/* FixMe: These macros are a bit nasty and perhaps misplaced here. - We'll get rid of them once decided on how to proceed with multivolume. */ -#ifdef HAVE_MULTIVOLUME -#define IF_MV(x) x /* optional volume/drive parameter */ -#define IF_MV2(x,y) x,y /* same, for a list of arguments */ -#define IF_MV_NONVOID(x) x /* for prototype with sole volume parameter */ -#define NUM_VOLUMES 2 -#else /* empty definitions if no multi-volume */ -#define IF_MV(x) -#define IF_MV2(x,y) -#define IF_MV_NONVOID(x) void -#define NUM_VOLUMES 1 -#endif +struct storage_info; -extern void ata_enable(bool on); -extern void ata_spindown(int seconds); -extern void ata_sleep(void); -extern void ata_sleepnow(void); +void ata_enable(bool on); +void ata_spindown(int seconds); +void ata_sleep(void); +void ata_sleepnow(void); /* NOTE: DO NOT use this to poll for disk activity. If you are waiting for the disk to become active before doing something use ata_idle_notify.h */ -extern bool ata_disk_is_active(void); -extern int ata_hard_reset(void); -extern int ata_soft_reset(void); -extern int ata_init(void); -extern void ata_close(void); -extern int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf); -extern int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf); -extern void ata_spin(void); +bool ata_disk_is_active(void); +int ata_hard_reset(void); +int ata_soft_reset(void); +int ata_init(void); +void ata_close(void); +int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf); +int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf); +void ata_spin(void); #if (CONFIG_LED == LED_REAL) -extern void ata_set_led_enabled(bool enabled); +void ata_set_led_enabled(bool enabled); +#endif +unsigned short* ata_get_identify(void); +void ata_get_info(IF_MV2(int drive,) struct storage_info *info); +#ifdef HAVE_HOTSWAP +bool ata_removable(IF_MV_NONVOID(int drive)); +bool ata_present(IF_MV_NONVOID(int drive)); #endif -extern unsigned short* ata_get_identify(void); -extern long last_disk_activity; -extern int ata_spinup_time; /* ticks */ + + +long ata_last_disk_activity(void); +int ata_spinup_time(void); /* ticks */ + #endif diff --git a/firmware/export/ata_idle_notify.h b/firmware/export/ata_idle_notify.h index aea2c92b06..ceba2eeda4 100644 --- a/firmware/export/ata_idle_notify.h +++ b/firmware/export/ata_idle_notify.h @@ -26,15 +26,15 @@ #include "events.h" /* - NOTE: ata_idle_notify usage notes.. + NOTE: storage_idle_notify usage notes.. 1) The callbacks are called in the ata thread, not main/your thread. 2) Asynchronous callbacks (like the buffer refill) should be avoided. - If you must use an async callback, remember to check ata_is_active() before + If you must use an async callback, remember to check storage_is_active() before accessing the disk, and do not call any functions between that check and the disk access which may cause a yield (lcd_update() does this!). 3) Do not call any yielding functions in the callback. -4) Do not call ata_sleep in the callbacks. +4) Do not call storage_sleep in the callbacks. 5) Don't Panic! */ @@ -43,21 +43,21 @@ enum { DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1), }; -#define USING_ATA_CALLBACK !defined(SIMULATOR) \ +#define USING_STORAGE_CALLBACK !defined(SIMULATOR) \ && ! ((CONFIG_STORAGE & STORAGE_NAND) \ && (CONFIG_NAND & NAND_IFP7XX)) \ && !defined(BOOTLOADER) -typedef bool (*ata_idle_notify)(void); +typedef bool (*storage_idle_notify)(void); -extern void register_ata_idle_func(ata_idle_notify function); -#if USING_ATA_CALLBACK -extern void unregister_ata_idle_func(ata_idle_notify function, bool run); -extern bool call_ata_idle_notifys(bool force); +extern void register_storage_idle_func(storage_idle_notify function); +#if USING_STORAGE_CALLBACK +extern void unregister_storage_idle_func(storage_idle_notify function, bool run); +extern bool call_storage_idle_notifys(bool force); #else -#define unregister_ata_idle_func(f,r) -#define call_ata_idle_notifys(f) -#define ata_idle_notify_init(s) +#define unregister_storage_idle_func(f,r) +#define call_storage_idle_notifys(f) +#define storage_idle_notify_init(s) #endif #endif /* __ATACALLBACK_H__ */ diff --git a/firmware/export/disk.h b/firmware/export/disk.h index 8d440befaf..cec9bfa3fc 100644 --- a/firmware/export/disk.h +++ b/firmware/export/disk.h @@ -21,7 +21,7 @@ #ifndef _DISK_H_ #define _DISK_H_ -#include "ata.h" /* for volume definitions */ +#include "mv.h" /* for volume definitions */ struct partinfo { unsigned long start; /* first sector (LBA) */ diff --git a/firmware/export/fat.h b/firmware/export/fat.h index 0e83ca8b4d..c99a1a75f8 100644 --- a/firmware/export/fat.h +++ b/firmware/export/fat.h @@ -23,7 +23,7 @@ #define FAT_H #include -#include "ata.h" /* for volume definitions */ +#include "mv.h" /* for volume definitions */ #include "config.h" #define SECTOR_SIZE 512 diff --git a/firmware/export/nand_id.h b/firmware/export/nand_id.h index a47a38eea2..188b6c161a 100644 --- a/firmware/export/nand_id.h +++ b/firmware/export/nand_id.h @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: ata.h 17847 2008-06-28 18:10:04Z bagder $ + * $Id: $ * * Copyright (C) 2002 by Alan Korr * diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 6e0c03c94a..6f0c37b3c7 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -29,7 +29,7 @@ #include "adc.h" #include "string.h" #include "sprintf.h" -#include "ata.h" +#include "storage.h" #include "power.h" #include "button.h" #include "audio.h" @@ -451,7 +451,7 @@ static void handle_auto_poweroff(void) !sleeptimer_active))) { if(TIME_AFTER(current_tick, last_event_tick + timeout) && - TIME_AFTER(current_tick, last_disk_activity + timeout)) + TIME_AFTER(current_tick, storage_last_disk_activity() + timeout)) { sys_poweroff(); } @@ -579,7 +579,7 @@ int pid_i = 0; /* PID integral term */ static inline void charging_algorithm_small_step(void) { - if (ata_disk_is_active()) { + if (storage_disk_is_active()) { /* flag hdd use for charging calculation */ disk_activity_last_cycle = true; } @@ -589,7 +589,7 @@ static inline void charging_algorithm_small_step(void) * If we have a lot of pending writes or if the disk is spining, * fsync the debug log file. */ - if((wrcount > 10) || ((wrcount > 0) && ata_disk_is_active())) { + if((wrcount > 10) || ((wrcount > 0) && storage_disk_is_active())) { fsync(fd); wrcount = 0; } @@ -1014,7 +1014,7 @@ static void power_thread_sleep(int ticks) * the disk is spinning unless we are in USB mode (the disk will most * likely always be spinning in USB mode). */ - if (!ata_disk_is_active() || usb_inserted()) { + if (!storage_disk_is_active() || usb_inserted()) { avgbat += battery_adc_voltage() - (avgbat / BATT_AVE_SAMPLES); /* * battery_millivolts is the millivolt-scaled filtered battery value. @@ -1152,10 +1152,10 @@ void shutdown_hw(void) #ifdef HAVE_LCD_BITMAP glyph_cache_save(); #endif - if(ata_disk_is_active()) - ata_spindown(1); + if(storage_disk_is_active()) + storage_spindown(1); } - while(ata_disk_is_active()) + while(storage_disk_is_active()) sleep(HZ/10); #if CONFIG_CODEC != SWCODEC @@ -1166,7 +1166,7 @@ void shutdown_hw(void) /* If HD is still active we try to wait for spindown, otherwise the shutdown_timeout in power_thread_sleep will force a power off */ - while(ata_disk_is_active()) + while(storage_disk_is_active()) sleep(HZ/10); #ifndef IAUDIO_X5 lcd_set_contrast(0); diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c index 1c135650f1..4276c10d64 100644 --- a/firmware/target/arm/ata-nand-telechips.c +++ b/firmware/target/arm/ata-nand-telechips.c @@ -18,7 +18,7 @@ * KIND, either express or implied. * ****************************************************************************/ -#include "ata.h" +#include "nand.h" #include "ata-nand-target.h" #include "system.h" #include @@ -31,6 +31,7 @@ #include "lcd.h" #include "font.h" #include "button.h" +#include "storage.h" #include #define SECTOR_SIZE 512 @@ -43,9 +44,6 @@ int ata_spinup_time = 0; long last_disk_activity = -1; -/* as we aren't actually ata manually fill some fields */ -static unsigned short ata_identify[SECTOR_SIZE/2]; - /** static, private data **/ static bool initialized = false; @@ -662,7 +660,7 @@ static void read_write_cache_segment(int bank, int phys_segment) } -int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, +int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) { #ifdef HAVE_MULTIVOLUME @@ -702,7 +700,7 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, return 0; } -int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, +int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* outbuf) { #ifdef HAVE_MULTIVOLUME @@ -716,83 +714,21 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, return -1; } -void ata_spindown(int seconds) -{ - /* null */ - (void)seconds; -} - -bool ata_disk_is_active(void) -{ - /* null */ - return 0; -} - -void ata_sleep(void) +void nand_get_info(struct storage_info *info) { - /* null */ -} - -void ata_spin(void) -{ - /* null */ -} - -/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ -int ata_hard_reset(void) -{ - /* null */ - return 0; -} - -int ata_soft_reset(void) -{ - /* null */ - return 0; -} - -void ata_enable(bool on) -{ - /* null - flash controller is enabled/disabled as needed. */ - (void)on; -} - -static void fill_identify(void) -{ - char buf[80]; - unsigned short *wbuf = (unsigned short *) buf; - unsigned long blocks; - int i; - - memset(ata_identify, 0, sizeof(ata_identify)); - /* firmware version */ - memset(buf, ' ', 8); - memcpy(buf, "0.00", 4); + info->revision="0.00"; - for (i = 0; i < 4; i++) - ata_identify[23 + i] = betoh16(wbuf[i]); - - /* model field, need better name? */ - memset(buf, ' ', 80); - memcpy(buf, "TNFL", 4); - - for (i = 0; i < 40; i++) - ata_identify[27 + i] = betoh16(wbuf[i]); + info->vendor="Rockbox"; + info->product="Internal Storage"; /* blocks count */ - blocks = (pages_per_block * blocks_per_bank / SECTOR_SIZE) - * page_size * total_banks; - ata_identify[60] = blocks & 0xffff; - ata_identify[61] = blocks >> 16; - - /* TODO: discover where is s/n in TNFL */ - for (i = 10; i < 20; i++) { - ata_identify[i] = 0; - } + info->num_sectors = (pages_per_block * blocks_per_bank / SECTOR_SIZE) + * page_size * total_banks; + info->sector_size=SECTOR_SIZE; } -int ata_init(void) +int nand_init(void) { int i, bank, phys_segment; unsigned char spare_buf[16]; @@ -909,13 +845,12 @@ int ata_init(void) } #endif - fill_identify(); initialized = true; return 0; } -unsigned short* ata_get_identify(void) +long nand_last_disk_activity(void) { - return ata_identify; + return last_disk_activity; } diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c index b15b3634d8..a12aafc718 100644 --- a/firmware/target/arm/ata-sd-pp.c +++ b/firmware/target/arm/ata-sd-pp.c @@ -30,6 +30,8 @@ #include "cpu.h" #include "panic.h" #include "usb.h" +#include "sd.h" +#include "storage.h" #define BLOCK_SIZE 512 #define SECTOR_SIZE 512 @@ -128,15 +130,13 @@ /** global, exported variables **/ #ifdef HAVE_MULTIVOLUME -#define NUM_VOLUMES 2 +#define NUM_DRIVES 2 #else -#define NUM_VOLUMES 1 +#define NUM_DRIVES 1 #endif /* for compatibility */ -int ata_spinup_time = 0; - -long last_disk_activity = -1; +static long last_disk_activity = -1; /** static, private data **/ static bool initialized = false; @@ -153,7 +153,7 @@ struct sd_card_status int retry_max; }; -static struct sd_card_status sd_status[NUM_VOLUMES] = +static struct sd_card_status sd_status[NUM_DRIVES] = { { 0, 1 }, #ifdef HAVE_MULTIVOLUME @@ -786,12 +786,12 @@ static void sd_select_device(int card_no) /* API Functions */ -static void ata_led(bool onoff) +static void sd_led(bool onoff) { led(onoff); } -int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, +int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) { #ifndef HAVE_MULTIVOLUME @@ -805,14 +805,14 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, mutex_lock(&sd_mtx); - ata_led(true); + sd_led(true); -ata_read_retry: +sd_read_retry: if (drive != 0 && !card_detect_target()) { /* no external sd-card inserted */ ret = -EC_NOCARD; - goto ata_read_error; + goto sd_read_error; } sd_select_device(drive); @@ -820,7 +820,7 @@ ata_read_retry: if (currcard->initialized < 0) { ret = currcard->initialized; - goto ata_read_error; + goto sd_read_error; } last_disk_activity = current_tick; @@ -834,7 +834,7 @@ ata_read_retry: { ret = sd_select_bank(bank); if (ret < 0) - goto ata_read_error; + goto sd_read_error; } start -= bank * BLOCKS_PER_BANK; @@ -842,7 +842,7 @@ ata_read_retry: ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); if (ret < 0) - goto ata_read_error; + goto sd_read_error; BLOCK_COUNT_REG = incount; @@ -858,7 +858,7 @@ ata_read_retry: ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); } if (ret < 0) - goto ata_read_error; + goto sd_read_error; /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ @@ -874,38 +874,38 @@ ata_read_retry: } ret = -EC_FIFO_READ_FULL; - goto ata_read_error; + goto sd_read_error; } last_disk_activity = current_tick; ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); if (ret < 0) - goto ata_read_error; + goto sd_read_error; ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT); if (ret < 0) - goto ata_read_error; + goto sd_read_error; while (1) { - ata_led(false); + sd_led(false); mutex_unlock(&sd_mtx); return ret; -ata_read_error: +sd_read_error: if (sd_status[drive].retry < sd_status[drive].retry_max && ret != -EC_NOCARD) { sd_status[drive].retry++; currcard->initialized = 0; - goto ata_read_retry; + goto sd_read_retry; } } } -int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, +int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* outbuf) { /* Write support is not finished yet */ @@ -920,14 +920,14 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, mutex_lock(&sd_mtx); - ata_led(true); + sd_led(true); -ata_write_retry: +sd_write_retry: if (drive != 0 && !card_detect_target()) { /* no external sd-card inserted */ ret = -EC_NOCARD; - goto ata_write_error; + goto sd_write_error; } sd_select_device(drive); @@ -935,7 +935,7 @@ ata_write_retry: if (currcard->initialized < 0) { ret = currcard->initialized; - goto ata_write_error; + goto sd_write_error; } /* Only switch banks with non-SDHC cards */ @@ -947,7 +947,7 @@ ata_write_retry: { ret = sd_select_bank(bank); if (ret < 0) - goto ata_write_error; + goto sd_write_error; } start -= bank * BLOCKS_PER_BANK; @@ -957,7 +957,7 @@ ata_write_retry: ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY); if (ret < 0) - goto ata_write_error; + goto sd_write_error; BLOCK_COUNT_REG = count; @@ -973,7 +973,7 @@ ata_write_retry: ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); } if (ret < 0) - goto ata_write_error; + goto sd_write_error; buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN; @@ -996,7 +996,7 @@ ata_write_retry: } ret = -EC_FIFO_WR_EMPTY; - goto ata_write_error; + goto sd_write_error; } last_disk_activity = current_tick; @@ -1004,31 +1004,31 @@ ata_write_retry: if (!sd_poll_status(DATA_DONE, 0x80000)) { ret = -EC_FIFO_WR_DONE; - goto ata_write_error; + goto sd_write_error; } ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); if (ret < 0) - goto ata_write_error; + goto sd_write_error; ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT); if (ret < 0) - goto ata_write_error; + goto sd_write_error; while (1) { - ata_led(false); + sd_led(false); mutex_unlock(&sd_mtx); return ret; -ata_write_error: +sd_write_error: if (sd_status[drive].retry < sd_status[drive].retry_max && ret != -EC_NOCARD) { sd_status[drive].retry++; currcard->initialized = 0; - goto ata_write_retry; + goto sd_write_retry; } } } @@ -1088,7 +1088,7 @@ static void sd_thread(void) if (!idle_notified) { - call_ata_idle_notifys(false); + call_storage_idle_notifys(false); idle_notified = true; } } @@ -1106,37 +1106,7 @@ static void sd_thread(void) } } - -void ata_spindown(int seconds) -{ - (void)seconds; -} - -bool ata_disk_is_active(void) -{ - return 0; -} - -void ata_sleep(void) -{ -} - -void ata_spin(void) -{ -} - -/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ -int ata_hard_reset(void) -{ - return 0; -} - -int ata_soft_reset(void) -{ - return 0; -} - -void ata_enable(bool on) +void sd_enable(bool on) { if(on) { @@ -1170,7 +1140,7 @@ void card_enable_monitoring_target(bool on) } #endif -int ata_init(void) +int sd_init(void) { int ret = 0; @@ -1179,7 +1149,7 @@ int ata_init(void) mutex_lock(&sd_mtx); - ata_led(false); + sd_led(false); if (!initialized) { @@ -1324,3 +1294,46 @@ void microsd_int(void) } #endif /* HAVE_HOTSWAP */ + +long sd_last_disk_activity(void) +{ + return last_disk_activity; +} + +void sd_get_info(IF_MV2(int drive,) struct storage_info *info) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + info->sector_size=card_info[drive].block_size; + info->num_sectors=card_info[drive].numblocks; + info->vendor="Rockbox"; + if(drive==0) + { + info->product="Internal Storage"; + } + else + { + info->product="SD Card Slot"; + } + info->revision="0.00"; +} + +#ifdef HAVE_HOTSWAP +bool sd_removable(IF_MV_NONVOID(int drive)) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + return (drive==1); +} + +bool sd_present(IF_MV_NONVOID(int drive)) +{ +#ifndef HAVE_MULTIVOLUME + const int drive=0; +#endif + return (card_info[drive].initialized && card_info[drive].numblocks > 0); +} +#endif + diff --git a/firmware/usb.c b/firmware/usb.c index 9064987ed1..bfb99e0607 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -29,7 +29,7 @@ #include "thread.h" #include "system.h" #include "debug.h" -#include "ata.h" +#include "storage.h" #include "fat.h" #include "disk.h" #include "panic.h" @@ -86,7 +86,7 @@ static struct event_queue usb_queue; static int last_usb_status; static bool usb_monitor_enabled; #ifdef HAVE_USBSTACK -static bool exclusive_ata_access; +static bool exclusive_storage_access; #endif @@ -105,9 +105,9 @@ static void usb_slave_mode(bool on) if(on) { DEBUGF("Entering USB slave mode\n"); - ata_soft_reset(); - ata_init(); - ata_enable(false); + storage_soft_reset(); + storage_init(); + storage_enable(false); usb_enable(true); } else @@ -119,9 +119,9 @@ static void usb_slave_mode(bool on) usb_enable(false); - rc = ata_init(); + rc = storage_init(); if(rc) - panicf("ata: %d",rc); + panicf("storage: %d",rc); rc = disk_mount_all(); if (rc <= 0) /* no partition */ @@ -134,7 +134,7 @@ static void usb_slave_mode(bool on) static void try_reboot(void) { #ifdef HAVE_DISK_STORAGE - ata_sleepnow(); /* Immediately spindown the disk. */ + storage_sleepnow(); /* Immediately spindown the disk. */ sleep(HZ*2); #endif @@ -262,7 +262,7 @@ static void usb_thread(void) #ifdef HAVE_PRIORITY_SCHEDULING thread_set_priority(usb_thread_entry,PRIORITY_REALTIME); #endif - exclusive_ata_access = true; + exclusive_storage_access = true; #else usb_slave_mode(true); @@ -310,12 +310,12 @@ static void usb_thread(void) usb_state = USB_EXTRACTED; #ifdef HAVE_USBSTACK - if(exclusive_ata_access) + if(exclusive_storage_access) { int rc = disk_mount_all(); if (rc <= 0) /* no partition */ panicf("mount: %d",rc); - exclusive_ata_access = false; + exclusive_storage_access = false; #endif /* Tell all threads that we are back in business */ num_acks_to_expect = @@ -455,7 +455,7 @@ void usb_init(void) { usb_state = USB_EXTRACTED; #ifdef HAVE_USBSTACK - exclusive_ata_access = false; + exclusive_storage_access = false; #endif usb_monitor_enabled = false; countdown = -1; @@ -561,7 +561,7 @@ void usb_request_exclusive_ata(void) * currently the best one. We want to get rid of having to boost the cpu * for usb anyway */ trigger_cpu_boost(); - if(!exclusive_ata_access) { + if(!exclusive_storage_access) { queue_post(&usb_queue, USB_REQUEST_DISK, 0); } } @@ -569,15 +569,15 @@ void usb_request_exclusive_ata(void) void usb_release_exclusive_ata(void) { cancel_cpu_boost(); - if(exclusive_ata_access) { + if(exclusive_storage_access) { queue_post(&usb_queue, USB_RELEASE_DISK, 0); - exclusive_ata_access = false; + exclusive_storage_access = false; } } bool usb_exclusive_ata(void) { - return exclusive_ata_access; + return exclusive_storage_access; } #endif diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index fa0ff5ea04..7724049415 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -50,7 +50,7 @@ #include "as3514.h" #endif -#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) +#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) && (CONFIG_STORAGE & STORAGE_ATA) #include "ata.h" #endif @@ -281,7 +281,7 @@ static void set_serial_descriptor(void) } usb_string_iSerial.bLength=68; } -#else +#elif (CONFIG_STORAGE & STORAGE_ATA) /* If we don't know the device serial number, use the one * from the disk */ static void set_serial_descriptor(void) @@ -300,6 +300,8 @@ static void set_serial_descriptor(void) } usb_string_iSerial.bLength=84; } +#else +#error No set_serial_descriptor() implementation for this target #endif void usb_core_init(void) diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 198ff46a56..24ac00138d 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -24,7 +24,7 @@ #include "usb_drv.h" //#define LOGF_ENABLE #include "logf.h" -#include "ata.h" +#include "storage.h" #include "hotswap.h" #include "disk.h" /* Needed to get at the audio buffer */ @@ -36,7 +36,7 @@ /* The SD card driver on Sansa c200 and e200 can cause write corruption, * often triggered by simultaneous USB activity. This can be largely avoided - * by not overlapping ata_write_sector() with USB transfers. This does reduce + * by not overlapping storage_write_sector() with USB transfers. This does reduce * write performance, so we only do it for the affected DAPs */ #if (CONFIG_STORAGE & STORAGE_SD) @@ -147,10 +147,8 @@ struct inquiry_data { struct report_lun_data { unsigned int lun_list_length; unsigned int reserved1; - unsigned char lun0[8]; -#ifdef HAVE_HOTSWAP - unsigned char lun1[8]; -#endif + // TODO this should be cleaned up with the VOLUMES vs DRIVES mess + unsigned char luns[NUM_VOLUMES][8]; } __attribute__ ((packed)); struct sense_data { @@ -263,7 +261,7 @@ static void send_command_result(void *data,int size); static void send_command_failed_result(void); static void send_block_data(void *data,int size); static void receive_block_data(void *data,int size); -static void identify2inquiry(int lun); +static void fill_inquiry(IF_MV_NONVOID(int lun)); static void send_and_read_next(void); static bool ejected[NUM_VOLUMES]; @@ -289,7 +287,7 @@ static bool check_disk_present(IF_MV_NONVOID(int volume)) return true; #else unsigned char sector[512]; - return ata_read_sectors(IF_MV2(volume,)0,1,sector) == 0; + return storage_read_sectors(IF_MV2(volume,)0,1,sector) == 0; #endif } @@ -460,7 +458,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length) cur_cmd.data[cur_cmd.data_select], MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); #else - int result = ata_write_sectors(IF_MV2(cur_cmd.lun,) + int result = storage_write_sectors(IF_MV2(cur_cmd.lun,) cur_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), @@ -639,7 +637,7 @@ static void send_and_read_next(void) ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); #else - cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,) + cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,) cur_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), @@ -654,6 +652,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) /* USB Mass Storage assumes LBA capability. TODO: support 48-bit LBA */ + struct storage_info info; unsigned int length = cbw->data_transfer_length; unsigned int block_size = 0; unsigned int block_count = 0; @@ -664,25 +663,20 @@ static void handle_scsi(struct command_block_wrapper* cbw) unsigned char lun = cbw->lun; #endif unsigned int block_size_mult = 1; + storage_get_info(IF_MV2(lun,)&info); #ifdef USB_USE_RAMDISK block_size = SECTOR_SIZE; block_count = RAMDISK_SIZE; #else -#if (CONFIG_STORAGE & STORAGE_SD) || defined(HAVE_HOTSWAP) - tCardInfo* cinfo = card_get_info(lun); - if(cinfo->initialized && cinfo->numblocks > 0) { - block_size = cinfo->blocksize; - block_count = cinfo->numblocks; - } - else { + block_size=info.sector_size; + block_count=info.num_sectors; +#endif + +#ifdef HAVE_HOTSWAP + if(storage_removable(IF_MV(lun)) && !storage_present(IF_MV(lun))) { ejected[lun] = true; try_release_ata(); } -#else - unsigned short* identify = ata_get_identify(); - block_size = SECTOR_SIZE; - block_count = (identify[61] << 16 | identify[60]); -#endif #endif if(ejected[lun]) @@ -719,19 +713,22 @@ static void handle_scsi(struct command_block_wrapper* cbw) case SCSI_REPORT_LUNS: { logf("scsi inquiry %d",lun); int allocation_length=0; + int i; allocation_length|=(cbw->command_block[6]<<24); allocation_length|=(cbw->command_block[7]<<16); allocation_length|=(cbw->command_block[8]<<8); allocation_length|=(cbw->command_block[9]); memset(tb.lun_data,0,sizeof(struct report_lun_data)); + tb.lun_data->lun_list_length=htobe32(8*NUM_VOLUMES); + for(i=0;ilun_list_length=htobe32(16); - tb.lun_data->lun1[1]=1; -#else - tb.lun_data->lun_list_length=htobe32(8); + if(storage_removable(IF_MV(i))) + tb.lun_data->luns[i][1]=1; + else #endif - tb.lun_data->lun0[1]=0; - + tb.lun_data->luns[i][1]=0; + } send_command_result(tb.lun_data, MIN(sizeof(struct report_lun_data), length)); break; @@ -739,7 +736,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) case SCSI_INQUIRY: logf("scsi inquiry %d",lun); - identify2inquiry(lun); + fill_inquiry(IF_MV(lun)); length = MIN(length, cbw->command_block[4]); send_command_result(tb.inquiry, MIN(sizeof(struct inquiry_data), length)); @@ -975,7 +972,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); #else - cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,) + cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,) cur_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), @@ -1072,46 +1069,30 @@ static void send_csw(int status) } } -/* convert ATA IDENTIFY to SCSI INQUIRY */ -static void identify2inquiry(int lun) +static void copy_padded(char *dest, char *src, int len) { -#ifdef HAVE_FLASH_STORAGE - if(lun==0) { - memcpy(&tb.inquiry->VendorId,"Rockbox ",8); - memcpy(&tb.inquiry->ProductId,"Internal Storage",16); - memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); - } - else { - memcpy(&tb.inquiry->VendorId,"Rockbox ",8); - memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16); - memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); - } -#else - unsigned int i; - unsigned short* dest; - unsigned short* src; - unsigned short* identify = ata_get_identify(); - (void)lun; - memset(tb.inquiry, 0, sizeof(struct inquiry_data)); - -#if 0 - if (identify[82] & 4) - tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; -#endif + int i=0; + while(src[i]!=0 && iVendorId; - for (i=0;i<12;i++) - dest[i] = htobe16(src[i]); - - src = (unsigned short*)&identify[23]; - dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel; - for (i=0;i<2;i++) - dest[i] = htobe16(src[i]); -#endif +/* build SCSI INQUIRY */ +static void fill_inquiry(IF_MV_NONVOID(int lun)) +{ + memset(tb.inquiry, 0, sizeof(struct inquiry_data)); + struct storage_info info; + storage_get_info(IF_MV2(lun,)&info); + copy_padded(tb.inquiry->VendorId,info.vendor,sizeof(tb.inquiry->VendorId)); + copy_padded(tb.inquiry->ProductId,info.product,sizeof(tb.inquiry->ProductId)); + copy_padded(tb.inquiry->ProductRevisionLevel,info.revision,sizeof(tb.inquiry->ProductRevisionLevel)); tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE; tb.inquiry->AdditionalLength = 0x1f; @@ -1119,14 +1100,6 @@ static void identify2inquiry(int lun) tb.inquiry->Versions = 4; /* SPC-2 */ tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ -#if 0 -#ifdef HAVE_HOTSWAP - if(lun>0) - tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; -#endif -#endif - /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set. - TODO : this can probably be solved by providing caching mode page */ #ifdef TOSHIBA_GIGABEAT_S tb.inquiry->DeviceTypeModifier = 0; #else -- cgit v1.2.3