summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-11-01 16:14:28 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-11-01 16:14:28 +0000
commit2f8a0081c64534da23fc0fa9cc685eb7454fd9c9 (patch)
tree84dbdbd5326cb48f43d2ebd5a4c86e992c1d5288 /firmware
parent646cac0bde7b11fa7bcb670d1d76eec78e360485 (diff)
downloadrockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.zip
rockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.tar.gz
rockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.tar.bz2
rockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.tar.xz
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
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/ata_idle_notify.c10
-rw-r--r--firmware/common/disk.c4
-rw-r--r--firmware/drivers/ata.c57
-rw-r--r--firmware/drivers/ata_flash.c89
-rw-r--r--firmware/drivers/ata_mmc.c80
-rw-r--r--firmware/drivers/fat.c20
-rw-r--r--firmware/export/ata.h55
-rw-r--r--firmware/export/ata_idle_notify.h24
-rw-r--r--firmware/export/disk.h2
-rw-r--r--firmware/export/fat.h2
-rw-r--r--firmware/export/nand_id.h2
-rw-r--r--firmware/powermgmt.c18
-rw-r--r--firmware/target/arm/ata-nand-telechips.c93
-rw-r--r--firmware/target/arm/ata-sd-pp.c153
-rw-r--r--firmware/usb.c32
-rw-r--r--firmware/usbstack/usb_core.c6
-rw-r--r--firmware/usbstack/usb_storage.c125
18 files changed, 365 insertions, 408 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 724f092..3bdf089 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 3dde52f..99b1d4d 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 4add5b9..32b15b8 100644
--- a/firmware/common/disk.c
+++ b/firmware/common/disk.c
@@ -19,7 +19,7 @@
*
****************************************************************************/
#include <stdio.h>
-#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, &sector);
+ storage_read_sectors(IF_MV2(drive,) 0,1, &sector);
/* 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 b80f615..c2882a5 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 d77e056..9b1b641 100644
--- a/firmware/drivers/ata_flash.c
+++ b/firmware/drivers/ata_flash.c
@@ -19,7 +19,7 @@
*
****************************************************************************/
-#include "ata.h"
+#include "storage.h"
#include <stdbool.h>
#include <string.h>
@@ -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 1040ab0..953bb90 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -19,7 +19,7 @@
*
****************************************************************************/
#include <stdbool.h>
-#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 90be93f..4317b70 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -24,7 +24,7 @@
#include <ctype.h>
#include <stdbool.h>
#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 164261a..f09a463 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -23,43 +23,40 @@
#include <stdbool.h>
#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 aea2c92..ceba2ee 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 8d440be..cec9bfa 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 0e83ca8..c99a1a7 100644
--- a/firmware/export/fat.h
+++ b/firmware/export/fat.h
@@ -23,7 +23,7 @@
#define FAT_H
#include <stdbool.h>
-#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 a47a38e..188b6c1 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 6e0c03c..6f0c37b 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 1c13565..4276c10 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 <string.h>
@@ -31,6 +31,7 @@
#include "lcd.h"
#include "font.h"
#include "button.h"
+#include "storage.h"
#include <sprintf.h>
#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 b15b363..a12aafc 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 9064987..bfb99e0 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 fa0ff5e..7724049 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 198ff46..24ac001 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;i<NUM_VOLUMES;i++)
+ {
#ifdef HAVE_HOTSWAP
- tb.lun_data->lun_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 && i<len)
+ {
+ dest[i]=src[i];
+ i++;
+ }
+ while(i<len)
+ {
+ dest[i]=' ';
+ i++;
+ }
+}
- /* ATA only has a 'model' field, so we copy the
- first 8 bytes to 'vendor' and the rest to 'product' (they are
- consecutive in the inquiry struct) */
- src = (unsigned short*)&identify[27];
- dest = (unsigned short*)&tb.inquiry->VendorId;
- 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