summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/common/disk.c20
-rw-r--r--firmware/common/disk_cache.c8
-rw-r--r--firmware/common/pathfuncs.c66
-rw-r--r--firmware/drivers/ata.c36
-rw-r--r--firmware/drivers/fat.c44
-rw-r--r--firmware/drivers/ramdisk.c6
-rw-r--r--firmware/drivers/sd.c12
-rw-r--r--firmware/export/ata.h20
-rw-r--r--firmware/export/config.h51
-rw-r--r--firmware/export/config/cowond2.h3
-rw-r--r--firmware/export/config/creativezen.h1
-rw-r--r--firmware/export/config/creativezenxfi.h1
-rw-r--r--firmware/export/config/creativezenxfi2.h1
-rw-r--r--firmware/export/config/creativezenxfi3.h1
-rw-r--r--firmware/export/config/erosqnative.h2
-rw-r--r--firmware/export/config/fiiom3k.h2
-rw-r--r--firmware/export/config/ihifi760.h3
-rw-r--r--firmware/export/config/ihifi770.h7
-rw-r--r--firmware/export/config/ihifi770c.h7
-rw-r--r--firmware/export/config/ihifi800.h7
-rw-r--r--firmware/export/config/ihifi960.h2
-rw-r--r--firmware/export/config/mini2440.h3
-rw-r--r--firmware/export/config/ondavx747.h4
-rw-r--r--firmware/export/config/ondavx777.h4
-rw-r--r--firmware/export/config/rk27generic.h2
-rw-r--r--firmware/export/config/sansae200.h1
-rw-r--r--firmware/export/config/shanlingq1.h2
-rw-r--r--firmware/export/config/xduoox3.h4
-rw-r--r--firmware/export/disk.h4
-rw-r--r--firmware/export/fat.h4
-rw-r--r--firmware/export/hostfs.h4
-rw-r--r--firmware/export/mmc.h4
-rw-r--r--firmware/export/mv.h19
-rw-r--r--firmware/export/nand.h4
-rw-r--r--firmware/export/pathfuncs.h2
-rw-r--r--firmware/export/ramdisk.h4
-rw-r--r--firmware/export/rbpaths.h6
-rw-r--r--firmware/export/sd.h5
-rw-r--r--firmware/export/sdmmc.h8
-rw-r--r--firmware/export/storage.h15
-rw-r--r--firmware/include/dircache_redirect.h26
-rw-r--r--firmware/include/disk_cache.h4
-rw-r--r--firmware/storage.c37
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c15
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c8
-rw-r--r--firmware/target/arm/ata-nand-telechips.c92
-rw-r--r--firmware/target/arm/imx233/nand-imx233.c4
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.c8
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.h6
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c20
-rw-r--r--firmware/target/arm/pp/ata-pp5020.c24
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c40
-rw-r--r--firmware/target/arm/rk27xx/ata-nand-rk27xx.c8
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c9
-rw-r--r--firmware/target/arm/s3c2440/sd-s3c2440.c171
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c8
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c11
-rw-r--r--firmware/target/arm/tcc780x/sd-tcc780x.c94
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c22
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-target.h4
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c23
-rw-r--r--firmware/target/hosted/filesystem-hosted.h3
-rw-r--r--firmware/target/hosted/filesystem-unix.c6
-rw-r--r--firmware/target/hosted/filesystem-win32.c5
-rw-r--r--firmware/target/hosted/lcd-linuxfb.c24
-rw-r--r--firmware/target/hosted/sdl/button-sdl.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/app.lds8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c24
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c26
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c30
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c17
-rw-r--r--firmware/target/mips/ingenic_jz47xx/crt0.S2
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c40
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c26
-rw-r--r--firmware/target/mips/ingenic_x1000/msc-x1000.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/sd-x1000.c14
-rw-r--r--firmware/usbstack/usb_storage.c116
78 files changed, 827 insertions, 553 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 75ea8b136e..4e6fcbf70c 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1646,9 +1646,9 @@ target/mips/ingenic_jz47xx/kernel-jz4760.c
1646target/mips/ingenic_jz47xx/i2c-jz4760.c 1646target/mips/ingenic_jz47xx/i2c-jz4760.c
1647target/mips/ingenic_jz47xx/lcd-jz4760.c 1647target/mips/ingenic_jz47xx/lcd-jz4760.c
1648target/mips/ingenic_jz47xx/system-jz4760.c 1648target/mips/ingenic_jz47xx/system-jz4760.c
1649target/mips/ingenic_jz47xx/usb-jz4760.c
1650target/mips/ingenic_jz47xx/timer-jz4760.c 1649target/mips/ingenic_jz47xx/timer-jz4760.c
1651#ifndef BOOTLOADER 1650#ifndef BOOTLOADER
1651target/mips/ingenic_jz47xx/usb-jz4760.c
1652target/mips/ingenic_jz47xx/codec-jz4760.c 1652target/mips/ingenic_jz47xx/codec-jz4760.c
1653target/mips/ingenic_jz47xx/pcm-jz4760.c 1653target/mips/ingenic_jz47xx/pcm-jz4760.c
1654#endif /* BOOTLOADER */ 1654#endif /* BOOTLOADER */
diff --git a/firmware/common/disk.c b/firmware/common/disk.c
index 9b6454c9a2..576eede143 100644
--- a/firmware/common/disk.c
+++ b/firmware/common/disk.c
@@ -172,6 +172,8 @@ bool disk_init(IF_MD_NONVOID(int drive))
172 } 172 }
173 } 173 }
174 174
175 // XXX backup GPT header at final LBA of drive...
176
175 while (is_gpt) { 177 while (is_gpt) {
176 /* Re-start partition parsing using GPT */ 178 /* Re-start partition parsing using GPT */
177 uint64_t part_lba; 179 uint64_t part_lba;
@@ -243,20 +245,24 @@ reload:
243 goto skip; /* Any flag makes us ignore this */ 245 goto skip; /* Any flag makes us ignore this */
244 } 246 }
245 tmp = BYTES2INT64(pptr, 32); /* FIRST LBA */ 247 tmp = BYTES2INT64(pptr, 32); /* FIRST LBA */
246 if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo! 248#ifndef STORAGE_64BIT_SECTOR
247 DEBUGF("GPT: partition starts after 2GiB mark\n"); 249 if (tmp > UINT32_MAX) {
250 DEBUGF("GPT: partition starts after 2TiB mark\n");
248 goto skip; 251 goto skip;
249 } 252 }
253#endif
250 if (tmp < 34) { 254 if (tmp < 34) {
251 DEBUGF("GPT: Invalid start LBA\n"); 255 DEBUGF("GPT: Invalid start LBA\n");
252 goto skip; 256 goto skip;
253 } 257 }
254 pinfo[part].start = tmp; 258 pinfo[part].start = tmp;
255 tmp = BYTES2INT64(pptr, 40); /* LAST LBA */ 259 tmp = BYTES2INT64(pptr, 40); /* LAST LBA */
256 if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo! 260#ifndef STORAGE_64BIT_SECTOR
257 DEBUGF("GPT: partition ends after 2GiB mark\n"); 261 if (tmp > UINT32_MAX) {
262 DEBUGF("GPT: partition ends after 2TiB mark\n");
258 goto skip; 263 goto skip;
259 } 264 }
265#endif
260 if (tmp <= pinfo[part].start) { 266 if (tmp <= pinfo[part].start) {
261 DEBUGF("GPT: Invalid end LBA\n"); 267 DEBUGF("GPT: Invalid end LBA\n");
262 goto skip; 268 goto skip;
@@ -264,7 +270,7 @@ reload:
264 pinfo[part].size = tmp - pinfo[part].start + 1; 270 pinfo[part].size = tmp - pinfo[part].start + 1;
265 pinfo[part].type = PARTITION_TYPE_FAT32_LBA; 271 pinfo[part].type = PARTITION_TYPE_FAT32_LBA;
266 272
267 DEBUGF("GPart%d: start: %08lx size: %08lx\n", 273 DEBUGF("GPart%d: start: %016lx size: %016lx\n",
268 part,pinfo[part].start,pinfo[part].size); 274 part,pinfo[part].start,pinfo[part].size);
269 part++; 275 part++;
270 276
@@ -499,13 +505,13 @@ unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume))
499 return clustersize; 505 return clustersize;
500} 506}
501 507
502void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) 508void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
503{ 509{
504 disk_reader_lock(); 510 disk_reader_lock();
505 511
506 if (!CHECK_VOL(volume) || !fat_size(IF_MV(volume,) sizep, freep)) 512 if (!CHECK_VOL(volume) || !fat_size(IF_MV(volume,) sizep, freep))
507 { 513 {
508 if (freep) *sizep = 0; 514 if (sizep) *sizep = 0;
509 if (freep) *freep = 0; 515 if (freep) *freep = 0;
510 } 516 }
511 517
diff --git a/firmware/common/disk_cache.c b/firmware/common/disk_cache.c
index 9e4dee6a91..74c4d5f35b 100644
--- a/firmware/common/disk_cache.c
+++ b/firmware/common/disk_cache.c
@@ -71,12 +71,12 @@ struct disk_cache_entry
71#ifdef HAVE_MULTIVOLUME 71#ifdef HAVE_MULTIVOLUME
72 unsigned char volume; /* volume of sector */ 72 unsigned char volume; /* volume of sector */
73#endif 73#endif
74 unsigned long sector; /* cached disk sector number */ 74 sector_t sector; /* cached disk sector number */
75}; 75};
76 76
77BITARRAY_TYPE_DECLARE(cache_map_entry_t, cache_map, DC_NUM_ENTRIES) 77BITARRAY_TYPE_DECLARE(cache_map_entry_t, cache_map, DC_NUM_ENTRIES)
78 78
79static inline unsigned int map_sector(unsigned long sector) 79static inline unsigned int map_sector(sector_t sector)
80{ 80{
81 /* keep sector hash simple for now */ 81 /* keep sector hash simple for now */
82 return sector % DC_MAP_NUM_ENTRIES; 82 return sector % DC_MAP_NUM_ENTRIES;
@@ -172,7 +172,7 @@ static inline void cache_discard_entry(struct disk_cache_entry *dce,
172/* search the cache for the specified sector, returning a buffer, either 172/* search the cache for the specified sector, returning a buffer, either
173 to the specified sector, if it exists, or a new/evicted entry that must 173 to the specified sector, if it exists, or a new/evicted entry that must
174 be filled */ 174 be filled */
175void * dc_cache_probe(IF_MV(int volume,) unsigned long sector, 175void * dc_cache_probe(IF_MV(int volume,) sector_t sector,
176 unsigned int *flagsp) 176 unsigned int *flagsp)
177{ 177{
178 unsigned int mapnum = map_sector(sector); 178 unsigned int mapnum = map_sector(sector);
@@ -200,7 +200,7 @@ void * dc_cache_probe(IF_MV(int volume,) unsigned long sector,
200 if (old_flags) 200 if (old_flags)
201 { 201 {
202 int old_volume = IF_MV_VOL(dce->volume); 202 int old_volume = IF_MV_VOL(dce->volume);
203 unsigned long sector = dce->sector; 203 sector_t sector = dce->sector;
204 unsigned int old_mapnum = map_sector(sector); 204 unsigned int old_mapnum = map_sector(sector);
205 205
206 if (old_flags & DCE_DIRTY) 206 if (old_flags & DCE_DIRTY)
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c
index db3abe6940..b5e5ecb0cf 100644
--- a/firmware/common/pathfuncs.c
+++ b/firmware/common/pathfuncs.c
@@ -24,10 +24,14 @@
24#include "pathfuncs.h" 24#include "pathfuncs.h"
25#include "string-extra.h" 25#include "string-extra.h"
26#include <stdio.h> 26#include <stdio.h>
27#include "file_internal.h"
28#include "debug.h"
27 29
28#ifdef HAVE_MULTIVOLUME 30#ifdef HAVE_MULTIVOLUME
29#include "storage.h" 31#include "storage.h"
30 32
33static char vol_dec_strings[NUM_VOLUMES][ALIGN_UP(VOL_MAX_LEN+2, 4)] = {{0}};
34
31enum storage_name_dec_indexes 35enum storage_name_dec_indexes
32{ 36{
33#if (CONFIG_STORAGE & STORAGE_ATA) 37#if (CONFIG_STORAGE & STORAGE_ATA)
@@ -106,6 +110,54 @@ static const unsigned char storage_dec_indexes[STORAGE_NUM_TYPES+1] =
106#endif 110#endif
107}; 111};
108 112
113/* builds a list of drive/volume specifiers <volstr#> */
114void init_volume_names(void)
115{
116 DEBUGF("%s: ", __func__);
117 FOR_EACH_VOLUME(-1, volume)
118 {
119 const char *voldec = "";
120 char *buffer = vol_dec_strings[volume];
121
122 int type = storage_driver_type(volume_drive(volume));
123 if (type < 0 || type > STORAGE_NUM_TYPES)
124 type = STORAGE_NUM_TYPES;
125 voldec = storage_dec_names[storage_dec_indexes[type]];
126 snprintf(buffer, VOL_MAX_LEN + 1, "%c%s%d%c",
127 VOL_START_TOK, voldec, volume, VOL_END_TOK);
128 DEBUGF("vol<%d> = %s ", volume, buffer);
129 }
130 DEBUGF("\n");
131}
132
133#include <stdio.h>
134
135int path_get_volume_id(const char *name)
136{
137 int v = -1;
138
139 if (!name || *name != VOL_START_TOK)
140 goto bail;
141
142 do {
143 switch (*name)
144 {
145 case '0' ... '9': /* digit; parse volume number */
146 v = (v * 10 + *name - '0') % VOL_NUM_MAX;
147 break;
148 case '\0':
149 case PATH_SEPCH: /* no closing bracket; no volume */
150 v = -1;
151 goto bail;
152 default: /* something else; reset volume */
153 v = 0;
154 }
155 } while (*++name != VOL_END_TOK); /* found end token? */
156
157bail:
158 return v;
159}
160
109/* Returns on which volume this is and sets *nameptr to the portion of the 161/* Returns on which volume this is and sets *nameptr to the portion of the
110 * path after the volume specifier, which could be the null if the path is 162 * path after the volume specifier, which could be the null if the path is
111 * just a volume root. If *nameptr > name, then a volume specifier was 163 * just a volume root. If *nameptr > name, then a volume specifier was
@@ -203,7 +255,8 @@ int path_strip_last_volume(const char *name, const char **nameptr, bool greedy)
203} 255}
204 256
205/* Returns the volume specifier decorated with the storage type name. 257/* Returns the volume specifier decorated with the storage type name.
206 * Assumes the supplied buffer size is at least {VOL_MAX_LEN}+1. 258 * Assumes the supplied buffer size is at least {VOL_MAX_LEN}+1,
259 * vol_dec_strings has been initialized by init_volume_names().
207 */ 260 */
208int get_volume_name(int volume, char *buffer) 261int get_volume_name(int volume, char *buffer)
209{ 262{
@@ -218,17 +271,12 @@ int get_volume_name(int volume, char *buffer)
218 271
219 volume %= VOL_NUM_MAX; /* as path parser would have it */ 272 volume %= VOL_NUM_MAX; /* as path parser would have it */
220 273
221 int type = storage_driver_type(volume_drive(volume)); 274 return strlcpy(buffer, vol_dec_strings[volume], VOL_MAX_LEN + 1);
222 if (type < 0 || type > STORAGE_NUM_TYPES)
223 type = STORAGE_NUM_TYPES;
224
225 const char *voldec = storage_dec_names[storage_dec_indexes[type]];
226 return snprintf(buffer, VOL_MAX_LEN + 1, "%c%s%d%c",
227 VOL_START_TOK, voldec, volume, VOL_END_TOK);
228} 275}
229 276
230/* Returns volume name formatted with the root. Assumes buffer size is at 277/* Returns volume name formatted with the root. Assumes buffer size is at
231 * least {VOL_MAX_LEN}+2 */ 278 * least {VOL_MAX_LEN}+2, vol_dec_strings has been initialized by init_volume_names().
279 */
232int make_volume_root(int volume, char *buffer) 280int make_volume_root(int volume, char *buffer)
233{ 281{
234 char *t = buffer; 282 char *t = buffer;
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index d82fb173cc..7b9c4910cf 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -109,15 +109,15 @@ static long last_disk_activity = -1;
109static long power_off_tick = 0; 109static long power_off_tick = 0;
110#endif 110#endif
111 111
112static unsigned long total_sectors; 112static sector_t total_sectors;
113static int multisectors; /* number of supported multisectors */ 113static int multisectors; /* number of supported multisectors */
114static unsigned short identify_info[SECTOR_SIZE/2]; 114static unsigned short identify_info[ATA_IDENTIFY_WORDS];
115 115
116#ifdef MAX_PHYS_SECTOR_SIZE 116#ifdef MAX_PHYS_SECTOR_SIZE
117 117
118struct sector_cache_entry { 118struct sector_cache_entry {
119 bool inuse; 119 bool inuse;
120 unsigned long sectornum; /* logical sector */ 120 sector_t sectornum; /* logical sector */
121 unsigned char data[MAX_PHYS_SECTOR_SIZE]; 121 unsigned char data[MAX_PHYS_SECTOR_SIZE];
122}; 122};
123/* buffer for reading and writing large physical sectors */ 123/* buffer for reading and writing large physical sectors */
@@ -381,7 +381,7 @@ static ICODE_ATTR void copy_write_sectors(const unsigned char* buf,
381} 381}
382#endif /* !ATA_OPTIMIZED_WRITING */ 382#endif /* !ATA_OPTIMIZED_WRITING */
383 383
384static int ata_transfer_sectors(unsigned long start, 384static int ata_transfer_sectors(uint64_t start,
385 int incount, 385 int incount,
386 void* inbuf, 386 void* inbuf,
387 int write) 387 int write)
@@ -443,9 +443,9 @@ static int ata_transfer_sectors(unsigned long start,
443 ATA_OUT8(ATA_NSECTOR, count & 0xff); 443 ATA_OUT8(ATA_NSECTOR, count & 0xff);
444 ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */ 444 ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
445 ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */ 445 ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */
446 ATA_OUT8(ATA_LCYL, 0); /* 39:32 */ 446 ATA_OUT8(ATA_LCYL, (start >> 32) & 0xff); /* 39:32 */
447 ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */ 447 ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
448 ATA_OUT8(ATA_HCYL, 0); /* 47:40 */ 448 ATA_OUT8(ATA_HCYL, (start >> 40) & 0xff); /* 47:40 */
449 ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */ 449 ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
450 ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device); 450 ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device);
451#ifdef HAVE_ATA_DMA 451#ifdef HAVE_ATA_DMA
@@ -592,7 +592,7 @@ static int ata_transfer_sectors(unsigned long start,
592 592
593#ifndef MAX_PHYS_SECTOR_SIZE 593#ifndef MAX_PHYS_SECTOR_SIZE
594int ata_read_sectors(IF_MD(int drive,) 594int ata_read_sectors(IF_MD(int drive,)
595 unsigned long start, 595 sector_t start,
596 int incount, 596 int incount,
597 void* inbuf) 597 void* inbuf)
598{ 598{
@@ -607,7 +607,7 @@ int ata_read_sectors(IF_MD(int drive,)
607} 607}
608 608
609int ata_write_sectors(IF_MD(int drive,) 609int ata_write_sectors(IF_MD(int drive,)
610 unsigned long start, 610 sector_t start,
611 int count, 611 int count,
612 const void* buf) 612 const void* buf)
613{ 613{
@@ -623,7 +623,7 @@ int ata_write_sectors(IF_MD(int drive,)
623#endif /* ndef MAX_PHYS_SECTOR_SIZE */ 623#endif /* ndef MAX_PHYS_SECTOR_SIZE */
624 624
625#ifdef MAX_PHYS_SECTOR_SIZE 625#ifdef MAX_PHYS_SECTOR_SIZE
626static int cache_sector(unsigned long sector) 626static int cache_sector(sector_t sector)
627{ 627{
628 int rc; 628 int rc;
629 629
@@ -652,7 +652,7 @@ static inline int flush_current_sector(void)
652} 652}
653 653
654int ata_read_sectors(IF_MD(int drive,) 654int ata_read_sectors(IF_MD(int drive,)
655 unsigned long start, 655 sector_t start,
656 int incount, 656 int incount,
657 void* inbuf) 657 void* inbuf)
658{ 658{
@@ -718,7 +718,7 @@ int ata_read_sectors(IF_MD(int drive,)
718} 718}
719 719
720int ata_write_sectors(IF_MD(int drive,) 720int ata_write_sectors(IF_MD(int drive,)
721 unsigned long start, 721 sector_t start,
722 int count, 722 int count,
723 const void* buf) 723 const void* buf)
724{ 724{
@@ -916,7 +916,7 @@ static int identify(void)
916 return -2; 916 return -2;
917 } 917 }
918 918
919 for (i=0; i<SECTOR_SIZE/2; i++) { 919 for (i=0; i<ATA_IDENTIFY_WORDS; i++) {
920 /* the IDENTIFY words are already swapped, so we need to treat 920 /* the IDENTIFY words are already swapped, so we need to treat
921 this info differently that normal sector data */ 921 this info differently that normal sector data */
922 identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); 922 identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA));
@@ -1269,10 +1269,8 @@ int STORAGE_INIT_ATTR ata_init(void)
1269 if (identify_info[83] & 0x0400 /* 48 bit address support */ 1269 if (identify_info[83] & 0x0400 /* 48 bit address support */
1270 && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */ 1270 && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */
1271 { /* (needs BigLBA addressing) */ 1271 { /* (needs BigLBA addressing) */
1272 if (identify_info[102] || identify_info[103]) 1272 total_sectors = identify_info[100] | (identify_info[101] << 16) | ((uint64_t)identify_info[102] << 32) | ((uint64_t)identify_info[103] << 48);
1273 panicf("Unsupported disk size: >= 2^32 sectors");
1274 1273
1275 total_sectors = identify_info[100] | (identify_info[101] << 16);
1276 lba48 = true; /* use BigLBA */ 1274 lba48 = true; /* use BigLBA */
1277 } 1275 }
1278#endif /* HAVE_LBA48 */ 1276#endif /* HAVE_LBA48 */
@@ -1360,7 +1358,13 @@ void ata_get_info(IF_MD(int drive,)struct storage_info *info)
1360 (void)drive; /* unused for now */ 1358 (void)drive; /* unused for now */
1361#endif 1359#endif
1362 int i; 1360 int i;
1363 info->sector_size = SECTOR_SIZE; 1361
1362 /* Logical sector size */
1363 if ((identify_info[106] & 0xd000) == 0x5000)
1364 info->sector_size = identify_info[117] | (identify_info[118] << 16);
1365 else
1366 info->sector_size = SECTOR_SIZE;
1367
1364 info->num_sectors = total_sectors; 1368 info->num_sectors = total_sectors;
1365 1369
1366 src = (unsigned short*)&identify_info[27]; 1370 src = (unsigned short*)&identify_info[27];
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index ebf0f92798..f3c273cc05 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -173,9 +173,9 @@ union raw_dirent
173 173
174struct fsinfo 174struct fsinfo
175{ 175{
176 unsigned long freecount; /* last known free cluster count */ 176 sector_t freecount; /* last known free cluster count */
177 unsigned long nextfree; /* first cluster to start looking for free 177 sector_t nextfree; /* first cluster to start looking for free
178 clusters, or 0xffffffff for no hint */ 178 clusters, or 0xffffffff for no hint */
179}; 179};
180/* fsinfo offsets */ 180/* fsinfo offsets */
181#define FSINFO_SIGNATURE 0 181#define FSINFO_SIGNATURE 0
@@ -233,7 +233,7 @@ static struct bpb
233 unsigned long totalsectors; 233 unsigned long totalsectors;
234 unsigned long rootdirsector; 234 unsigned long rootdirsector;
235 unsigned long firstdatasector; 235 unsigned long firstdatasector;
236 unsigned long startsector; 236 sector_t startsector;
237 unsigned long dataclusters; 237 unsigned long dataclusters;
238 unsigned long fatrgnstart; 238 unsigned long fatrgnstart;
239 unsigned long fatrgnend; 239 unsigned long fatrgnend;
@@ -241,8 +241,8 @@ static struct bpb
241#ifdef HAVE_FAT16SUPPORT 241#ifdef HAVE_FAT16SUPPORT
242 unsigned int bpb_rootentcnt; /* Number of dir entries in the root */ 242 unsigned int bpb_rootentcnt; /* Number of dir entries in the root */
243 /* internals for FAT16 support */ 243 /* internals for FAT16 support */
244 unsigned long rootdirsectornum; /* sector offset of root dir relative to start 244 sector_t rootdirsectornum; /* sector offset of root dir relative to start
245 * of first pseudo cluster */ 245 * of first pseudo cluster */
246#endif /* HAVE_FAT16SUPPORT */ 246#endif /* HAVE_FAT16SUPPORT */
247 247
248 /** Additional information kept for each volume **/ 248 /** Additional information kept for each volume **/
@@ -329,7 +329,7 @@ static void cache_discard(IF_MV_NONVOID(struct bpb *fat_bpb))
329} 329}
330 330
331/* caches a FAT or data area sector */ 331/* caches a FAT or data area sector */
332static void * cache_sector(struct bpb *fat_bpb, unsigned long secnum) 332static void * cache_sector(struct bpb *fat_bpb, sector_t secnum)
333{ 333{
334 unsigned int flags; 334 unsigned int flags;
335 void *buf = dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags); 335 void *buf = dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags);
@@ -340,8 +340,8 @@ static void * cache_sector(struct bpb *fat_bpb, unsigned long secnum)
340 secnum + fat_bpb->startsector, 1, buf); 340 secnum + fat_bpb->startsector, 1, buf);
341 if (UNLIKELY(rc < 0)) 341 if (UNLIKELY(rc < 0))
342 { 342 {
343 DEBUGF("%s() - Could not read sector %ld" 343 DEBUGF("%s() - Could not read sector %llu"
344 " (error %d)\n", __func__, secnum, rc); 344 " (error %d)\n", __func__, (uint64_t)secnum, rc);
345 dc_discard_buf(buf); 345 dc_discard_buf(buf);
346 return NULL; 346 return NULL;
347 } 347 }
@@ -354,14 +354,14 @@ static void * cache_sector(struct bpb *fat_bpb, unsigned long secnum)
354 * contents are NOT loaded before returning - use when completely overwriting 354 * contents are NOT loaded before returning - use when completely overwriting
355 * a sector's contents in order to avoid a fill */ 355 * a sector's contents in order to avoid a fill */
356static void * cache_sector_buffer(IF_MV(struct bpb *fat_bpb,) 356static void * cache_sector_buffer(IF_MV(struct bpb *fat_bpb,)
357 unsigned long secnum) 357 sector_t secnum)
358{ 358{
359 unsigned int flags; 359 unsigned int flags;
360 return dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags); 360 return dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags);
361} 361}
362 362
363/* flush a cache buffer to storage */ 363/* flush a cache buffer to storage */
364void dc_writeback_callback(IF_MV(int volume,) unsigned long sector, void *buf) 364void dc_writeback_callback(IF_MV(int volume,) sector_t sector, void *buf)
365{ 365{
366 struct bpb * const fat_bpb = &fat_bpbs[IF_MV_VOL(volume)]; 366 struct bpb * const fat_bpb = &fat_bpbs[IF_MV_VOL(volume)];
367 unsigned int copies = !IS_FAT_SECTOR(fat_bpb, sector) ? 367 unsigned int copies = !IS_FAT_SECTOR(fat_bpb, sector) ?
@@ -374,8 +374,8 @@ void dc_writeback_callback(IF_MV(int volume,) unsigned long sector, void *buf)
374 int rc = storage_write_sectors(IF_MD(fat_bpb->drive,) sector, 1, buf); 374 int rc = storage_write_sectors(IF_MD(fat_bpb->drive,) sector, 1, buf);
375 if (rc < 0) 375 if (rc < 0)
376 { 376 {
377 panicf("%s() - Could not write sector %ld" 377 panicf("%s() - Could not write sector %llu"
378 " (error %d)\n", __func__, sector, rc); 378 " (error %d)\n", __func__, (uint64_t)sector, rc);
379 } 379 }
380 380
381 if (--copies == 0) 381 if (--copies == 0)
@@ -2397,12 +2397,12 @@ unsigned long fat_query_sectornum(const struct fat_filestr *filestr)
2397} 2397}
2398 2398
2399/* helper for fat_readwrite */ 2399/* helper for fat_readwrite */
2400static long transfer(struct bpb *fat_bpb, unsigned long start, long count, 2400static long transfer(struct bpb *fat_bpb, sector_t start, long count,
2401 char *buf, bool write) 2401 char *buf, bool write)
2402{ 2402{
2403 long rc = 0; 2403 long rc = 0;
2404 2404
2405 DEBUGF("%s(s=%lx, c=%lx, wr=%u)\n", __func__, 2405 DEBUGF("%s(s=%llx, c=%lx, wr=%u)\n", __func__,
2406 start + fat_bpb->startsector, count, write ? 1 : 0); 2406 start + fat_bpb->startsector, count, write ? 1 : 0);
2407 2407
2408 if (write) 2408 if (write)
@@ -2416,12 +2416,12 @@ static long transfer(struct bpb *fat_bpb, unsigned long start, long count,
2416 firstallowed = fat_bpb->firstdatasector; 2416 firstallowed = fat_bpb->firstdatasector;
2417 2417
2418 if (start < firstallowed) 2418 if (start < firstallowed)
2419 panicf("Write %ld before data\n", firstallowed - start); 2419 panicf("Write %llu before data\n", (uint64_t)(firstallowed - start));
2420 2420
2421 if (start + count > fat_bpb->totalsectors) 2421 if (start + count > fat_bpb->totalsectors)
2422 { 2422 {
2423 panicf("Write %ld after data\n", 2423 panicf("Write %llu after data\n",
2424 start + count - fat_bpb->totalsectors); 2424 (uint64_t)(start + count - fat_bpb->totalsectors));
2425 } 2425 }
2426 } 2426 }
2427 2427
@@ -2487,14 +2487,14 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
2487 long rc; 2487 long rc;
2488 2488
2489 long cluster = filestr->lastcluster; 2489 long cluster = filestr->lastcluster;
2490 unsigned long sector = filestr->lastsector; 2490 sector_t sector = filestr->lastsector;
2491 long clusternum = filestr->clusternum; 2491 long clusternum = filestr->clusternum;
2492 unsigned long sectornum = filestr->sectornum; 2492 unsigned long sectornum = filestr->sectornum;
2493 2493
2494 DEBUGF("%s(file:%lx,count:0x%lx,buf:%lx,%s)\n", __func__, 2494 DEBUGF("%s(file:%lx,count:0x%lx,buf:%lx,%s)\n", __func__,
2495 file->firstcluster, sectorcount, (long)buf, 2495 file->firstcluster, sectorcount, (long)buf,
2496 write ? "write":"read"); 2496 write ? "write":"read");
2497 DEBUGF("%s: sec:%lx numsec:%ld eof:%d\n", __func__, 2497 DEBUGF("%s: sec:%llx numsec:%ld eof:%d\n", __func__,
2498 sector, (long)sectornum, eof ? 1 : 0); 2498 sector, (long)sectornum, eof ? 1 : 0);
2499 2499
2500 eof = false; 2500 eof = false;
@@ -2534,7 +2534,7 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
2534 2534
2535 unsigned long transferred = 0; 2535 unsigned long transferred = 0;
2536 unsigned long count = 0; 2536 unsigned long count = 0;
2537 unsigned long last = sector; 2537 sector_t last = sector;
2538 2538
2539 while (transferred + count < sectorcount) 2539 while (transferred + count < sectorcount)
2540 { 2540 {
@@ -2961,7 +2961,7 @@ void fat_recalc_free(IF_MV_NONVOID(int volume))
2961 dc_unlock_cache(); 2961 dc_unlock_cache();
2962} 2962}
2963 2963
2964bool fat_size(IF_MV(int volume,) unsigned long *size, unsigned long *free) 2964bool fat_size(IF_MV(int volume,) sector_t *size, sector_t *free)
2965{ 2965{
2966 struct bpb * const fat_bpb = FAT_BPB(volume); 2966 struct bpb * const fat_bpb = FAT_BPB(volume);
2967 if (!fat_bpb) 2967 if (!fat_bpb)
diff --git a/firmware/drivers/ramdisk.c b/firmware/drivers/ramdisk.c
index 9f73b6b5c3..cecc943352 100644
--- a/firmware/drivers/ramdisk.c
+++ b/firmware/drivers/ramdisk.c
@@ -32,7 +32,7 @@ static unsigned char ramdisk[SECTOR_SIZE * NUM_SECTORS];
32static long last_disk_activity = -1; 32static long last_disk_activity = -1;
33 33
34int ramdisk_read_sectors(IF_MD(int drive,) 34int ramdisk_read_sectors(IF_MD(int drive,)
35 unsigned long start, 35 sector_t start,
36 int count, 36 int count,
37 void* buf) 37 void* buf)
38{ 38{
@@ -48,7 +48,7 @@ int ramdisk_read_sectors(IF_MD(int drive,)
48} 48}
49 49
50int ramdisk_write_sectors(IF_MD(int drive,) 50int ramdisk_write_sectors(IF_MD(int drive,)
51 unsigned long start, 51 sector_t start,
52 int count, 52 int count,
53 const void* buf) 53 const void* buf)
54{ 54{
@@ -134,7 +134,7 @@ int ramdisk_num_drives(int first_drive)
134{ 134{
135 /* We don't care which logical drive number(s) we have been assigned */ 135 /* We don't care which logical drive number(s) we have been assigned */
136 (void)first_drive; 136 (void)first_drive;
137 137
138 return 1; 138 return 1;
139} 139}
140#endif 140#endif
diff --git a/firmware/drivers/sd.c b/firmware/drivers/sd.c
index 6185d5382d..ca83498087 100644
--- a/firmware/drivers/sd.c
+++ b/firmware/drivers/sd.c
@@ -49,6 +49,13 @@ void sd_parse_csd(tCardInfo *card)
49 c_size = card_extract_bits(card->csd, 69, 22) + 1; 49 c_size = card_extract_bits(card->csd, 69, 22) + 1;
50 card->numblocks = c_size << 10; 50 card->numblocks = c_size << 10;
51 } 51 }
52 else if(csd_version == 2)
53 {
54 /* CSD version 3.0 */
55 c_size = card_extract_bits(card->csd, 75, 28) + 1;
56 card->numblocks = c_size << 10;
57 }
58 card->sd2plus = csd_version >= 1;
52 59
53 card->blocksize = 512; /* Always use 512 byte blocks */ 60 card->blocksize = 512; /* Always use 512 byte blocks */
54 61
@@ -62,7 +69,9 @@ void sd_parse_csd(tCardInfo *card)
62 69
63 card->r2w_factor = card_extract_bits(card->csd, 28, 3); 70 card->r2w_factor = card_extract_bits(card->csd, 28, 3);
64 71
65 logf("CSD%d.0 numblocks:%ld speed:%ld", csd_version+1, card->numblocks, card->speed); 72
73
74 logf("CSD%d.0 numblocks:%lld speed:%ld", csd_version+1, card->numblocks, card->speed);
66 logf("nsac: %d taac: %ld r2w: %d", card->nsac, card->taac, card->r2w_factor); 75 logf("nsac: %d taac: %ld r2w: %d", card->nsac, card->taac, card->r2w_factor);
67} 76}
68 77
@@ -99,4 +108,3 @@ void sd_get_info(IF_MD(int drive,) struct storage_info *info)
99 info->revision="0.00"; 108 info->revision="0.00";
100} 109}
101#endif 110#endif
102
diff --git a/firmware/export/ata.h b/firmware/export/ata.h
index 62c9467643..6165eaf633 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -140,8 +140,8 @@ bool ata_disk_is_active(void);
140int ata_soft_reset(void); 140int ata_soft_reset(void);
141int ata_init(void) STORAGE_INIT_ATTR; 141int ata_init(void) STORAGE_INIT_ATTR;
142void ata_close(void); 142void ata_close(void);
143int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 143int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
144int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 144int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
145void ata_spin(void); 145void ata_spin(void);
146#if (CONFIG_LED == LED_REAL) 146#if (CONFIG_LED == LED_REAL)
147void ata_set_led_enabled(bool enabled); 147void ata_set_led_enabled(bool enabled);
@@ -191,22 +191,22 @@ static inline int ata_disk_isssd(void)
191 However microdrives pose a problem as they support CFA but are not 191 However microdrives pose a problem as they support CFA but are not
192 SSD. 192 SSD.
193 193
194 Offset 163 shows CF Advanced timing modes; microdrives all seems to
195 report 0, but all others (including iFlash) report higher! This
196 is often present even when the "CFA supported" bit is 0.
197
194 Offset 160 b15 indicates support for CF+ power level 1, if not set 198 Offset 160 b15 indicates support for CF+ power level 1, if not set
195 then device is standard flash CF. However this is not foolproof 199 then device is standard flash CF. However this is not foolproof
196 as newer CF cards may support it for extra performance. 200 as newer CF cards (and those CF->SD adapters) may report this.
197
198 Offset 163 shows CF Advanced timing modes; microdrive seems to
199 report 0, but all others (including iFlash) report higher!
200 201
201 So if device support CFA _AND_ reports higher speeds modes, it is SSD.
202 202
203 */ 203 */
204 return ( (identify_info[217] == 0x0001 || identify_info[217] == 0x0100) /* "Solid state" rotational rate */ 204 return ( (identify_info[217] == 0x0001 || identify_info[217] == 0x0100) /* "Solid state" rotational rate */
205 || ((identify_info[168] & 0x0f) >= 0x06) /* Explicit SSD form factors */ 205 || ((identify_info[168] & 0x0f) >= 0x06) /* Explicit SSD form factors */
206 || (identify_info[169] & (1<<0)) /* TRIM supported */ 206 || (identify_info[169] & (1<<0)) /* TRIM supported */
207 || (identify_info[163] > 0) /* CF Advanced timing modes */
207 || ((identify_info[83] & (1<<2)) && /* CFA compliant */ 208 || ((identify_info[83] & (1<<2)) && /* CFA compliant */
208 (((identify_info[160] & (1<<15)) == 0) || /* CF level 0 */ 209 ((identify_info[160] & (1<<15)) == 0)) /* CF power level 0 */
209 (identify_info[163] > 0))) /* Advanced timing modes */
210 ); 210 );
211} 211}
212 212
@@ -233,4 +233,6 @@ int ata_read_smart(struct ata_smart_values*);
233#define STORAGE_CLOSE 233#define STORAGE_CLOSE
234#endif 234#endif
235 235
236#define ATA_IDENTIFY_WORDS 256
237
236#endif /* __ATA_H__ */ 238#endif /* __ATA_H__ */
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 5ea5c71c70..ede1825f88 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -868,22 +868,41 @@ Lyre prototype 1 */
868#define CONFIG_STORAGE_MULTI 868#define CONFIG_STORAGE_MULTI
869#endif 869#endif
870 870
871/* Explicit HAVE_MULTIVOLUME in the config file. Allow the maximum number */
872#ifdef HAVE_MULTIVOLUME
873#define NUM_VOLUMES_PER_DRIVE 4
874#else
875#define NUM_VOLUMES_PER_DRIVE 1
876#endif
877#if defined(CONFIG_STORAGE_MULTI) && !defined(HAVE_MULTIDRIVE) 871#if defined(CONFIG_STORAGE_MULTI) && !defined(HAVE_MULTIDRIVE)
878#define HAVE_MULTIDRIVE 872#define HAVE_MULTIDRIVE
879#endif 873#endif
880 874
881#if defined(HAVE_MULTIDRIVE) && !defined(HAVE_MULTIVOLUME) 875#if defined(HAVE_MULTIDRIVE) && !defined(NUM_DRIVES)
876#error HAVE_MULTIDRIVE needs to have an explicit NUM_DRIVES
877#endif
878
879#ifndef NUM_DRIVES
880#define NUM_DRIVES 1
881#endif
882
883#if !defined(HAVE_MULTIVOLUME)
884#if defined(HAVE_MULTIDRIVE)
885/* Multidrive strongly implies multivolume */
886#define HAVE_MULTIVOLUME
887#elif (CONFIG_STORAGE & STORAGE_SD)
888/* SD routinely have multiple partitions */
889#elif (CONFIG_STORAGE & STORAGE_ATA) && defined(HAVE_LBA48)
890/* ATA routinely haves multiple partitions, but don't bother if we can't do LBA48 */
882#define HAVE_MULTIVOLUME 891#define HAVE_MULTIVOLUME
883#endif 892#endif
893#endif
884 894
885#if defined(HAVE_MULTIDRIVE) && !defined(NUM_DRIVES) 895/* Bootloaders don't need multivolume awareness */
886#error HAVE_MULTIDRIVE needs to have an explicit NUM_DRIVES 896#if defined(BOOTLOADER) && defined(HAVE_MULTIVOLUME) \
897 && !(CONFIG_PLATFORM & PLATFORM_HOSTED) && !defined(BOOT_REDIR)
898#undef HAVE_MULTIVOLUME
899#endif
900
901/* Number of volumes per drive */
902#if defined(HAVE_MULTIVOLUME) && !defined(SIMULATOR) && !(CONFIG_PLATFORM & PLATFORM_HOSTED)
903#define NUM_VOLUMES_PER_DRIVE 4
904#else
905#define NUM_VOLUMES_PER_DRIVE 1
887#endif 906#endif
888 907
889/* note to remove multi-partition booting this could be changed to MULTIDRIVE */ 908/* note to remove multi-partition booting this could be changed to MULTIDRIVE */
@@ -897,10 +916,6 @@ Lyre prototype 1 */
897# define MULTIBOOT_MIN_VOLUME 0 916# define MULTIBOOT_MIN_VOLUME 0
898#endif 917#endif
899 918
900#ifndef NUM_DRIVES
901#define NUM_DRIVES 1
902#endif
903
904#define NUM_VOLUMES (NUM_DRIVES * NUM_VOLUMES_PER_DRIVE) 919#define NUM_VOLUMES (NUM_DRIVES * NUM_VOLUMES_PER_DRIVE)
905 920
906#if defined(BOOTLOADER) && defined(HAVE_ADJUSTABLE_CPU_FREQ) 921#if defined(BOOTLOADER) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
@@ -934,31 +949,35 @@ Lyre prototype 1 */
934#ifdef HAVE_BOOTLOADER_USB_MODE 949#ifdef HAVE_BOOTLOADER_USB_MODE
935/* Priority in bootloader is wanted */ 950/* Priority in bootloader is wanted */
936#define HAVE_PRIORITY_SCHEDULING 951#define HAVE_PRIORITY_SCHEDULING
952
937#if (CONFIG_CPU == S5L8702) 953#if (CONFIG_CPU == S5L8702)
938#define USB_DRIVER_CLOSE 954#define USB_DRIVER_CLOSE
939#else 955#else
940#define USB_STATUS_BY_EVENT 956#define USB_STATUS_BY_EVENT
941#define USB_DETECT_BY_REQUEST 957#define USB_DETECT_BY_REQUEST
942#endif 958#endif
959
943#if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC 960#if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC
944#define INCLUDE_TIMEOUT_API 961#define INCLUDE_TIMEOUT_API
945#define USB_DRIVER_CLOSE 962#define USB_DRIVER_CLOSE
946#endif 963#endif
964
947#if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_TNETV105 965#if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_TNETV105
948#define INCLUDE_TIMEOUT_API 966#define INCLUDE_TIMEOUT_API
949#define USB_DRIVER_CLOSE 967#define USB_DRIVER_CLOSE
950#endif 968#endif
969
951#if CONFIG_CPU == X1000 970#if CONFIG_CPU == X1000
952#define USB_DRIVER_CLOSE 971#define USB_DRIVER_CLOSE
953#endif 972#endif
954#endif 973
974#endif /* BOOTLOADER_USB_MODE */
955 975
956#else /* !BOOTLOADER */ 976#else /* !BOOTLOADER */
957 977
958#define HAVE_EXTENDED_MESSAGING_AND_NAME 978#define HAVE_EXTENDED_MESSAGING_AND_NAME
959#define HAVE_WAKEUP_EXT_CB 979#define HAVE_WAKEUP_EXT_CB
960 980
961
962#if defined(ASSEMBLER_THREADS) \ 981#if defined(ASSEMBLER_THREADS) \
963 || defined(HAVE_WIN32_FIBER_THREADS) \ 982 || defined(HAVE_WIN32_FIBER_THREADS) \
964 || defined(HAVE_SIGALTSTACK_THREADS) 983 || defined(HAVE_SIGALTSTACK_THREADS)
@@ -993,7 +1012,7 @@ Lyre prototype 1 */
993#endif /* CONFIG_USB == */ 1012#endif /* CONFIG_USB == */
994#endif /* HAVE_USBSTACK */ 1013#endif /* HAVE_USBSTACK */
995 1014
996#endif /* BOOTLOADER */ 1015#endif /* !BOOTLOADER */
997 1016
998#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) || (CONFIG_CPU == JZ4760B) \ 1017#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) || (CONFIG_CPU == JZ4760B) \
999 || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ 1018 || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \
diff --git a/firmware/export/config/cowond2.h b/firmware/export/config/cowond2.h
index 5912fb63eb..fbfcc2c089 100644
--- a/firmware/export/config/cowond2.h
+++ b/firmware/export/config/cowond2.h
@@ -61,9 +61,8 @@
61/* NAND is broken. */ 61/* NAND is broken. */
62//#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) 62//#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD)
63#define CONFIG_STORAGE STORAGE_SD 63#define CONFIG_STORAGE STORAGE_SD
64#define HAVE_MULTIDRIVE 64#define HAVE_MULTIVOLUME
65#define HAVE_HOTSWAP 65#define HAVE_HOTSWAP
66#define NUM_DRIVES 1
67 66
68#define CONFIG_NAND NAND_TCC 67#define CONFIG_NAND NAND_TCC
69 68
diff --git a/firmware/export/config/creativezen.h b/firmware/export/config/creativezen.h
index b1f438c354..d70749e59f 100644
--- a/firmware/export/config/creativezen.h
+++ b/firmware/export/config/creativezen.h
@@ -133,7 +133,6 @@
133#define CONFIG_STORAGE STORAGE_SD 133#define CONFIG_STORAGE STORAGE_SD
134#define NUM_DRIVES 2 134#define NUM_DRIVES 2
135#define HAVE_MULTIDRIVE 135#define HAVE_MULTIDRIVE
136#define HAVE_MULTIVOLUME
137#define HAVE_HOTSWAP 136#define HAVE_HOTSWAP
138 137
139/* todo */ 138/* todo */
diff --git a/firmware/export/config/creativezenxfi.h b/firmware/export/config/creativezenxfi.h
index 34cde37d9a..489dea80b7 100644
--- a/firmware/export/config/creativezenxfi.h
+++ b/firmware/export/config/creativezenxfi.h
@@ -138,7 +138,6 @@
138#define CONFIG_STORAGE STORAGE_SD 138#define CONFIG_STORAGE STORAGE_SD
139#define NUM_DRIVES 2 139#define NUM_DRIVES 2
140#define HAVE_MULTIDRIVE 140#define HAVE_MULTIDRIVE
141#define HAVE_MULTIVOLUME
142#define HAVE_HOTSWAP 141#define HAVE_HOTSWAP
143 142
144/* todo */ 143/* todo */
diff --git a/firmware/export/config/creativezenxfi2.h b/firmware/export/config/creativezenxfi2.h
index 47a600e8f5..5db228e559 100644
--- a/firmware/export/config/creativezenxfi2.h
+++ b/firmware/export/config/creativezenxfi2.h
@@ -140,7 +140,6 @@
140#define CONFIG_STORAGE (/*STORAGE_NAND |*/ STORAGE_SD) 140#define CONFIG_STORAGE (/*STORAGE_NAND |*/ STORAGE_SD)
141#define NUM_DRIVES 2 141#define NUM_DRIVES 2
142#define HAVE_MULTIDRIVE 142#define HAVE_MULTIDRIVE
143#define HAVE_MULTIVOLUME
144#define HAVE_HOTSWAP_STORAGE_AS_MAIN 143#define HAVE_HOTSWAP_STORAGE_AS_MAIN
145#define HAVE_HOTSWAP 144#define HAVE_HOTSWAP
146#define CONFIG_NAND NAND_IMX233 145#define CONFIG_NAND NAND_IMX233
diff --git a/firmware/export/config/creativezenxfi3.h b/firmware/export/config/creativezenxfi3.h
index a558c2a7df..5ff5d889c7 100644
--- a/firmware/export/config/creativezenxfi3.h
+++ b/firmware/export/config/creativezenxfi3.h
@@ -144,7 +144,6 @@
144#define CONFIG_STORAGE STORAGE_SD 144#define CONFIG_STORAGE STORAGE_SD
145#define NUM_DRIVES 2 145#define NUM_DRIVES 2
146#define HAVE_MULTIDRIVE 146#define HAVE_MULTIDRIVE
147#define HAVE_MULTIVOLUME
148#define HAVE_HOTSWAP 147#define HAVE_HOTSWAP
149 148
150/* Extra threads: touchpad */ 149/* Extra threads: touchpad */
diff --git a/firmware/export/config/erosqnative.h b/firmware/export/config/erosqnative.h
index f6e5b0d55e..26073a5f34 100644
--- a/firmware/export/config/erosqnative.h
+++ b/firmware/export/config/erosqnative.h
@@ -77,9 +77,7 @@
77#define CONFIG_STORAGE STORAGE_SD 77#define CONFIG_STORAGE STORAGE_SD
78#define HAVE_HOTSWAP 78#define HAVE_HOTSWAP
79#define HAVE_HOTSWAP_STORAGE_AS_MAIN 79#define HAVE_HOTSWAP_STORAGE_AS_MAIN
80#define HAVE_MULTIDRIVE
81#define HAVE_MULTIVOLUME 80#define HAVE_MULTIVOLUME
82#define NUM_DRIVES 1
83#define STORAGE_WANTS_ALIGN 81#define STORAGE_WANTS_ALIGN
84#define STORAGE_NEEDS_BOUNCE_BUFFER 82#define STORAGE_NEEDS_BOUNCE_BUFFER
85 83
diff --git a/firmware/export/config/fiiom3k.h b/firmware/export/config/fiiom3k.h
index cf8509405f..a5e32af2a0 100644
--- a/firmware/export/config/fiiom3k.h
+++ b/firmware/export/config/fiiom3k.h
@@ -81,9 +81,7 @@
81#define CONFIG_STORAGE STORAGE_SD 81#define CONFIG_STORAGE STORAGE_SD
82#define HAVE_HOTSWAP 82#define HAVE_HOTSWAP
83#define HAVE_HOTSWAP_STORAGE_AS_MAIN 83#define HAVE_HOTSWAP_STORAGE_AS_MAIN
84#define HAVE_MULTIDRIVE
85#define HAVE_MULTIVOLUME 84#define HAVE_MULTIVOLUME
86#define NUM_DRIVES 1
87#define STORAGE_WANTS_ALIGN 85#define STORAGE_WANTS_ALIGN
88#define STORAGE_NEEDS_BOUNCE_BUFFER 86#define STORAGE_NEEDS_BOUNCE_BUFFER
89 87
diff --git a/firmware/export/config/ihifi760.h b/firmware/export/config/ihifi760.h
index cc4152f5d8..ca62948bd2 100644
--- a/firmware/export/config/ihifi760.h
+++ b/firmware/export/config/ihifi760.h
@@ -49,6 +49,7 @@
49#define HAVE_FLASH_STORAGE 49#define HAVE_FLASH_STORAGE
50 50
51#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 51#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
52#define NUM_DRIVES 1 /* NAND doesn't work yet */
52 53
53#define CONFIG_NAND NAND_RK27XX 54#define CONFIG_NAND NAND_RK27XX
54#define HAVE_SW_TONE_CONTROLS 55#define HAVE_SW_TONE_CONTROLS
@@ -57,8 +58,6 @@
57 58
58/* commented for now */ 59/* commented for now */
59/* #define HAVE_HOTSWAP */ 60/* #define HAVE_HOTSWAP */
60
61#define NUM_DRIVES 1
62#define SECTOR_SIZE 512 61#define SECTOR_SIZE 512
63 62
64/* for small(ish) SD cards */ 63/* for small(ish) SD cards */
diff --git a/firmware/export/config/ihifi770.h b/firmware/export/config/ihifi770.h
index 74b12de994..68f6c71b90 100644
--- a/firmware/export/config/ihifi770.h
+++ b/firmware/export/config/ihifi770.h
@@ -50,13 +50,13 @@
50#define HAVE_FLASH_STORAGE 50#define HAVE_FLASH_STORAGE
51 51
52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
53#define NUM_DRIVES 1 /* NAND doesn't work yet */
53 54
54#define CONFIG_NAND NAND_RK27XX 55#define CONFIG_NAND NAND_RK27XX
55#define HAVE_SW_TONE_CONTROLS 56#define HAVE_SW_TONE_CONTROLS
56 57
57#define HAVE_HOTSWAP 58// #define HAVE_HOTSWAP
58 59
59#define NUM_DRIVES 1
60#define SECTOR_SIZE 512 60#define SECTOR_SIZE 512
61 61
62/* for small(ish) SD cards */ 62/* for small(ish) SD cards */
@@ -183,7 +183,4 @@
183#define BOOTFILE "rockbox." BOOTFILE_EXT 183#define BOOTFILE "rockbox." BOOTFILE_EXT
184#define BOOTDIR "/.rockbox" 184#define BOOTDIR "/.rockbox"
185 185
186/* disabled for now */
187#undef HAVE_HOTSWAP
188
189#endif /* SIMULATOR */ 186#endif /* SIMULATOR */
diff --git a/firmware/export/config/ihifi770c.h b/firmware/export/config/ihifi770c.h
index 8224e2f368..a34d1b85c2 100644
--- a/firmware/export/config/ihifi770c.h
+++ b/firmware/export/config/ihifi770c.h
@@ -50,13 +50,13 @@
50#define HAVE_FLASH_STORAGE 50#define HAVE_FLASH_STORAGE
51 51
52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
53#define NUM_DRIVES 1 /* NAND doesn't work yet */
53 54
54#define CONFIG_NAND NAND_RK27XX 55#define CONFIG_NAND NAND_RK27XX
55#define HAVE_SW_TONE_CONTROLS 56#define HAVE_SW_TONE_CONTROLS
56 57
57#define HAVE_HOTSWAP 58// #define HAVE_HOTSWAP
58 59
59#define NUM_DRIVES 1
60#define SECTOR_SIZE 512 60#define SECTOR_SIZE 512
61 61
62/* for small(ish) SD cards */ 62/* for small(ish) SD cards */
@@ -183,7 +183,4 @@
183#define BOOTFILE "rockbox." BOOTFILE_EXT 183#define BOOTFILE "rockbox." BOOTFILE_EXT
184#define BOOTDIR "/.rockbox" 184#define BOOTDIR "/.rockbox"
185 185
186/* disabled for now */
187#undef HAVE_HOTSWAP
188
189#endif /* SIMULATOR */ 186#endif /* SIMULATOR */
diff --git a/firmware/export/config/ihifi800.h b/firmware/export/config/ihifi800.h
index 91981682c1..e0cd1e1161 100644
--- a/firmware/export/config/ihifi800.h
+++ b/firmware/export/config/ihifi800.h
@@ -50,13 +50,13 @@
50#define HAVE_FLASH_STORAGE 50#define HAVE_FLASH_STORAGE
51 51
52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 52#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
53#define NUM_DRIVES 1 /* NAND doesn't work yet */
53 54
54#define CONFIG_NAND NAND_RK27XX 55#define CONFIG_NAND NAND_RK27XX
55#define HAVE_SW_TONE_CONTROLS 56#define HAVE_SW_TONE_CONTROLS
56 57
57#define HAVE_HOTSWAP 58//#define HAVE_HOTSWAP
58 59
59#define NUM_DRIVES 1
60#define SECTOR_SIZE 512 60#define SECTOR_SIZE 512
61 61
62/* for small(ish) SD cards */ 62/* for small(ish) SD cards */
@@ -184,7 +184,4 @@
184#define BOOTFILE "rockbox." BOOTFILE_EXT 184#define BOOTFILE "rockbox." BOOTFILE_EXT
185#define BOOTDIR "/.rockbox" 185#define BOOTDIR "/.rockbox"
186 186
187/* disabled for now */
188#undef HAVE_HOTSWAP
189
190#endif /* SIMULATOR */ 187#endif /* SIMULATOR */
diff --git a/firmware/export/config/ihifi960.h b/firmware/export/config/ihifi960.h
index 64c6c90874..c0af676f28 100644
--- a/firmware/export/config/ihifi960.h
+++ b/firmware/export/config/ihifi960.h
@@ -49,6 +49,7 @@
49#define HAVE_FLASH_STORAGE 49#define HAVE_FLASH_STORAGE
50 50
51#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 51#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
52#define NUM_DRIVES 1 /* NAND doesn't work yet */
52 53
53#define CONFIG_NAND NAND_RK27XX 54#define CONFIG_NAND NAND_RK27XX
54#define HAVE_SW_TONE_CONTROLS 55#define HAVE_SW_TONE_CONTROLS
@@ -58,7 +59,6 @@
58/* commented for now */ 59/* commented for now */
59/* #define HAVE_HOTSWAP */ 60/* #define HAVE_HOTSWAP */
60 61
61#define NUM_DRIVES 1
62#define SECTOR_SIZE 512 62#define SECTOR_SIZE 512
63 63
64/* for small(ish) SD cards */ 64/* for small(ish) SD cards */
diff --git a/firmware/export/config/mini2440.h b/firmware/export/config/mini2440.h
index 4fc483b324..4149835eec 100644
--- a/firmware/export/config/mini2440.h
+++ b/firmware/export/config/mini2440.h
@@ -38,8 +38,7 @@
38/* define the storage type */ 38/* define the storage type */
39#define CONFIG_STORAGE STORAGE_SD 39#define CONFIG_STORAGE STORAGE_SD
40 40
41#define HAVE_MULTIDRIVE 41#define HAVE_MULTIVOLUME
42#define NUM_DRIVES 1 // no access to NAND yet
43#define HAVE_HOTSWAP 42#define HAVE_HOTSWAP
44#define HAVE_HOTSWAP_STORAGE_AS_MAIN 43#define HAVE_HOTSWAP_STORAGE_AS_MAIN
45#define INCLUDE_TIMEOUT_API 44#define INCLUDE_TIMEOUT_API
diff --git a/firmware/export/config/ondavx747.h b/firmware/export/config/ondavx747.h
index 7f4f1ea843..a9d4f0fecf 100644
--- a/firmware/export/config/ondavx747.h
+++ b/firmware/export/config/ondavx747.h
@@ -161,11 +161,11 @@
161No access to the NAND yet.. 161No access to the NAND yet..
162 162
163#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) 163#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD)
164#define HAVE_MULTIDRIVE
164#define NUM_DRIVES 2 165#define NUM_DRIVES 2
165*/ 166*/
166#define CONFIG_STORAGE (STORAGE_SD) 167#define CONFIG_STORAGE (STORAGE_SD)
167#define HAVE_MULTIDRIVE 168#define HAVE_MULTIVOLUME
168#define NUM_DRIVES 1
169#define HAVE_HOTSWAP_STORAGE_AS_MAIN 169#define HAVE_HOTSWAP_STORAGE_AS_MAIN
170#define INCLUDE_TIMEOUT_API 170#define INCLUDE_TIMEOUT_API
171 171
diff --git a/firmware/export/config/ondavx777.h b/firmware/export/config/ondavx777.h
index ceea151d8c..1387898eff 100644
--- a/firmware/export/config/ondavx777.h
+++ b/firmware/export/config/ondavx777.h
@@ -152,11 +152,11 @@
152No access to the NAND yet.. 152No access to the NAND yet..
153 153
154#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) 154#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD)
155#define HAVE_MULTIDRIVE
155#define NUM_DRIVES 2 156#define NUM_DRIVES 2
156*/ 157*/
157#define CONFIG_STORAGE (STORAGE_SD) 158#define CONFIG_STORAGE (STORAGE_SD)
158#define HAVE_MULTIDRIVE 159#define HAVE_MULTIVOLUME
159#define NUM_DRIVES 1
160#define HAVE_HOTSWAP_STORAGE_AS_MAIN 160#define HAVE_HOTSWAP_STORAGE_AS_MAIN
161#define INCLUDE_TIMEOUT_API 161#define INCLUDE_TIMEOUT_API
162 162
diff --git a/firmware/export/config/rk27generic.h b/firmware/export/config/rk27generic.h
index 967fc6d8ff..23768c1d2e 100644
--- a/firmware/export/config/rk27generic.h
+++ b/firmware/export/config/rk27generic.h
@@ -56,6 +56,7 @@
56#define HAVE_FLASH_STORAGE 56#define HAVE_FLASH_STORAGE
57 57
58#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) 58#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
59#define NUM_DRIVES 1 /* NAND doesn't work yet */
59 60
60#define CONFIG_NAND NAND_RK27XX 61#define CONFIG_NAND NAND_RK27XX
61#define HAVE_SW_TONE_CONTROLS 62#define HAVE_SW_TONE_CONTROLS
@@ -63,7 +64,6 @@
63/* commented for now */ 64/* commented for now */
64/* #define HAVE_HOTSWAP */ 65/* #define HAVE_HOTSWAP */
65 66
66#define NUM_DRIVES 1
67#define SECTOR_SIZE 512 67#define SECTOR_SIZE 512
68 68
69/* for small(ish) SD cards */ 69/* for small(ish) SD cards */
diff --git a/firmware/export/config/sansae200.h b/firmware/export/config/sansae200.h
index 1c10f74845..70782aa147 100644
--- a/firmware/export/config/sansae200.h
+++ b/firmware/export/config/sansae200.h
@@ -181,7 +181,6 @@
181#define CONFIG_LCD LCD_X5 181#define CONFIG_LCD LCD_X5
182 182
183#define HAVE_MULTIDRIVE 183#define HAVE_MULTIDRIVE
184//#define HAVE_MULTIVOLUME
185#define NUM_DRIVES 2 184#define NUM_DRIVES 2
186#define HAVE_HOTSWAP /* required to access sd from bootloader */ 185#define HAVE_HOTSWAP /* required to access sd from bootloader */
187 186
diff --git a/firmware/export/config/shanlingq1.h b/firmware/export/config/shanlingq1.h
index a708cfc2a9..4e74f9e33c 100644
--- a/firmware/export/config/shanlingq1.h
+++ b/firmware/export/config/shanlingq1.h
@@ -64,9 +64,7 @@
64#define CONFIG_STORAGE STORAGE_SD 64#define CONFIG_STORAGE STORAGE_SD
65#define HAVE_HOTSWAP 65#define HAVE_HOTSWAP
66#define HAVE_HOTSWAP_STORAGE_AS_MAIN 66#define HAVE_HOTSWAP_STORAGE_AS_MAIN
67#define HAVE_MULTIDRIVE
68#define HAVE_MULTIVOLUME 67#define HAVE_MULTIVOLUME
69#define NUM_DRIVES 1
70#define STORAGE_WANTS_ALIGN 68#define STORAGE_WANTS_ALIGN
71#define STORAGE_NEEDS_BOUNCE_BUFFER 69#define STORAGE_NEEDS_BOUNCE_BUFFER
72 70
diff --git a/firmware/export/config/xduoox3.h b/firmware/export/config/xduoox3.h
index 46e1a61712..0d413ad372 100644
--- a/firmware/export/config/xduoox3.h
+++ b/firmware/export/config/xduoox3.h
@@ -174,6 +174,7 @@
174/* Type of LCD */ 174/* Type of LCD */
175#define CONFIG_LCD LCD_XDUOOX3 175#define CONFIG_LCD LCD_XDUOOX3
176 176
177#ifndef BOOTLOADER
177/* USB On-the-go */ 178/* USB On-the-go */
178#define CONFIG_USBOTG USBOTG_JZ4760 179#define CONFIG_USBOTG USBOTG_JZ4760
179 180
@@ -189,6 +190,7 @@
189 190
190#define USB_NUM_ENDPOINTS 3 191#define USB_NUM_ENDPOINTS 3
191#define USB_DEVBSS_ATTR IBSS_ATTR 192#define USB_DEVBSS_ATTR IBSS_ATTR
193#endif /* !BOOTLOADER */
192 194
193#define BOOTFILE_EXT "x3" 195#define BOOTFILE_EXT "x3"
194#define BOOTFILE "rockbox." BOOTFILE_EXT 196#define BOOTFILE "rockbox." BOOTFILE_EXT
@@ -198,7 +200,7 @@
198 200
199#define ICODE_ATTR_TREMOR_NOT_MDCT 201#define ICODE_ATTR_TREMOR_NOT_MDCT
200 202
201#endif /* SIMULATOR */ 203#endif /* !SIMULATOR */
202 204
203/** Port-specific settings **/ 205/** Port-specific settings **/
204 206
diff --git a/firmware/export/disk.h b/firmware/export/disk.h
index e465552fdc..a19e011170 100644
--- a/firmware/export/disk.h
+++ b/firmware/export/disk.h
@@ -26,8 +26,8 @@
26 26
27struct partinfo 27struct partinfo
28{ 28{
29 unsigned long start; /* first sector (LBA) */ 29 sector_t start; /* first sector (LBA) */
30 unsigned long size; /* number of sectors */ 30 sector_t size; /* number of sectors */
31 unsigned char type; 31 unsigned char type;
32}; 32};
33 33
diff --git a/firmware/export/fat.h b/firmware/export/fat.h
index 70152985b5..7382d85ce4 100644
--- a/firmware/export/fat.h
+++ b/firmware/export/fat.h
@@ -115,7 +115,7 @@ struct fat_filestr
115{ 115{
116 struct fat_file *fatfilep; /* common file information */ 116 struct fat_file *fatfilep; /* common file information */
117 long lastcluster; /* cluster of last access */ 117 long lastcluster; /* cluster of last access */
118 unsigned long lastsector; /* sector of last access */ 118 sector_t lastsector; /* sector of last access */
119 long clusternum; /* cluster number of last access */ 119 long clusternum; /* cluster number of last access */
120 unsigned long sectornum; /* sector number within current cluster */ 120 unsigned long sectornum; /* sector number within current cluster */
121 bool eof; /* end-of-file reached */ 121 bool eof; /* end-of-file reached */
@@ -173,7 +173,7 @@ int fat_get_bytes_per_sector(IF_MV_NONVOID(int volume));
173#endif /* MAX_LOG_SECTOR_SIZE */ 173#endif /* MAX_LOG_SECTOR_SIZE */
174unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); 174unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume));
175void fat_recalc_free(IF_MV_NONVOID(int volume)); 175void fat_recalc_free(IF_MV_NONVOID(int volume));
176bool fat_size(IF_MV(int volume,) unsigned long *size, unsigned long *free); 176bool fat_size(IF_MV(int volume,) sector_t *size, sector_t *free);
177 177
178/** Misc. **/ 178/** Misc. **/
179void fat_empty_fat_direntry(struct fat_direntry *entry); 179void fat_empty_fat_direntry(struct fat_direntry *entry);
diff --git a/firmware/export/hostfs.h b/firmware/export/hostfs.h
index c0fe85236e..c59868110a 100644
--- a/firmware/export/hostfs.h
+++ b/firmware/export/hostfs.h
@@ -37,8 +37,8 @@ extern int hostfs_init(void);
37extern int hostfs_flush(void); 37extern int hostfs_flush(void);
38 38
39#ifdef HAVE_HOTSWAP 39#ifdef HAVE_HOTSWAP
40extern bool hostfs_removable(int drive); 40extern bool hostfs_removable(IF_MD_NONVOID(int drive));
41extern bool hostfs_present(int drive); 41extern bool hostfs_present(IF_MD_NONVOID(int drive));
42#endif 42#endif
43 43
44/* This has to be repeated here for now for sim's sake since HAVE_HOSTFS 44/* This has to be repeated here for now for sim's sake since HAVE_HOSTFS
diff --git a/firmware/export/mmc.h b/firmware/export/mmc.h
index 0d27e20a64..06df979b81 100644
--- a/firmware/export/mmc.h
+++ b/firmware/export/mmc.h
@@ -36,8 +36,8 @@ bool mmc_disk_is_active(void);
36int mmc_soft_reset(void); 36int mmc_soft_reset(void);
37int mmc_init(void) STORAGE_INIT_ATTR; 37int mmc_init(void) STORAGE_INIT_ATTR;
38void mmc_close(void); 38void mmc_close(void);
39int mmc_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 39int mmc_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
40int mmc_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 40int mmc_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
41void mmc_spin(void); 41void mmc_spin(void);
42int mmc_spinup_time(void); 42int mmc_spinup_time(void);
43 43
diff --git a/firmware/export/mv.h b/firmware/export/mv.h
index 966ff9a032..9d202a8087 100644
--- a/firmware/export/mv.h
+++ b/firmware/export/mv.h
@@ -23,6 +23,7 @@
23#define __MV_H__ 23#define __MV_H__
24 24
25#include <stdbool.h> 25#include <stdbool.h>
26#include <stdint.h>
26#include "config.h" 27#include "config.h"
27 28
28/* FixMe: These macros are a bit nasty and perhaps misplaced here. 29/* FixMe: These macros are a bit nasty and perhaps misplaced here.
@@ -40,6 +41,19 @@
40#define IF_MD_DRV(d) 0 41#define IF_MD_DRV(d) 0
41#endif /* HAVE_MULTIDRIVE */ 42#endif /* HAVE_MULTIDRIVE */
42 43
44/* Storage size */
45#if (CONFIG_STORAGE & STORAGE_ATA) && defined(HAVE_LBA48)
46typedef uint64_t sector_t;
47#define STORAGE_64BIT_SECTOR
48#elif (CONFIG_STORAGE & STORAGE_SD) && defined(HAVE_SDUC)
49typedef uint64_t sector_t;
50#define STORAGE_64BIT_SECTOR
51#else
52typedef unsigned long sector_t;
53#undef STORAGE_64BIT_SECTOR
54#endif
55
56
43/* Volumes mean things that have filesystems on them, like partitions */ 57/* Volumes mean things that have filesystems on them, like partitions */
44#ifdef HAVE_MULTIVOLUME 58#ifdef HAVE_MULTIVOLUME
45#define IF_MV(x...) x /* valist contents or empty */ 59#define IF_MV(x...) x /* valist contents or empty */
@@ -113,13 +127,16 @@ struct volumeinfo
113/* Volume-centric functions (in disk.c) */ 127/* Volume-centric functions (in disk.c) */
114void volume_recalc_free(IF_MV_NONVOID(int volume)); 128void volume_recalc_free(IF_MV_NONVOID(int volume));
115unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume)); 129unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume));
116void volume_size(IF_MV(int volume,) unsigned long *size, unsigned long *free); 130void volume_size(IF_MV(int volume,) sector_t *size, sector_t *free);
117#ifdef HAVE_DIRCACHE 131#ifdef HAVE_DIRCACHE
118bool volume_ismounted(IF_MV_NONVOID(int volume)); 132bool volume_ismounted(IF_MV_NONVOID(int volume));
119#endif 133#endif
120#ifdef HAVE_HOTSWAP 134#ifdef HAVE_HOTSWAP
121bool volume_removable(int volume); 135bool volume_removable(int volume);
122bool volume_present(int volume); 136bool volume_present(int volume);
137#else
138#define volume_present(x) 1
139#define volueme_removeable(x) 0
123#endif /* HAVE_HOTSWAP */ 140#endif /* HAVE_HOTSWAP */
124 141
125#ifdef HAVE_MULTIDRIVE 142#ifdef HAVE_MULTIDRIVE
diff --git a/firmware/export/nand.h b/firmware/export/nand.h
index fe25c9b407..d4fd6028ed 100644
--- a/firmware/export/nand.h
+++ b/firmware/export/nand.h
@@ -36,8 +36,8 @@ bool nand_disk_is_active(void);
36int nand_soft_reset(void); 36int nand_soft_reset(void);
37int nand_init(void) STORAGE_INIT_ATTR; 37int nand_init(void) STORAGE_INIT_ATTR;
38void nand_close(void); 38void nand_close(void);
39int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 39int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
40int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 40int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
41#ifdef HAVE_STORAGE_FLUSH 41#ifdef HAVE_STORAGE_FLUSH
42int nand_flush(void); 42int nand_flush(void);
43#endif 43#endif
diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h
index 1b18f22d06..fce8e5851c 100644
--- a/firmware/export/pathfuncs.h
+++ b/firmware/export/pathfuncs.h
@@ -82,6 +82,8 @@ int path_strip_volume(const char *name, const char **nameptr, bool greedy);
82int path_strip_last_volume(const char *name, const char **nameptr, bool greedy); 82int path_strip_last_volume(const char *name, const char **nameptr, bool greedy);
83int get_volume_name(int volume, char *name); 83int get_volume_name(int volume, char *name);
84int make_volume_root(int volume, char *dst); 84int make_volume_root(int volume, char *dst);
85void init_volume_names(void);
86int path_get_volume_id(const char *name);
85#endif 87#endif
86 88
87int path_strip_drive(const char *name, const char **nameptr, bool greedy); 89int path_strip_drive(const char *name, const char **nameptr, bool greedy);
diff --git a/firmware/export/ramdisk.h b/firmware/export/ramdisk.h
index d79ac50836..eb06ea9650 100644
--- a/firmware/export/ramdisk.h
+++ b/firmware/export/ramdisk.h
@@ -35,8 +35,8 @@ bool ramdisk_disk_is_active(void);
35int ramdisk_soft_reset(void); 35int ramdisk_soft_reset(void);
36int ramdisk_init(void) STORAGE_INIT_ATTR; 36int ramdisk_init(void) STORAGE_INIT_ATTR;
37void ramdisk_close(void); 37void ramdisk_close(void);
38int ramdisk_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 38int ramdisk_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
39int ramdisk_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 39int ramdisk_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
40void ramdisk_spin(void); 40void ramdisk_spin(void);
41void ramdisk_sleepnow(void); 41void ramdisk_sleepnow(void);
42int ramdisk_spinup_time(void); 42int ramdisk_spinup_time(void);
diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h
index 9dd0a24c6f..2376163180 100644
--- a/firmware/export/rbpaths.h
+++ b/firmware/export/rbpaths.h
@@ -54,6 +54,8 @@
54 54
55#define RB_ROOT_VOL_HIDDEN(v) (IF_MV_VOL(v) == 0) 55#define RB_ROOT_VOL_HIDDEN(v) (IF_MV_VOL(v) == 0)
56#define RB_ROOT_CONTENTS_DIR "/" IF_MV("<0>") 56#define RB_ROOT_CONTENTS_DIR "/" IF_MV("<0>")
57#define REC_BASE_DIR HOME_DIR "Recordings"
58#define PLAYLIST_CATALOG_DEFAULT_DIR HOME_DIR "Playlists"
57 59
58#else /* APPLICATION */ 60#else /* APPLICATION */
59 61
@@ -67,13 +69,11 @@
67#define CODECS_DIR ROCKBOX_LIBRARY_PATH "/rockbox/codecs" 69#define CODECS_DIR ROCKBOX_LIBRARY_PATH "/rockbox/codecs"
68#endif 70#endif
69 71
70#endif /* !APPLICATION || SAMSUNG_YPR0 */
71
72#define REC_BASE_DIR HOME_DIR "/Recordings" 72#define REC_BASE_DIR HOME_DIR "/Recordings"
73#define PLAYLIST_CATALOG_DEFAULT_DIR HOME_DIR "/Playlists" 73#define PLAYLIST_CATALOG_DEFAULT_DIR HOME_DIR "/Playlists"
74#endif /* !APPLICATION || SAMSUNG_YPR0 */
74 75
75#define LANG_DIR ROCKBOX_DIR "/langs" 76#define LANG_DIR ROCKBOX_DIR "/langs"
76
77#define PLUGIN_GAMES_DIR PLUGIN_DIR "/games" 77#define PLUGIN_GAMES_DIR PLUGIN_DIR "/games"
78#define PLUGIN_APPS_DIR PLUGIN_DIR "/apps" 78#define PLUGIN_APPS_DIR PLUGIN_DIR "/apps"
79#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos" 79#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos"
diff --git a/firmware/export/sd.h b/firmware/export/sd.h
index c657f8a545..d66e6f899c 100644
--- a/firmware/export/sd.h
+++ b/firmware/export/sd.h
@@ -42,8 +42,8 @@ bool sd_disk_is_active(void);
42int sd_soft_reset(void); 42int sd_soft_reset(void);
43int sd_init(void) STORAGE_INIT_ATTR; 43int sd_init(void) STORAGE_INIT_ATTR;
44void sd_close(void); 44void sd_close(void);
45int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 45int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
46int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 46int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
47void sd_spin(void); 47void sd_spin(void);
48int sd_spinup_time(void); /* ticks */ 48int sd_spinup_time(void); /* ticks */
49 49
@@ -93,6 +93,7 @@ int sd_num_drives(int first_drive);
93#define SD_READ_SINGLE_BLOCK 17 93#define SD_READ_SINGLE_BLOCK 17
94#define SD_READ_MULTIPLE_BLOCK 18 94#define SD_READ_MULTIPLE_BLOCK 18
95#define SD_SEND_NUM_WR_BLOCKS 22 /* acmd22 */ 95#define SD_SEND_NUM_WR_BLOCKS 22 /* acmd22 */
96#define SD_UC_ADDRESS_EXTENSION 22
96#define SD_SET_WR_BLK_ERASE_COUNT 23 /* acmd23 */ 97#define SD_SET_WR_BLK_ERASE_COUNT 23 /* acmd23 */
97#define SD_WRITE_BLOCK 24 98#define SD_WRITE_BLOCK 24
98#define SD_WRITE_MULTIPLE_BLOCK 25 99#define SD_WRITE_MULTIPLE_BLOCK 25
diff --git a/firmware/export/sdmmc.h b/firmware/export/sdmmc.h
index 35539169d9..f84a7b96fa 100644
--- a/firmware/export/sdmmc.h
+++ b/firmware/export/sdmmc.h
@@ -22,9 +22,11 @@
22#define __SDMMC_H__ 22#define __SDMMC_H__
23 23
24#include <stdbool.h> 24#include <stdbool.h>
25#include <stdint.h>
26#include <mv.h> /* for sector_t */
25 27
26typedef struct 28typedef struct
27{ 29{
28 bool initialized; 30 bool initialized;
29 31
30 unsigned long read_timeout; /* n * 8 clock cycles */ 32 unsigned long read_timeout; /* n * 8 clock cycles */
@@ -37,7 +39,7 @@ typedef struct
37 unsigned int nsac; /* clock cycles */ 39 unsigned int nsac; /* clock cycles */
38 unsigned long taac; /* n * 0.1 ns */ 40 unsigned long taac; /* n * 0.1 ns */
39 unsigned int r2w_factor; 41 unsigned int r2w_factor;
40 unsigned long numblocks; /* size in flash blocks */ 42 sector_t numblocks; /* size in flash blocks */
41 unsigned int blocksize; /* block size in bytes */ 43 unsigned int blocksize; /* block size in bytes */
42 unsigned long rca; /* RCA register */ 44 unsigned long rca; /* RCA register */
43 45
@@ -48,6 +50,8 @@ typedef struct
48#if (CONFIG_STORAGE & STORAGE_SD) 50#if (CONFIG_STORAGE & STORAGE_SD)
49 unsigned int current_bank; 51 unsigned int current_bank;
50#endif 52#endif
53
54 unsigned int sd2plus; /* SD 2.0 or better */
51} tCardInfo; 55} tCardInfo;
52 56
53#if (CONFIG_STORAGE & STORAGE_SD) 57#if (CONFIG_STORAGE & STORAGE_SD)
diff --git a/firmware/export/storage.h b/firmware/export/storage.h
index ee1423c93a..e2ae4056be 100644
--- a/firmware/export/storage.h
+++ b/firmware/export/storage.h
@@ -107,7 +107,7 @@ int ramdisk_event(long id, intptr_t data);
107struct storage_info 107struct storage_info
108{ 108{
109 unsigned int sector_size; 109 unsigned int sector_size;
110 unsigned int num_sectors; 110 sector_t num_sectors;
111 char *vendor; 111 char *vendor;
112 char *product; 112 char *product;
113 char *revision; 113 char *revision;
@@ -227,7 +227,7 @@ static inline void storage_sleep(void) {};
227 #define storage_last_disk_activity() mmc_last_disk_activity() 227 #define storage_last_disk_activity() mmc_last_disk_activity()
228 #define storage_spinup_time() 0 228 #define storage_spinup_time() 0
229 #define storage_get_identify() mmc_get_identify() 229 #define storage_get_identify() mmc_get_identify()
230 230
231 #ifdef STORAGE_GET_INFO 231 #ifdef STORAGE_GET_INFO
232 #define storage_get_info(drive, info) mmc_get_info(IF_MD(drive,) info) 232 #define storage_get_info(drive, info) mmc_get_info(IF_MD(drive,) info)
233 #endif 233 #endif
@@ -251,7 +251,7 @@ static inline void storage_sleep(void) {};
251 #define storage_last_disk_activity() nand_last_disk_activity() 251 #define storage_last_disk_activity() nand_last_disk_activity()
252 #define storage_spinup_time() 0 252 #define storage_spinup_time() 0
253 #define storage_get_identify() nand_get_identify() 253 #define storage_get_identify() nand_get_identify()
254 254
255 #ifdef STORAGE_GET_INFO 255 #ifdef STORAGE_GET_INFO
256 #define storage_get_info(drive, info) nand_get_info(IF_MD(drive,) info) 256 #define storage_get_info(drive, info) nand_get_info(IF_MD(drive,) info)
257 #endif 257 #endif
@@ -275,7 +275,7 @@ static inline void storage_sleep(void) {};
275 #define storage_last_disk_activity() ramdisk_last_disk_activity() 275 #define storage_last_disk_activity() ramdisk_last_disk_activity()
276 #define storage_spinup_time() 0 276 #define storage_spinup_time() 0
277 #define storage_get_identify() ramdisk_get_identify() 277 #define storage_get_identify() ramdisk_get_identify()
278 278
279 #ifdef STORAGE_GET_INFO 279 #ifdef STORAGE_GET_INFO
280 #define storage_get_info(drive, info) ramdisk_get_info(IF_MD(drive,) info) 280 #define storage_get_info(drive, info) ramdisk_get_info(IF_MD(drive,) info)
281 #endif 281 #endif
@@ -310,11 +310,14 @@ void storage_get_info(int drive, struct storage_info *info);
310#ifdef HAVE_HOTSWAP 310#ifdef HAVE_HOTSWAP
311bool storage_removable(int drive); 311bool storage_removable(int drive);
312bool storage_present(int drive); 312bool storage_present(int drive);
313#else
314#define storage_removable(x) 0
315#define storage_present(x) 1
313#endif 316#endif
314int storage_driver_type(int drive); 317int storage_driver_type(int drive);
315 318
316#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/ 319#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/
317 320
318int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 321int storage_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
319int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 322int storage_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
320#endif 323#endif
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h
index ddd86c6d86..d7314cf3b1 100644
--- a/firmware/include/dircache_redirect.h
+++ b/firmware/include/dircache_redirect.h
@@ -24,6 +24,7 @@
24#include "pathfuncs.h" 24#include "pathfuncs.h"
25#include "dir.h" 25#include "dir.h"
26#include "dircache.h" 26#include "dircache.h"
27#include "file.h"
27 28
28#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) 29#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER)
29#include "rb-loader.h" 30#include "rb-loader.h"
@@ -185,22 +186,33 @@ static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
185 186
186 if (multiboot_is_boot_volume(IF_MV_VOL(volume))) 187 if (multiboot_is_boot_volume(IF_MV_VOL(volume)))
187 { 188 {
188 int rtlen = get_redirect_dir(rtpath, sizeof(rtpath), volume, "", ""); 189 /* get the full path to the BOOTFILE
189 while (rtlen > 0 && rtpath[--rtlen] == PATH_SEPCH) 190 ie. /<0>/redirectdir/.rockbox/rockbox.ext */
190 rtpath[rtlen] = '\0'; /* remove extra separators */ 191 int rtlen = get_redirect_dir(rtpath, sizeof(rtpath),
192 volume, BOOTDIR, BOOTFILE);
193
194 if (rtlen <= 0 || rtlen >= (int) sizeof(rtpath))
195 rtlen = 0; /* path too long or sprintf error */
196 else if (file_exists(rtpath))
197 {
198 rtlen = get_redirect_dir(rtpath, sizeof(rtpath), volume, "", "");
199 while (rtlen > 0 && rtpath[--rtlen] == PATH_SEPCH)
200 rtpath[rtlen] = '\0'; /* remove separators */
201 }
202 else
203 rtlen = 0; /* No BOOTFILE found */
191 204
192#if 0 /*removed, causes issues with playback for now?*/ 205#if 0 /*removed, causes issues with playback for now?*/
193 if (rtlen <= 0 || rtpath[rtlen] == VOL_END_TOK) 206 if (rtlen <= 0 || rtpath[rtlen] == VOL_END_TOK)
194 root_unmount_volume(volume); /* unmount so root can be hidden*/ 207 root_unmount_volume(volume); /* unmount so root can be hidden*/
195#endif 208#endif
196 if (rtlen <= 0) /* Error occurred, card removed? Set root to default */ 209 if (rtlen <= 0 || root_mount_path(rtpath, NSITEM_CONTENTS) != 0)
197 { 210 { /* Error occurred, card removed? Set root to default */
211 boot_data_valid = false;
198 root_unmount_volume(volume); /* unmount so root can be hidden*/ 212 root_unmount_volume(volume); /* unmount so root can be hidden*/
199 goto standard_redirect; 213 goto standard_redirect;
200 } 214 }
201 root_mount_path(rtpath, NSITEM_CONTENTS);
202 } 215 }
203
204 } 216 }
205 else 217 else
206 { 218 {
diff --git a/firmware/include/disk_cache.h b/firmware/include/disk_cache.h
index 79b2ccf2c6..9787c64aec 100644
--- a/firmware/include/disk_cache.h
+++ b/firmware/include/disk_cache.h
@@ -36,7 +36,7 @@ static inline void dc_unlock_cache(void)
36 mutex_unlock(&disk_cache_mutex); 36 mutex_unlock(&disk_cache_mutex);
37} 37}
38 38
39void * dc_cache_probe(IF_MV(int volume,) unsigned long secnum, 39void * dc_cache_probe(IF_MV(int volume,) sector_t secnum,
40 unsigned int *flags); 40 unsigned int *flags);
41void dc_dirty_buf(void *buf); 41void dc_dirty_buf(void *buf);
42void dc_discard_buf(void *buf); 42void dc_discard_buf(void *buf);
@@ -46,7 +46,7 @@ void dc_discard_all(IF_MV_NONVOID(int volume));
46void dc_init(void) INIT_ATTR; 46void dc_init(void) INIT_ATTR;
47 47
48/* in addition to filling, writeback is implemented by the client */ 48/* in addition to filling, writeback is implemented by the client */
49extern void dc_writeback_callback(IF_MV(int volume, ) unsigned long sector, 49extern void dc_writeback_callback(IF_MV(int volume, ) sector_t sector,
50 void *buf); 50 void *buf);
51 51
52 52
diff --git a/firmware/storage.c b/firmware/storage.c
index 267b0b8dfb..da3e06146d 100644
--- a/firmware/storage.c
+++ b/firmware/storage.c
@@ -23,6 +23,7 @@
23#include "ata_idle_notify.h" 23#include "ata_idle_notify.h"
24#include "usb.h" 24#include "usb.h"
25#include "disk.h" 25#include "disk.h"
26#include "pathfuncs.h"
26 27
27#ifdef CONFIG_STORAGE_MULTI 28#ifdef CONFIG_STORAGE_MULTI
28 29
@@ -275,21 +276,21 @@ int storage_init(void)
275#ifdef CONFIG_STORAGE_MULTI 276#ifdef CONFIG_STORAGE_MULTI
276 int i; 277 int i;
277 num_drives=0; 278 num_drives=0;
278 279
279#if (CONFIG_STORAGE & STORAGE_ATA) 280#if (CONFIG_STORAGE & STORAGE_ATA)
280 if ((rc=ata_init())) return rc; 281 if ((rc=ata_init())) return rc;
281 282
282 int ata_drives = ata_num_drives(num_drives); 283 int ata_drives = ata_num_drives(num_drives);
283 for (i=0; i<ata_drives; i++) 284 for (i=0; i<ata_drives; i++)
284 { 285 {
285 storage_drivers[num_drives++] = 286 storage_drivers[num_drives++] =
286 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET); 287 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
287 } 288 }
288#endif 289#endif
289 290
290#if (CONFIG_STORAGE & STORAGE_MMC) 291#if (CONFIG_STORAGE & STORAGE_MMC)
291 if ((rc=mmc_init())) return rc; 292 if ((rc=mmc_init())) return rc;
292 293
293 int mmc_drives = mmc_num_drives(num_drives); 294 int mmc_drives = mmc_num_drives(num_drives);
294 for (i=0; i<mmc_drives ;i++) 295 for (i=0; i<mmc_drives ;i++)
295 { 296 {
@@ -300,7 +301,7 @@ int storage_init(void)
300 301
301#if (CONFIG_STORAGE & STORAGE_SD) 302#if (CONFIG_STORAGE & STORAGE_SD)
302 if ((rc=sd_init())) return rc; 303 if ((rc=sd_init())) return rc;
303 304
304 int sd_drives = sd_num_drives(num_drives); 305 int sd_drives = sd_num_drives(num_drives);
305 for (i=0; i<sd_drives; i++) 306 for (i=0; i<sd_drives; i++)
306 { 307 {
@@ -311,7 +312,7 @@ int storage_init(void)
311 312
312#if (CONFIG_STORAGE & STORAGE_NAND) 313#if (CONFIG_STORAGE & STORAGE_NAND)
313 if ((rc=nand_init())) return rc; 314 if ((rc=nand_init())) return rc;
314 315
315 int nand_drives = nand_num_drives(num_drives); 316 int nand_drives = nand_num_drives(num_drives);
316 for (i=0; i<nand_drives; i++) 317 for (i=0; i<nand_drives; i++)
317 { 318 {
@@ -322,7 +323,7 @@ int storage_init(void)
322 323
323#if (CONFIG_STORAGE & STORAGE_RAMDISK) 324#if (CONFIG_STORAGE & STORAGE_RAMDISK)
324 if ((rc=ramdisk_init())) return rc; 325 if ((rc=ramdisk_init())) return rc;
325 326
326 int ramdisk_drives = ramdisk_num_drives(num_drives); 327 int ramdisk_drives = ramdisk_num_drives(num_drives);
327 for (i=0; i<ramdisk_drives; i++) 328 for (i=0; i<ramdisk_drives; i++)
328 { 329 {
@@ -334,11 +335,15 @@ int storage_init(void)
334 rc = STORAGE_FUNCTION(init)(); 335 rc = STORAGE_FUNCTION(init)();
335#endif /* CONFIG_STORAGE_MULTI */ 336#endif /* CONFIG_STORAGE_MULTI */
336 337
338#ifdef HAVE_MULTIVOLUME
339 init_volume_names();
340#endif
341
337 storage_thread_init(); 342 storage_thread_init();
338 return rc; 343 return rc;
339} 344}
340 345
341int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count, 346int storage_read_sectors(IF_MD(int drive,) sector_t start, int count,
342 void* buf) 347 void* buf)
343{ 348{
344#ifdef CONFIG_STORAGE_MULTI 349#ifdef CONFIG_STORAGE_MULTI
@@ -380,7 +385,7 @@ int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count,
380 385
381} 386}
382 387
383int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count, 388int storage_write_sectors(IF_MD(int drive,) sector_t start, int count,
384 const void* buf) 389 const void* buf)
385{ 390{
386#ifdef CONFIG_STORAGE_MULTI 391#ifdef CONFIG_STORAGE_MULTI
@@ -520,7 +525,7 @@ bool storage_disk_is_active(void)
520int storage_soft_reset(void) 525int storage_soft_reset(void)
521{ 526{
522 int rc=0; 527 int rc=0;
523 528
524#if (CONFIG_STORAGE & STORAGE_ATA) 529#if (CONFIG_STORAGE & STORAGE_ATA)
525 if ((rc=ata_soft_reset())) return rc; 530 if ((rc=ata_soft_reset())) return rc;
526#endif 531#endif
@@ -548,7 +553,7 @@ int storage_soft_reset(void)
548int storage_flush(void) 553int storage_flush(void)
549{ 554{
550 int rc=0; 555 int rc=0;
551 556
552#if (CONFIG_STORAGE & STORAGE_ATA) 557#if (CONFIG_STORAGE & STORAGE_ATA)
553 //if ((rc=ata_flush())) return rc; 558 //if ((rc=ata_flush())) return rc;
554#endif 559#endif
@@ -648,7 +653,7 @@ long storage_last_disk_activity(void)
648{ 653{
649 long max=0; 654 long max=0;
650 long t; 655 long t;
651 656
652#if (CONFIG_STORAGE & STORAGE_ATA) 657#if (CONFIG_STORAGE & STORAGE_ATA)
653 t=ata_last_disk_activity(); 658 t=ata_last_disk_activity();
654 if (t>max) max=t; 659 if (t>max) max=t;
@@ -681,7 +686,7 @@ int storage_spinup_time(void)
681{ 686{
682 int max=0; 687 int max=0;
683 int t; 688 int t;
684 689
685#if (CONFIG_STORAGE & STORAGE_ATA) 690#if (CONFIG_STORAGE & STORAGE_ATA)
686 t=ata_spinup_time(); 691 t=ata_spinup_time();
687 if (t>max) max=t; 692 if (t>max) max=t;
@@ -716,7 +721,7 @@ void storage_get_info(int drive, struct storage_info *info)
716{ 721{
717 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 722 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
718 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 723 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
719 724
720 switch(driver) 725 switch(driver)
721 { 726 {
722#if (CONFIG_STORAGE & STORAGE_ATA) 727#if (CONFIG_STORAGE & STORAGE_ATA)
@@ -752,7 +757,7 @@ bool storage_removable(int drive)
752{ 757{
753 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 758 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
754 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 759 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
755 760
756 switch(driver) 761 switch(driver)
757 { 762 {
758#if (CONFIG_STORAGE & STORAGE_ATA) 763#if (CONFIG_STORAGE & STORAGE_ATA)
@@ -789,7 +794,7 @@ bool storage_present(int drive)
789{ 794{
790 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET; 795 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
791 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET; 796 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
792 797
793 switch(driver) 798 switch(driver)
794 { 799 {
795#if (CONFIG_STORAGE & STORAGE_ATA) 800#if (CONFIG_STORAGE & STORAGE_ATA)
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 70e0778d2b..df39cba495 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -446,7 +446,7 @@ static int sd_init_card(const int drive)
446 sd_parse_csd(&card_info[drive]); 446 sd_parse_csd(&card_info[drive]);
447 447
448#if defined(HAVE_MULTIDRIVE) 448#if defined(HAVE_MULTIDRIVE)
449 hs_card = (card_info[drive].speed == 50000000); 449 hs_card = (card_info[drive].speed >= 50000000);
450#endif 450#endif
451 451
452 /* Boost MCICLK to operating speed */ 452 /* Boost MCICLK to operating speed */
@@ -455,7 +455,7 @@ static int sd_init_card(const int drive)
455#if defined(HAVE_MULTIDRIVE) 455#if defined(HAVE_MULTIDRIVE)
456 else 456 else
457 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ 457 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/
458 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) | 458 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) |
459 MCI_CLOCK_POWERSAVE; /* SD supports powersave */ 459 MCI_CLOCK_POWERSAVE; /* SD supports powersave */
460#endif 460#endif
461 461
@@ -680,7 +680,7 @@ static int sd_select_bank(signed char bank)
680 return 0; 680 return 0;
681} 681}
682 682
683static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, 683static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
684 int count, void* buf, const bool write) 684 int count, void* buf, const bool write)
685{ 685{
686#ifndef HAVE_MULTIDRIVE 686#ifndef HAVE_MULTIDRIVE
@@ -735,7 +735,8 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
735 unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ 735 unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */
736 void *dma_buf; 736 void *dma_buf;
737 737
738 unsigned long bank_start = start; 738 sector_t bank_start = start;
739 // XXX 64-bit sectors?
739 740
740 /* Only switch banks for internal storage */ 741 /* Only switch banks for internal storage */
741 if(drive == INTERNAL_AS3525) 742 if(drive == INTERNAL_AS3525)
@@ -869,7 +870,7 @@ sd_transfer_error_nodma:
869 return ret; 870 return ret;
870} 871}
871 872
872int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 873int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
873 void* buf) 874 void* buf)
874{ 875{
875 int ret; 876 int ret;
@@ -881,11 +882,11 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
881 return ret; 882 return ret;
882} 883}
883 884
884int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 885int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
885 const void* buf) 886 const void* buf)
886{ 887{
887#ifdef VERIFY_WRITE 888#ifdef VERIFY_WRITE
888 unsigned long saved_start = start; 889 sector_t saved_start = start;
889 int saved_count = count; 890 int saved_count = count;
890 void *saved_buf = (void*)buf; 891 void *saved_buf = (void*)buf;
891#endif 892#endif
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index b512cc2ea4..f9ef7d9c97 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -677,7 +677,7 @@ int sd_init(void)
677 return 0; 677 return 0;
678} 678}
679 679
680static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, 680static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
681 int count, void* buf, bool write) 681 int count, void* buf, bool write)
682{ 682{
683 unsigned long response; 683 unsigned long response;
@@ -776,7 +776,7 @@ retry_with_reinit:
776 776
777 MCI_BYTCNT = transfer * SD_BLOCK_SIZE; 777 MCI_BYTCNT = transfer * SD_BLOCK_SIZE;
778 778
779 int arg = start; 779 sector_t arg = start; // XXX 64-bit
780 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ 780 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
781 arg *= SD_BLOCK_SIZE; 781 arg *= SD_BLOCK_SIZE;
782 782
@@ -858,13 +858,13 @@ exit:
858 return ret; 858 return ret;
859} 859}
860 860
861int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 861int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
862 void* buf) 862 void* buf)
863{ 863{
864 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); 864 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
865} 865}
866 866
867int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 867int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
868 const void* buf) 868 const void* buf)
869{ 869{
870 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); 870 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index d61c223219..453a51ed1b 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -179,7 +179,7 @@ static int phys_segment_to_page_addr(int phys_segment, int page_in_seg)
179 break; 179 break;
180 } 180 }
181 } 181 }
182 182
183 page_addr += (page_in_seg / nand_data->planes); 183 page_addr += (page_in_seg / nand_data->planes);
184 184
185 return page_addr; 185 return page_addr;
@@ -222,7 +222,7 @@ static void nand_chip_select(int bank)
222static void nand_read_id(int bank, unsigned char* id_buf) 222static void nand_read_id(int bank, unsigned char* id_buf)
223{ 223{
224 int i; 224 int i;
225 225
226 /* Enable NFC bus clock */ 226 /* Enable NFC bus clock */
227 BCLKCTR |= DEV_NAND; 227 BCLKCTR |= DEV_NAND;
228 228
@@ -358,7 +358,7 @@ static void nand_setup_read(int bank, int row, int column)
358static void nand_end_read(void) 358static void nand_end_read(void)
359{ 359{
360 nand_chip_select(-1); 360 nand_chip_select(-1);
361 361
362 /* Disable NFC bus clock */ 362 /* Disable NFC bus clock */
363 BCLKCTR &= ~DEV_NAND; 363 BCLKCTR &= ~DEV_NAND;
364} 364}
@@ -367,7 +367,7 @@ static void nand_end_read(void)
367static void nand_read_raw(int bank, int row, int column, int size, void* buf) 367static void nand_read_raw(int bank, int row, int column, int size, void* buf)
368{ 368{
369 int i; 369 int i;
370 370
371 nand_setup_read(bank, row, column); 371 nand_setup_read(bank, row, column);
372 372
373 /* Read data into page buffer */ 373 /* Read data into page buffer */
@@ -388,7 +388,7 @@ static void nand_read_raw(int bank, int row, int column, int size, void* buf)
388 ((unsigned int*)buf)[i] = NFC_WDATA; 388 ((unsigned int*)buf)[i] = NFC_WDATA;
389 } 389 }
390 } 390 }
391 391
392 nand_end_read(); 392 nand_end_read();
393} 393}
394 394
@@ -422,7 +422,7 @@ static void nand_get_chip_info(void)
422 sectors_per_page = nand_data->page_size / SECTOR_SIZE; 422 sectors_per_page = nand_data->page_size / SECTOR_SIZE;
423 423
424 sectors_per_segment = bytes_per_segment / SECTOR_SIZE; 424 sectors_per_segment = bytes_per_segment / SECTOR_SIZE;
425 425
426 pages_per_segment = sectors_per_segment / sectors_per_page; 426 pages_per_segment = sectors_per_segment / sectors_per_page;
427 427
428 /* Establish how many banks are present */ 428 /* Establish how many banks are present */
@@ -494,7 +494,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
494 494
495#ifdef USE_ECC_CORRECTION 495#ifdef USE_ECC_CORRECTION
496 unsigned long spare_buf[4]; 496 unsigned long spare_buf[4];
497 497
498 /* Set up the ECC controller to monitor reads from NFC_WDATA */ 498 /* Set up the ECC controller to monitor reads from NFC_WDATA */
499 BCLKCTR |= DEV_ECC; 499 BCLKCTR |= DEV_ECC;
500 ECC_BASE = (unsigned long)&NFC_WDATA; 500 ECC_BASE = (unsigned long)&NFC_WDATA;
@@ -514,27 +514,27 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
514 This way, reads are always done through NFC_WDATA - otherwise they 514 This way, reads are always done through NFC_WDATA - otherwise they
515 would not be 'seen' by the ECC controller. */ 515 would not be 'seen' by the ECC controller. */
516 static char temp_buf[SECTOR_SIZE]; 516 static char temp_buf[SECTOR_SIZE];
517 517
518 unsigned int* ptr = (unsigned int*) temp_buf; 518 unsigned int* ptr = (unsigned int*) temp_buf;
519 519
520 for (i = 0; i < (SECTOR_SIZE/4); i++) 520 for (i = 0; i < (SECTOR_SIZE/4); i++)
521 { 521 {
522 *ptr++ = NFC_WDATA; 522 *ptr++ = NFC_WDATA;
523 } 523 }
524 524
525 memcpy(buf, temp_buf, SECTOR_SIZE); 525 memcpy(buf, temp_buf, SECTOR_SIZE);
526 } 526 }
527 else 527 else
528 { 528 {
529 /* Use straight word copy as buffer and size are both word-aligned */ 529 /* Use straight word copy as buffer and size are both word-aligned */
530 unsigned int* ptr = (unsigned int*) buf; 530 unsigned int* ptr = (unsigned int*) buf;
531 531
532 for (i = 0; i < (SECTOR_SIZE/4); i++) 532 for (i = 0; i < (SECTOR_SIZE/4); i++)
533 { 533 {
534 *ptr++ = NFC_WDATA; 534 *ptr++ = NFC_WDATA;
535 } 535 }
536 } 536 }
537 537
538#ifdef USE_ECC_CORRECTION 538#ifdef USE_ECC_CORRECTION
539 /* Stop monitoring before we read the OOB data */ 539 /* Stop monitoring before we read the OOB data */
540 ECC_CTRL &= ~ECC_M4EN; 540 ECC_CTRL &= ~ECC_M4EN;
@@ -549,29 +549,29 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
549 /* Calculate MLC4 ECC using bytes 0,1,8-15 */ 549 /* Calculate MLC4 ECC using bytes 0,1,8-15 */
550 BCLKCTR |= DEV_ECC; 550 BCLKCTR |= DEV_ECC;
551 ECC_CTRL |= ECC_M4EN; 551 ECC_CTRL |= ECC_M4EN;
552 552
553 MLC_ECC0W = *(unsigned short*)spare_buf; 553 MLC_ECC0W = *(unsigned short*)spare_buf;
554 MLC_ECC1W = spare_buf[2]; 554 MLC_ECC1W = spare_buf[2];
555 MLC_ECC2W = spare_buf[3]; 555 MLC_ECC2W = spare_buf[3];
556 556
557 while (!(ECC_CTRL & ECC_READY)) {}; 557 while (!(ECC_CTRL & ECC_READY)) {};
558 558
559 int errors = ECC_ERR_NUM & 7; 559 int errors = ECC_ERR_NUM & 7;
560 560
561 switch (errors) 561 switch (errors)
562 { 562 {
563 case 4: /* nothing to correct */ 563 case 4: /* nothing to correct */
564 break; 564 break;
565 565
566 case 7: /* fail, can't correct */ 566 case 7: /* fail, can't correct */
567 ret = false; 567 ret = false;
568 break; 568 break;
569 569
570 default: /* between 1 and 4 errors */ 570 default: /* between 1 and 4 errors */
571 { 571 {
572 int i; 572 int i;
573 unsigned char* char_buf = (unsigned char*)buf; 573 unsigned char* char_buf = (unsigned char*)buf;
574 574
575 for (i = 0; i < errors + 1; i++) 575 for (i = 0; i < errors + 1; i++)
576 { 576 {
577 int offset = 0x207 - ECC_ERRADDR(i); 577 int offset = 0x207 - ECC_ERRADDR(i);
@@ -584,7 +584,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
584 ECC_CTRL &= ~ECC_M4EN; 584 ECC_CTRL &= ~ECC_M4EN;
585 BCLKCTR &= ~DEV_ECC; 585 BCLKCTR &= ~DEV_ECC;
586#endif 586#endif
587 587
588 nand_end_read(); 588 nand_end_read();
589 589
590 return ret; 590 return ret;
@@ -619,7 +619,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
619 619
620 int cache_num = 0; 620 int cache_num = 0;
621 bool found = false; 621 bool found = false;
622 622
623 while (!found && cache_num < write_caches_in_use) 623 while (!found && cache_num < write_caches_in_use)
624 { 624 {
625 if (write_caches[cache_num].log_segment == log_segment) 625 if (write_caches[cache_num].log_segment == log_segment)
@@ -628,10 +628,10 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
628 { 628 {
629 /* data is located in random pages cache */ 629 /* data is located in random pages cache */
630 found = true; 630 found = true;
631 631
632 bank = write_caches[cache_num].random_bank; 632 bank = write_caches[cache_num].random_bank;
633 phys_segment = write_caches[cache_num].random_phys_segment; 633 phys_segment = write_caches[cache_num].random_phys_segment;
634 634
635 page_in_segment = 635 page_in_segment =
636 write_caches[cache_num].page_map[page_in_segment]; 636 write_caches[cache_num].page_map[page_in_segment];
637 } 637 }
@@ -640,7 +640,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
640 { 640 {
641 /* data is located in in-place pages cache */ 641 /* data is located in in-place pages cache */
642 found = true; 642 found = true;
643 643
644 bank = write_caches[cache_num].inplace_bank; 644 bank = write_caches[cache_num].inplace_bank;
645 phys_segment = write_caches[cache_num].inplace_phys_segment; 645 phys_segment = write_caches[cache_num].inplace_phys_segment;
646 } 646 }
@@ -664,7 +664,7 @@ static inline unsigned char get_sector_type(char* spare_buf)
664static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf) 664static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf)
665{ 665{
666 (void)phys_seg; 666 (void)phys_seg;
667 667
668 return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) | 668 return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
669 spare_buf[OFF_LOG_SEG_LOBYTE]) 669 spare_buf[OFF_LOG_SEG_LOBYTE])
670#if defined(FTL_V1) 670#if defined(FTL_V1)
@@ -702,7 +702,7 @@ static void read_random_writes_cache(int bank, int phys_segment)
702 16, spare_buf); 702 16, spare_buf);
703 703
704 log_segment = get_log_segment_id(phys_segment, spare_buf); 704 log_segment = get_log_segment_id(phys_segment, spare_buf);
705 705
706 if (log_segment == -1) 706 if (log_segment == -1)
707 return; 707 return;
708 708
@@ -734,13 +734,13 @@ static void read_random_writes_cache(int bank, int phys_segment)
734 page++) 734 page++)
735 { 735 {
736 unsigned short cached_page; 736 unsigned short cached_page;
737 737
738 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page), 738 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page),
739 SECTOR_SIZE, /* offset to first sector's spare */ 739 SECTOR_SIZE, /* offset to first sector's spare */
740 16, spare_buf); 740 16, spare_buf);
741 741
742 cached_page = get_cached_page_id(spare_buf); 742 cached_page = get_cached_page_id(spare_buf);
743 743
744 if (cached_page != 0xFFFF) 744 if (cached_page != 0xFFFF)
745 write_caches[cache_no].page_map[cached_page] = page; 745 write_caches[cache_no].page_map[cached_page] = page;
746 } 746 }
@@ -759,10 +759,10 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
759 16, spare_buf); 759 16, spare_buf);
760 760
761 log_segment = get_log_segment_id(phys_segment, spare_buf); 761 log_segment = get_log_segment_id(phys_segment, spare_buf);
762 762
763 if (log_segment == -1) 763 if (log_segment == -1)
764 return; 764 return;
765 765
766 /* Find which cache this is related to */ 766 /* Find which cache this is related to */
767 int cache_no = find_write_cache(log_segment); 767 int cache_no = find_write_cache(log_segment);
768 768
@@ -780,7 +780,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
780 } 780 }
781 781
782 write_caches[cache_no].log_segment = log_segment; 782 write_caches[cache_no].log_segment = log_segment;
783 783
784 /* Find how many pages have been written to the new segment */ 784 /* Find how many pages have been written to the new segment */
785 while (log_segment != -1 && 785 while (log_segment != -1 &&
786 page < (nand_data->pages_per_block * nand_data->planes) - 1) 786 page < (nand_data->pages_per_block * nand_data->planes) - 1)
@@ -791,7 +791,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
791 791
792 log_segment = get_log_segment_id(phys_segment, spare_buf); 792 log_segment = get_log_segment_id(phys_segment, spare_buf);
793 } 793 }
794 794
795 if (page != 0) 795 if (page != 0)
796 { 796 {
797 write_caches[cache_no].inplace_bank = bank; 797 write_caches[cache_no].inplace_bank = bank;
@@ -801,7 +801,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
801} 801}
802 802
803 803
804int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 804int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
805 void* inbuf) 805 void* inbuf)
806{ 806{
807#ifdef HAVE_MULTIDRIVE 807#ifdef HAVE_MULTIDRIVE
@@ -809,15 +809,15 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
809#endif 809#endif
810 810
811 int ret = 0; 811 int ret = 0;
812 812
813 mutex_lock(&ata_mtx); 813 mutex_lock(&ata_mtx);
814 814
815 led(true); 815 led(true);
816 816
817 while (incount > 0) 817 while (incount > 0)
818 { 818 {
819 int done = 0; 819 int done = 0;
820 int segment = start / sectors_per_segment; 820 sector_t segment = start / sectors_per_segment;
821 int secmod = start % sectors_per_segment; 821 int secmod = start % sectors_per_segment;
822 822
823 while (incount > 0 && secmod < sectors_per_segment) 823 while (incount > 0 && secmod < sectors_per_segment)
@@ -839,7 +839,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
839 secmod++; 839 secmod++;
840 done++; 840 done++;
841 } 841 }
842 842
843 if (done < 0) 843 if (done < 0)
844 { 844 {
845 ret = -1; 845 ret = -1;
@@ -852,11 +852,11 @@ nand_read_error:
852 852
853 mutex_unlock(&ata_mtx); 853 mutex_unlock(&ata_mtx);
854 led(false); 854 led(false);
855 855
856 return ret; 856 return ret;
857} 857}
858 858
859int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 859int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
860 const void* outbuf) 860 const void* outbuf)
861{ 861{
862#ifdef HAVE_MULTIDRIVE 862#ifdef HAVE_MULTIDRIVE
@@ -903,7 +903,7 @@ int nand_init(void)
903 unsigned char spare_buf[16]; 903 unsigned char spare_buf[16];
904 904
905 if (initialized) return 0; 905 if (initialized) return 0;
906 906
907 mutex_init(&ata_mtx); 907 mutex_init(&ata_mtx);
908 908
909 /* Set GPIO direction for chip select & write protect */ 909 /* Set GPIO direction for chip select & write protect */
@@ -924,7 +924,7 @@ int nand_init(void)
924 924
925 memset(lpt_lookup, 0xff, lptbuf_size); 925 memset(lpt_lookup, 0xff, lptbuf_size);
926 memset(write_caches, 0xff, sizeof(write_caches)); 926 memset(write_caches, 0xff, sizeof(write_caches));
927 927
928 write_caches_in_use = 0; 928 write_caches_in_use = 0;
929 929
930 /* Scan banks to build up block translation table */ 930 /* Scan banks to build up block translation table */
@@ -936,7 +936,7 @@ int nand_init(void)
936 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0), 936 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0),
937 SECTOR_SIZE, /* offset */ 937 SECTOR_SIZE, /* offset */
938 16, spare_buf); 938 16, spare_buf);
939 939
940 int type = get_sector_type(spare_buf); 940 int type = get_sector_type(spare_buf);
941 941
942#ifdef FTL_V2 942#ifdef FTL_V2
@@ -948,7 +948,7 @@ int nand_init(void)
948 nand_read_raw(bank, phys_segment_to_page_addr 948 nand_read_raw(bank, phys_segment_to_page_addr
949 (phys_segment, pages_per_segment - 1), 949 (phys_segment, pages_per_segment - 1),
950 SECTOR_SIZE, 16, spare_buf); 950 SECTOR_SIZE, 16, spare_buf);
951 951
952 if (get_sector_type(spare_buf) != 0xff) 952 if (get_sector_type(spare_buf) != 0xff)
953 { 953 {
954 type = SECTYPE_MAIN_DATA; 954 type = SECTYPE_MAIN_DATA;
@@ -982,14 +982,14 @@ int nand_init(void)
982 } 982 }
983 break; 983 break;
984 } 984 }
985 985
986 case SECTYPE_MAIN_RANDOM_CACHE: 986 case SECTYPE_MAIN_RANDOM_CACHE:
987 { 987 {
988 /* Newly-written random page data (Main data area) */ 988 /* Newly-written random page data (Main data area) */
989 read_random_writes_cache(bank, phys_segment); 989 read_random_writes_cache(bank, phys_segment);
990 break; 990 break;
991 } 991 }
992 992
993 case SECTYPE_MAIN_INPLACE_CACHE: 993 case SECTYPE_MAIN_INPLACE_CACHE:
994 { 994 {
995 /* Newly-written sequential page data (Main data area) */ 995 /* Newly-written sequential page data (Main data area) */
@@ -999,7 +999,7 @@ int nand_init(void)
999 } 999 }
1000 } 1000 }
1001 } 1001 }
1002 1002
1003 initialized = true; 1003 initialized = true;
1004 1004
1005 return 0; 1005 return 0;
@@ -1029,7 +1029,7 @@ int nand_num_drives(int first_drive)
1029{ 1029{
1030 /* We don't care which logical drive number we have been assigned */ 1030 /* We don't care which logical drive number we have been assigned */
1031 (void)first_drive; 1031 (void)first_drive;
1032 1032
1033 return 1; 1033 return 1;
1034} 1034}
1035 1035
diff --git a/firmware/target/arm/imx233/nand-imx233.c b/firmware/target/arm/imx233/nand-imx233.c
index a7afba7d43..22da408e05 100644
--- a/firmware/target/arm/imx233/nand-imx233.c
+++ b/firmware/target/arm/imx233/nand-imx233.c
@@ -36,13 +36,13 @@ int nand_init(void)
36{ 36{
37 return -1; 37 return -1;
38} 38}
39int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, 39int nand_read_sectors(IF_MD(int drive,) sector_t start, int count,
40 void* buf) 40 void* buf)
41{ 41{
42 return -1; 42 return -1;
43} 43}
44 44
45int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 45int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
46 const void* buf) 46 const void* buf)
47{ 47{
48 return -1; 48 return -1;
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
index 83a0bf8b42..69d0ba4199 100644
--- a/firmware/target/arm/imx233/partitions-imx233.c
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -71,7 +71,7 @@ static const char *creative_part_name(enum imx233_part_t part)
71} 71}
72 72
73static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, 73static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
74 enum imx233_part_t part, unsigned *start, unsigned *end) 74 enum imx233_part_t part, sector_t *start, sector_t *end)
75{ 75{
76 uint8_t mblk[512]; 76 uint8_t mblk[512];
77 int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk); 77 int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk);
@@ -99,7 +99,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
99 } 99 }
100 else 100 else
101 *end = *start + ent[i].size * hdr->block_size / 512; 101 *end = *start + ent[i].size * hdr->block_size / 512;
102 102
103 return 0; 103 return 0;
104 } 104 }
105 } 105 }
@@ -109,7 +109,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
109 109
110#if (IMX233_PARTITIONS & IMX233_FREESCALE) 110#if (IMX233_PARTITIONS & IMX233_FREESCALE)
111static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn, 111static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
112 enum imx233_part_t part, unsigned *start, unsigned *end) 112 enum imx233_part_t part, sector_t *start, sector_t *end)
113{ 113{
114 uint8_t mbr[512]; 114 uint8_t mbr[512];
115 int ret = read_fn(user, 0, 1, mbr); 115 int ret = read_fn(user, 0, 1, mbr);
@@ -179,7 +179,7 @@ static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
179#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */ 179#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
180 180
181int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, 181int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
182 enum imx233_part_t part, unsigned *start, unsigned *end) 182 enum imx233_part_t part, sector_t *start, sector_t *end)
183{ 183{
184 int ret = -1; 184 int ret = -1;
185#if (IMX233_PARTITIONS & IMX233_CREATIVE) 185#if (IMX233_PARTITIONS & IMX233_CREATIVE)
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
index e5378dadbb..edc6c1b2f4 100644
--- a/firmware/target/arm/imx233/partitions-imx233.h
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -45,7 +45,7 @@ enum imx233_part_t
45/** The computation function can be called very early in the boot, at which point 45/** The computation function can be called very early in the boot, at which point
46 * usual storage read/write function may not be available. To workaround this 46 * usual storage read/write function may not be available. To workaround this
47 * issue, one must provide a read function. */ 47 * issue, one must provide a read function. */
48typedef int (*part_read_fn_t)(intptr_t user, unsigned long start, int count, void* buf); 48typedef int (*part_read_fn_t)(intptr_t user, sector_t start, int count, void* buf);
49/* Enable/Disable window computations for internal storage following the 49/* Enable/Disable window computations for internal storage following the
50 * Freescale/Creative convention */ 50 * Freescale/Creative convention */
51void imx233_partitions_enable_window(bool enable); 51void imx233_partitions_enable_window(bool enable);
@@ -55,6 +55,6 @@ bool imx233_partitions_is_window_enabled(void);
55 * for a whole disk, *end should be the size of the disk when the function is 55 * for a whole disk, *end should be the size of the disk when the function is
56 * called */ 56 * called */
57int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, 57int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
58 enum imx233_part_t part, unsigned *start, unsigned *end); 58 enum imx233_part_t part, sector_t *start, sector_t *end);
59 59
60#endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file 60#endif /* __PARTITIONS_IMX233__ */
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index af090e8a07..02f59a50f4 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -203,8 +203,8 @@ struct sdmmc_status_t
203 * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */ 203 * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */
204 204
205/* common */ 205/* common */
206static unsigned window_start[SDMMC_NUM_DRIVES]; 206static sector_t window_start[SDMMC_NUM_DRIVES];
207static unsigned window_end[SDMMC_NUM_DRIVES]; 207static sector_t window_end[SDMMC_NUM_DRIVES];
208static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; 208static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
209static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; 209static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
210static struct mutex mutex[SDMMC_NUM_DRIVES]; 210static struct mutex mutex[SDMMC_NUM_DRIVES];
@@ -648,7 +648,7 @@ int mmc_event(long id, intptr_t data)
648#endif /* CONFIG_STORAGE & STORAGE_MMC */ 648#endif /* CONFIG_STORAGE & STORAGE_MMC */
649 649
650/* low-level function, don't call directly! */ 650/* low-level function, don't call directly! */
651static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 651static int __xfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
652{ 652{
653 uint32_t resp; 653 uint32_t resp;
654 int ret = 0; 654 int ret = 0;
@@ -660,7 +660,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
660 need_stop = false; 660 need_stop = false;
661 /* Set bank_start to the correct unit (blocks or bytes). 661 /* Set bank_start to the correct unit (blocks or bytes).
662 * MMC drives use block addressing, SD cards bytes or blocks */ 662 * MMC drives use block addressing, SD cards bytes or blocks */
663 int bank_start = start; 663 sector_t bank_start = start;
664 if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */ 664 if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */
665 bank_start *= SD_BLOCK_SIZE; 665 bank_start *= SD_BLOCK_SIZE;
666 /* issue read/write 666 /* issue read/write
@@ -686,7 +686,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
686 return ret; 686 return ret;
687} 687}
688 688
689static int transfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 689static int transfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
690{ 690{
691 int ret = 0; 691 int ret = 0;
692 /* the function doesn't work when count is 0 */ 692 /* the function doesn't work when count is 0 */
@@ -806,7 +806,7 @@ static int transfer_sectors(int drive, unsigned long start, int count, void *buf
806} 806}
807 807
808/* user specifies the sdmmc drive */ 808/* user specifies the sdmmc drive */
809static int part_read_fn(intptr_t user, unsigned long start, int count, void* buf) 809static int part_read_fn(intptr_t user, sector_t start, int count, void* buf)
810{ 810{
811 return transfer_sectors(user, start, count, buf, true); 811 return transfer_sectors(user, start, count, buf, true);
812} 812}
@@ -917,7 +917,7 @@ void sd_enable(bool on)
917 (void) on; 917 (void) on;
918} 918}
919 919
920int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *buf) 920int sd_read_sectors(IF_MD(int sd_drive,) sector_t start, int count, void *buf)
921{ 921{
922#ifndef HAVE_MULTIDRIVE 922#ifndef HAVE_MULTIDRIVE
923 int sd_drive = 0; 923 int sd_drive = 0;
@@ -925,7 +925,7 @@ int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *b
925 return transfer_sectors(sd_map[sd_drive], start, count, buf, true); 925 return transfer_sectors(sd_map[sd_drive], start, count, buf, true);
926} 926}
927 927
928int sd_write_sectors(IF_MD(int sd_drive,) unsigned long start, int count, const void* buf) 928int sd_write_sectors(IF_MD(int sd_drive,) sector_t start, int count, const void* buf)
929{ 929{
930#ifndef HAVE_MULTIDRIVE 930#ifndef HAVE_MULTIDRIVE
931 int sd_drive = 0; 931 int sd_drive = 0;
@@ -1039,7 +1039,7 @@ int mmc_spinup_time(void)
1039 return 0; 1039 return 0;
1040} 1040}
1041 1041
1042int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void *buf) 1042int mmc_read_sectors(IF_MD(int mmc_drive,) sector_t start, int count, void *buf)
1043{ 1043{
1044#ifndef HAVE_MULTIDRIVE 1044#ifndef HAVE_MULTIDRIVE
1045 int mmc_drive = 0; 1045 int mmc_drive = 0;
@@ -1047,7 +1047,7 @@ int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void
1047 return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true); 1047 return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true);
1048} 1048}
1049 1049
1050int mmc_write_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, const void* buf) 1050int mmc_write_sectors(IF_MD(int mmc_drive,) sector_t start, int count, const void* buf)
1051{ 1051{
1052#ifndef HAVE_MULTIDRIVE 1052#ifndef HAVE_MULTIDRIVE
1053 int mmc_drive = 0; 1053 int mmc_drive = 0;
diff --git a/firmware/target/arm/pp/ata-pp5020.c b/firmware/target/arm/pp/ata-pp5020.c
index 176e74993c..7351215693 100644
--- a/firmware/target/arm/pp/ata-pp5020.c
+++ b/firmware/target/arm/pp/ata-pp5020.c
@@ -48,8 +48,8 @@ bool ata_is_coldstart()
48 rest are the same. They go in IDE0_PRI_TIMING0. 48 rest are the same. They go in IDE0_PRI_TIMING0.
49 49
50 Rockbox used to use 0x10, and test_disk shows that leads to faster PIO. 50 Rockbox used to use 0x10, and test_disk shows that leads to faster PIO.
51 However on some disks connected with mSATA adapters this causes corrupt data 51 However when used with mSATA and some SD adapters this causes corrupt data
52 so we now just use these timings from the OF. 52 so we now unconditionally use these timings from the OF.
53*/ 53*/
54static const unsigned long pio80mhz[] = { 54static const unsigned long pio80mhz[] = {
55 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 55 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131
@@ -83,10 +83,7 @@ void ata_device_init()
83/* Setup the timing for PIO mode */ 83/* Setup the timing for PIO mode */
84void ata_set_pio_timings(int mode) 84void ata_set_pio_timings(int mode)
85{ 85{
86 if (ata_disk_isssd()) 86 IDE0_PRI_TIMING0 = pio80mhz[mode];
87 IDE0_PRI_TIMING0 = pio80mhz[mode];
88 else
89 IDE0_PRI_TIMING0 = 0x10;
90} 87}
91 88
92#ifdef HAVE_ATA_DMA 89#ifdef HAVE_ATA_DMA
@@ -109,6 +106,8 @@ static bool dma_boosted = false;
109static bool dma_needs_boost; 106static bool dma_needs_boost;
110#endif 107#endif
111 108
109static int ata_is_ssd = 0;
110
112/* This function sets up registers for 80 Mhz. 111/* This function sets up registers for 80 Mhz.
113 Ultra DMA mode 2 works at 30 Mhz. 112 Ultra DMA mode 2 works at 30 Mhz.
114 */ 113 */
@@ -136,6 +135,8 @@ void ata_dma_set_mode(unsigned char mode) {
136#if !defined(IPOD_NANO) 135#if !defined(IPOD_NANO)
137 IDE0_CFG |= 0x20000000; /* >= 50 Mhz */ 136 IDE0_CFG |= 0x20000000; /* >= 50 Mhz */
138#endif 137#endif
138
139 ata_is_ssd = ata_disk_isssd();
139} 140}
140 141
141#define IDE_CFG_INTRQ 8 142#define IDE_CFG_INTRQ 8
@@ -175,11 +176,12 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
175 /* Writes only need to be word-aligned, but by default DMA 176 /* Writes only need to be word-aligned, but by default DMA
176 * is not used for writing on non-SSDs as it appears to be slower. 177 * is not used for writing on non-SSDs as it appears to be slower.
177 */ 178 */
178 if (!ata_disk_isssd()) 179 if (write) {
179 return false; 180 if ((unsigned long)addr & 3)
180 181 return false;
181 if (write && ((unsigned long)addr & 3)) 182 if (!ata_is_ssd)
182 return false; 183 return false;
184 }
183 185
184#if ATA_MAX_UDMA > 2 186#if ATA_MAX_UDMA > 2
185 if (dma_needs_boost && !dma_boosted) { 187 if (dma_needs_boost && !dma_boosted) {
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index fb0a9e150e..b998afd21e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -82,7 +82,7 @@
82#define STAT_TIME_OUT_RES (1 << 1) 82#define STAT_TIME_OUT_RES (1 << 1)
83#define STAT_TIME_OUT_READ (1) 83#define STAT_TIME_OUT_READ (1)
84#define STAT_ERROR_BITS (0x3f) 84#define STAT_ERROR_BITS (0x3f)
85 85
86/* MMC_CMDAT bits */ 86/* MMC_CMDAT bits */
87/* Some of the bits used by the OF don't make much sense with these */ 87/* Some of the bits used by the OF don't make much sense with these */
88/* definitions. So they're probably different between PXA and PP502x */ 88/* definitions. So they're probably different between PXA and PP502x */
@@ -101,7 +101,7 @@
101#define CMDAT_RES_TYPE3 (3) 101#define CMDAT_RES_TYPE3 (3)
102#define CMDAT_RES_TYPE2 (2) 102#define CMDAT_RES_TYPE2 (2)
103#define CMDAT_RES_TYPE1 (1) 103#define CMDAT_RES_TYPE1 (1)
104 104
105/* MMC_I_MASK bits */ 105/* MMC_I_MASK bits */
106/* PP502x apparently only has bits 0-3 */ 106/* PP502x apparently only has bits 0-3 */
107#define I_MASK_SDIO_SUSPEND_ACK (1 << 12) 107#define I_MASK_SDIO_SUSPEND_ACK (1 << 12)
@@ -499,18 +499,18 @@ static inline void copy_write_sectors(const unsigned char** buf)
499 { 499 {
500 asm volatile ( 500 asm volatile (
501 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" 501 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
502 "mov r4, r3, lsr #16 \r\n" 502 "mov r4, r3, lsr #16 \r\n"
503 "mov r6, r5, lsr #16 \r\n" 503 "mov r6, r5, lsr #16 \r\n"
504 "mov r8, r7, lsr #16 \r\n" 504 "mov r8, r7, lsr #16 \r\n"
505 "mov r10, r9, lsr #16 \r\n" 505 "mov r10, r9, lsr #16 \r\n"
506 "stmia %[data], { r3-r10 } \r\n" 506 "stmia %[data], { r3-r10 } \r\n"
507 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" 507 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
508 "mov r4, r3, lsr #16 \r\n" 508 "mov r4, r3, lsr #16 \r\n"
509 "mov r6, r5, lsr #16 \r\n" 509 "mov r6, r5, lsr #16 \r\n"
510 "mov r8, r7, lsr #16 \r\n" 510 "mov r8, r7, lsr #16 \r\n"
511 "mov %[t], r9, lsr #16 \r\n" 511 "mov %[t], r9, lsr #16 \r\n"
512 "stmia %[data], { r3-r9 } \r\n" 512 "stmia %[data], { r3-r9 } \r\n"
513 : [buf]"+&r"(*buf), [t]"=&r"(t) 513 : [buf]"+&r"(*buf), [t]"=&r"(t)
514 : [data]"r"(&MMC_DATA_FIFO) 514 : [data]"r"(&MMC_DATA_FIFO)
515 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" 515 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
516 ); 516 );
@@ -760,7 +760,7 @@ static void sd_init_device(int card_no)
760 currcard->csd[i] = temp_reg[3-i]; 760 currcard->csd[i] = temp_reg[3-i];
761 761
762 sd_parse_csd(currcard); 762 sd_parse_csd(currcard);
763 763
764 MMC_CLKRT = 0; /* switch to highest clock rate */ 764 MMC_CLKRT = 0; /* switch to highest clock rate */
765 765
766 ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL, 766 ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
@@ -849,7 +849,7 @@ static void sd_select_device(int card_no)
849 849
850/* API Functions */ 850/* API Functions */
851 851
852int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 852int sd_read_sectors(IF_MD(int drive,) sector_t start, int incount,
853 void* inbuf) 853 void* inbuf)
854{ 854{
855#ifndef HAVE_MULTIDRIVE 855#ifndef HAVE_MULTIDRIVE
@@ -857,8 +857,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
857#endif 857#endif
858 int ret; 858 int ret;
859 unsigned char *buf, *buf_end; 859 unsigned char *buf, *buf_end;
860 unsigned int bank; 860 sector_t bank;
861 861
862 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
863 863
864 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
@@ -894,7 +894,7 @@ sd_read_retry:
894 if (ret < 0) 894 if (ret < 0)
895 goto sd_read_error; 895 goto sd_read_error;
896 } 896 }
897 897
898 start -= bank * BLOCKS_PER_BANK; 898 start -= bank * BLOCKS_PER_BANK;
899 } 899 }
900 900
@@ -904,6 +904,8 @@ sd_read_retry:
904 904
905 MMC_NUMBLK = incount; 905 MMC_NUMBLK = incount;
906 906
907 // XXX 64-bit addresses..
908
907#ifdef HAVE_HOTSWAP 909#ifdef HAVE_HOTSWAP
908 if(currcard->ocr & (1<<30) ) 910 if(currcard->ocr & (1<<30) )
909 { 911 {
@@ -966,7 +968,7 @@ sd_read_error:
966 } 968 }
967} 969}
968 970
969int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 971int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
970 const void* outbuf) 972 const void* outbuf)
971{ 973{
972/* Write support is not finished yet */ 974/* Write support is not finished yet */
@@ -1010,7 +1012,7 @@ sd_write_retry:
1010 if (ret < 0) 1012 if (ret < 0)
1011 goto sd_write_error; 1013 goto sd_write_error;
1012 } 1014 }
1013 1015
1014 start -= bank * BLOCKS_PER_BANK; 1016 start -= bank * BLOCKS_PER_BANK;
1015 } 1017 }
1016 1018
@@ -1250,7 +1252,7 @@ int sd_num_drives(int first_drive)
1250#else 1252#else
1251 (void)first_drive; 1253 (void)first_drive;
1252#endif 1254#endif
1253 1255
1254#ifdef HAVE_MULTIDRIVE 1256#ifdef HAVE_MULTIDRIVE
1255 return 2; 1257 return 2;
1256#else 1258#else
diff --git a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
index e257416cd0..54a1223cfc 100644
--- a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
+++ b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
@@ -31,18 +31,18 @@
31 31
32/* This file provides only STUBS for now */ 32/* This file provides only STUBS for now */
33 33
34/** static, private data **/ 34/** static, private data **/
35static bool initialized = false; 35static bool initialized = false;
36 36
37/* API Functions */ 37/* API Functions */
38int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 38int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
39 void* inbuf) 39 void* inbuf)
40{ 40{
41 (void)drive; 41 (void)drive;
42 return ftl_read(start, incount, inbuf); 42 return ftl_read(start, incount, inbuf);
43} 43}
44 44
45int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 45int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
46 const void* outbuf) 46 const void* outbuf)
47{ 47{
48 (void)drive; 48 (void)drive;
@@ -112,7 +112,7 @@ int nand_num_drives(int first_drive)
112{ 112{
113 /* We don't care which logical drive number(s) we have been assigned */ 113 /* We don't care which logical drive number(s) we have been assigned */
114 (void)first_drive; 114 (void)first_drive;
115 115
116 return 1; 116 return 1;
117} 117}
118#endif 118#endif
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 2ddf91a67e..e082a8bf2e 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -35,7 +35,7 @@
35#include "panic.h" 35#include "panic.h"
36#include "stdbool.h" 36#include "stdbool.h"
37#include "storage.h" 37#include "storage.h"
38 38#include "timeout.h"
39#include "lcd.h" 39#include "lcd.h"
40#include <stdarg.h> 40#include <stdarg.h>
41#include "sysfont.h" 41#include "sysfont.h"
@@ -453,7 +453,7 @@ static inline void write_sd_data(unsigned char **src)
453 *src += 512; 453 *src += 512;
454} 454}
455 455
456int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 456int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
457 void* buf) 457 void* buf)
458{ 458{
459#ifdef HAVE_MULTIDRIVE 459#ifdef HAVE_MULTIDRIVE
@@ -498,6 +498,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
498 DATA_XFER_MULTI; 498 DATA_XFER_MULTI;
499 } 499 }
500 500
501 // XXX 64-bit
502
501 /* issue read command to the card */ 503 /* issue read command to the card */
502 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) 504 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
503 { 505 {
@@ -576,7 +578,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
576} 578}
577 579
578/* Not tested */ 580/* Not tested */
579int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 581int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
580 const void* buf) 582 const void* buf)
581{ 583{
582#ifdef HAVE_MULTIDRIVE 584#ifdef HAVE_MULTIDRIVE
@@ -620,6 +622,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
620 622
621 write_sd_data(&src); /* put data into transfer buffer */ 623 write_sd_data(&src); /* put data into transfer buffer */
622 624
625 // XXX 64-bit
623 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) 626 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
624 { 627 {
625 ret = -3; 628 ret = -3;
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index 2ff68aa4ee..82fd60c711 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -18,7 +18,7 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22//#define SD_DEBUG 22//#define SD_DEBUG
23 23
24#include "system.h" 24#include "system.h"
@@ -33,7 +33,7 @@
33#include "sdmmc.h" 33#include "sdmmc.h"
34#endif 34#endif
35#include "storage.h" 35#include "storage.h"
36#include "dma-target.h" 36#include "dma-target.h"
37#include "system-target.h" 37#include "system-target.h"
38#include "led-mini2440.h" 38#include "led-mini2440.h"
39 39
@@ -83,7 +83,7 @@ struct sd_card_status
83 int retry_max; 83 int retry_max;
84}; 84};
85 85
86/** static, private data **/ 86/** static, private data **/
87 87
88/* for compatibility */ 88/* for compatibility */
89static long last_disk_activity = -1; 89static long last_disk_activity = -1;
@@ -117,13 +117,13 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
117static struct semaphore transfer_completion_signal; 117static struct semaphore transfer_completion_signal;
118static volatile unsigned int transfer_error[NUM_DRIVES]; 118static volatile unsigned int transfer_error[NUM_DRIVES];
119/* align on cache line size */ 119/* align on cache line size */
120static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 120static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
121 __attribute__((aligned(32))); 121 __attribute__((aligned(32)));
122static unsigned char * uncached_buffer; 122static unsigned char * uncached_buffer;
123 123
124static inline void mci_delay(void) 124static inline void mci_delay(void)
125{ 125{
126 int i = 0xffff; 126 int i = 0xffff;
127 while (i--) 127 while (i--)
128 asm volatile ("nop\n"); 128 asm volatile ("nop\n");
129} 129}
@@ -146,7 +146,7 @@ static void get_regs (unsigned *regs)
146{ 146{
147 unsigned j; 147 unsigned j;
148 volatile unsigned long *sdi_reg = &SDICON; 148 volatile unsigned long *sdi_reg = &SDICON;
149 149
150 for (j=0; j < 16;j++) 150 for (j=0; j < 16;j++)
151 { 151 {
152 *regs++ = *sdi_reg++; 152 *regs++ = *sdi_reg++;
@@ -158,7 +158,7 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
158 unsigned j; 158 unsigned j;
159 volatile unsigned long*sdi_reg = &SDICON; 159 volatile unsigned long*sdi_reg = &SDICON;
160 unsigned long diff; 160 unsigned long diff;
161 161
162 for (j=0; j < 16;j++) 162 for (j=0; j < 16;j++)
163 { 163 {
164 diff = *regs1 ^ *regs2; 164 diff = *regs1 ^ *regs2;
@@ -174,23 +174,23 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
174static void debug_r1(int cmd) 174static void debug_r1(int cmd)
175{ 175{
176#if defined(SD_DEBUG) 176#if defined(SD_DEBUG)
177 dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n", 177 dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n",
178 cmd, 178 cmd,
179 SDICSTA, 179 SDICSTA,
180 (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ', 180 (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ',
181 (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ', 181 (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ',
182 (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ', 182 (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ',
183 (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ', 183 (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ',
184 (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ', 184 (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ',
185 185
186 (SDICSTA & 0x40) ? 'P' : ' ', 186 (SDICSTA & 0x40) ? 'P' : ' ',
187 (SDICSTA & 0x20) ? 'A' : ' ', 187 (SDICSTA & 0x20) ? 'A' : ' ',
188 (SDICSTA & 0x10) ? 'E' : ' ', 188 (SDICSTA & 0x10) ? 'E' : ' ',
189 (SDICSTA & 0x08) ? 'C' : ' ', 189 (SDICSTA & 0x08) ? 'C' : ' ',
190 (SDICSTA & 0x04) ? 'I' : ' ', 190 (SDICSTA & 0x04) ? 'I' : ' ',
191 (SDICSTA & 0x02) ? 'R' : ' ', 191 (SDICSTA & 0x02) ? 'R' : ' ',
192 (SDICSTA & 0x01) ? 'Z' : ' ', 192 (SDICSTA & 0x01) ? 'Z' : ' ',
193 193
194 SDIRSP0, 194 SDIRSP0,
195 SD_R1_CURRENT_STATE(SDIRSP0), 195 SD_R1_CURRENT_STATE(SDIRSP0),
196 (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " " 196 (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " "
@@ -205,8 +205,8 @@ void SDI (void)
205 int status = SDIDSTA; 205 int status = SDIDSTA;
206#ifndef HAVE_MULTIDRIVE 206#ifndef HAVE_MULTIDRIVE
207 const int curr_card = 0; 207 const int curr_card = 0;
208#endif 208#endif
209 209
210 transfer_error[curr_card] = status 210 transfer_error[curr_card] = status
211#if 0 211#if 0
212 & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL | 212 & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL |
@@ -217,7 +217,7 @@ void SDI (void)
217 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ 217 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
218 218
219 dbgprintf ("SDI %x\n", transfer_error[curr_card]); 219 dbgprintf ("SDI %x\n", transfer_error[curr_card]);
220 220
221 semaphore_release(&transfer_completion_signal); 221 semaphore_release(&transfer_completion_signal);
222 222
223 /* Ack the interrupt */ 223 /* Ack the interrupt */
@@ -229,13 +229,13 @@ void SDI (void)
229void dma_callback (void) 229void dma_callback (void)
230{ 230{
231 const int status = SDIDSTA; 231 const int status = SDIDSTA;
232 232
233 transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL | 233 transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL |
234 S3C2410_SDIDSTA_RXCRCFAIL | 234 S3C2410_SDIDSTA_RXCRCFAIL |
235 S3C2410_SDIDSTA_DATATIMEOUT ); 235 S3C2410_SDIDSTA_DATATIMEOUT );
236 236
237 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ 237 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
238 238
239 dbgprintf ("dma_cb\n"); 239 dbgprintf ("dma_cb\n");
240 semaphore_release(&transfer_completion_signal); 240 semaphore_release(&transfer_completion_signal);
241} 241}
@@ -248,14 +248,14 @@ static void init_sdi_controller(const int card_no)
248/*****************************************************************************/ 248/*****************************************************************************/
249#ifdef MINI2440 249#ifdef MINI2440
250 /* Specific to Mini2440 */ 250 /* Specific to Mini2440 */
251 251
252 /* Enable pullups on SDCMD and SDDAT pins */ 252 /* Enable pullups on SDCMD and SDDAT pins */
253 S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE); 253 S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE);
254 S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE); 254 S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE);
255 S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE); 255 S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE);
256 S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE); 256 S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE);
257 S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE); 257 S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE);
258 258
259 /* Enable special function for SDCMD, SDCLK and SDDAT pins */ 259 /* Enable special function for SDCMD, SDCLK and SDDAT pins */
260 S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION); 260 S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION);
261 S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION); 261 S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION);
@@ -263,15 +263,15 @@ static void init_sdi_controller(const int card_no)
263 S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION); 263 S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION);
264 S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION); 264 S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION);
265 S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION); 265 S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION);
266 266
267 /* Card Detect input */ 267 /* Card Detect input */
268 S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT); 268 S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT);
269 /* enable external irq 8-23 on the internal interrupt controller */ 269 /* enable external irq 8-23 on the internal interrupt controller */
270 INTMSK &= ~1<<5; 270 INTMSK &= ~1<<5;
271 /* enable GPG8 IRQ on the external interrupt controller */ 271 /* enable GPG8 IRQ on the external interrupt controller */
272 EINTMASK &= ~(1<<16); 272 EINTMASK &= ~(1<<16);
273 273
274 274
275 /* Write Protect input */ 275 /* Write Protect input */
276 S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT); 276 S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT);
277/*****************************************************************************/ 277/*****************************************************************************/
@@ -279,11 +279,11 @@ static void init_sdi_controller(const int card_no)
279#error Unsupported target 279#error Unsupported target
280#endif 280#endif
281/*****************************************************************************/ 281/*****************************************************************************/
282 282
283 /* About 400KHz for initial comms with card */ 283 /* About 400KHz for initial comms with card */
284 SDIPRE = PCLK / INITIAL_CLK - 1; 284 SDIPRE = PCLK / INITIAL_CLK - 1;
285 /* Byte order=Type A (Little Endian), clock enable */ 285 /* Byte order=Type A (Little Endian), clock enable */
286 SDICON = S3C2410_SDICON_CLOCKTYPE; 286 SDICON = S3C2410_SDICON_CLOCKTYPE;
287 SDIFSTA |= S3C2440_SDIFSTA_FIFORESET; 287 SDIFSTA |= S3C2440_SDIFSTA_FIFORESET;
288 SDIBSIZE = SD_BLOCK_SIZE; 288 SDIBSIZE = SD_BLOCK_SIZE;
289 SDIDTIMER= 0x7fffff; /* Set timeout count - max value */ 289 SDIDTIMER= 0x7fffff; /* Set timeout count - max value */
@@ -297,11 +297,11 @@ static void init_sdi_controller(const int card_no)
297 /* Enable interrupt in controller */ 297 /* Enable interrupt in controller */
298 bitclr32(&INTMOD, SDI_MASK); 298 bitclr32(&INTMOD, SDI_MASK);
299 bitclr32(&INTMSK, SDI_MASK); 299 bitclr32(&INTMSK, SDI_MASK);
300 300
301 SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH 301 SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH
302 | S3C2410_SDIIMSK_DATATIMEOUT 302 | S3C2410_SDIIMSK_DATATIMEOUT
303 | S3C2410_SDIIMSK_DATACRC 303 | S3C2410_SDIIMSK_DATACRC
304 | S3C2410_SDIIMSK_CRCSTATUS 304 | S3C2410_SDIIMSK_CRCSTATUS
305 | S3C2410_SDIIMSK_FIFOFAIL 305 | S3C2410_SDIIMSK_FIFOFAIL
306 ; 306 ;
307#endif 307#endif
@@ -325,18 +325,18 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
325 get_regs (reg_copy2); 325 get_regs (reg_copy2);
326 dump_regs (reg_copy, reg_copy2); 326 dump_regs (reg_copy, reg_copy2);
327#endif 327#endif
328 328
329#if 0 329#if 0
330 while (SDICSTA & S3C2410_SDICMDSTAT_XFERING) 330 while (SDICSTA & S3C2410_SDICMDSTAT_XFERING)
331 ; /* wait ?? */ 331 ; /* wait ?? */
332#endif 332#endif
333 /* set up new command */ 333 /* set up new command */
334 334
335 if (flags & MCI_ARG) 335 if (flags & MCI_ARG)
336 SDICARG = arg; 336 SDICARG = arg;
337 else 337 else
338 SDICARG = 0; 338 SDICARG = 0;
339 339
340 val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST; 340 val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST;
341 if(flags & MCI_RESP) 341 if(flags & MCI_RESP)
342 { 342 {
@@ -344,27 +344,27 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
344 if(flags & MCI_LONG_RESP) 344 if(flags & MCI_LONG_RESP)
345 val |= S3C2410_SDICMDCON_LONGRSP; 345 val |= S3C2410_SDICMDCON_LONGRSP;
346 } 346 }
347 347
348 /* Clear command/data status flags */ 348 /* Clear command/data status flags */
349 SDICSTA |= 0x0f << 9; 349 SDICSTA |= 0x0f << 9;
350 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; 350 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS;
351 351
352 /* Initiate the command */ 352 /* Initiate the command */
353 SDICCON = val; 353 SDICCON = val;
354 354
355 if (flags & MCI_RESP) 355 if (flags & MCI_RESP)
356 { 356 {
357 /* wait for response or timeout */ 357 /* wait for response or timeout */
358 do 358 do
359 { 359 {
360 status = SDICSTA; 360 status = SDICSTA;
361 } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN | 361 } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN |
362 S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0); 362 S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0);
363 debug_r1(cmd); 363 debug_r1(cmd);
364 if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT) 364 if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT)
365 ret = false; 365 ret = false;
366 else if (status & (S3C2410_SDICMDSTAT_RSPFIN)) 366 else if (status & (S3C2410_SDICMDSTAT_RSPFIN))
367 { 367 {
368 /* resp received */ 368 /* resp received */
369 if(flags & MCI_LONG_RESP) 369 if(flags & MCI_LONG_RESP)
370 { 370 {
@@ -381,10 +381,10 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
381 else 381 else
382 ret = true; 382 ret = true;
383 } 383 }
384 else 384 else
385 { 385 {
386 /* wait for command completion or timeout */ 386 /* wait for command completion or timeout */
387 do 387 do
388 { 388 {
389 status = SDICSTA; 389 status = SDICSTA;
390 } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT | 390 } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT |
@@ -395,12 +395,12 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
395 else 395 else
396 ret = true; 396 ret = true;
397 } 397 }
398 398
399 /* Clear Command status flags */ 399 /* Clear Command status flags */
400 SDICSTA |= 0x0f << 9; 400 SDICSTA |= 0x0f << 9;
401 401
402 mci_delay(); 402 mci_delay();
403 403
404 return ret; 404 return ret;
405} 405}
406 406
@@ -558,7 +558,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
558 const int card_no = 0; 558 const int card_no = 0;
559#endif 559#endif
560 (void)card_no; 560 (void)card_no;
561 561
562 /* not applicable */ 562 /* not applicable */
563 dbgprintf ("sd_remov"); 563 dbgprintf ("sd_remov");
564 return false; 564 return false;
@@ -596,7 +596,7 @@ static int sd_wait_for_state(const int card_no, unsigned int state)
596 } 596 }
597} 597}
598 598
599static int sd_transfer_sectors(int card_no, unsigned long start, 599static int sd_transfer_sectors(int card_no, sector_t start,
600 int count, void* buf, const bool write) 600 int count, void* buf, const bool write)
601{ 601{
602 int ret = EC_OK; 602 int ret = EC_OK;
@@ -636,7 +636,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
636 void *dma_buf; 636 void *dma_buf;
637 const int cmd = 637 const int cmd =
638 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; 638 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
639 unsigned long start_addr = start; 639 sector_t start_addr = start;
640 640
641 dma_buf = aligned_buffer; 641 dma_buf = aligned_buffer;
642 if(transfer > UNALIGNED_NUM_SECTORS) 642 if(transfer > UNALIGNED_NUM_SECTORS)
@@ -650,10 +650,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
650 650
651 /* TODO? */ 651 /* TODO? */
652 SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET; 652 SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET;
653 SDIDCON = S3C2440_SDIDCON_DS_WORD | 653 SDIDCON = S3C2440_SDIDCON_DS_WORD |
654 S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS | 654 S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS |
655 S3C2410_SDIDCON_DMAEN | 655 S3C2410_SDIDCON_DMAEN |
656 S3C2440_SDIDCON_DATSTART | 656 S3C2440_SDIDCON_DATSTART |
657 ( transfer << 0); 657 ( transfer << 0);
658 if (write) 658 if (write)
659 SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART; 659 SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART;
@@ -665,6 +665,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
665 INTPND = SDI_MASK; 665 INTPND = SDI_MASK;
666 666
667 /* Initiate read/write command */ 667 /* Initiate read/write command */
668 // XXX 64-bit
668 if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL)) 669 if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL))
669 { 670 {
670 ret -= 3*20; 671 ret -= 3*20;
@@ -674,32 +675,32 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
674 if(write) 675 if(write)
675 { 676 {
676 request.source_addr = dma_buf; 677 request.source_addr = dma_buf;
677 request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; 678 request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
678 request.dest_addr = &SDIDAT_LLE; 679 request.dest_addr = &SDIDAT_LLE;
679 request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; 680 request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
680 request.count = transfer * SD_BLOCK_SIZE / sizeof(long); 681 request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
681 request.source_map = DMA_SRC_MAP_SDI; 682 request.source_map = DMA_SRC_MAP_SDI;
682 request.control = DCON_DMD_HS | DCON_SYNC_APB | 683 request.control = DCON_DMD_HS | DCON_SYNC_APB |
683 DCON_HW_SEL | 684 DCON_HW_SEL |
684 DCON_NO_RELOAD | DCON_DSZ_WORD; 685 DCON_NO_RELOAD | DCON_DSZ_WORD;
685 request.callback = NULL; 686 request.callback = NULL;
686 687
687 dma_enable_channel(0, &request); 688 dma_enable_channel(0, &request);
688 } 689 }
689 else 690 else
690 { 691 {
691 request.source_addr = &SDIDAT_LLE; 692 request.source_addr = &SDIDAT_LLE;
692 request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; 693 request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
693 request.dest_addr = dma_buf; 694 request.dest_addr = dma_buf;
694 request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; 695 request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
695 request.count = transfer * SD_BLOCK_SIZE / sizeof(long); 696 request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
696 request.source_map = DMA_SRC_MAP_SDI; 697 request.source_map = DMA_SRC_MAP_SDI;
697 request.control = DCON_DMD_HS | DCON_SYNC_APB | 698 request.control = DCON_DMD_HS | DCON_SYNC_APB |
698 DCON_HW_SEL | 699 DCON_HW_SEL |
699 DCON_NO_RELOAD | DCON_DSZ_WORD; 700 DCON_NO_RELOAD | DCON_DSZ_WORD;
700 request.callback = NULL; 701 request.callback = NULL;
701 702
702 dma_enable_channel(0, &request); 703 dma_enable_channel(0, &request);
703 } 704 }
704 705
705#if 0 706#if 0
@@ -716,12 +717,12 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
716#endif 717#endif
717 718
718 semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/); 719 semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
719 720
720 /* wait for DMA to finish */ 721 /* wait for DMA to finish */
721 while (DSTAT0 & DSTAT_STAT_BUSY) 722 while (DSTAT0 & DSTAT_STAT_BUSY)
722 ; 723 ;
723 724
724#if 0 725#if 0
725 status = SDIDSTA; 726 status = SDIDSTA;
726 while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0) 727 while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0)
727 { 728 {
@@ -738,10 +739,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
738 count -= transfer; 739 count -= transfer;
739 loops = 0; /* reset errors counter */ 740 loops = 0; /* reset errors counter */
740 } 741 }
741 else 742 else
742 { 743 {
743 dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]); 744 dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]);
744 745
745 if(loops++ > MAX_TRANSFER_ERRORS) 746 if(loops++ > MAX_TRANSFER_ERRORS)
746 { 747 {
747 led_flash(LED1|LED2, LED3|LED4); 748 led_flash(LED1|LED2, LED3|LED4);
@@ -783,11 +784,11 @@ sd_transfer_error:
783 return ret; 784 return ret;
784} 785}
785 786
786int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 787int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
787 void* inbuf) 788 void* inbuf)
788{ 789{
789 int ret; 790 int ret;
790 791
791#ifdef HAVE_MULTIDRIVE 792#ifdef HAVE_MULTIDRIVE
792 dbgprintf ("sd_read %d %x %d\n", card_no, start, incount); 793 dbgprintf ("sd_read %d %x %d\n", card_no, start, incount);
793#else 794#else
@@ -804,7 +805,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
804} 805}
805 806
806/*****************************************************************************/ 807/*****************************************************************************/
807int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 808int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
808 const void* outbuf) 809 const void* outbuf)
809{ 810{
810#ifdef BOOTLOADER /* we don't need write support in bootloader */ 811#ifdef BOOTLOADER /* we don't need write support in bootloader */
@@ -835,7 +836,7 @@ void sd_enable(bool on)
835{ 836{
836 dbgprintf ("sd_enable %d\n", on); 837 dbgprintf ("sd_enable %d\n", on);
837 /* TODO: enable/disable SDI clock */ 838 /* TODO: enable/disable SDI clock */
838 839
839 if (sd_enabled == on) 840 if (sd_enabled == on)
840 return; /* nothing to do */ 841 return; /* nothing to do */
841 if (on) 842 if (on)
@@ -847,14 +848,14 @@ void sd_enable(bool on)
847 sd_enabled = false; 848 sd_enabled = false;
848 } 849 }
849} 850}
850 851
851int sd_init(void) 852int sd_init(void)
852{ 853{
853 int ret = EC_OK; 854 int ret = EC_OK;
854 dbgprintf ("\n==============================\n"); 855 dbgprintf ("\n==============================\n");
855 dbgprintf (" sd_init\n"); 856 dbgprintf (" sd_init\n");
856 dbgprintf ("==============================\n"); 857 dbgprintf ("==============================\n");
857 858
858 init_sdi_controller (0); 859 init_sdi_controller (0);
859#ifndef BOOTLOADER 860#ifndef BOOTLOADER
860 sd_enabled = true; 861 sd_enabled = true;
@@ -893,7 +894,7 @@ long sd_last_disk_activity(void)
893} 894}
894 895
895tCardInfo *card_get_info_target(int card_no) 896tCardInfo *card_get_info_target(int card_no)
896{ 897{
897 return &card_info[card_no]; 898 return &card_info[card_no];
898} 899}
899 900
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 7f68b82a0d..34a1c46043 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -29,17 +29,17 @@
29#include "ftl-target.h" 29#include "ftl-target.h"
30#include "nand-target.h" 30#include "nand-target.h"
31 31
32/** static, private data **/ 32/** static, private data **/
33static bool initialized = false; 33static bool initialized = false;
34 34
35/* API Functions */ 35/* API Functions */
36int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 36int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
37 void* inbuf) 37 void* inbuf)
38{ 38{
39 return ftl_read(start, incount, inbuf); 39 return ftl_read(start, incount, inbuf);
40} 40}
41 41
42int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 42int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
43 const void* outbuf) 43 const void* outbuf)
44{ 44{
45 return ftl_write(start, count, outbuf); 45 return ftl_write(start, count, outbuf);
@@ -106,7 +106,7 @@ int nand_num_drives(int first_drive)
106{ 106{
107 /* We don't care which logical drive number(s) we have been assigned */ 107 /* We don't care which logical drive number(s) we have been assigned */
108 (void)first_drive; 108 (void)first_drive;
109 109
110 return 1; 110 return 1;
111} 111}
112#endif 112#endif
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index 7a3be20577..9629b3e30f 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -58,10 +58,9 @@
58#define CEATA_DAT_NONBUSY_TIMEOUT 5000000 58#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
59#define CEATA_MMC_RCA 1 59#define CEATA_MMC_RCA 1
60 60
61
62/** static, private data **/ 61/** static, private data **/
63static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; 62static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
64static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; 63static uint16_t ata_identify_data[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR;
65static bool ceata; 64static bool ceata;
66static bool ata_lba48; 65static bool ata_lba48;
67static bool ata_dma; 66static bool ata_dma;
@@ -510,7 +509,7 @@ static int ata_identify(uint16_t* buf)
510 ata_write_cbr(&ATA_PIO_DVR, 0); 509 ata_write_cbr(&ATA_PIO_DVR, 0);
511 ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); 510 ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY);
512 PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); 511 PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
513 for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); 512 for (i = 0; i < ATA_IDENTIFY_WORDS; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR);
514 } 513 }
515 return 0; 514 return 0;
516} 515}
@@ -701,7 +700,7 @@ static int ata_power_up(void)
701 | (((uint64_t)ata_identify_data[103]) << 48); 700 | (((uint64_t)ata_identify_data[103]) << 48);
702 else 701 else
703 ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); 702 ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
704 ata_total_sectors >>= 3; 703 ata_total_sectors >>= 3; /* ie SECTOR_SIZE/512. */
705 ata_powered = true; 704 ata_powered = true;
706 ata_set_active(); 705 ata_set_active();
707 return 0; 706 return 0;
@@ -966,7 +965,7 @@ static int ata_reset(void)
966 return rc; 965 return rc;
967} 966}
968 967
969int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 968int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount,
970 void* inbuf) 969 void* inbuf)
971{ 970{
972 mutex_lock(&ata_mutex); 971 mutex_lock(&ata_mutex);
@@ -975,7 +974,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
975 return rc; 974 return rc;
976} 975}
977 976
978int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, 977int ata_write_sectors(IF_MD(int drive,) sector_t start, int count,
979 const void* outbuf) 978 const void* outbuf)
980{ 979{
981 mutex_lock(&ata_mutex); 980 mutex_lock(&ata_mutex);
diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c
index c80c3b746f..3ef8972ee9 100644
--- a/firmware/target/arm/tcc780x/sd-tcc780x.c
+++ b/firmware/target/arm/tcc780x/sd-tcc780x.c
@@ -104,19 +104,19 @@ static bool sd_poll_status(unsigned int trigger, long timeout)
104 return true; 104 return true;
105} 105}
106 106
107static int sd_command(unsigned int cmd, unsigned int arg, 107static int sd_command(unsigned int cmd, unsigned int arg,
108 unsigned long* response, unsigned int resp_type) 108 unsigned long* response, unsigned int resp_type)
109{ 109{
110 int sdi_cmd = cmd; 110 int sdi_cmd = cmd;
111 111
112 sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */ 112 sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */
113 113
114 if (resp_type) 114 if (resp_type)
115 { 115 {
116 /* response type & response required flag */ 116 /* response type & response required flag */
117 sdi_cmd |= (resp_type<<7) | (1<<6); 117 sdi_cmd |= (resp_type<<7) | (1<<6);
118 } 118 }
119 119
120 if (cmd == SD_READ_SINGLE_BLOCK || 120 if (cmd == SD_READ_SINGLE_BLOCK ||
121 cmd == SD_READ_MULTIPLE_BLOCK || 121 cmd == SD_READ_MULTIPLE_BLOCK ||
122 cmd == SD_WRITE_BLOCK || 122 cmd == SD_WRITE_BLOCK ||
@@ -124,18 +124,18 @@ static int sd_command(unsigned int cmd, unsigned int arg,
124 { 124 {
125 sdi_cmd |= (1<<10); /* request data transfer */ 125 sdi_cmd |= (1<<10); /* request data transfer */
126 } 126 }
127 127
128 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) 128 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
129 return -EC_COMMAND; 129 return -EC_COMMAND;
130 130
131 SDIARGU = arg; 131 SDIARGU = arg;
132 SDICMD = sdi_cmd; 132 SDICMD = sdi_cmd;
133 133
134 udelay(10); 134 udelay(10);
135 135
136 if (response == NULL) 136 if (response == NULL)
137 return 0; 137 return 0;
138 138
139 if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000)) 139 if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000))
140 return -EC_COMMAND; 140 return -EC_COMMAND;
141 141
@@ -150,7 +150,7 @@ static int sd_command(unsigned int cmd, unsigned int arg,
150 { 150 {
151 response[0] = SDIRSPARGU0; 151 response[0] = SDIRSPARGU0;
152 } 152 }
153 153
154 return 0; 154 return 0;
155} 155}
156 156
@@ -220,7 +220,7 @@ static int sd1_oneshot_callback(struct timeout *tmo)
220void EXT0(void) 220void EXT0(void)
221{ 221{
222 static struct timeout sd1_oneshot; 222 static struct timeout sd1_oneshot;
223 223
224 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); 224 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
225} 225}
226 226
@@ -248,7 +248,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
248 const int card_no = 0; 248 const int card_no = 0;
249#endif 249#endif
250 (void)card_no; 250 (void)card_no;
251 251
252 return false; 252 return false;
253} 253}
254 254
@@ -259,7 +259,7 @@ static void sd_init_device(int card_no)
259{ 259{
260 int ret; 260 int ret;
261 unsigned long response; 261 unsigned long response;
262 262
263 /* Initialise card data as blank */ 263 /* Initialise card data as blank */
264 memset(currcard, 0, sizeof(*currcard)); 264 memset(currcard, 0, sizeof(*currcard));
265 265
@@ -282,7 +282,7 @@ static void sd_init_device(int card_no)
282#endif 282#endif
283 283
284 ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1); 284 ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1);
285 285
286 if (ret < 0) 286 if (ret < 0)
287 goto card_init_error; 287 goto card_init_error;
288 288
@@ -290,30 +290,30 @@ static void sd_init_device(int card_no)
290 SDICLK = (1<<12) | 59; 290 SDICLK = (1<<12) | 59;
291 291
292 sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3); 292 sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3);
293 293
294 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) 294 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
295 goto card_init_error; 295 goto card_init_error;
296 296
297 currcard->ocr = 0; 297 currcard->ocr = 0;
298 298
299 long start_tick = current_tick; 299 long start_tick = current_tick;
300 300
301 while ((currcard->ocr & (1<<31)) == 0 301 while ((currcard->ocr & (1<<31)) == 0
302 && TIME_BEFORE(current_tick, start_tick + HZ)) 302 && TIME_BEFORE(current_tick, start_tick + HZ))
303 { 303 {
304 udelay(100); 304 udelay(100);
305 sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1); 305 sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1);
306 306
307 int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0); 307 int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0);
308 sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3); 308 sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3);
309 } 309 }
310 310
311 if ((currcard->ocr & (1<<31)) == 0) 311 if ((currcard->ocr & (1<<31)) == 0)
312 { 312 {
313 ret = -EC_POWER_UP; 313 ret = -EC_POWER_UP;
314 goto card_init_error; 314 goto card_init_error;
315 } 315 }
316 316
317 ret = sd_command 317 ret = sd_command
318 (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2); 318 (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2);
319 319
@@ -322,39 +322,39 @@ static void sd_init_device(int card_no)
322 322
323 ret = sd_command 323 ret = sd_command
324 (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1); 324 (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1);
325 325
326 if (ret < 0) 326 if (ret < 0)
327 goto card_init_error; 327 goto card_init_error;
328 328
329 ret = sd_command 329 ret = sd_command
330 (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2); 330 (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2);
331 331
332 if (ret < 0) 332 if (ret < 0)
333 goto card_init_error; 333 goto card_init_error;
334 334
335 sd_parse_csd(currcard); 335 sd_parse_csd(currcard);
336 336
337 ret = sd_command 337 ret = sd_command
338 (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1); 338 (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1);
339 339
340 if (ret < 0) 340 if (ret < 0)
341 goto card_init_error; 341 goto card_init_error;
342 342
343 ret = sd_command 343 ret = sd_command
344 (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1); 344 (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1);
345 345
346 if (ret < 0) 346 if (ret < 0)
347 goto card_init_error; 347 goto card_init_error;
348 348
349 ret = sd_command /* 4 bit */ 349 ret = sd_command /* 4 bit */
350 (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1); 350 (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1);
351 351
352 if (ret < 0) 352 if (ret < 0)
353 goto card_init_error; 353 goto card_init_error;
354 354
355 ret = sd_command 355 ret = sd_command
356 (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1); 356 (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1);
357 357
358 if (ret < 0) 358 if (ret < 0)
359 goto card_init_error; 359 goto card_init_error;
360 360
@@ -386,7 +386,7 @@ static void sd_select_device(int card_no)
386 } 386 }
387} 387}
388 388
389int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 389int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
390 void* inbuf) 390 void* inbuf)
391{ 391{
392#ifndef HAVE_MULTIDRIVE 392#ifndef HAVE_MULTIDRIVE
@@ -416,23 +416,24 @@ sd_read_retry:
416 ret = currcard->initialized; 416 ret = currcard->initialized;
417 goto sd_read_error; 417 goto sd_read_error;
418 } 418 }
419 419
420 last_disk_activity = current_tick; 420 last_disk_activity = current_tick;
421 421
422 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY); 422 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
423 423
424 if (ret < 0) 424 if (ret < 0)
425 goto sd_read_error; 425 goto sd_read_error;
426 426
427 /* Use full SD clock for data transfer (PCK_SDMMC) */ 427 /* Use full SD clock for data transfer (PCK_SDMMC) */
428 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ 428 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
429 429
430 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ 430 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */
431 SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2); 431 SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2);
432 SDIDCTRL |= (1<<12); /* nReset */ 432 SDIDCTRL |= (1<<12); /* nReset */
433 433
434 SDIDCTRL2 = (1<<2); /* multi block, read */ 434 SDIDCTRL2 = (1<<2); /* multi block, read */
435 435
436 // XXX 64-bit
436 if (currcard->ocr & (1<<30)) 437 if (currcard->ocr & (1<<30))
437 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); 438 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
438 else 439 else
@@ -500,7 +501,7 @@ sd_read_error:
500 } 501 }
501} 502}
502 503
503int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, 504int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
504 const void* outbuf) 505 const void* outbuf)
505{ 506{
506/* Write support is not finished yet */ 507/* Write support is not finished yet */
@@ -538,21 +539,22 @@ sd_write_retry:
538 ret = currcard->initialized; 539 ret = currcard->initialized;
539 goto sd_write_error; 540 goto sd_write_error;
540 } 541 }
541 542
542 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY); 543 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
543 544
544 if (ret < 0) 545 if (ret < 0)
545 goto sd_write_error; 546 goto sd_write_error;
546 547
547 /* Use full SD clock for data transfer (PCK_SDMMC) */ 548 /* Use full SD clock for data transfer (PCK_SDMMC) */
548 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ 549 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
549 550
550 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ 551 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */
551 SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2); 552 SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2);
552 SDIDCTRL |= (1<<12); /* nReset */ 553 SDIDCTRL |= (1<<12); /* nReset */
553 554
554 SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */ 555 SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */
555 556
557 // XXX 64-bit
556 if (currcard->ocr & (1<<30)) 558 if (currcard->ocr & (1<<30))
557 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); 559 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
558 else 560 else
@@ -578,7 +580,7 @@ sd_write_retry:
578 else 580 else
579 { 581 {
580 int tmp_buf[4]; 582 int tmp_buf[4];
581 583
582 memcpy(tmp_buf, outbuf, 16); 584 memcpy(tmp_buf, outbuf, 16);
583 585
584 SDIWDATA = tmp_buf[0]; 586 SDIWDATA = tmp_buf[0];
@@ -646,12 +648,12 @@ void sd_enable(bool on)
646 PCLK_SDMMC &= ~PCK_EN; 648 PCLK_SDMMC &= ~PCK_EN;
647 } 649 }
648} 650}
649 651
650int sd_init(void) 652int sd_init(void)
651{ 653{
652 static bool initialized = false; 654 static bool initialized = false;
653 int ret = 0; 655 int ret = 0;
654 656
655 if (!initialized) 657 if (!initialized)
656 mutex_init(&sd_mtx); 658 mutex_init(&sd_mtx);
657 659
@@ -678,7 +680,7 @@ int sd_init(void)
678 GPIOC_DIR |= (1<<24); 680 GPIOC_DIR |= (1<<24);
679 681
680 sleep(HZ/10); 682 sleep(HZ/10);
681 683
682#ifdef HAVE_HOTSWAP 684#ifdef HAVE_HOTSWAP
683 /* Configure interrupts for the card slot */ 685 /* Configure interrupts for the card slot */
684 TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */ 686 TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */
@@ -696,7 +698,7 @@ long sd_last_disk_activity(void)
696} 698}
697 699
698tCardInfo *card_get_info_target(int card_no) 700tCardInfo *card_get_info_target(int card_no)
699{ 701{
700 return &card_info[card_no]; 702 return &card_info[card_no];
701} 703}
702 704
@@ -706,7 +708,7 @@ int sd_num_drives(int first_drive)
706{ 708{
707 /* Store which logical drive number(s) we have been assigned */ 709 /* Store which logical drive number(s) we have been assigned */
708 sd_first_drive = first_drive; 710 sd_first_drive = first_drive;
709 711
710#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) 712#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
711 return 2; 713 return 2;
712#else 714#else
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
index a1985472a0..76929e603e 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
+++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
@@ -126,8 +126,10 @@ void GIO2(void)
126 126
127#define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */ 127#define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */
128 128
129extern int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 129extern int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
130extern int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 130extern int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
131
132// XXX 64-bit: Due to this it's not likely that this target will ever handle 64-bit storage.
131 133
132struct main_header 134struct main_header
133{ 135{
@@ -253,9 +255,9 @@ static void cfs_init(void)
253 /* Read root inode */ 255 /* Read root inode */
254 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2); 256 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2);
255 root_inode = (struct cfs_inode*)&sector2; 257 root_inode = (struct cfs_inode*)&sector2;
256 258
257 logf("Root inode = 0x%x", root_inode); 259 logf("Root inode = 0x%x", root_inode);
258 260
259 logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]); 261 logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]);
260 262
261 /* Read root inode's first sector */ 263 /* Read root inode's first sector */
@@ -277,9 +279,9 @@ static void cfs_init(void)
277 vfat_inode_nr = root_direntry_items[i].inode_number; 279 vfat_inode_nr = root_direntry_items[i].inode_number;
278 } 280 }
279 } 281 }
280 282
281 logf("VFAT inode = 0x%x", vfat_inode_nr); 283 logf("VFAT inode = 0x%x", vfat_inode_nr);
282 284
283 if(vfat_inode_nr != 0) 285 if(vfat_inode_nr != 0)
284 { 286 {
285 /* Read VFAT inode */ 287 /* Read VFAT inode */
@@ -384,19 +386,19 @@ static void cfs_init(void)
384 cfs_inited = true; 386 cfs_inited = true;
385} 387}
386 388
387static inline unsigned long map_sector(unsigned long sector) 389static inline sector_t map_sector(sector_t sector)
388{ 390{
389 /* 391 /*
390 * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part 392 * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part
391 * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes. 393 * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes.
392 */ 394 */
393#ifndef BOOTLOADER 395#ifndef BOOTLOADER
394 unsigned long *sectors = core_get_data(sectors_handle); 396 sector_t *sectors = core_get_data(sectors_handle);
395#endif 397#endif
396 return cfs_start+sectors[sector/64]*64+sector%64; 398 return cfs_start+sectors[sector/64]*64+sector%64;
397} 399}
398 400
399int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 401int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
400{ 402{
401 if(!cfs_inited) 403 if(!cfs_inited)
402 cfs_init(); 404 cfs_init();
@@ -423,7 +425,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf
423 } 425 }
424} 426}
425 427
426int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) 428int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
427{ 429{
428 if(!cfs_inited) 430 if(!cfs_inited)
429 cfs_init(); 431 cfs_init();
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
index d0aa12e040..41b8e73ad4 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
+++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
@@ -36,8 +36,8 @@
36/* Nasty hack, but Creative is nasty... */ 36/* Nasty hack, but Creative is nasty... */
37#define ata_read_sectors _ata_read_sectors 37#define ata_read_sectors _ata_read_sectors
38#define ata_write_sectors _ata_write_sectors 38#define ata_write_sectors _ata_write_sectors
39extern int _ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 39extern int _ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
40extern int _ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 40extern int _ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
41 41
42/* General purpose memory region #1 */ 42/* General purpose memory region #1 */
43#define ATA_IOBASE 0x50FEE000 43#define ATA_IOBASE 0x50FEE000
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
index e66a4cb3c7..17cb239374 100644
--- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -18,7 +18,7 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "system.h" 22#include "system.h"
23#include <string.h> 23#include <string.h>
24#include "gcc_extensions.h" 24#include "gcc_extensions.h"
@@ -97,7 +97,7 @@ struct sd_card_status
97 int retry_max; 97 int retry_max;
98}; 98};
99 99
100/** static, private data **/ 100/** static, private data **/
101 101
102/* for compatibility */ 102/* for compatibility */
103static long last_disk_activity = -1; 103static long last_disk_activity = -1;
@@ -123,7 +123,7 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
123static struct semaphore data_done SHAREDBSS_ATTR; 123static struct semaphore data_done SHAREDBSS_ATTR;
124static volatile unsigned int transfer_error[NUM_DRIVES]; 124static volatile unsigned int transfer_error[NUM_DRIVES];
125/* align on cache line size */ 125/* align on cache line size */
126static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 126static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
127 __attribute__((aligned(32))); 127 __attribute__((aligned(32)));
128 128
129static void sd_card_mux(int card_no) 129static void sd_card_mux(int card_no)
@@ -397,7 +397,7 @@ static int sd_init_card(const int card_no)
397 SDHC_RESP_FMT_1, &currcard->rca); 397 SDHC_RESP_FMT_1, &currcard->rca);
398 if (ret < 0) 398 if (ret < 0)
399 { 399 {
400 dbgprintf("SD_SEND_RELATIVE_ADDR failed"); 400 dbgprintf("SD_SEND_RELATIVE_ADDR failed");
401 return -1; 401 return -1;
402 } 402 }
403 403
@@ -559,7 +559,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
559#ifdef HAVE_MULTIDRIVE 559#ifdef HAVE_MULTIDRIVE
560 (void)card_no; 560 (void)card_no;
561#endif 561#endif
562 562
563 /* not applicable */ 563 /* not applicable */
564 return false; 564 return false;
565} 565}
@@ -597,17 +597,17 @@ static int sd_wait_for_state(unsigned int state)
597 } 597 }
598} 598}
599 599
600static int sd_transfer_sectors(int card_no, unsigned long start, 600static int sd_transfer_sectors(int card_no, sector_t start,
601 int count, void *buffer, bool write) 601 int count, void *buffer, bool write)
602{ 602{
603 int ret; 603 int ret;
604 unsigned long start_addr; 604 sector_t start_addr;
605 int dma_channel = -1; 605 int dma_channel = -1;
606 bool use_direct_dma; 606 bool use_direct_dma;
607 int count_per_dma; 607 int count_per_dma;
608 unsigned long rel_addr; 608 unsigned long rel_addr;
609 609
610 dbgprintf("transfer %d %d %d", card_no, start, count); 610 dbgprintf("transfer %d %lu %d", card_no, start, count);
611 mutex_lock(&sd_mtx); 611 mutex_lock(&sd_mtx);
612 enable_controller(true); 612 enable_controller(true);
613 613
@@ -673,6 +673,7 @@ sd_transfer_retry:
673 if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) 673 if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS))
674 start_addr *= SD_BLOCK_SIZE; /* not SDHC */ 674 start_addr *= SD_BLOCK_SIZE; /* not SDHC */
675 675
676 // XXX 64-bit
676 ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, 677 ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK,
677 start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | 678 start_addr, MMC_CMD_DCLR | MMC_CMD_DATA |
678 SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), 679 SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0),
@@ -765,7 +766,7 @@ sd_transfer_error:
765 } 766 }
766} 767}
767 768
768int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 769int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
769 void* inbuf) 770 void* inbuf)
770{ 771{
771#ifndef HAVE_MULTIDRIVE 772#ifndef HAVE_MULTIDRIVE
@@ -774,7 +775,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
774 return sd_transfer_sectors(card_no, start, incount, inbuf, false); 775 return sd_transfer_sectors(card_no, start, incount, inbuf, false);
775} 776}
776 777
777int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, 778int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
778 const void* outbuf) 779 const void* outbuf)
779{ 780{
780#ifndef HAVE_MULTIDRIVE 781#ifndef HAVE_MULTIDRIVE
@@ -862,7 +863,7 @@ long sd_last_disk_activity(void)
862} 863}
863 864
864tCardInfo *card_get_info_target(int card_no) 865tCardInfo *card_get_info_target(int card_no)
865{ 866{
866 return &card_info[card_no]; 867 return &card_info[card_no];
867} 868}
868 869
diff --git a/firmware/target/hosted/filesystem-hosted.h b/firmware/target/hosted/filesystem-hosted.h
index b9c7ce648a..348a921f82 100644
--- a/firmware/target/hosted/filesystem-hosted.h
+++ b/firmware/target/hosted/filesystem-hosted.h
@@ -21,9 +21,6 @@
21#ifndef _FILESYSTEM_HOSTED_H_ 21#ifndef _FILESYSTEM_HOSTED_H_
22#define _FILESYSTEM_HOSTED_H_ 22#define _FILESYSTEM_HOSTED_H_
23 23
24#include "mv.h"
25
26int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
27void * os_lc_open(const char *ospath); 24void * os_lc_open(const char *ospath);
28 25
29#endif /* _FILESYSTEM_HOSTED_H_ */ 26#endif /* _FILESYSTEM_HOSTED_H_ */
diff --git a/firmware/target/hosted/filesystem-unix.c b/firmware/target/hosted/filesystem-unix.c
index f0d7de640d..4869d07263 100644
--- a/firmware/target/hosted/filesystem-unix.c
+++ b/firmware/target/hosted/filesystem-unix.c
@@ -33,6 +33,8 @@
33#include "pathfuncs.h" 33#include "pathfuncs.h"
34#include "string-extra.h" 34#include "string-extra.h"
35 35
36int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
37
36#define SAME_FILE_INFO(sb1p, sb2p) \ 38#define SAME_FILE_INFO(sb1p, sb2p) \
37 ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino) 39 ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino)
38 40
@@ -207,9 +209,9 @@ int os_opendir_and_fd(const char *osdirname, DIR **osdirpp, int *osfdp)
207} 209}
208 210
209/* do we really need this in the app? (in the sim, yes) */ 211/* do we really need this in the app? (in the sim, yes) */
210void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) 212void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
211{ 213{
212 unsigned long size = 0, free = 0; 214 sector_t size = 0, free = 0;
213 char volpath[MAX_PATH]; 215 char volpath[MAX_PATH];
214 struct statfs fs; 216 struct statfs fs;
215 217
diff --git a/firmware/target/hosted/filesystem-win32.c b/firmware/target/hosted/filesystem-win32.c
index fac10d003b..ebb7f283ac 100644
--- a/firmware/target/hosted/filesystem-win32.c
+++ b/firmware/target/hosted/filesystem-win32.c
@@ -30,6 +30,7 @@
30#include "debug.h" 30#include "debug.h"
31#include "pathfuncs.h" 31#include "pathfuncs.h"
32#include "string-extra.h" 32#include "string-extra.h"
33#include "mv.h"
33 34
34#define SAME_FILE_INFO(lpInfo1, lpInfo2) \ 35#define SAME_FILE_INFO(lpInfo1, lpInfo2) \
35 ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \ 36 ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \
@@ -469,7 +470,9 @@ int os_modtime(const char *path, time_t modtime)
469 return 0; 470 return 0;
470} 471}
471 472
472void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) 473int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
474
475void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
473{ 476{
474 ULARGE_INTEGER free = { .QuadPart = 0 }, 477 ULARGE_INTEGER free = { .QuadPart = 0 },
475 size = { .QuadPart = 0 }; 478 size = { .QuadPart = 0 };
diff --git a/firmware/target/hosted/lcd-linuxfb.c b/firmware/target/hosted/lcd-linuxfb.c
index 14c8c30f89..5dda5cf1cc 100644
--- a/firmware/target/hosted/lcd-linuxfb.c
+++ b/firmware/target/hosted/lcd-linuxfb.c
@@ -59,14 +59,21 @@ void lcd_init_device(void)
59 panicf("Cannot read framebuffer fixed information"); 59 panicf("Cannot read framebuffer fixed information");
60 } 60 }
61 61
62#if 0 62 if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
63 /* check resolution and framebuffer size */
64 if(vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT || vinfo.bits_per_pixel != LCD_DEPTH)
65 { 63 {
66 panicf("Unexpected framebuffer resolution: %dx%dx%d\n", vinfo.xres, 64 panicf("Cannot read framebuffer variable information");
67 vinfo.yres, vinfo.bits_per_pixel); 65 }
66
67 /* Make sure we match our desired bitdepth */
68 if (vinfo.bits_per_pixel != LCD_DEPTH || vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT) {
69 vinfo.bits_per_pixel = LCD_DEPTH;
70 vinfo.xres = LCD_WIDTH;
71 vinfo.yres = LCD_HEIGHT;
72 if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) {
73 panicf("Cannot set framebuffer to %dx%dx%d",
74 vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
75 }
68 } 76 }
69#endif
70 /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the 77 /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the
71 * values returned by the driver for line_length */ 78 * values returned by the driver for line_length */
72 79
@@ -77,11 +84,6 @@ void lcd_init_device(void)
77 panicf("Cannot map framebuffer"); 84 panicf("Cannot map framebuffer");
78 } 85 }
79 86
80 if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
81 {
82 panicf("Cannot read framebuffer variable information");
83 }
84
85 memset(framebuffer, 0, finfo.smem_len); 87 memset(framebuffer, 0, finfo.smem_len);
86 88
87#ifdef HAVE_LCD_ENABLE 89#ifdef HAVE_LCD_ENABLE
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index 1055d7e0b9..b5f3720a3b 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -340,7 +340,7 @@ static void button_event(int key, bool pressed)
340 } 340 }
341 return; 341 return;
342#endif 342#endif
343#ifdef HAVE_MULTIDRIVE 343#ifdef HAVE_HOTSWAP
344 case EXT_KEY: 344 case EXT_KEY:
345 if (!pressed) 345 if (!pressed)
346 sim_trigger_external(!storage_present(1)); 346 sim_trigger_external(!storage_present(1));
diff --git a/firmware/target/mips/ingenic_jz47xx/app.lds b/firmware/target/mips/ingenic_jz47xx/app.lds
index 1d300fed82..29a973a0ca 100644
--- a/firmware/target/mips/ingenic_jz47xx/app.lds
+++ b/firmware/target/mips/ingenic_jz47xx/app.lds
@@ -37,15 +37,11 @@ SECTIONS
37{ 37{
38 . = DRAMORIG; 38 . = DRAMORIG;
39 39
40 .startup : 40 .text :
41 { 41 {
42 loadaddress = .; 42 loadaddress = .;
43 _loadaddress = .; 43 _loadaddress = .;
44 *(.startup.text); 44 *(.init.text);
45 } > DRAM
46
47 .text :
48 {
49 *(.text*); 45 *(.text*);
50#ifndef HAVE_INIT_ATTR 46#ifndef HAVE_INIT_ATTR
51 *(.init*); 47 *(.init*);
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 5f320f8e9b..77fd5c013b 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -84,7 +84,7 @@ struct nand_param
84 * 84 *
85 */ 85 */
86 86
87static volatile unsigned long nand_address; 87static volatile sector_t nand_address;
88#define NAND_DATAPORT (nand_address) 88#define NAND_DATAPORT (nand_address)
89#define NAND_ADDRPORT (nand_address+0x10000) 89#define NAND_ADDRPORT (nand_address+0x10000)
90#define NAND_COMMPORT (nand_address+0x08000) 90#define NAND_COMMPORT (nand_address+0x08000)
@@ -111,7 +111,7 @@ static volatile unsigned long nand_address;
111static struct nand_info* chip_info = NULL; 111static struct nand_info* chip_info = NULL;
112static struct nand_info* banks[4]; 112static struct nand_info* banks[4];
113static unsigned int nr_banks = 1; 113static unsigned int nr_banks = 1;
114static unsigned long bank_size; 114static sector_t bank_size;
115static struct nand_param internal_param; 115static struct nand_param internal_param;
116static struct mutex nand_mtx; 116static struct mutex nand_mtx;
117#ifdef USE_DMA 117#ifdef USE_DMA
@@ -282,7 +282,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
282/* 282/*
283 * Read oob 283 * Read oob
284 */ 284 */
285static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) 285static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
286{ 286{
287 struct nand_param *nandp = &internal_param; 287 struct nand_param *nandp = &internal_param;
288 int page_size, row_cycle, bus_width; 288 int page_size, row_cycle, bus_width;
@@ -338,7 +338,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz
338 * page - page number within a block: 0, 1, 2, ... 338 * page - page number within a block: 0, 1, 2, ...
339 * dst - pointer to target buffer 339 * dst - pointer to target buffer
340 */ 340 */
341static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) 341static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
342{ 342{
343 struct nand_param *nandp = &internal_param; 343 struct nand_param *nandp = &internal_param;
344 int page_size, oob_size; 344 int page_size, oob_size;
@@ -611,7 +611,7 @@ int nand_init(void)
611 return res; 611 return res;
612} 612}
613 613
614static inline int read_sector(unsigned long start, unsigned int count, 614static inline int read_sector(sector_t start, unsigned int count,
615 void* buf, unsigned int chip_size) 615 void* buf, unsigned int chip_size)
616{ 616{
617 register int ret; 617 register int ret;
@@ -627,14 +627,14 @@ static inline int read_sector(unsigned long start, unsigned int count,
627 return ret; 627 return ret;
628} 628}
629 629
630int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 630int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
631{ 631{
632#ifdef HAVE_MULTIVOLUME 632#ifdef HAVE_MULTIDRIVE
633 (void)drive; 633 (void)drive;
634#endif 634#endif
635 int ret = 0; 635 int ret = 0;
636 unsigned int i, _count, chip_size = chip_info->page_size; 636 unsigned int i, _count, chip_size = chip_info->page_size;
637 unsigned long _start; 637 sector_t _start;
638 638
639 logf("start"); 639 logf("start");
640 mutex_lock(&nand_mtx); 640 mutex_lock(&nand_mtx);
@@ -670,12 +670,12 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
670} 670}
671 671
672/* TODO */ 672/* TODO */
673int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 673int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
674{ 674{
675 (void)start; 675 (void)start;
676 (void)count; 676 (void)count;
677 (void)buf; 677 (void)buf;
678#ifdef HAVE_MULTIVOLUME 678#ifdef HAVE_MULTIDRIVE
679 (void)drive; 679 (void)drive;
680#endif 680#endif
681 681
@@ -727,9 +727,9 @@ void nand_sleepnow(void)
727} 727}
728 728
729#ifdef STORAGE_GET_INFO 729#ifdef STORAGE_GET_INFO
730void nand_get_info(IF_MV(int drive,) struct storage_info *info) 730void nand_get_info(IF_MD(int drive,) struct storage_info *info)
731{ 731{
732#ifdef HAVE_MULTIVOLUME 732#ifdef HAVE_MULTIDRIVE
733 (void)drive; 733 (void)drive;
734#endif 734#endif
735 735
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
index efce5742d0..ff9b7e419e 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
@@ -110,7 +110,7 @@ struct nand_param {
110 110
111static struct nand_info* chip_info = NULL; 111static struct nand_info* chip_info = NULL;
112static struct nand_info* bank; 112static struct nand_info* bank;
113static unsigned long nand_size; 113static sector_t nand_size;
114static struct nand_param internal_param; 114static struct nand_param internal_param;
115static struct mutex nand_mtx; 115static struct mutex nand_mtx;
116#ifdef USE_DMA 116#ifdef USE_DMA
@@ -281,7 +281,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
281/* 281/*
282 * Read oob 282 * Read oob
283 */ 283 */
284static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) 284static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
285{ 285{
286 struct nand_param *nandp = &internal_param; 286 struct nand_param *nandp = &internal_param;
287 int page_size, row_cycle, bus_width; 287 int page_size, row_cycle, bus_width;
@@ -337,7 +337,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz
337 * page - page number within a block: 0, 1, 2, ... 337 * page - page number within a block: 0, 1, 2, ...
338 * dst - pointer to target buffer 338 * dst - pointer to target buffer
339 */ 339 */
340static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) 340static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
341{ 341{
342 struct nand_param *nandp = &internal_param; 342 struct nand_param *nandp = &internal_param;
343 int page_size, oob_size; 343 int page_size, oob_size;
@@ -532,7 +532,7 @@ int nand_init(void)
532 return res; 532 return res;
533} 533}
534 534
535static inline int read_sector(unsigned long start, unsigned int count, 535static inline int read_sector(sector_t start, unsigned int count,
536 void* buf, unsigned int chip_size) 536 void* buf, unsigned int chip_size)
537{ 537{
538 register int ret; 538 register int ret;
@@ -548,7 +548,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
548 return ret; 548 return ret;
549} 549}
550 550
551static inline int write_sector(unsigned long start, unsigned int count, 551static inline int write_sector(sector_t start, unsigned int count,
552 const void* buf, unsigned int chip_size) 552 const void* buf, unsigned int chip_size)
553{ 553{
554 int ret = 0; 554 int ret = 0;
@@ -563,14 +563,14 @@ static inline int write_sector(unsigned long start, unsigned int count,
563 return ret; 563 return ret;
564} 564}
565 565
566int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 566int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
567{ 567{
568#ifdef HAVE_MULTIVOLUME 568#ifdef HAVE_MULTIDRIVE
569 (void)drive; 569 (void)drive;
570#endif 570#endif
571 int ret = 0; 571 int ret = 0;
572 unsigned int _count, chip_size = chip_info->page_size; 572 unsigned int _count, chip_size = chip_info->page_size;
573 unsigned long _start; 573 sector_t _start;
574 574
575 logf("start"); 575 logf("start");
576 mutex_lock(&nand_mtx); 576 mutex_lock(&nand_mtx);
@@ -590,14 +590,14 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
590 return ret; 590 return ret;
591} 591}
592 592
593int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 593int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
594{ 594{
595#ifdef HAVE_MULTIVOLUME 595#ifdef HAVE_MULTIDRIVE
596 (void)drive; 596 (void)drive;
597#endif 597#endif
598 int ret = 0; 598 int ret = 0;
599 unsigned int _count, chip_size = chip_info->page_size; 599 unsigned int _count, chip_size = chip_info->page_size;
600 unsigned long _start; 600 sector_t _start;
601 601
602 logf("start"); 602 logf("start");
603 mutex_lock(&nand_mtx); 603 mutex_lock(&nand_mtx);
@@ -662,9 +662,9 @@ void nand_sleepnow(void)
662} 662}
663 663
664#ifdef STORAGE_GET_INFO 664#ifdef STORAGE_GET_INFO
665void nand_get_info(IF_MV(int drive,) struct storage_info *info) 665void nand_get_info(IF_MD(int drive,) struct storage_info *info)
666{ 666{
667#ifdef HAVE_MULTIVOLUME 667#ifdef HAVE_MULTIDRIVE
668 (void)drive; 668 (void)drive;
669#endif 669#endif
670 670
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 56dd50814a..066be4e987 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -42,7 +42,6 @@ static struct mutex sd_mtx;
42 42
43static int use_4bit; 43static int use_4bit;
44static int num_6; 44static int num_6;
45static int sd2_0;
46 45
47//#define SD_DMA_ENABLE 46//#define SD_DMA_ENABLE
48#define SD_DMA_INTERRUPT 0 47#define SD_DMA_INTERRUPT 0
@@ -598,7 +597,7 @@ static int jz_sd_transmit_data(struct sd_request *req)
598static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) 597static inline unsigned int jz_sd_calc_clkrt(unsigned int rate)
599{ 598{
600 unsigned int clkrt; 599 unsigned int clkrt;
601 unsigned int clk_src = sd2_0 ? SD_CLOCK_HIGH : SD_CLOCK_FAST; 600 unsigned int clk_src = card.sd2plus ? SD_CLOCK_HIGH : SD_CLOCK_FAST;
602 601
603 clkrt = 0; 602 clkrt = 0;
604 while (rate < clk_src) 603 while (rate < clk_src)
@@ -716,7 +715,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
716 events = SD_EVENT_RX_DATA_DONE; 715 events = SD_EVENT_RX_DATA_DONE;
717 break; 716 break;
718 717
719 case 6: 718 case SD_SWITCH_FUNC:
720 if (num_6 < 2) 719 if (num_6 < 2)
721 { 720 {
722#if defined(SD_DMA_ENABLE) 721#if defined(SD_DMA_ENABLE)
@@ -1086,7 +1085,6 @@ static int sd_init_card_state(struct sd_request *request)
1086 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1085 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1087 1086
1088 sd_parse_csd(&card); 1087 sd_parse_csd(&card);
1089 sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1);
1090 1088
1091 logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); 1089 logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]);
1092 DEBUG("SD card is ready"); 1090 DEBUG("SD card is ready");
@@ -1155,7 +1153,7 @@ static int sd_select_card(void)
1155 if (retval) 1153 if (retval)
1156 return retval; 1154 return retval;
1157 1155
1158 if (sd2_0) 1156 if (card.sd2plus)
1159 { 1157 {
1160 retval = sd_read_switch(&request); 1158 retval = sd_read_switch(&request);
1161 if (!retval) 1159 if (!retval)
@@ -1188,7 +1186,6 @@ static int __sd_init_device(void)
1188 /* Initialise card data as blank */ 1186 /* Initialise card data as blank */
1189 memset(&card, 0, sizeof(tCardInfo)); 1187 memset(&card, 0, sizeof(tCardInfo));
1190 1188
1191 sd2_0 = 0;
1192 num_6 = 0; 1189 num_6 = 0;
1193 use_4bit = 0; 1190 use_4bit = 0;
1194 1191
@@ -1250,9 +1247,9 @@ static inline void sd_stop_transfer(void)
1250 mutex_unlock(&sd_mtx); 1247 mutex_unlock(&sd_mtx);
1251} 1248}
1252 1249
1253int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 1250int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
1254{ 1251{
1255#ifdef HAVE_MULTIVOLUME 1252#ifdef HAVE_MULTIDRIVE
1256 (void)drive; 1253 (void)drive;
1257#endif 1254#endif
1258 sd_start_transfer(); 1255 sd_start_transfer();
@@ -1276,7 +1273,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1276 if ((retval = sd_unpack_r1(&request, &r1))) 1273 if ((retval = sd_unpack_r1(&request, &r1)))
1277 goto err; 1274 goto err;
1278 1275
1279 if (sd2_0) 1276 // XXX 64-bit
1277 if (card.sd2plus)
1280 { 1278 {
1281 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, 1279 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
1282 count, SD_BLOCK_SIZE, RESPONSE_R1, buf); 1280 count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
@@ -1292,21 +1290,20 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1292 goto err; 1290 goto err;
1293 } 1291 }
1294 1292
1295 last_disk_activity = current_tick;
1296
1297 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); 1293 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
1298 if ((retval = sd_unpack_r1(&request, &r1))) 1294 if ((retval = sd_unpack_r1(&request, &r1)))
1299 goto err; 1295 goto err;
1300 1296
1301err: 1297err:
1298 last_disk_activity = current_tick;
1302 sd_stop_transfer(); 1299 sd_stop_transfer();
1303 1300
1304 return retval; 1301 return retval;
1305} 1302}
1306 1303
1307int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 1304int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
1308{ 1305{
1309#ifdef HAVE_MULTIVOLUME 1306#ifdef HAVE_MULTIDRIVE
1310 (void)drive; 1307 (void)drive;
1311#endif 1308#endif
1312 sd_start_transfer(); 1309 sd_start_transfer();
@@ -1330,7 +1327,8 @@ int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const voi
1330 if ((retval = sd_unpack_r1(&request, &r1))) 1327 if ((retval = sd_unpack_r1(&request, &r1)))
1331 goto err; 1328 goto err;
1332 1329
1333 if (sd2_0) 1330 // XXX 64-bit
1331 if (card.sd2plus)
1334 { 1332 {
1335 sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start, 1333 sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start,
1336 count, SD_BLOCK_SIZE, RESPONSE_R1, 1334 count, SD_BLOCK_SIZE, RESPONSE_R1,
@@ -1387,7 +1385,7 @@ int sd_soft_reset(void)
1387#ifdef HAVE_HOTSWAP 1385#ifdef HAVE_HOTSWAP
1388bool sd_removable(IF_MD_NONVOID(int drive)) 1386bool sd_removable(IF_MD_NONVOID(int drive))
1389{ 1387{
1390#ifdef HAVE_MULTIVOLUME 1388#ifdef HAVE_MULTIDRIVE
1391 (void)drive; 1389 (void)drive;
1392#endif 1390#endif
1393 return true; 1391 return true;
@@ -1415,7 +1413,7 @@ void MMC_CD_IRQ(void)
1415} 1413}
1416#endif 1414#endif
1417 1415
1418bool sd_present(IF_MV_NONVOID(int drive)) 1416bool sd_present(IF_MD_NONVOID(int drive))
1419{ 1417{
1420#ifdef HAVE_MULTIDRIVE 1418#ifdef HAVE_MULTIDRIVE
1421 (void)drive; 1419 (void)drive;
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
index 1960fcbd35..3810852686 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
@@ -57,8 +57,6 @@ static struct semaphore sd_wakeup[NUM_DRIVES];
57 57
58static int use_4bit[NUM_DRIVES]; 58static int use_4bit[NUM_DRIVES];
59static int num_6[NUM_DRIVES]; 59static int num_6[NUM_DRIVES];
60static int sd2_0[NUM_DRIVES];
61
62 60
63//#define DEBUG(x...) logf(x) 61//#define DEBUG(x...) logf(x)
64#define DEBUG(x, ...) 62#define DEBUG(x, ...)
@@ -698,7 +696,7 @@ static inline unsigned int jz_sd_calc_clkrt(const int drive, unsigned int rate)
698 unsigned int clkrt = 0; 696 unsigned int clkrt = 0;
699 unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */ 697 unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */
700 698
701 if (!sd2_0[drive] && rate > SD_CLOCK_FAST) 699 if (!card[drive].sd2plus && rate > SD_CLOCK_FAST)
702 rate = SD_CLOCK_FAST; 700 rate = SD_CLOCK_FAST;
703 701
704 while (rate < clk_src) 702 while (rate < clk_src)
@@ -1192,7 +1190,6 @@ static int sd_init_card_state(const int drive, struct sd_request *request)
1192 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1190 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1193 1191
1194 sd_parse_csd(&card[drive]); 1192 sd_parse_csd(&card[drive]);
1195 sd2_0[drive] = (card_extract_bits(card[drive].csd, 127, 2) == 1);
1196 1193
1197 logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]); 1194 logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]);
1198 DEBUG("SD card is ready"); 1195 DEBUG("SD card is ready");
@@ -1261,7 +1258,7 @@ static int sd_select_card(const int drive)
1261 if (retval) 1258 if (retval)
1262 return retval; 1259 return retval;
1263 1260
1264 if (sd2_0[drive]) 1261 if (card[drive].sd2plus)
1265 { 1262 {
1266 retval = sd_read_switch(drive, &request); 1263 retval = sd_read_switch(drive, &request);
1267 if (!retval) 1264 if (!retval)
@@ -1292,7 +1289,6 @@ static int __sd_init_device(const int drive)
1292 /* Initialise card data as blank */ 1289 /* Initialise card data as blank */
1293 memset(&card[drive], 0, sizeof(tCardInfo)); 1290 memset(&card[drive], 0, sizeof(tCardInfo));
1294 1291
1295 sd2_0[drive] = 0;
1296 num_6[drive] = 0; 1292 num_6[drive] = 0;
1297 use_4bit[drive] = 0; 1293 use_4bit[drive] = 0;
1298 active[drive] = 0; 1294 active[drive] = 0;
@@ -1402,7 +1398,7 @@ static inline void sd_stop_transfer(const int drive)
1402 mutex_unlock(&sd_mtx[drive]); 1398 mutex_unlock(&sd_mtx[drive]);
1403} 1399}
1404 1400
1405int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count, void* buf, bool write) 1401int sd_transfer_sectors(IF_MD(const int drive,) sector_t start, int count, void* buf, bool write)
1406{ 1402{
1407 struct sd_request request; 1403 struct sd_request request;
1408 struct sd_response_r1 r1; 1404 struct sd_response_r1 r1;
@@ -1427,11 +1423,12 @@ int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count,
1427 if ((retval = sd_unpack_r1(&request, &r1))) 1423 if ((retval = sd_unpack_r1(&request, &r1)))
1428 goto err; 1424 goto err;
1429 1425
1426 // XXX 64-bit
1430 sd_send_cmd(drive, &request, 1427 sd_send_cmd(drive, &request,
1431 (count > 1) ? 1428 (count > 1) ?
1432 (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) : 1429 (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) :
1433 (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK), 1430 (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK),
1434 sd2_0[drive] ? start : (start * SD_BLOCK_SIZE), 1431 card[drive].sd2plus ? start : (start * SD_BLOCK_SIZE),
1435 count, SD_BLOCK_SIZE, RESPONSE_R1, buf); 1432 count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
1436 if ((retval = sd_unpack_r1(&request, &r1))) 1433 if ((retval = sd_unpack_r1(&request, &r1)))
1437 goto err; 1434 goto err;
@@ -1451,12 +1448,12 @@ err:
1451 return retval; 1448 return retval;
1452} 1449}
1453 1450
1454int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 1451int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
1455{ 1452{
1456 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); 1453 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
1457} 1454}
1458 1455
1459int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) 1456int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
1460{ 1457{
1461 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); 1458 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
1462} 1459}
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index b73a43d8f2..ee203b3b4d 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -44,7 +44,7 @@
44 .extern main 44 .extern main
45 .global _start 45 .global _start
46 46
47 .section .startup.text,"ax",%progbits 47 .section .init.text
48 .set push 48 .set push
49 .set mips32 49 .set mips32
50 .set noreorder 50 .set noreorder
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
index df97aba0c8..6968a19a1c 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
@@ -104,6 +104,30 @@ void audiohw_postinit(void)
104 * for 24-bit data... */ 104 * for 24-bit data... */
105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data 105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data
106 106
107 /* Datasheet: Sets the number os FSR edges that must occur before *
108 * the DPLL and ASRC can lock on to the the incoming Signal. *
109 * When Samplerates >= 96khz could be used, STOP_DIV should be set *
110 * to 0 (= 16384 FSR Edges). *
111 * Reg #10 [3:0] (0x05 default, 2730 FSR Edges) */
112 es9018k2m_write_reg(ES9018K2M_REG10_MASTER_MODE_CTRL, 0x00);
113
114 /* Datasheet: The ES90x8Q2M/K2M contains a Jitter Eliminator block, *
115 * which employs the use of a digital phase locked loop (DPLL) to *
116 * lock to the incoming audio clock rate. When in I2S or SPDIF mode, *
117 * the DPLL will lock to the frame clock (1 x fs). However, when in *
118 * DSD mode, the DPLL has no frame clock information, and must in- *
119 * stead lock to the bit clock rate (BCK). For this reason, there are *
120 * two bandwidth settings for the DPLL. *
121 Reg #12 [7:4] (0x05 default) bandwidth for I2S / SPDIF mode.
122 Reg #12 [3:0] (0x0A default) bandwidth for DSD mode.
123 * The DPLL bandwidth sets how quickly the DPLL can adjust its intern *
124 * representation of the audio clock. The higher the jitter or *
125 * frequency drift on the audio clock, the higher the bandwidth must *
126 * be so that the DPLL can react. *
127 * ! If the bandwidth is “too low”, the DPLL will loose lock and you *
128 * ! will hear random dropouts. (Fixed my SurfansF20 v3.2 dropouts) */
129 es9018k2m_write_reg(ES9018K2M_REG12_DPLL_SETTINGS, 0xda);
130
107 } else { /* Default to SWVOL for PCM5102A DAC */ 131 } else { /* Default to SWVOL for PCM5102A DAC */
108 logf("Default to SWVOL: ret=%d", ret); 132 logf("Default to SWVOL: ret=%d", ret);
109 } 133 }
@@ -139,17 +163,19 @@ void audiohw_set_volume(int vol_l, int vol_r)
139 r = vol_r; 163 r = vol_r;
140 164
141#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) 165#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION))
142 /* make sure headphones aren't present - don't want to 166 /* Due to the hardware's detection method, make the Line-Out
143 * blow out our eardrums cranking it to full */ 167 * the default. The LO can only be detected if it is active
144 if (lineout_inserted() && !headphones_inserted()) 168 * (assuming a high-impedance device is attached). HP takes priority
169 * if both are present. */
170 if (headphones_inserted())
145 { 171 {
146 eros_qn_switch_output(1); 172 eros_qn_switch_output(0);
147
148 l = r = eros_qn_get_volume_limit();
149 } 173 }
150 else 174 else
151 { 175 {
152 eros_qn_switch_output(0); 176 eros_qn_switch_output(1);
177
178 l = r = eros_qn_get_volume_limit();
153 } 179 }
154#endif 180#endif
155 181
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
index 0d2207af2a..707dc372a8 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
@@ -75,12 +75,26 @@ volatile signed int enc_position = 0;
75/* Value of headphone detect register */ 75/* Value of headphone detect register */
76static uint8_t hp_detect_reg = 0x00; 76static uint8_t hp_detect_reg = 0x00;
77static uint8_t hp_detect_reg_old = 0x00; 77static uint8_t hp_detect_reg_old = 0x00;
78static uint8_t hp_detect_debounce1 = 0x00;
79static uint8_t hp_detect_debounce2 = 0x00;
80static uint8_t debounce_count = 0;
78 81
79/* Interval to poll the register */ 82/* Interval to poll the register */
80#define HPD_POLL_TIME (HZ/2) 83#define HPD_POLL_TIME (HZ/4)
81 84
82static int hp_detect_tmo_cb(struct timeout* tmo) 85static int hp_detect_tmo_cb(struct timeout* tmo)
83{ 86{
87 if (hp_detect_debounce1 == hp_detect_debounce2){
88 if (debounce_count >= 2){
89 debounce_count = 2;
90 } else {
91 debounce_count = debounce_count + 1;
92 }
93 } else {
94 debounce_count = 0;
95 hp_detect_debounce2 = hp_detect_debounce1;
96 }
97
84 i2c_descriptor* d = (i2c_descriptor*)tmo->data; 98 i2c_descriptor* d = (i2c_descriptor*)tmo->data;
85 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); 99 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d);
86 return HPD_POLL_TIME; 100 return HPD_POLL_TIME;
@@ -96,7 +110,7 @@ static void hp_detect_init(void)
96 .tran_mode = I2C_READ, 110 .tran_mode = I2C_READ,
97 .buffer[0] = (void*)&gpio_reg, 111 .buffer[0] = (void*)&gpio_reg,
98 .count[0] = 1, 112 .count[0] = 1,
99 .buffer[1] = &hp_detect_reg, 113 .buffer[1] = &hp_detect_debounce1,
100 .count[1] = 1, 114 .count[1] = 1,
101 .callback = NULL, 115 .callback = NULL,
102 .arg = 0, 116 .arg = 0,
@@ -113,6 +127,8 @@ static void hp_detect_init(void)
113 if(r >= 0) 127 if(r >= 0)
114 { 128 {
115 hp_detect_reg = r; 129 hp_detect_reg = r;
130 hp_detect_debounce1 = r;
131 hp_detect_debounce2 = r;
116 hp_detect_reg_old = hp_detect_reg; 132 hp_detect_reg_old = hp_detect_reg;
117 } 133 }
118 134
@@ -122,6 +138,9 @@ static void hp_detect_init(void)
122 138
123bool headphones_inserted(void) 139bool headphones_inserted(void)
124{ 140{
141 if (debounce_count > 1){
142 hp_detect_reg = hp_detect_debounce2;
143 }
125 /* if the status has changed, set the output volume accordingly */ 144 /* if the status has changed, set the output volume accordingly */
126 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 145 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
127 { 146 {
@@ -135,6 +154,9 @@ bool headphones_inserted(void)
135 154
136bool lineout_inserted(void) 155bool lineout_inserted(void)
137{ 156{
157 if (debounce_count > 1){
158 hp_detect_reg = hp_detect_debounce2;
159 }
138 /* if the status has changed, set the output volume accordingly */ 160 /* if the status has changed, set the output volume accordingly */
139 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 161 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
140 { 162 {
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c
index 62172fa213..f0d417e4f7 100644
--- a/firmware/target/mips/ingenic_x1000/msc-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c
@@ -844,7 +844,7 @@ int msc_cmd_send_csd(msc_drv* d)
844 d->cardinfo.csd[i] = req.response[i]; 844 d->cardinfo.csd[i] = req.response[i];
845 sd_parse_csd(&d->cardinfo); 845 sd_parse_csd(&d->cardinfo);
846 846
847 if((req.response[0] >> 30) == 1) 847 if(d->cardinfo.sd2plus)
848 d->driver_flags |= MSC_DF_V2_CARD; 848 d->driver_flags |= MSC_DF_V2_CARD;
849 849
850 return 0; 850 return 0;
diff --git a/firmware/target/mips/ingenic_x1000/sd-x1000.c b/firmware/target/mips/ingenic_x1000/sd-x1000.c
index 679a25a222..c1aec59aa3 100644
--- a/firmware/target/mips/ingenic_x1000/sd-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/sd-x1000.c
@@ -51,7 +51,7 @@ static int sd_init_card(msc_drv* d)
51} 51}
52 52
53static int sd_transfer(msc_drv* d, bool write, 53static int sd_transfer(msc_drv* d, bool write,
54 unsigned long start, int count, void* buf) 54 sector_t start, int count, void* buf)
55{ 55{
56 int status = -1; 56 int status = -1;
57 57
@@ -114,6 +114,7 @@ static int sd_transfer(msc_drv* d, bool write,
114 : SD_READ_MULTIPLE_BLOCK; 114 : SD_READ_MULTIPLE_BLOCK;
115 } 115 }
116 116
117 // XXX 64-bit
117 if(d->driver_flags & MSC_DF_V2_CARD) 118 if(d->driver_flags & MSC_DF_V2_CARD)
118 req.argument = start; 119 req.argument = start;
119 else 120 else
@@ -142,14 +143,14 @@ static int sd_transfer(msc_drv* d, bool write,
142 return status; 143 return status;
143} 144}
144 145
145int sd_read_sectors(IF_MD(int drive,) unsigned long start, 146int sd_read_sectors(IF_MD(int drive,) sector_t start,
146 int count, void* buf) 147 int count, void* buf)
147{ 148{
148 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false, 149 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false,
149 start, count, buf); 150 start, count, buf);
150} 151}
151 152
152int sd_write_sectors(IF_MD(int drive,) unsigned long start, 153int sd_write_sectors(IF_MD(int drive,) sector_t start,
153 int count, const void* buf) 154 int count, const void* buf)
154{ 155{
155 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true, 156 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true,
@@ -187,6 +188,9 @@ long sd_last_disk_activity(void)
187 188
188bool sd_present(IF_MD_NONVOID(int drive)) 189bool sd_present(IF_MD_NONVOID(int drive))
189{ 190{
191#ifndef HAVE_MULTIDRIVE
192 int drive = 0;
193#endif
190 /* Seems that volume_properties() in firmware/common/disk.c may pass 194 /* Seems that volume_properties() in firmware/common/disk.c may pass
191 * drive = -1 when the SD card is not inserted, so just return false. 195 * drive = -1 when the SD card is not inserted, so just return false.
192 */ 196 */
@@ -198,6 +202,10 @@ bool sd_present(IF_MD_NONVOID(int drive))
198 202
199bool sd_removable(IF_MD_NONVOID(int drive)) 203bool sd_removable(IF_MD_NONVOID(int drive))
200{ 204{
205#ifndef HAVE_MULTIDRIVE
206 int drive = 0;
207#endif
208
201 /* Same reason as sd_present() */ 209 /* Same reason as sd_present() */
202 if(drive < 0) 210 if(drive < 0)
203 return false; 211 return false;
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 81d90d01db..e226c15f99 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -114,6 +114,9 @@
114#define SCSI_REPORT_LUNS 0xa0 114#define SCSI_REPORT_LUNS 0xa0
115#define SCSI_WRITE_BUFFER 0x3b 115#define SCSI_WRITE_BUFFER 0x3b
116 116
117#define SCSI_READ_16 0x88
118#define SCSI_WRITE_16 0x8a
119
117#define UMS_STATUS_GOOD 0x00 120#define UMS_STATUS_GOOD 0x00
118#define UMS_STATUS_FAIL 0x01 121#define UMS_STATUS_FAIL 0x01
119 122
@@ -273,7 +276,7 @@ static union {
273static char *cbw_buffer; 276static char *cbw_buffer;
274 277
275static struct { 278static struct {
276 unsigned int sector; 279 sector_t sector;
277 unsigned int count; 280 unsigned int count;
278 unsigned int orig_count; 281 unsigned int orig_count;
279 unsigned int cur_cmd; 282 unsigned int cur_cmd;
@@ -503,7 +506,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
503 if(dir==USB_DIR_IN) { 506 if(dir==USB_DIR_IN) {
504 logf("IN received in RECEIVING"); 507 logf("IN received in RECEIVING");
505 } 508 }
506 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); 509 logf("scsi write %llu %d", cur_cmd.sector, cur_cmd.count);
507 if(status==0) { 510 if(status==0) {
508 if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count) 511 if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count)
509 && (unsigned int)length!=WRITE_BUFFER_SIZE) { 512 && (unsigned int)length!=WRITE_BUFFER_SIZE) {
@@ -511,7 +514,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
511 break; 514 break;
512 } 515 }
513 516
514 unsigned int next_sector = cur_cmd.sector + 517 sector_t next_sector = cur_cmd.sector +
515 (WRITE_BUFFER_SIZE/SECTOR_SIZE); 518 (WRITE_BUFFER_SIZE/SECTOR_SIZE);
516 unsigned int next_count = cur_cmd.count - 519 unsigned int next_count = cur_cmd.count -
517 MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE); 520 MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE);
@@ -739,12 +742,10 @@ static void send_and_read_next(void)
739 742
740static void handle_scsi(struct command_block_wrapper* cbw) 743static void handle_scsi(struct command_block_wrapper* cbw)
741{ 744{
742 /* USB Mass Storage assumes LBA capability.
743 TODO: support 48-bit LBA */
744
745 struct storage_info info; 745 struct storage_info info;
746 unsigned int length = cbw->data_transfer_length; 746 unsigned int length = cbw->data_transfer_length;
747 unsigned int block_size, block_count; 747 sector_t block_count;
748 unsigned int block_size;
748 bool lun_present=true; 749 bool lun_present=true;
749 unsigned char lun = cbw->lun; 750 unsigned char lun = cbw->lun;
750 unsigned int block_size_mult = 1; 751 unsigned int block_size_mult = 1;
@@ -888,6 +889,12 @@ static void handle_scsi(struct command_block_wrapper* cbw)
888 memset(tb.ms_data_10->block_descriptor.reserved,0,4); 889 memset(tb.ms_data_10->block_descriptor.reserved,0,4);
889 memset(tb.ms_data_10->block_descriptor.num_blocks,0,8); 890 memset(tb.ms_data_10->block_descriptor.num_blocks,0,8);
890 891
892#ifdef STORAGE_64BIT_SECTOR
893 tb.ms_data_10->block_descriptor.num_blocks[2] =
894 ((block_count/block_size_mult) & 0xff00000000ULL)>>40;
895 tb.ms_data_10->block_descriptor.num_blocks[3] =
896 ((block_count/block_size_mult) & 0x00ff000000ULL)>>32;
897#endif
891 tb.ms_data_10->block_descriptor.num_blocks[4] = 898 tb.ms_data_10->block_descriptor.num_blocks[4] =
892 ((block_count/block_size_mult) & 0xff000000)>>24; 899 ((block_count/block_size_mult) & 0xff000000)>>24;
893 tb.ms_data_10->block_descriptor.num_blocks[5] = 900 tb.ms_data_10->block_descriptor.num_blocks[5] =
@@ -1070,7 +1077,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1070 cbw->command_block[8]); 1077 cbw->command_block[8]);
1071 cur_cmd.orig_count = cur_cmd.count; 1078 cur_cmd.orig_count = cur_cmd.count;
1072 1079
1073 //logf("scsi read %d %d", cur_cmd.sector, cur_cmd.count); 1080 logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count);
1074 1081
1075 if((cur_cmd.sector + cur_cmd.count) > block_count) { 1082 if((cur_cmd.sector + cur_cmd.count) > block_count) {
1076 send_csw(UMS_STATUS_FAIL); 1083 send_csw(UMS_STATUS_FAIL);
@@ -1092,7 +1099,58 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1092 send_and_read_next(); 1099 send_and_read_next();
1093 } 1100 }
1094 break; 1101 break;
1102#ifdef STORAGE_64BIT_SECTOR
1103 case SCSI_READ_16:
1104 logf("scsi read16 %d",lun);
1105 if(!lun_present) {
1106 send_command_failed_result();
1107 cur_sense_data.sense_key=SENSE_NOT_READY;
1108 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
1109 cur_sense_data.ascq=0;
1110 break;
1111 }
1112 cur_cmd.data[0] = tb.transfer_buffer;
1113 cur_cmd.data[1] = &tb.transfer_buffer[READ_BUFFER_SIZE];
1114 cur_cmd.data_select=0;
1115 cur_cmd.sector = block_size_mult *
1116 ((uint64_t)cbw->command_block[2] << 56 |
1117 (uint64_t)cbw->command_block[3] << 48 |
1118 (uint64_t)cbw->command_block[4] << 40 |
1119 (uint64_t)cbw->command_block[5] << 32 |
1120 cbw->command_block[6] << 24 |
1121 cbw->command_block[7] << 16 |
1122 cbw->command_block[8] << 8 |
1123 cbw->command_block[9]);
1124 cur_cmd.count = block_size_mult *
1125 (cbw->command_block[10] << 24 |
1126 cbw->command_block[11] << 16 |
1127 cbw->command_block[12] << 8 |
1128 cbw->command_block[13]);
1129 cur_cmd.orig_count = cur_cmd.count;
1095 1130
1131 logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count);
1132
1133 if((cur_cmd.sector + cur_cmd.count) > block_count) {
1134 send_csw(UMS_STATUS_FAIL);
1135 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
1136 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
1137 cur_sense_data.ascq=0;
1138 }
1139 else {
1140#ifdef USB_USE_RAMDISK
1141 memcpy(cur_cmd.data[cur_cmd.data_select],
1142 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
1143 MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE);
1144#else
1145 cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,)
1146 cur_cmd.sector,
1147 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
1148 cur_cmd.data[cur_cmd.data_select]);
1149#endif
1150 send_and_read_next();
1151 }
1152 break;
1153#endif
1096 case SCSI_WRITE_10: 1154 case SCSI_WRITE_10:
1097 logf("scsi write10 %d",lun); 1155 logf("scsi write10 %d",lun);
1098 if(!lun_present) { 1156 if(!lun_present) {
@@ -1127,6 +1185,48 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1127 MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); 1185 MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
1128 } 1186 }
1129 break; 1187 break;
1188#ifdef STORAGE_64BIT_SECTOR
1189 case SCSI_WRITE_16:
1190 logf("scsi write16 %d",lun);
1191 if(!lun_present) {
1192 send_csw(UMS_STATUS_FAIL);
1193 cur_sense_data.sense_key=SENSE_NOT_READY;
1194 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
1195 cur_sense_data.ascq=0;
1196 break;
1197 }
1198 cur_cmd.data[0] = tb.transfer_buffer;
1199 cur_cmd.data[1] = &tb.transfer_buffer[WRITE_BUFFER_SIZE];
1200 cur_cmd.data_select=0;
1201 cur_cmd.sector = block_size_mult *
1202 ((uint64_t)cbw->command_block[2] << 56 |
1203 (uint64_t)cbw->command_block[3] << 48 |
1204 (uint64_t)cbw->command_block[4] << 40 |
1205 (uint64_t)cbw->command_block[5] << 32 |
1206 cbw->command_block[6] << 24 |
1207 cbw->command_block[7] << 16 |
1208 cbw->command_block[8] << 8 |
1209 cbw->command_block[9]);
1210 cur_cmd.count = block_size_mult *
1211 (cbw->command_block[10] << 24 |
1212 cbw->command_block[11] << 16 |
1213 cbw->command_block[12] << 8 |
1214 cbw->command_block[13]);
1215 cur_cmd.orig_count = cur_cmd.count;
1216
1217 /* expect data */
1218 if((cur_cmd.sector + cur_cmd.count) > block_count) {
1219 send_csw(UMS_STATUS_FAIL);
1220 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
1221 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
1222 cur_sense_data.ascq=0;
1223 }
1224 else {
1225 receive_block_data(cur_cmd.data[0],
1226 MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
1227 }
1228 break;
1229#endif
1130 1230
1131#if CONFIG_RTC 1231#if CONFIG_RTC
1132 case SCSI_WRITE_BUFFER: 1232 case SCSI_WRITE_BUFFER: