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.tar.gz
rockbox-2f8a0081c64534da23fc0fa9cc685eb7454fd9c9.zip
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 724f0920cf..3bdf089585 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -108,6 +108,7 @@ drivers/serial.c
108 108
109 109
110/* Storage */ 110/* Storage */
111storage.c
111#ifndef SIMULATOR 112#ifndef SIMULATOR
112#if (CONFIG_STORAGE & STORAGE_MMC) 113#if (CONFIG_STORAGE & STORAGE_MMC)
113drivers/ata_mmc.c 114drivers/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 @@
25#include "kernel.h" 25#include "kernel.h"
26#include "string.h" 26#include "string.h"
27 27
28void register_ata_idle_func(ata_idle_notify function) 28void register_storage_idle_func(storage_idle_notify function)
29{ 29{
30#if USING_ATA_CALLBACK 30#if USING_STORAGE_CALLBACK
31 add_event(DISK_EVENT_SPINUP, true, function); 31 add_event(DISK_EVENT_SPINUP, true, function);
32#else 32#else
33 function(); /* just call the function now */ 33 function(); /* just call the function now */
@@ -37,8 +37,8 @@ void register_ata_idle_func(ata_idle_notify function)
37#endif 37#endif
38} 38}
39 39
40#if USING_ATA_CALLBACK 40#if USING_STORAGE_CALLBACK
41void unregister_ata_idle_func(ata_idle_notify func, bool run) 41void unregister_storage_idle_func(storage_idle_notify func, bool run)
42{ 42{
43 remove_event(DISK_EVENT_SPINUP, func); 43 remove_event(DISK_EVENT_SPINUP, func);
44 44
@@ -46,7 +46,7 @@ void unregister_ata_idle_func(ata_idle_notify func, bool run)
46 func(); 46 func();
47} 47}
48 48
49bool call_ata_idle_notifys(bool force) 49bool call_storage_idle_notifys(bool force)
50{ 50{
51 static int lock_until = 0; 51 static int lock_until = 0;
52 52
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 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdio.h> 21#include <stdio.h>
22#include "ata.h" 22#include "storage.h"
23#include "debug.h" 23#include "debug.h"
24#include "fat.h" 24#include "fat.h"
25#ifdef HAVE_HOTSWAP 25#ifdef HAVE_HOTSWAP
@@ -80,7 +80,7 @@ struct partinfo* disk_init(IF_MV_NONVOID(int drive))
80 struct partinfo* pinfo = part; 80 struct partinfo* pinfo = part;
81#endif 81#endif
82 82
83 ata_read_sectors(IF_MV2(drive,) 0,1, &sector); 83 storage_read_sectors(IF_MV2(drive,) 0,1, &sector);
84 /* check that the boot sector is initialized */ 84 /* check that the boot sector is initialized */
85 if ( (sector[510] != 0x55) || 85 if ( (sector[510] != 0x55) ||
86 (sector[511] != 0xaa)) { 86 (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 @@
32#include "string.h" 32#include "string.h"
33#include "ata_idle_notify.h" 33#include "ata_idle_notify.h"
34#include "ata-target.h" 34#include "ata-target.h"
35#include "storage.h"
35 36
36#define SECTOR_SIZE (512) 37#define SECTOR_SIZE (512)
37 38
@@ -148,7 +149,7 @@ static void ata_lock_unlock(struct ata_lock *l)
148static struct mutex ata_mtx SHAREDBSS_ATTR; 149static struct mutex ata_mtx SHAREDBSS_ATTR;
149static int ata_device; /* device 0 (master) or 1 (slave) */ 150static int ata_device; /* device 0 (master) or 1 (slave) */
150 151
151int ata_spinup_time = 0; 152static int spinup_time = 0;
152#if (CONFIG_LED == LED_REAL) 153#if (CONFIG_LED == LED_REAL)
153static bool ata_led_enabled = true; 154static bool ata_led_enabled = true;
154static bool ata_led_on = false; 155static bool ata_led_on = false;
@@ -166,7 +167,7 @@ static struct event_queue ata_queue;
166static bool initialized = false; 167static bool initialized = false;
167 168
168static long last_user_activity = -1; 169static long last_user_activity = -1;
169long last_disk_activity = -1; 170static long last_disk_activity = -1;
170 171
171static unsigned long total_sectors; 172static unsigned long total_sectors;
172static int multisectors; /* number of supported multisectors */ 173static int multisectors; /* number of supported multisectors */
@@ -407,7 +408,7 @@ int ata_read_sectors(IF_MV2(int drive,)
407 } 408 }
408 409
409 if (spinup) { 410 if (spinup) {
410 ata_spinup_time = current_tick - spinup_start; 411 spinup_time = current_tick - spinup_start;
411 spinup = false; 412 spinup = false;
412 sleeping = false; 413 sleeping = false;
413 poweroff = false; 414 poweroff = false;
@@ -584,7 +585,7 @@ int ata_write_sectors(IF_MV2(int drive,)
584 } 585 }
585 586
586 if (spinup) { 587 if (spinup) {
587 ata_spinup_time = current_tick - spinup_start; 588 spinup_time = current_tick - spinup_start;
588 spinup = false; 589 spinup = false;
589 sleeping = false; 590 sleeping = false;
590 poweroff = false; 591 poweroff = false;
@@ -873,7 +874,7 @@ void ata_sleepnow(void)
873{ 874{
874 if (!spinup && !sleeping && !ata_mtx.locked && initialized) 875 if (!spinup && !sleeping && !ata_mtx.locked && initialized)
875 { 876 {
876 call_ata_idle_notifys(false); 877 call_storage_idle_notifys(false);
877 ata_perform_sleep(); 878 ata_perform_sleep();
878 } 879 }
879} 880}
@@ -908,7 +909,7 @@ static void ata_thread(void)
908#ifdef ALLOW_USB_SPINDOWN 909#ifdef ALLOW_USB_SPINDOWN
909 if(!usb_mode) 910 if(!usb_mode)
910#endif 911#endif
911 call_ata_idle_notifys(false); 912 call_storage_idle_notifys(false);
912 last_seen_mtx_unlock = 0; 913 last_seen_mtx_unlock = 0;
913 } 914 }
914 } 915 }
@@ -921,7 +922,7 @@ static void ata_thread(void)
921#ifdef ALLOW_USB_SPINDOWN 922#ifdef ALLOW_USB_SPINDOWN
922 if(!usb_mode) 923 if(!usb_mode)
923#endif 924#endif
924 call_ata_idle_notifys(true); 925 call_storage_idle_notifys(true);
925 ata_perform_sleep(); 926 ata_perform_sleep();
926 last_sleep = current_tick; 927 last_sleep = current_tick;
927 } 928 }
@@ -974,7 +975,7 @@ static void ata_thread(void)
974#ifdef ALLOW_USB_SPINDOWN 975#ifdef ALLOW_USB_SPINDOWN
975 if(!usb_mode) 976 if(!usb_mode)
976#endif 977#endif
977 call_ata_idle_notifys(false); 978 call_storage_idle_notifys(false);
978 last_disk_activity = current_tick - sleep_timeout + (HZ/2); 979 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
979 break; 980 break;
980 981
@@ -1391,3 +1392,43 @@ void ata_set_led_enabled(bool enabled)
1391 led(false); 1392 led(false);
1392} 1393}
1393#endif 1394#endif
1395
1396long ata_last_disk_activity(void)
1397{
1398 return last_disk_activity;
1399}
1400
1401int ata_spinup_time(void)
1402{
1403 return spinup_time;
1404}
1405
1406void ata_get_info(struct storage_info *info)
1407{
1408 unsigned short *src,*dest;
1409 static char vendor[8];
1410 static char product[16];
1411 static char revision[4];
1412 int i;
1413 info->sector_size = SECTOR_SIZE;
1414 info->num_sectors= ((unsigned long)identify_info[61] << 16 | \
1415 (unsigned long)identify_info[60]);
1416
1417 src = (unsigned short*)&identify_info[27];
1418 dest = (unsigned short*)vendor;
1419 for (i=0;i<4;i++)
1420 dest[i] = htobe16(src[i]);
1421 info->vendor=vendor;
1422
1423 src = (unsigned short*)&identify_info[31];
1424 dest = (unsigned short*)product;
1425 for (i=0;i<8;i++)
1426 dest[i] = htobe16(src[i]);
1427 info->product=product;
1428
1429 src = (unsigned short*)&identify_info[23];
1430 dest = (unsigned short*)revision;
1431 for (i=0;i<2;i++)
1432 dest[i] = htobe16(src[i]);
1433 info->revision=revision;
1434}
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 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "ata.h" 22#include "storage.h"
23#include <stdbool.h> 23#include <stdbool.h>
24#include <string.h> 24#include <string.h>
25 25
@@ -42,8 +42,6 @@
42 42
43#define SECTOR_SIZE (512) 43#define SECTOR_SIZE (512)
44 44
45static unsigned short identify_info[SECTOR_SIZE];
46int ata_spinup_time = 0;
47long last_disk_activity = -1; 45long last_disk_activity = -1;
48 46
49#if CONFIG_FLASH == FLASH_IFP7XX 47#if CONFIG_FLASH == FLASH_IFP7XX
@@ -386,7 +384,7 @@ int flash_disk_read_sectors(unsigned long start,
386 return done; 384 return done;
387} 385}
388 386
389int ata_read_sectors(IF_MV2(int drive,) 387int nand_read_sectors(IF_MV2(int drive,)
390 unsigned long start, 388 unsigned long start,
391 int incount, 389 int incount,
392 void* inbuf) 390 void* inbuf)
@@ -403,7 +401,7 @@ int ata_read_sectors(IF_MV2(int drive,)
403 return 0; 401 return 0;
404} 402}
405 403
406int ata_write_sectors(IF_MV2(int drive,) 404int nand_write_sectors(IF_MV2(int drive,)
407 unsigned long start, 405 unsigned long start,
408 int count, 406 int count,
409 const void* buf) 407 const void* buf)
@@ -414,60 +412,7 @@ int ata_write_sectors(IF_MV2(int drive,)
414 return -1; 412 return -1;
415} 413}
416 414
417/* schedule a single sector write, executed with the the next spinup 415int nand_init(void)
418 (volume 0 only, used for config sector) */
419extern void ata_delayed_write(unsigned long sector, const void* buf)
420{
421 (void)sector;
422 (void)buf;
423}
424
425/* write the delayed sector to volume 0 */
426extern void ata_flush(void)
427{
428
429}
430
431void ata_spindown(int seconds)
432{
433 (void)seconds;
434}
435
436bool ata_disk_is_active(void)
437{
438 return 0;
439}
440
441void ata_sleep(void)
442{
443}
444
445void ata_spin(void)
446{
447}
448
449/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
450int ata_hard_reset(void)
451{
452 return 0;
453}
454
455int ata_soft_reset(void)
456{
457 return 0;
458}
459
460void ata_enable(bool on)
461{
462 (void)on;
463}
464
465unsigned short* ata_get_identify(void)
466{
467 return identify_info;
468}
469
470int ata_init(void)
471{ 416{
472 int i, id, id2; 417 int i, id, id2;
473 418
@@ -499,3 +444,29 @@ int ata_init(void)
499 444
500 return 0; 445 return 0;
501} 446}
447
448long nand_last_disk_activity(void)
449{
450 return last_disk_activity;
451}
452
453void nand_get_info(struct storage_info *info)
454{
455 unsigned long blocks;
456 int i;
457
458 /* firmware version */
459 info->revision="0.00";
460
461 /* vendor field, need better name? */
462 info->vendor="Rockbox";
463 /* model field, need better name? */
464 info->product="TNFL";
465
466 /* blocks count */
467 info->num_sectors = 0;
468 info->sector_size=SECTOR_SIZE;
469
470 info->serial=0;
471}
472
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 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdbool.h> 21#include <stdbool.h>
22#include "ata.h" 22#include "mmc.h"
23#include "ata_mmc.h" 23#include "ata_mmc.h"
24#include "ata_idle_notify.h" 24#include "ata_idle_notify.h"
25#include "kernel.h" 25#include "kernel.h"
@@ -36,6 +36,7 @@
36#include "adc.h" 36#include "adc.h"
37#include "bitswap.h" 37#include "bitswap.h"
38#include "disk.h" /* for mount/unmount */ 38#include "disk.h" /* for mount/unmount */
39#include "storage.h"
39 40
40#define BLOCK_SIZE 512 /* fixed */ 41#define BLOCK_SIZE 512 /* fixed */
41 42
@@ -84,8 +85,7 @@
84#define DT_STOP_TRAN 0xfd 85#define DT_STOP_TRAN 0xfd
85 86
86/* for compatibility */ 87/* for compatibility */
87int ata_spinup_time = 0; 88static long last_disk_activity = -1;
88long last_disk_activity = -1;
89 89
90/* private variables */ 90/* private variables */
91 91
@@ -601,7 +601,7 @@ static int send_block_send(unsigned char start_token, long timeout,
601 return rc; 601 return rc;
602} 602}
603 603
604int ata_read_sectors(IF_MV2(int drive,) 604int mmc_read_sectors(IF_MV2(int drive,)
605 unsigned long start, 605 unsigned long start,
606 int incount, 606 int incount,
607 void* inbuf) 607 void* inbuf)
@@ -687,7 +687,7 @@ int ata_read_sectors(IF_MV2(int drive,)
687 return rc; 687 return rc;
688} 688}
689 689
690int ata_write_sectors(IF_MV2(int drive,) 690int mmc_write_sectors(IF_MV2(int drive,)
691 unsigned long start, 691 unsigned long start,
692 int count, 692 int count,
693 const void* buf) 693 const void* buf)
@@ -755,25 +755,12 @@ int ata_write_sectors(IF_MV2(int drive,)
755 return rc; 755 return rc;
756} 756}
757 757
758void ata_spindown(int seconds) 758bool mmc_disk_is_active(void)
759{
760 (void)seconds;
761}
762
763bool ata_disk_is_active(void)
764{ 759{
765 /* this is correct unless early return from write gets implemented */ 760 /* this is correct unless early return from write gets implemented */
766 return mmc_mutex.locked; 761 return mmc_mutex.locked;
767} 762}
768 763
769void ata_sleep(void)
770{
771}
772
773void ata_spin(void)
774{
775}
776
777static void mmc_thread(void) 764static void mmc_thread(void)
778{ 765{
779 struct queue_event ev; 766 struct queue_event ev;
@@ -810,7 +797,7 @@ static void mmc_thread(void)
810 { 797 {
811 if (!idle_notified) 798 if (!idle_notified)
812 { 799 {
813 call_ata_idle_notifys(false); 800 call_storage_idle_notifys(false);
814 idle_notified = true; 801 idle_notified = true;
815 } 802 }
816 } 803 }
@@ -904,12 +891,7 @@ static void mmc_tick(void)
904 } 891 }
905} 892}
906 893
907int ata_soft_reset(void) 894void mmc_enable(bool on)
908{
909 return 0;
910}
911
912void ata_enable(bool on)
913{ 895{
914 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, 896 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
915 * if not modified below */ 897 * if not modified below */
@@ -924,7 +906,7 @@ void ata_enable(bool on)
924 card_info[1].initialized = false; 906 card_info[1].initialized = false;
925} 907}
926 908
927int ata_init(void) 909int mmc_init(void)
928{ 910{
929 int rc = 0; 911 int rc = 0;
930 912
@@ -970,9 +952,51 @@ int ata_init(void)
970 tick_add_task(mmc_tick); 952 tick_add_task(mmc_tick);
971 initialized = true; 953 initialized = true;
972 } 954 }
973 ata_enable(true); 955 mmc_enable(true);
974 956
975 mutex_unlock(&mmc_mutex); 957 mutex_unlock(&mmc_mutex);
976 return rc; 958 return rc;
977} 959}
978 960
961long mmc_last_disk_activity(void)
962{
963 return last_disk_activity;
964}
965
966void mmc_get_info(IF_MV2(int drive,) struct storage_info *info)
967{
968#ifndef HAVE_MULTIVOLUME
969 const int drive=0;
970#endif
971 info->sector_size=card_info[drive].blocksize;
972 info->num_sectors=card_info[drive].numblocks;
973 info->vendor="Rockbox";
974 if(drive==0)
975 {
976 info->product="Internal Storage";
977 }
978 else
979 {
980 info->product="MMC Card Slot";
981 }
982 info->revision="0.00";
983}
984
985#ifdef HAVE_HOTSWAP
986bool mmc_removable(IF_MV_NONVOID(int drive))
987{
988#ifndef HAVE_MULTIVOLUME
989 const int drive=0;
990#endif
991 return (drive==1);
992}
993
994bool mmc_present(IF_MV_NONVOID(int drive))
995{
996#ifndef HAVE_MULTIVOLUME
997 const int drive=0;
998#endif
999 return (card_info[drive].initialized && card_info[drive].numblocks > 0);
1000}
1001#endif
1002
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 @@
24#include <ctype.h> 24#include <ctype.h>
25#include <stdbool.h> 25#include <stdbool.h>
26#include "fat.h" 26#include "fat.h"
27#include "ata.h" 27#include "storage.h"
28#include "debug.h" 28#include "debug.h"
29#include "panic.h" 29#include "panic.h"
30#include "system.h" 30#include "system.h"
@@ -300,7 +300,7 @@ int fat_mount(IF_MV2(int volume,) IF_MV2(int drive,) long startsector)
300#endif 300#endif
301 301
302 /* Read the sector */ 302 /* Read the sector */
303 rc = ata_read_sectors(IF_MV2(drive,) startsector,1,buf); 303 rc = storage_read_sectors(IF_MV2(drive,) startsector,1,buf);
304 if(rc) 304 if(rc)
305 { 305 {
306 DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc); 306 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)
422#endif /* #ifdef HAVE_FAT16SUPPORT */ 422#endif /* #ifdef HAVE_FAT16SUPPORT */
423 { 423 {
424 /* Read the fsinfo sector */ 424 /* Read the fsinfo sector */
425 rc = ata_read_sectors(IF_MV2(drive,) 425 rc = storage_read_sectors(IF_MV2(drive,)
426 startsector + fat_bpb->bpb_fsinfo, 1, buf); 426 startsector + fat_bpb->bpb_fsinfo, 1, buf);
427 if (rc < 0) 427 if (rc < 0)
428 { 428 {
@@ -597,7 +597,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce,
597#endif 597#endif
598 598
599 /* Write to the first FAT */ 599 /* Write to the first FAT */
600 rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) 600 rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,)
601 secnum, 1, 601 secnum, 1,
602 sectorbuf); 602 sectorbuf);
603 if(rc < 0) 603 if(rc < 0)
@@ -618,7 +618,7 @@ static void flush_fat_sector(struct fat_cache_entry *fce,
618#else 618#else
619 secnum += fat_bpbs[0].fatsize; 619 secnum += fat_bpbs[0].fatsize;
620#endif 620#endif
621 rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) 621 rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,)
622 secnum, 1, sectorbuf); 622 secnum, 1, sectorbuf);
623 if(rc < 0) 623 if(rc < 0)
624 { 624 {
@@ -664,7 +664,7 @@ static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,)
664 /* Load the sector if it is not cached */ 664 /* Load the sector if it is not cached */
665 if(!fce->inuse) 665 if(!fce->inuse)
666 { 666 {
667 rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) 667 rc = storage_read_sectors(IF_MV2(fat_bpb->drive,)
668 secnum + fat_bpb->startsector,1, 668 secnum + fat_bpb->startsector,1,
669 sectorbuf); 669 sectorbuf);
670 if(rc < 0) 670 if(rc < 0)
@@ -923,7 +923,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
923#endif /* #ifdef HAVE_FAT16SUPPORT */ 923#endif /* #ifdef HAVE_FAT16SUPPORT */
924 924
925 /* update fsinfo */ 925 /* update fsinfo */
926 rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) 926 rc = storage_read_sectors(IF_MV2(fat_bpb->drive,)
927 fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); 927 fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo);
928 if (rc < 0) 928 if (rc < 0)
929 { 929 {
@@ -936,7 +936,7 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
936 intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]); 936 intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]);
937 *intptr = htole32(fat_bpb->fsinfo.nextfree); 937 *intptr = htole32(fat_bpb->fsinfo.nextfree);
938 938
939 rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) 939 rc = storage_write_sectors(IF_MV2(fat_bpb->drive,)
940 fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); 940 fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo);
941 if (rc < 0) 941 if (rc < 0)
942 { 942 {
@@ -2077,11 +2077,11 @@ static int transfer(IF_MV2(struct bpb* fat_bpb,)
2077 if (start + count > fat_bpb->totalsectors) 2077 if (start + count > fat_bpb->totalsectors)
2078 panicf("Write %ld after data\n", 2078 panicf("Write %ld after data\n",
2079 start + count - fat_bpb->totalsectors); 2079 start + count - fat_bpb->totalsectors);
2080 rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) 2080 rc = storage_write_sectors(IF_MV2(fat_bpb->drive,)
2081 start + fat_bpb->startsector, count, buf); 2081 start + fat_bpb->startsector, count, buf);
2082 } 2082 }
2083 else 2083 else
2084 rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) 2084 rc = storage_read_sectors(IF_MV2(fat_bpb->drive,)
2085 start + fat_bpb->startsector, count, buf); 2085 start + fat_bpb->startsector, count, buf);
2086 if (rc < 0) { 2086 if (rc < 0) {
2087 DEBUGF( "transfer() - Couldn't %s sector %lx" 2087 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 @@
23 23
24#include <stdbool.h> 24#include <stdbool.h>
25#include "config.h" /* for HAVE_MULTIVOLUME or not */ 25#include "config.h" /* for HAVE_MULTIVOLUME or not */
26#include "mv.h" /* for IF_MV() and friends */
26 27
27/* FixMe: These macros are a bit nasty and perhaps misplaced here. 28struct storage_info;
28 We'll get rid of them once decided on how to proceed with multivolume. */
29#ifdef HAVE_MULTIVOLUME
30#define IF_MV(x) x /* optional volume/drive parameter */
31#define IF_MV2(x,y) x,y /* same, for a list of arguments */
32#define IF_MV_NONVOID(x) x /* for prototype with sole volume parameter */
33#define NUM_VOLUMES 2
34#else /* empty definitions if no multi-volume */
35#define IF_MV(x)
36#define IF_MV2(x,y)
37#define IF_MV_NONVOID(x) void
38#define NUM_VOLUMES 1
39#endif
40 29
41extern void ata_enable(bool on); 30void ata_enable(bool on);
42extern void ata_spindown(int seconds); 31void ata_spindown(int seconds);
43extern void ata_sleep(void); 32void ata_sleep(void);
44extern void ata_sleepnow(void); 33void ata_sleepnow(void);
45/* NOTE: DO NOT use this to poll for disk activity. 34/* NOTE: DO NOT use this to poll for disk activity.
46 If you are waiting for the disk to become active before 35 If you are waiting for the disk to become active before
47 doing something use ata_idle_notify.h 36 doing something use ata_idle_notify.h
48 */ 37 */
49extern bool ata_disk_is_active(void); 38bool ata_disk_is_active(void);
50extern int ata_hard_reset(void); 39int ata_hard_reset(void);
51extern int ata_soft_reset(void); 40int ata_soft_reset(void);
52extern int ata_init(void); 41int ata_init(void);
53extern void ata_close(void); 42void ata_close(void);
54extern int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf); 43int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf);
55extern int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf); 44int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf);
56extern void ata_spin(void); 45void ata_spin(void);
57#if (CONFIG_LED == LED_REAL) 46#if (CONFIG_LED == LED_REAL)
58extern void ata_set_led_enabled(bool enabled); 47void ata_set_led_enabled(bool enabled);
48#endif
49unsigned short* ata_get_identify(void);
50void ata_get_info(IF_MV2(int drive,) struct storage_info *info);
51#ifdef HAVE_HOTSWAP
52bool ata_removable(IF_MV_NONVOID(int drive));
53bool ata_present(IF_MV_NONVOID(int drive));
59#endif 54#endif
60extern unsigned short* ata_get_identify(void);
61 55
62extern long last_disk_activity; 56
63extern int ata_spinup_time; /* ticks */ 57
58long ata_last_disk_activity(void);
59int ata_spinup_time(void); /* ticks */
60
64 61
65#endif 62#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 @@
26#include "events.h" 26#include "events.h"
27 27
28/* 28/*
29 NOTE: ata_idle_notify usage notes.. 29 NOTE: storage_idle_notify usage notes..
30 30
311) The callbacks are called in the ata thread, not main/your thread. 311) The callbacks are called in the ata thread, not main/your thread.
322) Asynchronous callbacks (like the buffer refill) should be avoided. 322) Asynchronous callbacks (like the buffer refill) should be avoided.
33 If you must use an async callback, remember to check ata_is_active() before 33 If you must use an async callback, remember to check storage_is_active() before
34 accessing the disk, and do not call any functions between that check and the 34 accessing the disk, and do not call any functions between that check and the
35 disk access which may cause a yield (lcd_update() does this!). 35 disk access which may cause a yield (lcd_update() does this!).
363) Do not call any yielding functions in the callback. 363) Do not call any yielding functions in the callback.
374) Do not call ata_sleep in the callbacks. 374) Do not call storage_sleep in the callbacks.
385) Don't Panic! 385) Don't Panic!
39 39
40*/ 40*/
@@ -43,21 +43,21 @@ enum {
43 DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1), 43 DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1),
44}; 44};
45 45
46#define USING_ATA_CALLBACK !defined(SIMULATOR) \ 46#define USING_STORAGE_CALLBACK !defined(SIMULATOR) \
47 && ! ((CONFIG_STORAGE & STORAGE_NAND) \ 47 && ! ((CONFIG_STORAGE & STORAGE_NAND) \
48 && (CONFIG_NAND & NAND_IFP7XX)) \ 48 && (CONFIG_NAND & NAND_IFP7XX)) \
49 && !defined(BOOTLOADER) 49 && !defined(BOOTLOADER)
50 50
51typedef bool (*ata_idle_notify)(void); 51typedef bool (*storage_idle_notify)(void);
52 52
53extern void register_ata_idle_func(ata_idle_notify function); 53extern void register_storage_idle_func(storage_idle_notify function);
54#if USING_ATA_CALLBACK 54#if USING_STORAGE_CALLBACK
55extern void unregister_ata_idle_func(ata_idle_notify function, bool run); 55extern void unregister_storage_idle_func(storage_idle_notify function, bool run);
56extern bool call_ata_idle_notifys(bool force); 56extern bool call_storage_idle_notifys(bool force);
57#else 57#else
58#define unregister_ata_idle_func(f,r) 58#define unregister_storage_idle_func(f,r)
59#define call_ata_idle_notifys(f) 59#define call_storage_idle_notifys(f)
60#define ata_idle_notify_init(s) 60#define storage_idle_notify_init(s)
61#endif 61#endif
62 62
63#endif /* __ATACALLBACK_H__ */ 63#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 @@
21#ifndef _DISK_H_ 21#ifndef _DISK_H_
22#define _DISK_H_ 22#define _DISK_H_
23 23
24#include "ata.h" /* for volume definitions */ 24#include "mv.h" /* for volume definitions */
25 25
26struct partinfo { 26struct partinfo {
27 unsigned long start; /* first sector (LBA) */ 27 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 @@
23#define FAT_H 23#define FAT_H
24 24
25#include <stdbool.h> 25#include <stdbool.h>
26#include "ata.h" /* for volume definitions */ 26#include "mv.h" /* for volume definitions */
27#include "config.h" 27#include "config.h"
28 28
29#define SECTOR_SIZE 512 29#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 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id: ata.h 17847 2008-06-28 18:10:04Z bagder $ 8 * $Id: $
9 * 9 *
10 * Copyright (C) 2002 by Alan Korr 10 * Copyright (C) 2002 by Alan Korr
11 * 11 *
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 @@
29#include "adc.h" 29#include "adc.h"
30#include "string.h" 30#include "string.h"
31#include "sprintf.h" 31#include "sprintf.h"
32#include "ata.h" 32#include "storage.h"
33#include "power.h" 33#include "power.h"
34#include "button.h" 34#include "button.h"
35#include "audio.h" 35#include "audio.h"
@@ -451,7 +451,7 @@ static void handle_auto_poweroff(void)
451 !sleeptimer_active))) 451 !sleeptimer_active)))
452 { 452 {
453 if(TIME_AFTER(current_tick, last_event_tick + timeout) && 453 if(TIME_AFTER(current_tick, last_event_tick + timeout) &&
454 TIME_AFTER(current_tick, last_disk_activity + timeout)) 454 TIME_AFTER(current_tick, storage_last_disk_activity() + timeout))
455 { 455 {
456 sys_poweroff(); 456 sys_poweroff();
457 } 457 }
@@ -579,7 +579,7 @@ int pid_i = 0; /* PID integral term */
579 579
580static inline void charging_algorithm_small_step(void) 580static inline void charging_algorithm_small_step(void)
581{ 581{
582 if (ata_disk_is_active()) { 582 if (storage_disk_is_active()) {
583 /* flag hdd use for charging calculation */ 583 /* flag hdd use for charging calculation */
584 disk_activity_last_cycle = true; 584 disk_activity_last_cycle = true;
585 } 585 }
@@ -589,7 +589,7 @@ static inline void charging_algorithm_small_step(void)
589 * If we have a lot of pending writes or if the disk is spining, 589 * If we have a lot of pending writes or if the disk is spining,
590 * fsync the debug log file. 590 * fsync the debug log file.
591 */ 591 */
592 if((wrcount > 10) || ((wrcount > 0) && ata_disk_is_active())) { 592 if((wrcount > 10) || ((wrcount > 0) && storage_disk_is_active())) {
593 fsync(fd); 593 fsync(fd);
594 wrcount = 0; 594 wrcount = 0;
595 } 595 }
@@ -1014,7 +1014,7 @@ static void power_thread_sleep(int ticks)
1014 * the disk is spinning unless we are in USB mode (the disk will most 1014 * the disk is spinning unless we are in USB mode (the disk will most
1015 * likely always be spinning in USB mode). 1015 * likely always be spinning in USB mode).
1016 */ 1016 */
1017 if (!ata_disk_is_active() || usb_inserted()) { 1017 if (!storage_disk_is_active() || usb_inserted()) {
1018 avgbat += battery_adc_voltage() - (avgbat / BATT_AVE_SAMPLES); 1018 avgbat += battery_adc_voltage() - (avgbat / BATT_AVE_SAMPLES);
1019 /* 1019 /*
1020 * battery_millivolts is the millivolt-scaled filtered battery value. 1020 * battery_millivolts is the millivolt-scaled filtered battery value.
@@ -1152,10 +1152,10 @@ void shutdown_hw(void)
1152#ifdef HAVE_LCD_BITMAP 1152#ifdef HAVE_LCD_BITMAP
1153 glyph_cache_save(); 1153 glyph_cache_save();
1154#endif 1154#endif
1155 if(ata_disk_is_active()) 1155 if(storage_disk_is_active())
1156 ata_spindown(1); 1156 storage_spindown(1);
1157 } 1157 }
1158 while(ata_disk_is_active()) 1158 while(storage_disk_is_active())
1159 sleep(HZ/10); 1159 sleep(HZ/10);
1160 1160
1161#if CONFIG_CODEC != SWCODEC 1161#if CONFIG_CODEC != SWCODEC
@@ -1166,7 +1166,7 @@ void shutdown_hw(void)
1166 1166
1167 /* If HD is still active we try to wait for spindown, otherwise the 1167 /* If HD is still active we try to wait for spindown, otherwise the
1168 shutdown_timeout in power_thread_sleep will force a power off */ 1168 shutdown_timeout in power_thread_sleep will force a power off */
1169 while(ata_disk_is_active()) 1169 while(storage_disk_is_active())
1170 sleep(HZ/10); 1170 sleep(HZ/10);
1171#ifndef IAUDIO_X5 1171#ifndef IAUDIO_X5
1172 lcd_set_contrast(0); 1172 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 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "ata.h" 21#include "nand.h"
22#include "ata-nand-target.h" 22#include "ata-nand-target.h"
23#include "system.h" 23#include "system.h"
24#include <string.h> 24#include <string.h>
@@ -31,6 +31,7 @@
31#include "lcd.h" 31#include "lcd.h"
32#include "font.h" 32#include "font.h"
33#include "button.h" 33#include "button.h"
34#include "storage.h"
34#include <sprintf.h> 35#include <sprintf.h>
35 36
36#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
@@ -43,9 +44,6 @@ int ata_spinup_time = 0;
43 44
44long last_disk_activity = -1; 45long last_disk_activity = -1;
45 46
46/* as we aren't actually ata manually fill some fields */
47static unsigned short ata_identify[SECTOR_SIZE/2];
48
49/** static, private data **/ 47/** static, private data **/
50static bool initialized = false; 48static bool initialized = false;
51 49
@@ -662,7 +660,7 @@ static void read_write_cache_segment(int bank, int phys_segment)
662} 660}
663 661
664 662
665int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, 663int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
666 void* inbuf) 664 void* inbuf)
667{ 665{
668#ifdef HAVE_MULTIVOLUME 666#ifdef HAVE_MULTIVOLUME
@@ -702,7 +700,7 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
702 return 0; 700 return 0;
703} 701}
704 702
705int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, 703int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
706 const void* outbuf) 704 const void* outbuf)
707{ 705{
708#ifdef HAVE_MULTIVOLUME 706#ifdef HAVE_MULTIVOLUME
@@ -716,83 +714,21 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
716 return -1; 714 return -1;
717} 715}
718 716
719void ata_spindown(int seconds) 717void nand_get_info(struct storage_info *info)
720{
721 /* null */
722 (void)seconds;
723}
724
725bool ata_disk_is_active(void)
726{
727 /* null */
728 return 0;
729}
730
731void ata_sleep(void)
732{ 718{
733 /* null */
734}
735
736void ata_spin(void)
737{
738 /* null */
739}
740
741/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
742int ata_hard_reset(void)
743{
744 /* null */
745 return 0;
746}
747
748int ata_soft_reset(void)
749{
750 /* null */
751 return 0;
752}
753
754void ata_enable(bool on)
755{
756 /* null - flash controller is enabled/disabled as needed. */
757 (void)on;
758}
759
760static void fill_identify(void)
761{
762 char buf[80];
763 unsigned short *wbuf = (unsigned short *) buf;
764 unsigned long blocks;
765 int i;
766
767 memset(ata_identify, 0, sizeof(ata_identify));
768
769 /* firmware version */ 719 /* firmware version */
770 memset(buf, ' ', 8); 720 info->revision="0.00";
771 memcpy(buf, "0.00", 4);
772 721
773 for (i = 0; i < 4; i++) 722 info->vendor="Rockbox";
774 ata_identify[23 + i] = betoh16(wbuf[i]); 723 info->product="Internal Storage";
775
776 /* model field, need better name? */
777 memset(buf, ' ', 80);
778 memcpy(buf, "TNFL", 4);
779
780 for (i = 0; i < 40; i++)
781 ata_identify[27 + i] = betoh16(wbuf[i]);
782 724
783 /* blocks count */ 725 /* blocks count */
784 blocks = (pages_per_block * blocks_per_bank / SECTOR_SIZE) 726 info->num_sectors = (pages_per_block * blocks_per_bank / SECTOR_SIZE)
785 * page_size * total_banks; 727 * page_size * total_banks;
786 ata_identify[60] = blocks & 0xffff; 728 info->sector_size=SECTOR_SIZE;
787 ata_identify[61] = blocks >> 16;
788
789 /* TODO: discover where is s/n in TNFL */
790 for (i = 10; i < 20; i++) {
791 ata_identify[i] = 0;
792 }
793} 729}
794 730
795int ata_init(void) 731int nand_init(void)
796{ 732{
797 int i, bank, phys_segment; 733 int i, bank, phys_segment;
798 unsigned char spare_buf[16]; 734 unsigned char spare_buf[16];
@@ -909,13 +845,12 @@ int ata_init(void)
909 } 845 }
910#endif 846#endif
911 847
912 fill_identify();
913 initialized = true; 848 initialized = true;
914 849
915 return 0; 850 return 0;
916} 851}
917 852
918unsigned short* ata_get_identify(void) 853long nand_last_disk_activity(void)
919{ 854{
920 return ata_identify; 855 return last_disk_activity;
921} 856}
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 @@
30#include "cpu.h" 30#include "cpu.h"
31#include "panic.h" 31#include "panic.h"
32#include "usb.h" 32#include "usb.h"
33#include "sd.h"
34#include "storage.h"
33 35
34#define BLOCK_SIZE 512 36#define BLOCK_SIZE 512
35#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
@@ -128,15 +130,13 @@
128 130
129/** global, exported variables **/ 131/** global, exported variables **/
130#ifdef HAVE_MULTIVOLUME 132#ifdef HAVE_MULTIVOLUME
131#define NUM_VOLUMES 2 133#define NUM_DRIVES 2
132#else 134#else
133#define NUM_VOLUMES 1 135#define NUM_DRIVES 1
134#endif 136#endif
135 137
136/* for compatibility */ 138/* for compatibility */
137int ata_spinup_time = 0; 139static long last_disk_activity = -1;
138
139long last_disk_activity = -1;
140 140
141/** static, private data **/ 141/** static, private data **/
142static bool initialized = false; 142static bool initialized = false;
@@ -153,7 +153,7 @@ struct sd_card_status
153 int retry_max; 153 int retry_max;
154}; 154};
155 155
156static struct sd_card_status sd_status[NUM_VOLUMES] = 156static struct sd_card_status sd_status[NUM_DRIVES] =
157{ 157{
158 { 0, 1 }, 158 { 0, 1 },
159#ifdef HAVE_MULTIVOLUME 159#ifdef HAVE_MULTIVOLUME
@@ -786,12 +786,12 @@ static void sd_select_device(int card_no)
786 786
787/* API Functions */ 787/* API Functions */
788 788
789static void ata_led(bool onoff) 789static void sd_led(bool onoff)
790{ 790{
791 led(onoff); 791 led(onoff);
792} 792}
793 793
794int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, 794int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
795 void* inbuf) 795 void* inbuf)
796{ 796{
797#ifndef HAVE_MULTIVOLUME 797#ifndef HAVE_MULTIVOLUME
@@ -805,14 +805,14 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
805 805
806 mutex_lock(&sd_mtx); 806 mutex_lock(&sd_mtx);
807 807
808 ata_led(true); 808 sd_led(true);
809 809
810ata_read_retry: 810sd_read_retry:
811 if (drive != 0 && !card_detect_target()) 811 if (drive != 0 && !card_detect_target())
812 { 812 {
813 /* no external sd-card inserted */ 813 /* no external sd-card inserted */
814 ret = -EC_NOCARD; 814 ret = -EC_NOCARD;
815 goto ata_read_error; 815 goto sd_read_error;
816 } 816 }
817 817
818 sd_select_device(drive); 818 sd_select_device(drive);
@@ -820,7 +820,7 @@ ata_read_retry:
820 if (currcard->initialized < 0) 820 if (currcard->initialized < 0)
821 { 821 {
822 ret = currcard->initialized; 822 ret = currcard->initialized;
823 goto ata_read_error; 823 goto sd_read_error;
824 } 824 }
825 825
826 last_disk_activity = current_tick; 826 last_disk_activity = current_tick;
@@ -834,7 +834,7 @@ ata_read_retry:
834 { 834 {
835 ret = sd_select_bank(bank); 835 ret = sd_select_bank(bank);
836 if (ret < 0) 836 if (ret < 0)
837 goto ata_read_error; 837 goto sd_read_error;
838 } 838 }
839 839
840 start -= bank * BLOCKS_PER_BANK; 840 start -= bank * BLOCKS_PER_BANK;
@@ -842,7 +842,7 @@ ata_read_retry:
842 842
843 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); 843 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY);
844 if (ret < 0) 844 if (ret < 0)
845 goto ata_read_error; 845 goto sd_read_error;
846 846
847 BLOCK_COUNT_REG = incount; 847 BLOCK_COUNT_REG = incount;
848 848
@@ -858,7 +858,7 @@ ata_read_retry:
858 ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); 858 ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25);
859 } 859 }
860 if (ret < 0) 860 if (ret < 0)
861 goto ata_read_error; 861 goto sd_read_error;
862 862
863 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ 863 /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */
864 864
@@ -874,38 +874,38 @@ ata_read_retry:
874 } 874 }
875 875
876 ret = -EC_FIFO_READ_FULL; 876 ret = -EC_FIFO_READ_FULL;
877 goto ata_read_error; 877 goto sd_read_error;
878 } 878 }
879 879
880 last_disk_activity = current_tick; 880 last_disk_activity = current_tick;
881 881
882 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); 882 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
883 if (ret < 0) 883 if (ret < 0)
884 goto ata_read_error; 884 goto sd_read_error;
885 885
886 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT); 886 ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT);
887 if (ret < 0) 887 if (ret < 0)
888 goto ata_read_error; 888 goto sd_read_error;
889 889
890 while (1) 890 while (1)
891 { 891 {
892 ata_led(false); 892 sd_led(false);
893 mutex_unlock(&sd_mtx); 893 mutex_unlock(&sd_mtx);
894 894
895 return ret; 895 return ret;
896 896
897ata_read_error: 897sd_read_error:
898 if (sd_status[drive].retry < sd_status[drive].retry_max 898 if (sd_status[drive].retry < sd_status[drive].retry_max
899 && ret != -EC_NOCARD) 899 && ret != -EC_NOCARD)
900 { 900 {
901 sd_status[drive].retry++; 901 sd_status[drive].retry++;
902 currcard->initialized = 0; 902 currcard->initialized = 0;
903 goto ata_read_retry; 903 goto sd_read_retry;
904 } 904 }
905 } 905 }
906} 906}
907 907
908int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, 908int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
909 const void* outbuf) 909 const void* outbuf)
910{ 910{
911/* Write support is not finished yet */ 911/* Write support is not finished yet */
@@ -920,14 +920,14 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
920 920
921 mutex_lock(&sd_mtx); 921 mutex_lock(&sd_mtx);
922 922
923 ata_led(true); 923 sd_led(true);
924 924
925ata_write_retry: 925sd_write_retry:
926 if (drive != 0 && !card_detect_target()) 926 if (drive != 0 && !card_detect_target())
927 { 927 {
928 /* no external sd-card inserted */ 928 /* no external sd-card inserted */
929 ret = -EC_NOCARD; 929 ret = -EC_NOCARD;
930 goto ata_write_error; 930 goto sd_write_error;
931 } 931 }
932 932
933 sd_select_device(drive); 933 sd_select_device(drive);
@@ -935,7 +935,7 @@ ata_write_retry:
935 if (currcard->initialized < 0) 935 if (currcard->initialized < 0)
936 { 936 {
937 ret = currcard->initialized; 937 ret = currcard->initialized;
938 goto ata_write_error; 938 goto sd_write_error;
939 } 939 }
940 940
941 /* Only switch banks with non-SDHC cards */ 941 /* Only switch banks with non-SDHC cards */
@@ -947,7 +947,7 @@ ata_write_retry:
947 { 947 {
948 ret = sd_select_bank(bank); 948 ret = sd_select_bank(bank);
949 if (ret < 0) 949 if (ret < 0)
950 goto ata_write_error; 950 goto sd_write_error;
951 } 951 }
952 952
953 start -= bank * BLOCKS_PER_BANK; 953 start -= bank * BLOCKS_PER_BANK;
@@ -957,7 +957,7 @@ ata_write_retry:
957 957
958 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY); 958 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY);
959 if (ret < 0) 959 if (ret < 0)
960 goto ata_write_error; 960 goto sd_write_error;
961 961
962 BLOCK_COUNT_REG = count; 962 BLOCK_COUNT_REG = count;
963 963
@@ -973,7 +973,7 @@ ata_write_retry:
973 ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); 973 ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d);
974 } 974 }
975 if (ret < 0) 975 if (ret < 0)
976 goto ata_write_error; 976 goto sd_write_error;
977 977
978 buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN; 978 buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN;
979 979
@@ -996,7 +996,7 @@ ata_write_retry:
996 } 996 }
997 997
998 ret = -EC_FIFO_WR_EMPTY; 998 ret = -EC_FIFO_WR_EMPTY;
999 goto ata_write_error; 999 goto sd_write_error;
1000 } 1000 }
1001 1001
1002 last_disk_activity = current_tick; 1002 last_disk_activity = current_tick;
@@ -1004,31 +1004,31 @@ ata_write_retry:
1004 if (!sd_poll_status(DATA_DONE, 0x80000)) 1004 if (!sd_poll_status(DATA_DONE, 0x80000))
1005 { 1005 {
1006 ret = -EC_FIFO_WR_DONE; 1006 ret = -EC_FIFO_WR_DONE;
1007 goto ata_write_error; 1007 goto sd_write_error;
1008 } 1008 }
1009 1009
1010 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1); 1010 ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
1011 if (ret < 0) 1011 if (ret < 0)
1012 goto ata_write_error; 1012 goto sd_write_error;
1013 1013
1014 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT); 1014 ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT);
1015 if (ret < 0) 1015 if (ret < 0)
1016 goto ata_write_error; 1016 goto sd_write_error;
1017 1017
1018 while (1) 1018 while (1)
1019 { 1019 {
1020 ata_led(false); 1020 sd_led(false);
1021 mutex_unlock(&sd_mtx); 1021 mutex_unlock(&sd_mtx);
1022 1022
1023 return ret; 1023 return ret;
1024 1024
1025ata_write_error: 1025sd_write_error:
1026 if (sd_status[drive].retry < sd_status[drive].retry_max 1026 if (sd_status[drive].retry < sd_status[drive].retry_max
1027 && ret != -EC_NOCARD) 1027 && ret != -EC_NOCARD)
1028 { 1028 {
1029 sd_status[drive].retry++; 1029 sd_status[drive].retry++;
1030 currcard->initialized = 0; 1030 currcard->initialized = 0;
1031 goto ata_write_retry; 1031 goto sd_write_retry;
1032 } 1032 }
1033 } 1033 }
1034} 1034}
@@ -1088,7 +1088,7 @@ static void sd_thread(void)
1088 1088
1089 if (!idle_notified) 1089 if (!idle_notified)
1090 { 1090 {
1091 call_ata_idle_notifys(false); 1091 call_storage_idle_notifys(false);
1092 idle_notified = true; 1092 idle_notified = true;
1093 } 1093 }
1094 } 1094 }
@@ -1106,37 +1106,7 @@ static void sd_thread(void)
1106 } 1106 }
1107} 1107}
1108 1108
1109 1109void sd_enable(bool on)
1110void ata_spindown(int seconds)
1111{
1112 (void)seconds;
1113}
1114
1115bool ata_disk_is_active(void)
1116{
1117 return 0;
1118}
1119
1120void ata_sleep(void)
1121{
1122}
1123
1124void ata_spin(void)
1125{
1126}
1127
1128/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
1129int ata_hard_reset(void)
1130{
1131 return 0;
1132}
1133
1134int ata_soft_reset(void)
1135{
1136 return 0;
1137}
1138
1139void ata_enable(bool on)
1140{ 1110{
1141 if(on) 1111 if(on)
1142 { 1112 {
@@ -1170,7 +1140,7 @@ void card_enable_monitoring_target(bool on)
1170} 1140}
1171#endif 1141#endif
1172 1142
1173int ata_init(void) 1143int sd_init(void)
1174{ 1144{
1175 int ret = 0; 1145 int ret = 0;
1176 1146
@@ -1179,7 +1149,7 @@ int ata_init(void)
1179 1149
1180 mutex_lock(&sd_mtx); 1150 mutex_lock(&sd_mtx);
1181 1151
1182 ata_led(false); 1152 sd_led(false);
1183 1153
1184 if (!initialized) 1154 if (!initialized)
1185 { 1155 {
@@ -1324,3 +1294,46 @@ void microsd_int(void)
1324 1294
1325} 1295}
1326#endif /* HAVE_HOTSWAP */ 1296#endif /* HAVE_HOTSWAP */
1297
1298long sd_last_disk_activity(void)
1299{
1300 return last_disk_activity;
1301}
1302
1303void sd_get_info(IF_MV2(int drive,) struct storage_info *info)
1304{
1305#ifndef HAVE_MULTIVOLUME
1306 const int drive=0;
1307#endif
1308 info->sector_size=card_info[drive].block_size;
1309 info->num_sectors=card_info[drive].numblocks;
1310 info->vendor="Rockbox";
1311 if(drive==0)
1312 {
1313 info->product="Internal Storage";
1314 }
1315 else
1316 {
1317 info->product="SD Card Slot";
1318 }
1319 info->revision="0.00";
1320}
1321
1322#ifdef HAVE_HOTSWAP
1323bool sd_removable(IF_MV_NONVOID(int drive))
1324{
1325#ifndef HAVE_MULTIVOLUME
1326 const int drive=0;
1327#endif
1328 return (drive==1);
1329}
1330
1331bool sd_present(IF_MV_NONVOID(int drive))
1332{
1333#ifndef HAVE_MULTIVOLUME
1334 const int drive=0;
1335#endif
1336 return (card_info[drive].initialized && card_info[drive].numblocks > 0);
1337}
1338#endif
1339
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 @@
29#include "thread.h" 29#include "thread.h"
30#include "system.h" 30#include "system.h"
31#include "debug.h" 31#include "debug.h"
32#include "ata.h" 32#include "storage.h"
33#include "fat.h" 33#include "fat.h"
34#include "disk.h" 34#include "disk.h"
35#include "panic.h" 35#include "panic.h"
@@ -86,7 +86,7 @@ static struct event_queue usb_queue;
86static int last_usb_status; 86static int last_usb_status;
87static bool usb_monitor_enabled; 87static bool usb_monitor_enabled;
88#ifdef HAVE_USBSTACK 88#ifdef HAVE_USBSTACK
89static bool exclusive_ata_access; 89static bool exclusive_storage_access;
90#endif 90#endif
91 91
92 92
@@ -105,9 +105,9 @@ static void usb_slave_mode(bool on)
105 if(on) 105 if(on)
106 { 106 {
107 DEBUGF("Entering USB slave mode\n"); 107 DEBUGF("Entering USB slave mode\n");
108 ata_soft_reset(); 108 storage_soft_reset();
109 ata_init(); 109 storage_init();
110 ata_enable(false); 110 storage_enable(false);
111 usb_enable(true); 111 usb_enable(true);
112 } 112 }
113 else 113 else
@@ -119,9 +119,9 @@ static void usb_slave_mode(bool on)
119 119
120 usb_enable(false); 120 usb_enable(false);
121 121
122 rc = ata_init(); 122 rc = storage_init();
123 if(rc) 123 if(rc)
124 panicf("ata: %d",rc); 124 panicf("storage: %d",rc);
125 125
126 rc = disk_mount_all(); 126 rc = disk_mount_all();
127 if (rc <= 0) /* no partition */ 127 if (rc <= 0) /* no partition */
@@ -134,7 +134,7 @@ static void usb_slave_mode(bool on)
134static void try_reboot(void) 134static void try_reboot(void)
135{ 135{
136#ifdef HAVE_DISK_STORAGE 136#ifdef HAVE_DISK_STORAGE
137 ata_sleepnow(); /* Immediately spindown the disk. */ 137 storage_sleepnow(); /* Immediately spindown the disk. */
138 sleep(HZ*2); 138 sleep(HZ*2);
139#endif 139#endif
140 140
@@ -262,7 +262,7 @@ static void usb_thread(void)
262#ifdef HAVE_PRIORITY_SCHEDULING 262#ifdef HAVE_PRIORITY_SCHEDULING
263 thread_set_priority(usb_thread_entry,PRIORITY_REALTIME); 263 thread_set_priority(usb_thread_entry,PRIORITY_REALTIME);
264#endif 264#endif
265 exclusive_ata_access = true; 265 exclusive_storage_access = true;
266 266
267#else 267#else
268 usb_slave_mode(true); 268 usb_slave_mode(true);
@@ -310,12 +310,12 @@ static void usb_thread(void)
310 310
311 usb_state = USB_EXTRACTED; 311 usb_state = USB_EXTRACTED;
312#ifdef HAVE_USBSTACK 312#ifdef HAVE_USBSTACK
313 if(exclusive_ata_access) 313 if(exclusive_storage_access)
314 { 314 {
315 int rc = disk_mount_all(); 315 int rc = disk_mount_all();
316 if (rc <= 0) /* no partition */ 316 if (rc <= 0) /* no partition */
317 panicf("mount: %d",rc); 317 panicf("mount: %d",rc);
318 exclusive_ata_access = false; 318 exclusive_storage_access = false;
319#endif 319#endif
320 /* Tell all threads that we are back in business */ 320 /* Tell all threads that we are back in business */
321 num_acks_to_expect = 321 num_acks_to_expect =
@@ -455,7 +455,7 @@ void usb_init(void)
455{ 455{
456 usb_state = USB_EXTRACTED; 456 usb_state = USB_EXTRACTED;
457#ifdef HAVE_USBSTACK 457#ifdef HAVE_USBSTACK
458 exclusive_ata_access = false; 458 exclusive_storage_access = false;
459#endif 459#endif
460 usb_monitor_enabled = false; 460 usb_monitor_enabled = false;
461 countdown = -1; 461 countdown = -1;
@@ -561,7 +561,7 @@ void usb_request_exclusive_ata(void)
561 * currently the best one. We want to get rid of having to boost the cpu 561 * currently the best one. We want to get rid of having to boost the cpu
562 * for usb anyway */ 562 * for usb anyway */
563 trigger_cpu_boost(); 563 trigger_cpu_boost();
564 if(!exclusive_ata_access) { 564 if(!exclusive_storage_access) {
565 queue_post(&usb_queue, USB_REQUEST_DISK, 0); 565 queue_post(&usb_queue, USB_REQUEST_DISK, 0);
566 } 566 }
567} 567}
@@ -569,15 +569,15 @@ void usb_request_exclusive_ata(void)
569void usb_release_exclusive_ata(void) 569void usb_release_exclusive_ata(void)
570{ 570{
571 cancel_cpu_boost(); 571 cancel_cpu_boost();
572 if(exclusive_ata_access) { 572 if(exclusive_storage_access) {
573 queue_post(&usb_queue, USB_RELEASE_DISK, 0); 573 queue_post(&usb_queue, USB_RELEASE_DISK, 0);
574 exclusive_ata_access = false; 574 exclusive_storage_access = false;
575 } 575 }
576} 576}
577 577
578bool usb_exclusive_ata(void) 578bool usb_exclusive_ata(void)
579{ 579{
580 return exclusive_ata_access; 580 return exclusive_storage_access;
581} 581}
582#endif 582#endif
583 583
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 @@
50#include "as3514.h" 50#include "as3514.h"
51#endif 51#endif
52 52
53#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) 53#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) && (CONFIG_STORAGE & STORAGE_ATA)
54#include "ata.h" 54#include "ata.h"
55#endif 55#endif
56 56
@@ -281,7 +281,7 @@ static void set_serial_descriptor(void)
281 } 281 }
282 usb_string_iSerial.bLength=68; 282 usb_string_iSerial.bLength=68;
283} 283}
284#else 284#elif (CONFIG_STORAGE & STORAGE_ATA)
285/* If we don't know the device serial number, use the one 285/* If we don't know the device serial number, use the one
286 * from the disk */ 286 * from the disk */
287static void set_serial_descriptor(void) 287static void set_serial_descriptor(void)
@@ -300,6 +300,8 @@ static void set_serial_descriptor(void)
300 } 300 }
301 usb_string_iSerial.bLength=84; 301 usb_string_iSerial.bLength=84;
302} 302}
303#else
304#error No set_serial_descriptor() implementation for this target
303#endif 305#endif
304 306
305void usb_core_init(void) 307void 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 @@
24#include "usb_drv.h" 24#include "usb_drv.h"
25//#define LOGF_ENABLE 25//#define LOGF_ENABLE
26#include "logf.h" 26#include "logf.h"
27#include "ata.h" 27#include "storage.h"
28#include "hotswap.h" 28#include "hotswap.h"
29#include "disk.h" 29#include "disk.h"
30/* Needed to get at the audio buffer */ 30/* Needed to get at the audio buffer */
@@ -36,7 +36,7 @@
36 36
37/* The SD card driver on Sansa c200 and e200 can cause write corruption, 37/* The SD card driver on Sansa c200 and e200 can cause write corruption,
38 * often triggered by simultaneous USB activity. This can be largely avoided 38 * often triggered by simultaneous USB activity. This can be largely avoided
39 * by not overlapping ata_write_sector() with USB transfers. This does reduce 39 * by not overlapping storage_write_sector() with USB transfers. This does reduce
40 * write performance, so we only do it for the affected DAPs 40 * write performance, so we only do it for the affected DAPs
41 */ 41 */
42#if (CONFIG_STORAGE & STORAGE_SD) 42#if (CONFIG_STORAGE & STORAGE_SD)
@@ -147,10 +147,8 @@ struct inquiry_data {
147struct report_lun_data { 147struct report_lun_data {
148 unsigned int lun_list_length; 148 unsigned int lun_list_length;
149 unsigned int reserved1; 149 unsigned int reserved1;
150 unsigned char lun0[8]; 150 // TODO this should be cleaned up with the VOLUMES vs DRIVES mess
151#ifdef HAVE_HOTSWAP 151 unsigned char luns[NUM_VOLUMES][8];
152 unsigned char lun1[8];
153#endif
154} __attribute__ ((packed)); 152} __attribute__ ((packed));
155 153
156struct sense_data { 154struct sense_data {
@@ -263,7 +261,7 @@ static void send_command_result(void *data,int size);
263static void send_command_failed_result(void); 261static void send_command_failed_result(void);
264static void send_block_data(void *data,int size); 262static void send_block_data(void *data,int size);
265static void receive_block_data(void *data,int size); 263static void receive_block_data(void *data,int size);
266static void identify2inquiry(int lun); 264static void fill_inquiry(IF_MV_NONVOID(int lun));
267static void send_and_read_next(void); 265static void send_and_read_next(void);
268static bool ejected[NUM_VOLUMES]; 266static bool ejected[NUM_VOLUMES];
269 267
@@ -289,7 +287,7 @@ static bool check_disk_present(IF_MV_NONVOID(int volume))
289 return true; 287 return true;
290#else 288#else
291 unsigned char sector[512]; 289 unsigned char sector[512];
292 return ata_read_sectors(IF_MV2(volume,)0,1,sector) == 0; 290 return storage_read_sectors(IF_MV2(volume,)0,1,sector) == 0;
293#endif 291#endif
294} 292}
295 293
@@ -460,7 +458,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
460 cur_cmd.data[cur_cmd.data_select], 458 cur_cmd.data[cur_cmd.data_select],
461 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 459 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
462#else 460#else
463 int result = ata_write_sectors(IF_MV2(cur_cmd.lun,) 461 int result = storage_write_sectors(IF_MV2(cur_cmd.lun,)
464 cur_cmd.sector, 462 cur_cmd.sector,
465 MIN(BUFFER_SIZE/SECTOR_SIZE, 463 MIN(BUFFER_SIZE/SECTOR_SIZE,
466 cur_cmd.count), 464 cur_cmd.count),
@@ -639,7 +637,7 @@ static void send_and_read_next(void)
639 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 637 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
640 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 638 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
641#else 639#else
642 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,) 640 cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,)
643 cur_cmd.sector, 641 cur_cmd.sector,
644 MIN(BUFFER_SIZE/SECTOR_SIZE, 642 MIN(BUFFER_SIZE/SECTOR_SIZE,
645 cur_cmd.count), 643 cur_cmd.count),
@@ -654,6 +652,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
654 /* USB Mass Storage assumes LBA capability. 652 /* USB Mass Storage assumes LBA capability.
655 TODO: support 48-bit LBA */ 653 TODO: support 48-bit LBA */
656 654
655 struct storage_info info;
657 unsigned int length = cbw->data_transfer_length; 656 unsigned int length = cbw->data_transfer_length;
658 unsigned int block_size = 0; 657 unsigned int block_size = 0;
659 unsigned int block_count = 0; 658 unsigned int block_count = 0;
@@ -664,25 +663,20 @@ static void handle_scsi(struct command_block_wrapper* cbw)
664 unsigned char lun = cbw->lun; 663 unsigned char lun = cbw->lun;
665#endif 664#endif
666 unsigned int block_size_mult = 1; 665 unsigned int block_size_mult = 1;
666 storage_get_info(IF_MV2(lun,)&info);
667#ifdef USB_USE_RAMDISK 667#ifdef USB_USE_RAMDISK
668 block_size = SECTOR_SIZE; 668 block_size = SECTOR_SIZE;
669 block_count = RAMDISK_SIZE; 669 block_count = RAMDISK_SIZE;
670#else 670#else
671#if (CONFIG_STORAGE & STORAGE_SD) || defined(HAVE_HOTSWAP) 671 block_size=info.sector_size;
672 tCardInfo* cinfo = card_get_info(lun); 672 block_count=info.num_sectors;
673 if(cinfo->initialized && cinfo->numblocks > 0) { 673#endif
674 block_size = cinfo->blocksize; 674
675 block_count = cinfo->numblocks; 675#ifdef HAVE_HOTSWAP
676 } 676 if(storage_removable(IF_MV(lun)) && !storage_present(IF_MV(lun))) {
677 else {
678 ejected[lun] = true; 677 ejected[lun] = true;
679 try_release_ata(); 678 try_release_ata();
680 } 679 }
681#else
682 unsigned short* identify = ata_get_identify();
683 block_size = SECTOR_SIZE;
684 block_count = (identify[61] << 16 | identify[60]);
685#endif
686#endif 680#endif
687 681
688 if(ejected[lun]) 682 if(ejected[lun])
@@ -719,19 +713,22 @@ static void handle_scsi(struct command_block_wrapper* cbw)
719 case SCSI_REPORT_LUNS: { 713 case SCSI_REPORT_LUNS: {
720 logf("scsi inquiry %d",lun); 714 logf("scsi inquiry %d",lun);
721 int allocation_length=0; 715 int allocation_length=0;
716 int i;
722 allocation_length|=(cbw->command_block[6]<<24); 717 allocation_length|=(cbw->command_block[6]<<24);
723 allocation_length|=(cbw->command_block[7]<<16); 718 allocation_length|=(cbw->command_block[7]<<16);
724 allocation_length|=(cbw->command_block[8]<<8); 719 allocation_length|=(cbw->command_block[8]<<8);
725 allocation_length|=(cbw->command_block[9]); 720 allocation_length|=(cbw->command_block[9]);
726 memset(tb.lun_data,0,sizeof(struct report_lun_data)); 721 memset(tb.lun_data,0,sizeof(struct report_lun_data));
722 tb.lun_data->lun_list_length=htobe32(8*NUM_VOLUMES);
723 for(i=0;i<NUM_VOLUMES;i++)
724 {
727#ifdef HAVE_HOTSWAP 725#ifdef HAVE_HOTSWAP
728 tb.lun_data->lun_list_length=htobe32(16); 726 if(storage_removable(IF_MV(i)))
729 tb.lun_data->lun1[1]=1; 727 tb.lun_data->luns[i][1]=1;
730#else 728 else
731 tb.lun_data->lun_list_length=htobe32(8);
732#endif 729#endif
733 tb.lun_data->lun0[1]=0; 730 tb.lun_data->luns[i][1]=0;
734 731 }
735 send_command_result(tb.lun_data, 732 send_command_result(tb.lun_data,
736 MIN(sizeof(struct report_lun_data), length)); 733 MIN(sizeof(struct report_lun_data), length));
737 break; 734 break;
@@ -739,7 +736,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
739 736
740 case SCSI_INQUIRY: 737 case SCSI_INQUIRY:
741 logf("scsi inquiry %d",lun); 738 logf("scsi inquiry %d",lun);
742 identify2inquiry(lun); 739 fill_inquiry(IF_MV(lun));
743 length = MIN(length, cbw->command_block[4]); 740 length = MIN(length, cbw->command_block[4]);
744 send_command_result(tb.inquiry, 741 send_command_result(tb.inquiry,
745 MIN(sizeof(struct inquiry_data), length)); 742 MIN(sizeof(struct inquiry_data), length));
@@ -975,7 +972,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
975 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 972 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
976 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 973 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
977#else 974#else
978 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,) 975 cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,)
979 cur_cmd.sector, 976 cur_cmd.sector,
980 MIN(BUFFER_SIZE/SECTOR_SIZE, 977 MIN(BUFFER_SIZE/SECTOR_SIZE,
981 cur_cmd.count), 978 cur_cmd.count),
@@ -1072,46 +1069,30 @@ static void send_csw(int status)
1072 } 1069 }
1073} 1070}
1074 1071
1075/* convert ATA IDENTIFY to SCSI INQUIRY */ 1072static void copy_padded(char *dest, char *src, int len)
1076static void identify2inquiry(int lun)
1077{ 1073{
1078#ifdef HAVE_FLASH_STORAGE 1074 int i=0;
1079 if(lun==0) { 1075 while(src[i]!=0 && i<len)
1080 memcpy(&tb.inquiry->VendorId,"Rockbox ",8); 1076 {
1081 memcpy(&tb.inquiry->ProductId,"Internal Storage",16); 1077 dest[i]=src[i];
1082 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); 1078 i++;
1083 } 1079 }
1084 else { 1080 while(i<len)
1085 memcpy(&tb.inquiry->VendorId,"Rockbox ",8); 1081 {
1086 memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16); 1082 dest[i]=' ';
1087 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); 1083 i++;
1088 } 1084 }
1089#else 1085}
1090 unsigned int i;
1091 unsigned short* dest;
1092 unsigned short* src;
1093 unsigned short* identify = ata_get_identify();
1094 (void)lun;
1095 memset(tb.inquiry, 0, sizeof(struct inquiry_data));
1096
1097#if 0
1098 if (identify[82] & 4)
1099 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1100#endif
1101 1086
1102 /* ATA only has a 'model' field, so we copy the 1087/* build SCSI INQUIRY */
1103 first 8 bytes to 'vendor' and the rest to 'product' (they are 1088static void fill_inquiry(IF_MV_NONVOID(int lun))
1104 consecutive in the inquiry struct) */ 1089{
1105 src = (unsigned short*)&identify[27]; 1090 memset(tb.inquiry, 0, sizeof(struct inquiry_data));
1106 dest = (unsigned short*)&tb.inquiry->VendorId; 1091 struct storage_info info;
1107 for (i=0;i<12;i++) 1092 storage_get_info(IF_MV2(lun,)&info);
1108 dest[i] = htobe16(src[i]); 1093 copy_padded(tb.inquiry->VendorId,info.vendor,sizeof(tb.inquiry->VendorId));
1109 1094 copy_padded(tb.inquiry->ProductId,info.product,sizeof(tb.inquiry->ProductId));
1110 src = (unsigned short*)&identify[23]; 1095 copy_padded(tb.inquiry->ProductRevisionLevel,info.revision,sizeof(tb.inquiry->ProductRevisionLevel));
1111 dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel;
1112 for (i=0;i<2;i++)
1113 dest[i] = htobe16(src[i]);
1114#endif
1115 1096
1116 tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE; 1097 tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
1117 tb.inquiry->AdditionalLength = 0x1f; 1098 tb.inquiry->AdditionalLength = 0x1f;
@@ -1119,14 +1100,6 @@ static void identify2inquiry(int lun)
1119 tb.inquiry->Versions = 4; /* SPC-2 */ 1100 tb.inquiry->Versions = 4; /* SPC-2 */
1120 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ 1101 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */
1121 1102
1122#if 0
1123#ifdef HAVE_HOTSWAP
1124 if(lun>0)
1125 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1126#endif
1127#endif
1128 /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set.
1129 TODO : this can probably be solved by providing caching mode page */
1130#ifdef TOSHIBA_GIGABEAT_S 1103#ifdef TOSHIBA_GIGABEAT_S
1131 tb.inquiry->DeviceTypeModifier = 0; 1104 tb.inquiry->DeviceTypeModifier = 0;
1132#else 1105#else