storage: 64-bit sector offsets

* Create new 'sector_t' type alias:
    * uint64_t for all targets with HAVE_LBA48 or HAVE_SDUC
    * unsigned long for the everything else
 * Alter all storage APIs to use sector_t instead of 'unsigned long'
 * Alter Volume/Partition/storage info structures to use sector_t
 * Disk cache converted to sector_t
 * ATA Core:
    * convert to using sector_t for sector addresses and drive sizes
    * Always fill out upper 16 bits of LBA48 addresses
    * IDENTIFY INFO is fixed at 512 bytes, not SECTOR_SIZE
 * USB mass storage:
    * convert to using sector_t for sector addesses and drive sizes
    * Implement READ_16/WRITE_16 for LBA48 addresses
 * Convert FAT code to use sector_t for all sector references
 * output_dyn_value() now accepts int64_t instead of 'int'
 * Corrected "rockbox info" to work for (MULTIVOLUME & !MULTIDRIVE)
 * Better reporting of disk and (logical+physical) sector sizes in debug info
 * Detect SDUC cards and report on storage debug_info screen

To-do: SDUC

 * Refactor SD core to remove duplicate code in every driver
   * Card probe and init state machine
 * Implement core SDUC support
   * SD2.0 needs to be 2.0+ (fixed for jz47xx and x1000)
   * Host and Card ID (ACMD41)
   * 32-bit addressing for all read/write/erase operations (CMD22)
 * ADD SDUC to target device drivers, defining HAVE_SDUC as appropriate

Change-Id: Ib0138781a0081664d11511037685503df1b93608
This commit is contained in:
Solomon Peachy 2024-07-05 16:00:30 -04:00
parent 9ff308a589
commit 15e5237469
49 changed files with 629 additions and 435 deletions

View file

@ -557,14 +557,16 @@ static const char* dbg_partitions_getname(int selected_item, void *data,
if (!disk_partinfo(partition, &p)) if (!disk_partinfo(partition, &p))
return buffer; return buffer;
// XXX fix this up to use logical sector size
// XXX and if mounted, show free info...
if (selected_item%2) if (selected_item%2)
{ {
snprintf(buffer, buffer_len, " T:%x %ld MB", p.type, snprintf(buffer, buffer_len, " T:%x %llu MB", p.type,
p.size / ( 2048 / ( SECTOR_SIZE / 512 ))); (uint64_t)(p.size / ( 2048 / ( SECTOR_SIZE / 512 ))));
} }
else else
{ {
snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p.start); snprintf(buffer, buffer_len, "P%d: S:%llx", partition, (uint64_t)p.start);
} }
return buffer; return buffer;
} }
@ -572,7 +574,7 @@ static const char* dbg_partitions_getname(int selected_item, void *data,
static bool dbg_partitions(void) static bool dbg_partitions(void)
{ {
struct simplelist_info info; struct simplelist_info info;
simplelist_info_init(&info, "Partition Info", NUM_DRIVES * 4, NULL); simplelist_info_init(&info, "Partition Info", NUM_DRIVES * MAX_PARTITIONS_PER_DRIVE, NULL);
info.selection_size = 2; info.selection_size = 2;
info.scroll_all = true; info.scroll_all = true;
info.get_name = dbg_partitions_getname; info.get_name = dbg_partitions_getname;
@ -1343,6 +1345,22 @@ static int disk_callback(int btn, struct gui_synclist *lists)
"R2W: *%d", card->r2w_factor); "R2W: *%d", card->r2w_factor);
#if (CONFIG_STORAGE & STORAGE_SD) #if (CONFIG_STORAGE & STORAGE_SD)
int csd_structure = card_extract_bits(card->csd, 127, 2); int csd_structure = card_extract_bits(card->csd, 127, 2);
const char *ver;
switch(csd_structure) {
case 0:
ver = "1 (SD)";
break;
case 1:
ver = "2 (SDHC/SDXC)";
break;
case 2:
ver = "3 (SDUC)";
break;
default:
ver = "Unknown";
break;
}
simplelist_addline("SDVer: %s\n", ver);
if (csd_structure == 0) /* CSD version 1.0 */ if (csd_structure == 0) /* CSD version 1.0 */
#endif #endif
{ {
@ -1407,15 +1425,41 @@ static int disk_callback(int btn, struct gui_synclist *lists)
buf[8]=0; buf[8]=0;
simplelist_addline( simplelist_addline(
"Firmware: %s", buf); "Firmware: %s", buf);
snprintf(buf, sizeof buf, "%ld MB",
((unsigned long)identify_info[61] << 16 | uint64_t total_sectors = identify_info[60] | (identify_info[61] << 16);
(unsigned long)identify_info[60]) / 2048 ); #ifdef HAVE_LBA48
if (identify_info[83] & 0x0400
&& total_sectors == 0x0FFFFFFF)
total_sectors = identify_info[100] | (identify_info[101] << 16) | ((uint64_t)identify_info[102] << 32) | ((uint64_t)identify_info[103] << 48);
#endif
uint32_t sector_size;
/* Logical sector size > 512B ? */
if ((identify_info[106] & 0xd000) == 0x5000)
sector_size = identify_info[117] | (identify_info[118] << 16);
else
sector_size = SECTOR_SIZE;
total_sectors *= sector_size; /* Convert to bytes */
total_sectors /= (1024 * 1024); /* Convert to MB */
simplelist_addline("Size: %llu MB", total_sectors);
simplelist_addline("Logical sector size: %u B", sector_size);
if((identify_info[106] & 0xe000) == 0x6000)
sector_size *= BIT_N(identify_info[106] & 0x000f);
simplelist_addline( simplelist_addline(
"Size: %s", buf); "Physical sector size: %d B", sector_size);
unsigned long free;
#ifndef HAVE_MULTIVOLUME
// XXX this needs to be fixed for multi-volume setups
sector_t free;
volume_size( IF_MV(0,) NULL, &free ); volume_size( IF_MV(0,) NULL, &free );
simplelist_addline( simplelist_addline(
"Free: %ld MB", free / 1024); "Free: %llu MB", free / 1024);
#endif
simplelist_addline("SSD detected: %s", ata_disk_isssd() ? "yes" : "no"); simplelist_addline("SSD detected: %s", ata_disk_isssd() ? "yes" : "no");
simplelist_addline( simplelist_addline(
"Spinup time: %d ms", storage_spinup_time() * (1000/HZ)); "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
@ -1452,11 +1496,7 @@ static int disk_callback(int btn, struct gui_synclist *lists)
simplelist_addline( simplelist_addline(
"No timing info"); "No timing info");
} }
int sector_size = 512;
if((identify_info[106] & 0xe000) == 0x6000)
sector_size *= BIT_N(identify_info[106] & 0x000f);
simplelist_addline(
"Physical sector size: %d", sector_size);
#ifdef HAVE_ATA_DMA #ifdef HAVE_ATA_DMA
if (identify_info[63] & (1<<0)) { if (identify_info[63] & (1<<0)) {
simplelist_addline( simplelist_addline(
@ -1751,8 +1791,8 @@ static int disk_callback(int btn, struct gui_synclist *lists)
simplelist_addline("Model: %s", info.product); simplelist_addline("Model: %s", info.product);
simplelist_addline("Firmware: %s", info.revision); simplelist_addline("Firmware: %s", info.revision);
simplelist_addline( simplelist_addline(
"Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024); "Size: %lld MB", (uint64_t)(info.num_sectors*(info.sector_size/512)/2048));
unsigned long free; storage_t free;
volume_size( IF_MV(0,) NULL, &free ); volume_size( IF_MV(0,) NULL, &free );
simplelist_addline( simplelist_addline(
"Free: %ld MB", free / 1024); "Free: %ld MB", free / 1024);
@ -1771,13 +1811,13 @@ static bool dbg_identify_info(void)
const unsigned short *identify_info = ata_get_identify(); const unsigned short *identify_info = ata_get_identify();
#ifdef ROCKBOX_LITTLE_ENDIAN #ifdef ROCKBOX_LITTLE_ENDIAN
/* this is a pointer to a driver buffer so we can't modify it */ /* this is a pointer to a driver buffer so we can't modify it */
for (int i = 0; i < SECTOR_SIZE/2; ++i) for (int i = 0; i < ATA_IDENTIFY_WORDS; ++i)
{ {
unsigned short word = swap16(identify_info[i]); unsigned short word = swap16(identify_info[i]);
write(fd, &word, 2); write(fd, &word, 2);
} }
#else #else
write(fd, identify_info, SECTOR_SIZE); write(fd, identify_info, ATA_IDENTIFY_WORDS*2);
#endif #endif
close(fd); close(fd);
} }

View file

@ -134,8 +134,8 @@ static int show_legal(void)
struct info_data struct info_data
{ {
unsigned long size[NUM_VOLUMES]; sector_t size[NUM_VOLUMES];
unsigned long free[NUM_VOLUMES]; sector_t free[NUM_VOLUMES];
unsigned long name[NUM_VOLUMES]; unsigned long name[NUM_VOLUMES];
bool new_data; bool new_data;
}; };
@ -162,16 +162,19 @@ enum infoscreenorder
*/ */
static int refresh_data(struct info_data *info) static int refresh_data(struct info_data *info)
{ {
int i = 0; #ifdef HAVE_MULTIVOLUME
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
int drive;
int max = -1; int max = -1;
#endif
int drive = 0;
int i = 0;
for (i = 0 ; CHECK_VOL(i) ; i++) { for (i = 0 ; CHECK_VOL(i) ; i++) {
#endif #endif
volume_size(IF_MV(i,) &info->size[i], &info->free[i]); volume_size(IF_MV(i,) &info->size[i], &info->free[i]);
#ifdef HAVE_MULTIVOLUME
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
drive = volume_drive(i); drive = volume_drive(i);
#endif
if (drive > 0 || info->size[i] == 0) if (drive > 0 || info->size[i] == 0)
info->name[i] = LANG_DISK_NAME_MMC; info->name[i] = LANG_DISK_NAME_MMC;
else else
@ -182,9 +185,12 @@ static int refresh_data(struct info_data *info)
max = drive; max = drive;
else if (drive < max) else if (drive < max)
break; break;
#elif defined(HAVE_MULTIVOLUME)
if (volume_partition(i) == -1)
break;
#endif
#ifdef HAVE_MULTIVOLUME
} }
#else
i++;
#endif #endif
info->new_data = false; info->new_data = false;

View file

@ -139,7 +139,7 @@ const unsigned char * const unit_strings_core[] =
* voiced.*/ * voiced.*/
char *output_dyn_value(char *buf, char *output_dyn_value(char *buf,
int buf_size, int buf_size,
int value, int64_t value,
const unsigned char * const *units, const unsigned char * const *units,
unsigned int unit_count, unsigned int unit_count,
bool binary_scale) bool binary_scale)
@ -147,8 +147,9 @@ char *output_dyn_value(char *buf,
unsigned int scale = binary_scale ? 1024 : 1000; unsigned int scale = binary_scale ? 1024 : 1000;
unsigned int fraction = 0; unsigned int fraction = 0;
unsigned int unit_no = 0; unsigned int unit_no = 0;
unsigned int value_abs = (value < 0) ? -value : value; uint64_t value_abs = (value < 0) ? -value : value;
char tbuf[5]; char tbuf[5];
int value2;
while (value_abs >= scale && unit_no < (unit_count - 1)) while (value_abs >= scale && unit_no < (unit_count - 1))
{ {
@ -157,7 +158,7 @@ char *output_dyn_value(char *buf,
unit_no++; unit_no++;
} }
value = (value < 0) ? -value_abs : value_abs; /* preserve sign */ value2 = (value < 0) ? -value_abs : value_abs; /* preserve sign */
fraction = (fraction * 1000 / scale) / 10; fraction = (fraction * 1000 / scale) / 10;
if (value_abs >= 100 || fraction >= 100 || !unit_no) if (value_abs >= 100 || fraction >= 100 || !unit_no)
@ -170,10 +171,10 @@ char *output_dyn_value(char *buf,
if (buf) if (buf)
{ {
if (*tbuf) if (*tbuf)
snprintf(buf, buf_size, "%d%s%s%s", value, str(LANG_POINT), snprintf(buf, buf_size, "%d%s%s%s", value2, str(LANG_POINT),
tbuf, P2STR(units[unit_no])); tbuf, P2STR(units[unit_no]));
else else
snprintf(buf, buf_size, "%d%s", value, P2STR(units[unit_no])); snprintf(buf, buf_size, "%d%s", value2, P2STR(units[unit_no]));
} }
else else
{ {

View file

@ -22,6 +22,7 @@
#define MISC_H #define MISC_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include "config.h" #include "config.h"
#include "screen_access.h" #include "screen_access.h"
@ -36,7 +37,7 @@ extern const unsigned char * const unit_strings_core[];
* voiced.*/ * voiced.*/
char *output_dyn_value(char *buf, char *output_dyn_value(char *buf,
int buf_size, int buf_size,
int value, int64_t value,
const unsigned char * const *units, const unsigned char * const *units,
unsigned int unit_count, unsigned int unit_count,
bool binary_scale); bool binary_scale);

View file

@ -649,7 +649,7 @@ struct plugin_api {
int (*memcmp)(const void *s1, const void *s2, size_t n); int (*memcmp)(const void *s1, const void *s2, size_t n);
char *(*strcasestr) (const char* phaystack, const char* pneedle); char *(*strcasestr) (const char* phaystack, const char* pneedle);
char* (*strtok_r)(char *ptr, const char *sep, char **end); char* (*strtok_r)(char *ptr, const char *sep, char **end);
char* (*output_dyn_value)(char *buf, int buf_size, int value, char* (*output_dyn_value)(char *buf, int buf_size, int64_t value,
const unsigned char * const *units, const unsigned char * const *units,
unsigned int unit_count, bool binary_scale); unsigned int unit_count, bool binary_scale);
/* unicode stuff */ /* unicode stuff */

View file

@ -172,6 +172,8 @@ bool disk_init(IF_MD_NONVOID(int drive))
} }
} }
// XXX backup GPT header at final LBA of drive...
while (is_gpt) { while (is_gpt) {
/* Re-start partition parsing using GPT */ /* Re-start partition parsing using GPT */
uint64_t part_lba; uint64_t part_lba;
@ -243,20 +245,24 @@ reload:
goto skip; /* Any flag makes us ignore this */ goto skip; /* Any flag makes us ignore this */
} }
tmp = BYTES2INT64(pptr, 32); /* FIRST LBA */ tmp = BYTES2INT64(pptr, 32); /* FIRST LBA */
if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo! #ifndef STORAGE_64BIT_SECTOR
DEBUGF("GPT: partition starts after 2GiB mark\n"); if (tmp > UINT32_MAX) {
DEBUGF("GPT: partition starts after 2TiB mark\n");
goto skip; goto skip;
} }
#endif
if (tmp < 34) { if (tmp < 34) {
DEBUGF("GPT: Invalid start LBA\n"); DEBUGF("GPT: Invalid start LBA\n");
goto skip; goto skip;
} }
pinfo[part].start = tmp; pinfo[part].start = tmp;
tmp = BYTES2INT64(pptr, 40); /* LAST LBA */ tmp = BYTES2INT64(pptr, 40); /* LAST LBA */
if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo! #ifndef STORAGE_64BIT_SECTOR
DEBUGF("GPT: partition ends after 2GiB mark\n"); if (tmp > UINT32_MAX) {
DEBUGF("GPT: partition ends after 2TiB mark\n");
goto skip; goto skip;
} }
#endif
if (tmp <= pinfo[part].start) { if (tmp <= pinfo[part].start) {
DEBUGF("GPT: Invalid end LBA\n"); DEBUGF("GPT: Invalid end LBA\n");
goto skip; goto skip;
@ -264,7 +270,7 @@ reload:
pinfo[part].size = tmp - pinfo[part].start + 1; pinfo[part].size = tmp - pinfo[part].start + 1;
pinfo[part].type = PARTITION_TYPE_FAT32_LBA; pinfo[part].type = PARTITION_TYPE_FAT32_LBA;
DEBUGF("GPart%d: start: %08lx size: %08lx\n", DEBUGF("GPart%d: start: %016lx size: %016lx\n",
part,pinfo[part].start,pinfo[part].size); part,pinfo[part].start,pinfo[part].size);
part++; part++;
@ -499,13 +505,13 @@ unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume))
return clustersize; return clustersize;
} }
void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
{ {
disk_reader_lock(); disk_reader_lock();
if (!CHECK_VOL(volume) || !fat_size(IF_MV(volume,) sizep, freep)) if (!CHECK_VOL(volume) || !fat_size(IF_MV(volume,) sizep, freep))
{ {
if (freep) *sizep = 0; if (sizep) *sizep = 0;
if (freep) *freep = 0; if (freep) *freep = 0;
} }

View file

@ -71,12 +71,12 @@ struct disk_cache_entry
#ifdef HAVE_MULTIVOLUME #ifdef HAVE_MULTIVOLUME
unsigned char volume; /* volume of sector */ unsigned char volume; /* volume of sector */
#endif #endif
unsigned long sector; /* cached disk sector number */ sector_t sector; /* cached disk sector number */
}; };
BITARRAY_TYPE_DECLARE(cache_map_entry_t, cache_map, DC_NUM_ENTRIES) BITARRAY_TYPE_DECLARE(cache_map_entry_t, cache_map, DC_NUM_ENTRIES)
static inline unsigned int map_sector(unsigned long sector) static inline unsigned int map_sector(sector_t sector)
{ {
/* keep sector hash simple for now */ /* keep sector hash simple for now */
return sector % DC_MAP_NUM_ENTRIES; return sector % DC_MAP_NUM_ENTRIES;
@ -172,7 +172,7 @@ static inline void cache_discard_entry(struct disk_cache_entry *dce,
/* search the cache for the specified sector, returning a buffer, either /* search the cache for the specified sector, returning a buffer, either
to the specified sector, if it exists, or a new/evicted entry that must to the specified sector, if it exists, or a new/evicted entry that must
be filled */ be filled */
void * dc_cache_probe(IF_MV(int volume,) unsigned long sector, void * dc_cache_probe(IF_MV(int volume,) sector_t sector,
unsigned int *flagsp) unsigned int *flagsp)
{ {
unsigned int mapnum = map_sector(sector); unsigned int mapnum = map_sector(sector);
@ -200,7 +200,7 @@ void * dc_cache_probe(IF_MV(int volume,) unsigned long sector,
if (old_flags) if (old_flags)
{ {
int old_volume = IF_MV_VOL(dce->volume); int old_volume = IF_MV_VOL(dce->volume);
unsigned long sector = dce->sector; sector_t sector = dce->sector;
unsigned int old_mapnum = map_sector(sector); unsigned int old_mapnum = map_sector(sector);
if (old_flags & DCE_DIRTY) if (old_flags & DCE_DIRTY)

View file

@ -109,15 +109,15 @@ static long last_disk_activity = -1;
static long power_off_tick = 0; static long power_off_tick = 0;
#endif #endif
static unsigned long total_sectors; static sector_t total_sectors;
static int multisectors; /* number of supported multisectors */ static int multisectors; /* number of supported multisectors */
static unsigned short identify_info[SECTOR_SIZE/2]; static unsigned short identify_info[ATA_IDENTIFY_WORDS];
#ifdef MAX_PHYS_SECTOR_SIZE #ifdef MAX_PHYS_SECTOR_SIZE
struct sector_cache_entry { struct sector_cache_entry {
bool inuse; bool inuse;
unsigned long sectornum; /* logical sector */ sector_t sectornum; /* logical sector */
unsigned char data[MAX_PHYS_SECTOR_SIZE]; unsigned char data[MAX_PHYS_SECTOR_SIZE];
}; };
/* buffer for reading and writing large physical sectors */ /* buffer for reading and writing large physical sectors */
@ -381,7 +381,7 @@ static ICODE_ATTR void copy_write_sectors(const unsigned char* buf,
} }
#endif /* !ATA_OPTIMIZED_WRITING */ #endif /* !ATA_OPTIMIZED_WRITING */
static int ata_transfer_sectors(unsigned long start, static int ata_transfer_sectors(uint64_t start,
int incount, int incount,
void* inbuf, void* inbuf,
int write) int write)
@ -443,9 +443,9 @@ static int ata_transfer_sectors(unsigned long start,
ATA_OUT8(ATA_NSECTOR, count & 0xff); ATA_OUT8(ATA_NSECTOR, count & 0xff);
ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */ ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */ ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */
ATA_OUT8(ATA_LCYL, 0); /* 39:32 */ ATA_OUT8(ATA_LCYL, (start >> 32) & 0xff); /* 39:32 */
ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */ ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
ATA_OUT8(ATA_HCYL, 0); /* 47:40 */ ATA_OUT8(ATA_HCYL, (start >> 40) & 0xff); /* 47:40 */
ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */ ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device); ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device);
#ifdef HAVE_ATA_DMA #ifdef HAVE_ATA_DMA
@ -592,7 +592,7 @@ static int ata_transfer_sectors(unsigned long start,
#ifndef MAX_PHYS_SECTOR_SIZE #ifndef MAX_PHYS_SECTOR_SIZE
int ata_read_sectors(IF_MD(int drive,) int ata_read_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int incount, int incount,
void* inbuf) void* inbuf)
{ {
@ -607,7 +607,7 @@ int ata_read_sectors(IF_MD(int drive,)
} }
int ata_write_sectors(IF_MD(int drive,) int ata_write_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int count, int count,
const void* buf) const void* buf)
{ {
@ -623,7 +623,7 @@ int ata_write_sectors(IF_MD(int drive,)
#endif /* ndef MAX_PHYS_SECTOR_SIZE */ #endif /* ndef MAX_PHYS_SECTOR_SIZE */
#ifdef MAX_PHYS_SECTOR_SIZE #ifdef MAX_PHYS_SECTOR_SIZE
static int cache_sector(unsigned long sector) static int cache_sector(sector_t sector)
{ {
int rc; int rc;
@ -652,7 +652,7 @@ static inline int flush_current_sector(void)
} }
int ata_read_sectors(IF_MD(int drive,) int ata_read_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int incount, int incount,
void* inbuf) void* inbuf)
{ {
@ -718,7 +718,7 @@ int ata_read_sectors(IF_MD(int drive,)
} }
int ata_write_sectors(IF_MD(int drive,) int ata_write_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int count, int count,
const void* buf) const void* buf)
{ {
@ -916,7 +916,7 @@ static int identify(void)
return -2; return -2;
} }
for (i=0; i<SECTOR_SIZE/2; i++) { for (i=0; i<ATA_IDENTIFY_WORDS; i++) {
/* the IDENTIFY words are already swapped, so we need to treat /* the IDENTIFY words are already swapped, so we need to treat
this info differently that normal sector data */ this info differently that normal sector data */
identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA));
@ -1269,10 +1269,8 @@ int STORAGE_INIT_ATTR ata_init(void)
if (identify_info[83] & 0x0400 /* 48 bit address support */ if (identify_info[83] & 0x0400 /* 48 bit address support */
&& total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */ && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */
{ /* (needs BigLBA addressing) */ { /* (needs BigLBA addressing) */
if (identify_info[102] || identify_info[103]) total_sectors = identify_info[100] | (identify_info[101] << 16) | ((uint64_t)identify_info[102] << 32) | ((uint64_t)identify_info[103] << 48);
panicf("Unsupported disk size: >= 2^32 sectors");
total_sectors = identify_info[100] | (identify_info[101] << 16);
lba48 = true; /* use BigLBA */ lba48 = true; /* use BigLBA */
} }
#endif /* HAVE_LBA48 */ #endif /* HAVE_LBA48 */
@ -1360,7 +1358,13 @@ void ata_get_info(IF_MD(int drive,)struct storage_info *info)
(void)drive; /* unused for now */ (void)drive; /* unused for now */
#endif #endif
int i; int i;
/* Logical sector size */
if ((identify_info[106] & 0xd000) == 0x5000)
info->sector_size = identify_info[117] | (identify_info[118] << 16);
else
info->sector_size = SECTOR_SIZE; info->sector_size = SECTOR_SIZE;
info->num_sectors = total_sectors; info->num_sectors = total_sectors;
src = (unsigned short*)&identify_info[27]; src = (unsigned short*)&identify_info[27];

View file

@ -173,8 +173,8 @@ union raw_dirent
struct fsinfo struct fsinfo
{ {
unsigned long freecount; /* last known free cluster count */ sector_t freecount; /* last known free cluster count */
unsigned long nextfree; /* first cluster to start looking for free sector_t nextfree; /* first cluster to start looking for free
clusters, or 0xffffffff for no hint */ clusters, or 0xffffffff for no hint */
}; };
/* fsinfo offsets */ /* fsinfo offsets */
@ -233,7 +233,7 @@ static struct bpb
unsigned long totalsectors; unsigned long totalsectors;
unsigned long rootdirsector; unsigned long rootdirsector;
unsigned long firstdatasector; unsigned long firstdatasector;
unsigned long startsector; sector_t startsector;
unsigned long dataclusters; unsigned long dataclusters;
unsigned long fatrgnstart; unsigned long fatrgnstart;
unsigned long fatrgnend; unsigned long fatrgnend;
@ -241,7 +241,7 @@ static struct bpb
#ifdef HAVE_FAT16SUPPORT #ifdef HAVE_FAT16SUPPORT
unsigned int bpb_rootentcnt; /* Number of dir entries in the root */ unsigned int bpb_rootentcnt; /* Number of dir entries in the root */
/* internals for FAT16 support */ /* internals for FAT16 support */
unsigned long rootdirsectornum; /* sector offset of root dir relative to start sector_t rootdirsectornum; /* sector offset of root dir relative to start
* of first pseudo cluster */ * of first pseudo cluster */
#endif /* HAVE_FAT16SUPPORT */ #endif /* HAVE_FAT16SUPPORT */
@ -329,7 +329,7 @@ static void cache_discard(IF_MV_NONVOID(struct bpb *fat_bpb))
} }
/* caches a FAT or data area sector */ /* caches a FAT or data area sector */
static void * cache_sector(struct bpb *fat_bpb, unsigned long secnum) static void * cache_sector(struct bpb *fat_bpb, sector_t secnum)
{ {
unsigned int flags; unsigned int flags;
void *buf = dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags); 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)
secnum + fat_bpb->startsector, 1, buf); secnum + fat_bpb->startsector, 1, buf);
if (UNLIKELY(rc < 0)) if (UNLIKELY(rc < 0))
{ {
DEBUGF("%s() - Could not read sector %ld" DEBUGF("%s() - Could not read sector %llu"
" (error %d)\n", __func__, secnum, rc); " (error %d)\n", __func__, (uint64_t)secnum, rc);
dc_discard_buf(buf); dc_discard_buf(buf);
return NULL; return NULL;
} }
@ -354,14 +354,14 @@ static void * cache_sector(struct bpb *fat_bpb, unsigned long secnum)
* contents are NOT loaded before returning - use when completely overwriting * contents are NOT loaded before returning - use when completely overwriting
* a sector's contents in order to avoid a fill */ * a sector's contents in order to avoid a fill */
static void * cache_sector_buffer(IF_MV(struct bpb *fat_bpb,) static void * cache_sector_buffer(IF_MV(struct bpb *fat_bpb,)
unsigned long secnum) sector_t secnum)
{ {
unsigned int flags; unsigned int flags;
return dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags); return dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags);
} }
/* flush a cache buffer to storage */ /* flush a cache buffer to storage */
void dc_writeback_callback(IF_MV(int volume,) unsigned long sector, void *buf) void dc_writeback_callback(IF_MV(int volume,) sector_t sector, void *buf)
{ {
struct bpb * const fat_bpb = &fat_bpbs[IF_MV_VOL(volume)]; struct bpb * const fat_bpb = &fat_bpbs[IF_MV_VOL(volume)];
unsigned int copies = !IS_FAT_SECTOR(fat_bpb, sector) ? 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)
int rc = storage_write_sectors(IF_MD(fat_bpb->drive,) sector, 1, buf); int rc = storage_write_sectors(IF_MD(fat_bpb->drive,) sector, 1, buf);
if (rc < 0) if (rc < 0)
{ {
panicf("%s() - Could not write sector %ld" panicf("%s() - Could not write sector %llu"
" (error %d)\n", __func__, sector, rc); " (error %d)\n", __func__, (uint64_t)sector, rc);
} }
if (--copies == 0) if (--copies == 0)
@ -2397,12 +2397,12 @@ unsigned long fat_query_sectornum(const struct fat_filestr *filestr)
} }
/* helper for fat_readwrite */ /* helper for fat_readwrite */
static long transfer(struct bpb *fat_bpb, unsigned long start, long count, static long transfer(struct bpb *fat_bpb, sector_t start, long count,
char *buf, bool write) char *buf, bool write)
{ {
long rc = 0; long rc = 0;
DEBUGF("%s(s=%lx, c=%lx, wr=%u)\n", __func__, DEBUGF("%s(s=%llx, c=%lx, wr=%u)\n", __func__,
start + fat_bpb->startsector, count, write ? 1 : 0); start + fat_bpb->startsector, count, write ? 1 : 0);
if (write) if (write)
@ -2416,12 +2416,12 @@ static long transfer(struct bpb *fat_bpb, unsigned long start, long count,
firstallowed = fat_bpb->firstdatasector; firstallowed = fat_bpb->firstdatasector;
if (start < firstallowed) if (start < firstallowed)
panicf("Write %ld before data\n", firstallowed - start); panicf("Write %llu before data\n", (uint64_t)(firstallowed - start));
if (start + count > fat_bpb->totalsectors) if (start + count > fat_bpb->totalsectors)
{ {
panicf("Write %ld after data\n", panicf("Write %llu after data\n",
start + count - fat_bpb->totalsectors); (uint64_t)(start + count - fat_bpb->totalsectors));
} }
} }
@ -2487,14 +2487,14 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
long rc; long rc;
long cluster = filestr->lastcluster; long cluster = filestr->lastcluster;
unsigned long sector = filestr->lastsector; sector_t sector = filestr->lastsector;
long clusternum = filestr->clusternum; long clusternum = filestr->clusternum;
unsigned long sectornum = filestr->sectornum; unsigned long sectornum = filestr->sectornum;
DEBUGF("%s(file:%lx,count:0x%lx,buf:%lx,%s)\n", __func__, DEBUGF("%s(file:%lx,count:0x%lx,buf:%lx,%s)\n", __func__,
file->firstcluster, sectorcount, (long)buf, file->firstcluster, sectorcount, (long)buf,
write ? "write":"read"); write ? "write":"read");
DEBUGF("%s: sec:%lx numsec:%ld eof:%d\n", __func__, DEBUGF("%s: sec:%llx numsec:%ld eof:%d\n", __func__,
sector, (long)sectornum, eof ? 1 : 0); sector, (long)sectornum, eof ? 1 : 0);
eof = false; eof = false;
@ -2534,7 +2534,7 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
unsigned long transferred = 0; unsigned long transferred = 0;
unsigned long count = 0; unsigned long count = 0;
unsigned long last = sector; sector_t last = sector;
while (transferred + count < sectorcount) while (transferred + count < sectorcount)
{ {
@ -2961,7 +2961,7 @@ void fat_recalc_free(IF_MV_NONVOID(int volume))
dc_unlock_cache(); dc_unlock_cache();
} }
bool fat_size(IF_MV(int volume,) unsigned long *size, unsigned long *free) bool fat_size(IF_MV(int volume,) sector_t *size, sector_t *free)
{ {
struct bpb * const fat_bpb = FAT_BPB(volume); struct bpb * const fat_bpb = FAT_BPB(volume);
if (!fat_bpb) if (!fat_bpb)

View file

@ -32,7 +32,7 @@ static unsigned char ramdisk[SECTOR_SIZE * NUM_SECTORS];
static long last_disk_activity = -1; static long last_disk_activity = -1;
int ramdisk_read_sectors(IF_MD(int drive,) int ramdisk_read_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int count, int count,
void* buf) void* buf)
{ {
@ -48,7 +48,7 @@ int ramdisk_read_sectors(IF_MD(int drive,)
} }
int ramdisk_write_sectors(IF_MD(int drive,) int ramdisk_write_sectors(IF_MD(int drive,)
unsigned long start, sector_t start,
int count, int count,
const void* buf) const void* buf)
{ {

View file

@ -49,6 +49,13 @@ void sd_parse_csd(tCardInfo *card)
c_size = card_extract_bits(card->csd, 69, 22) + 1; c_size = card_extract_bits(card->csd, 69, 22) + 1;
card->numblocks = c_size << 10; card->numblocks = c_size << 10;
} }
else if(csd_version == 2)
{
/* CSD version 3.0 */
c_size = card_extract_bits(card->csd, 75, 28) + 1;
card->numblocks = c_size << 10;
}
card->sd2plus = csd_version >= 1;
card->blocksize = 512; /* Always use 512 byte blocks */ card->blocksize = 512; /* Always use 512 byte blocks */
@ -62,7 +69,9 @@ void sd_parse_csd(tCardInfo *card)
card->r2w_factor = card_extract_bits(card->csd, 28, 3); card->r2w_factor = card_extract_bits(card->csd, 28, 3);
logf("CSD%d.0 numblocks:%ld speed:%ld", csd_version+1, card->numblocks, card->speed);
logf("CSD%d.0 numblocks:%lld speed:%ld", csd_version+1, card->numblocks, card->speed);
logf("nsac: %d taac: %ld r2w: %d", card->nsac, card->taac, card->r2w_factor); logf("nsac: %d taac: %ld r2w: %d", card->nsac, card->taac, card->r2w_factor);
} }
@ -99,4 +108,3 @@ void sd_get_info(IF_MD(int drive,) struct storage_info *info)
info->revision="0.00"; info->revision="0.00";
} }
#endif #endif

View file

@ -140,8 +140,8 @@ bool ata_disk_is_active(void);
int ata_soft_reset(void); int ata_soft_reset(void);
int ata_init(void) STORAGE_INIT_ATTR; int ata_init(void) STORAGE_INIT_ATTR;
void ata_close(void); void ata_close(void);
int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
void ata_spin(void); void ata_spin(void);
#if (CONFIG_LED == LED_REAL) #if (CONFIG_LED == LED_REAL)
void ata_set_led_enabled(bool enabled); void ata_set_led_enabled(bool enabled);
@ -233,4 +233,6 @@ int ata_read_smart(struct ata_smart_values*);
#define STORAGE_CLOSE #define STORAGE_CLOSE
#endif #endif
#define ATA_IDENTIFY_WORDS 256
#endif /* __ATA_H__ */ #endif /* __ATA_H__ */

View file

@ -26,8 +26,8 @@
struct partinfo struct partinfo
{ {
unsigned long start; /* first sector (LBA) */ sector_t start; /* first sector (LBA) */
unsigned long size; /* number of sectors */ sector_t size; /* number of sectors */
unsigned char type; unsigned char type;
}; };

View file

@ -115,7 +115,7 @@ struct fat_filestr
{ {
struct fat_file *fatfilep; /* common file information */ struct fat_file *fatfilep; /* common file information */
long lastcluster; /* cluster of last access */ long lastcluster; /* cluster of last access */
unsigned long lastsector; /* sector of last access */ sector_t lastsector; /* sector of last access */
long clusternum; /* cluster number of last access */ long clusternum; /* cluster number of last access */
unsigned long sectornum; /* sector number within current cluster */ unsigned long sectornum; /* sector number within current cluster */
bool eof; /* end-of-file reached */ bool eof; /* end-of-file reached */
@ -173,7 +173,7 @@ int fat_get_bytes_per_sector(IF_MV_NONVOID(int volume));
#endif /* MAX_LOG_SECTOR_SIZE */ #endif /* MAX_LOG_SECTOR_SIZE */
unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume));
void fat_recalc_free(IF_MV_NONVOID(int volume)); void fat_recalc_free(IF_MV_NONVOID(int volume));
bool fat_size(IF_MV(int volume,) unsigned long *size, unsigned long *free); bool fat_size(IF_MV(int volume,) sector_t *size, sector_t *free);
/** Misc. **/ /** Misc. **/
void fat_empty_fat_direntry(struct fat_direntry *entry); void fat_empty_fat_direntry(struct fat_direntry *entry);

View file

@ -36,8 +36,8 @@ bool mmc_disk_is_active(void);
int mmc_soft_reset(void); int mmc_soft_reset(void);
int mmc_init(void) STORAGE_INIT_ATTR; int mmc_init(void) STORAGE_INIT_ATTR;
void mmc_close(void); void mmc_close(void);
int mmc_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int mmc_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int mmc_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int mmc_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
void mmc_spin(void); void mmc_spin(void);
int mmc_spinup_time(void); int mmc_spinup_time(void);

View file

@ -23,6 +23,7 @@
#define __MV_H__ #define __MV_H__
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include "config.h" #include "config.h"
/* FixMe: These macros are a bit nasty and perhaps misplaced here. /* FixMe: These macros are a bit nasty and perhaps misplaced here.
@ -40,6 +41,19 @@
#define IF_MD_DRV(d) 0 #define IF_MD_DRV(d) 0
#endif /* HAVE_MULTIDRIVE */ #endif /* HAVE_MULTIDRIVE */
/* Storage size */
#if (CONFIG_STORAGE & STORAGE_ATA) && defined(HAVE_LBA48)
typedef uint64_t sector_t;
#define STORAGE_64BIT_SECTOR
#elif (CONFIG_STORAGE & STORAGE_SD) && defined(HAVE_SDUC)
typedef uint64_t sector_t;
#define STORAGE_64BIT_SECTOR
#else
typedef unsigned long sector_t;
#undef STORAGE_64BIT_SECTOR
#endif
/* Volumes mean things that have filesystems on them, like partitions */ /* Volumes mean things that have filesystems on them, like partitions */
#ifdef HAVE_MULTIVOLUME #ifdef HAVE_MULTIVOLUME
#define IF_MV(x...) x /* valist contents or empty */ #define IF_MV(x...) x /* valist contents or empty */
@ -113,7 +127,7 @@ struct volumeinfo
/* Volume-centric functions (in disk.c) */ /* Volume-centric functions (in disk.c) */
void volume_recalc_free(IF_MV_NONVOID(int volume)); void volume_recalc_free(IF_MV_NONVOID(int volume));
unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume)); unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume));
void volume_size(IF_MV(int volume,) unsigned long *size, unsigned long *free); void volume_size(IF_MV(int volume,) sector_t *size, sector_t *free);
#ifdef HAVE_DIRCACHE #ifdef HAVE_DIRCACHE
bool volume_ismounted(IF_MV_NONVOID(int volume)); bool volume_ismounted(IF_MV_NONVOID(int volume));
#endif #endif

View file

@ -36,8 +36,8 @@ bool nand_disk_is_active(void);
int nand_soft_reset(void); int nand_soft_reset(void);
int nand_init(void) STORAGE_INIT_ATTR; int nand_init(void) STORAGE_INIT_ATTR;
void nand_close(void); void nand_close(void);
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
#ifdef HAVE_STORAGE_FLUSH #ifdef HAVE_STORAGE_FLUSH
int nand_flush(void); int nand_flush(void);
#endif #endif

View file

@ -35,8 +35,8 @@ bool ramdisk_disk_is_active(void);
int ramdisk_soft_reset(void); int ramdisk_soft_reset(void);
int ramdisk_init(void) STORAGE_INIT_ATTR; int ramdisk_init(void) STORAGE_INIT_ATTR;
void ramdisk_close(void); void ramdisk_close(void);
int ramdisk_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int ramdisk_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int ramdisk_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int ramdisk_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
void ramdisk_spin(void); void ramdisk_spin(void);
void ramdisk_sleepnow(void); void ramdisk_sleepnow(void);
int ramdisk_spinup_time(void); int ramdisk_spinup_time(void);

View file

@ -42,8 +42,8 @@ bool sd_disk_is_active(void);
int sd_soft_reset(void); int sd_soft_reset(void);
int sd_init(void) STORAGE_INIT_ATTR; int sd_init(void) STORAGE_INIT_ATTR;
void sd_close(void); void sd_close(void);
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
void sd_spin(void); void sd_spin(void);
int sd_spinup_time(void); /* ticks */ int sd_spinup_time(void); /* ticks */
@ -93,6 +93,7 @@ int sd_num_drives(int first_drive);
#define SD_READ_SINGLE_BLOCK 17 #define SD_READ_SINGLE_BLOCK 17
#define SD_READ_MULTIPLE_BLOCK 18 #define SD_READ_MULTIPLE_BLOCK 18
#define SD_SEND_NUM_WR_BLOCKS 22 /* acmd22 */ #define SD_SEND_NUM_WR_BLOCKS 22 /* acmd22 */
#define SD_UC_ADDRESS_EXTENSION 22
#define SD_SET_WR_BLK_ERASE_COUNT 23 /* acmd23 */ #define SD_SET_WR_BLK_ERASE_COUNT 23 /* acmd23 */
#define SD_WRITE_BLOCK 24 #define SD_WRITE_BLOCK 24
#define SD_WRITE_MULTIPLE_BLOCK 25 #define SD_WRITE_MULTIPLE_BLOCK 25

View file

@ -22,6 +22,8 @@
#define __SDMMC_H__ #define __SDMMC_H__
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <mv.h> /* for sector_t */
typedef struct typedef struct
{ {
@ -37,7 +39,7 @@ typedef struct
unsigned int nsac; /* clock cycles */ unsigned int nsac; /* clock cycles */
unsigned long taac; /* n * 0.1 ns */ unsigned long taac; /* n * 0.1 ns */
unsigned int r2w_factor; unsigned int r2w_factor;
unsigned long numblocks; /* size in flash blocks */ sector_t numblocks; /* size in flash blocks */
unsigned int blocksize; /* block size in bytes */ unsigned int blocksize; /* block size in bytes */
unsigned long rca; /* RCA register */ unsigned long rca; /* RCA register */
@ -48,6 +50,8 @@ typedef struct
#if (CONFIG_STORAGE & STORAGE_SD) #if (CONFIG_STORAGE & STORAGE_SD)
unsigned int current_bank; unsigned int current_bank;
#endif #endif
unsigned int sd2plus; /* SD 2.0 or better */
} tCardInfo; } tCardInfo;
#if (CONFIG_STORAGE & STORAGE_SD) #if (CONFIG_STORAGE & STORAGE_SD)

View file

@ -107,7 +107,7 @@ int ramdisk_event(long id, intptr_t data);
struct storage_info struct storage_info
{ {
unsigned int sector_size; unsigned int sector_size;
unsigned int num_sectors; sector_t num_sectors;
char *vendor; char *vendor;
char *product; char *product;
char *revision; char *revision;
@ -318,6 +318,6 @@ int storage_driver_type(int drive);
#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/ #endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/
int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); int storage_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); int storage_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
#endif #endif

View file

@ -36,7 +36,7 @@ static inline void dc_unlock_cache(void)
mutex_unlock(&disk_cache_mutex); mutex_unlock(&disk_cache_mutex);
} }
void * dc_cache_probe(IF_MV(int volume,) unsigned long secnum, void * dc_cache_probe(IF_MV(int volume,) sector_t secnum,
unsigned int *flags); unsigned int *flags);
void dc_dirty_buf(void *buf); void dc_dirty_buf(void *buf);
void dc_discard_buf(void *buf); void dc_discard_buf(void *buf);
@ -46,7 +46,7 @@ void dc_discard_all(IF_MV_NONVOID(int volume));
void dc_init(void) INIT_ATTR; void dc_init(void) INIT_ATTR;
/* in addition to filling, writeback is implemented by the client */ /* in addition to filling, writeback is implemented by the client */
extern void dc_writeback_callback(IF_MV(int volume, ) unsigned long sector, extern void dc_writeback_callback(IF_MV(int volume, ) sector_t sector,
void *buf); void *buf);

View file

@ -343,7 +343,7 @@ int storage_init(void)
return rc; return rc;
} }
int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count, int storage_read_sectors(IF_MD(int drive,) sector_t start, int count,
void* buf) void* buf)
{ {
#ifdef CONFIG_STORAGE_MULTI #ifdef CONFIG_STORAGE_MULTI
@ -385,7 +385,7 @@ int storage_read_sectors(IF_MD(int drive,) unsigned long start, int count,
} }
int storage_write_sectors(IF_MD(int drive,) unsigned long start, int count, int storage_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* buf) const void* buf)
{ {
#ifdef CONFIG_STORAGE_MULTI #ifdef CONFIG_STORAGE_MULTI

View file

@ -446,7 +446,7 @@ static int sd_init_card(const int drive)
sd_parse_csd(&card_info[drive]); sd_parse_csd(&card_info[drive]);
#if defined(HAVE_MULTIDRIVE) #if defined(HAVE_MULTIDRIVE)
hs_card = (card_info[drive].speed == 50000000); hs_card = (card_info[drive].speed >= 50000000);
#endif #endif
/* Boost MCICLK to operating speed */ /* Boost MCICLK to operating speed */
@ -680,7 +680,7 @@ static int sd_select_bank(signed char bank)
return 0; return 0;
} }
static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
int count, void* buf, const bool write) int count, void* buf, const bool write)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
@ -735,7 +735,8 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */
void *dma_buf; void *dma_buf;
unsigned long bank_start = start; sector_t bank_start = start;
// XXX 64-bit sectors?
/* Only switch banks for internal storage */ /* Only switch banks for internal storage */
if(drive == INTERNAL_AS3525) if(drive == INTERNAL_AS3525)
@ -869,7 +870,7 @@ sd_transfer_error_nodma:
return ret; return ret;
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
void* buf) void* buf)
{ {
int ret; int ret;
@ -881,11 +882,11 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
return ret; return ret;
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* buf) const void* buf)
{ {
#ifdef VERIFY_WRITE #ifdef VERIFY_WRITE
unsigned long saved_start = start; sector_t saved_start = start;
int saved_count = count; int saved_count = count;
void *saved_buf = (void*)buf; void *saved_buf = (void*)buf;
#endif #endif

View file

@ -677,7 +677,7 @@ int sd_init(void)
return 0; return 0;
} }
static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
int count, void* buf, bool write) int count, void* buf, bool write)
{ {
unsigned long response; unsigned long response;
@ -776,7 +776,7 @@ retry_with_reinit:
MCI_BYTCNT = transfer * SD_BLOCK_SIZE; MCI_BYTCNT = transfer * SD_BLOCK_SIZE;
int arg = start; sector_t arg = start; // XXX 64-bit
if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
arg *= SD_BLOCK_SIZE; arg *= SD_BLOCK_SIZE;
@ -858,13 +858,13 @@ exit:
return ret; return ret;
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
void* buf) void* buf)
{ {
return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* buf) const void* buf)
{ {
return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);

View file

@ -801,7 +801,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
} }
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
@ -817,7 +817,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
while (incount > 0) while (incount > 0)
{ {
int done = 0; int done = 0;
int segment = start / sectors_per_segment; sector_t segment = start / sectors_per_segment;
int secmod = start % sectors_per_segment; int secmod = start % sectors_per_segment;
while (incount > 0 && secmod < sectors_per_segment) while (incount > 0 && secmod < sectors_per_segment)
@ -856,7 +856,7 @@ nand_read_error:
return ret; return ret;
} }
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE

View file

@ -36,13 +36,13 @@ int nand_init(void)
{ {
return -1; return -1;
} }
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, int nand_read_sectors(IF_MD(int drive,) sector_t start, int count,
void* buf) void* buf)
{ {
return -1; return -1;
} }
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* buf) const void* buf)
{ {
return -1; return -1;

View file

@ -71,7 +71,7 @@ static const char *creative_part_name(enum imx233_part_t part)
} }
static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
enum imx233_part_t part, unsigned *start, unsigned *end) enum imx233_part_t part, sector_t *start, unsigned *end)
{ {
uint8_t mblk[512]; uint8_t mblk[512];
int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk); int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk);

View file

@ -45,7 +45,7 @@ enum imx233_part_t
/** The computation function can be called very early in the boot, at which point /** The computation function can be called very early in the boot, at which point
* usual storage read/write function may not be available. To workaround this * usual storage read/write function may not be available. To workaround this
* issue, one must provide a read function. */ * issue, one must provide a read function. */
typedef int (*part_read_fn_t)(intptr_t user, unsigned long start, int count, void* buf); typedef int (*part_read_fn_t)(intptr_t user, sector_t start, int count, void* buf);
/* Enable/Disable window computations for internal storage following the /* Enable/Disable window computations for internal storage following the
* Freescale/Creative convention */ * Freescale/Creative convention */
void imx233_partitions_enable_window(bool enable); void imx233_partitions_enable_window(bool enable);
@ -55,6 +55,6 @@ bool imx233_partitions_is_window_enabled(void);
* for a whole disk, *end should be the size of the disk when the function is * for a whole disk, *end should be the size of the disk when the function is
* called */ * called */
int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
enum imx233_part_t part, unsigned *start, unsigned *end); enum imx233_part_t part, sector_t *start, unsigned *end);
#endif /* __PARTITIONS_IMX233__ */ #endif /* __PARTITIONS_IMX233__ */

View file

@ -648,7 +648,7 @@ int mmc_event(long id, intptr_t data)
#endif /* CONFIG_STORAGE & STORAGE_MMC */ #endif /* CONFIG_STORAGE & STORAGE_MMC */
/* low-level function, don't call directly! */ /* low-level function, don't call directly! */
static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) static int __xfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
{ {
uint32_t resp; uint32_t resp;
int ret = 0; int ret = 0;
@ -660,7 +660,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
need_stop = false; need_stop = false;
/* Set bank_start to the correct unit (blocks or bytes). /* Set bank_start to the correct unit (blocks or bytes).
* MMC drives use block addressing, SD cards bytes or blocks */ * MMC drives use block addressing, SD cards bytes or blocks */
int bank_start = start; sector_t bank_start = start;
if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */ if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */
bank_start *= SD_BLOCK_SIZE; bank_start *= SD_BLOCK_SIZE;
/* issue read/write /* issue read/write
@ -686,7 +686,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
return ret; return ret;
} }
static int transfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) static int transfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
{ {
int ret = 0; int ret = 0;
/* the function doesn't work when count is 0 */ /* 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
} }
/* user specifies the sdmmc drive */ /* user specifies the sdmmc drive */
static int part_read_fn(intptr_t user, unsigned long start, int count, void* buf) static int part_read_fn(intptr_t user, sector_t start, int count, void* buf)
{ {
return transfer_sectors(user, start, count, buf, true); return transfer_sectors(user, start, count, buf, true);
} }
@ -917,7 +917,7 @@ void sd_enable(bool on)
(void) on; (void) on;
} }
int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *buf) int sd_read_sectors(IF_MD(int sd_drive,) sector_t start, int count, void *buf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
int sd_drive = 0; int sd_drive = 0;
@ -925,7 +925,7 @@ int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *b
return transfer_sectors(sd_map[sd_drive], start, count, buf, true); return transfer_sectors(sd_map[sd_drive], start, count, buf, true);
} }
int sd_write_sectors(IF_MD(int sd_drive,) unsigned long start, int count, const void* buf) int sd_write_sectors(IF_MD(int sd_drive,) sector_t start, int count, const void* buf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
int sd_drive = 0; int sd_drive = 0;
@ -1039,7 +1039,7 @@ int mmc_spinup_time(void)
return 0; return 0;
} }
int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void *buf) int mmc_read_sectors(IF_MD(int mmc_drive,) sector_t start, int count, void *buf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
int mmc_drive = 0; int mmc_drive = 0;
@ -1047,7 +1047,7 @@ int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void
return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true); return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true);
} }
int mmc_write_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, const void* buf) int mmc_write_sectors(IF_MD(int mmc_drive,) sector_t start, int count, const void* buf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
int mmc_drive = 0; int mmc_drive = 0;

View file

@ -849,7 +849,7 @@ static void sd_select_device(int card_no)
/* API Functions */ /* API Functions */
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount, int sd_read_sectors(IF_MD(int drive,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
@ -857,7 +857,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
#endif #endif
int ret; int ret;
unsigned char *buf, *buf_end; unsigned char *buf, *buf_end;
unsigned int bank; sector_t bank;
/* TODO: Add DMA support. */ /* TODO: Add DMA support. */
@ -904,6 +904,8 @@ sd_read_retry:
MMC_NUMBLK = incount; MMC_NUMBLK = incount;
// XXX 64-bit addresses..
#ifdef HAVE_HOTSWAP #ifdef HAVE_HOTSWAP
if(currcard->ocr & (1<<30) ) if(currcard->ocr & (1<<30) )
{ {
@ -966,7 +968,7 @@ sd_read_error:
} }
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
/* Write support is not finished yet */ /* Write support is not finished yet */

View file

@ -35,14 +35,14 @@
static bool initialized = false; static bool initialized = false;
/* API Functions */ /* API Functions */
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
(void)drive; (void)drive;
return ftl_read(start, incount, inbuf); return ftl_read(start, incount, inbuf);
} }
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
(void)drive; (void)drive;

View file

@ -453,7 +453,7 @@ static inline void write_sd_data(unsigned char **src)
*src += 512; *src += 512;
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
void* buf) void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
@ -498,6 +498,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
DATA_XFER_MULTI; DATA_XFER_MULTI;
} }
// XXX 64-bit
/* issue read command to the card */ /* issue read command to the card */
if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
{ {
@ -576,7 +578,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
} }
/* Not tested */ /* Not tested */
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* buf) const void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
@ -620,6 +622,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
write_sd_data(&src); /* put data into transfer buffer */ write_sd_data(&src); /* put data into transfer buffer */
// XXX 64-bit
if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
{ {
ret = -3; ret = -3;

View file

@ -596,7 +596,7 @@ static int sd_wait_for_state(const int card_no, unsigned int state)
} }
} }
static int sd_transfer_sectors(int card_no, unsigned long start, static int sd_transfer_sectors(int card_no, sector_t start,
int count, void* buf, const bool write) int count, void* buf, const bool write)
{ {
int ret = EC_OK; int ret = EC_OK;
@ -636,7 +636,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
void *dma_buf; void *dma_buf;
const int cmd = const int cmd =
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
unsigned long start_addr = start; sector_t start_addr = start;
dma_buf = aligned_buffer; dma_buf = aligned_buffer;
if(transfer > UNALIGNED_NUM_SECTORS) if(transfer > UNALIGNED_NUM_SECTORS)
@ -665,6 +665,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
INTPND = SDI_MASK; INTPND = SDI_MASK;
/* Initiate read/write command */ /* Initiate read/write command */
// XXX 64-bit
if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL)) if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL))
{ {
ret -= 3*20; ret -= 3*20;
@ -783,7 +784,7 @@ sd_transfer_error:
return ret; return ret;
} }
int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
int ret; int ret;
@ -804,7 +805,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
} }
/*****************************************************************************/ /*****************************************************************************/
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
#ifdef BOOTLOADER /* we don't need write support in bootloader */ #ifdef BOOTLOADER /* we don't need write support in bootloader */

View file

@ -33,13 +33,13 @@
static bool initialized = false; static bool initialized = false;
/* API Functions */ /* API Functions */
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
return ftl_read(start, incount, inbuf); return ftl_read(start, incount, inbuf);
} }
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
return ftl_write(start, count, outbuf); return ftl_write(start, count, outbuf);

View file

@ -58,10 +58,9 @@
#define CEATA_DAT_NONBUSY_TIMEOUT 5000000 #define CEATA_DAT_NONBUSY_TIMEOUT 5000000
#define CEATA_MMC_RCA 1 #define CEATA_MMC_RCA 1
/** static, private data **/ /** static, private data **/
static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; static uint16_t ata_identify_data[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR;
static bool ceata; static bool ceata;
static bool ata_lba48; static bool ata_lba48;
static bool ata_dma; static bool ata_dma;
@ -510,7 +509,7 @@ static int ata_identify(uint16_t* buf)
ata_write_cbr(&ATA_PIO_DVR, 0); ata_write_cbr(&ATA_PIO_DVR, 0);
ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY);
PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); for (i = 0; i < ATA_IDENTIFY_WORDS; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR);
} }
return 0; return 0;
} }
@ -701,7 +700,7 @@ static int ata_power_up(void)
| (((uint64_t)ata_identify_data[103]) << 48); | (((uint64_t)ata_identify_data[103]) << 48);
else else
ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
ata_total_sectors >>= 3; ata_total_sectors >>= 3; /* ie SECTOR_SIZE/512. */
ata_powered = true; ata_powered = true;
ata_set_active(); ata_set_active();
return 0; return 0;
@ -966,7 +965,7 @@ static int ata_reset(void)
return rc; return rc;
} }
int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount, int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
mutex_lock(&ata_mutex); mutex_lock(&ata_mutex);
@ -975,7 +974,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
return rc; return rc;
} }
int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, int ata_write_sectors(IF_MD(int drive,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
mutex_lock(&ata_mutex); mutex_lock(&ata_mutex);

View file

@ -386,7 +386,7 @@ static void sd_select_device(int card_no)
} }
} }
int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
@ -433,6 +433,7 @@ sd_read_retry:
SDIDCTRL2 = (1<<2); /* multi block, read */ SDIDCTRL2 = (1<<2); /* multi block, read */
// XXX 64-bit
if (currcard->ocr & (1<<30)) if (currcard->ocr & (1<<30))
ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
else else
@ -500,7 +501,7 @@ sd_read_error:
} }
} }
int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
/* Write support is not finished yet */ /* Write support is not finished yet */
@ -553,6 +554,7 @@ sd_write_retry:
SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */ SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */
// XXX 64-bit
if (currcard->ocr & (1<<30)) if (currcard->ocr & (1<<30))
ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
else else

View file

@ -126,8 +126,10 @@ void GIO2(void)
#define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */ #define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */
extern int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); extern int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
extern int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); extern int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
// XXX 64-bit: Due to this it's not likely that this target will ever handle 64-bit storage.
struct main_header struct main_header
{ {
@ -384,19 +386,19 @@ static void cfs_init(void)
cfs_inited = true; cfs_inited = true;
} }
static inline unsigned long map_sector(unsigned long sector) static inline sector_t map_sector(sector_t sector)
{ {
/* /*
* Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part
* FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes. * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes.
*/ */
#ifndef BOOTLOADER #ifndef BOOTLOADER
unsigned long *sectors = core_get_data(sectors_handle); sector_t *sectors = core_get_data(sectors_handle);
#endif #endif
return cfs_start+sectors[sector/64]*64+sector%64; return cfs_start+sectors[sector/64]*64+sector%64;
} }
int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
{ {
if(!cfs_inited) if(!cfs_inited)
cfs_init(); cfs_init();
@ -423,7 +425,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf
} }
} }
int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
{ {
if(!cfs_inited) if(!cfs_inited)
cfs_init(); cfs_init();

View file

@ -36,8 +36,8 @@
/* Nasty hack, but Creative is nasty... */ /* Nasty hack, but Creative is nasty... */
#define ata_read_sectors _ata_read_sectors #define ata_read_sectors _ata_read_sectors
#define ata_write_sectors _ata_write_sectors #define ata_write_sectors _ata_write_sectors
extern int _ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); extern int _ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
extern int _ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); extern int _ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
/* General purpose memory region #1 */ /* General purpose memory region #1 */
#define ATA_IOBASE 0x50FEE000 #define ATA_IOBASE 0x50FEE000

View file

@ -597,17 +597,17 @@ static int sd_wait_for_state(unsigned int state)
} }
} }
static int sd_transfer_sectors(int card_no, unsigned long start, static int sd_transfer_sectors(int card_no, sector_t start,
int count, void *buffer, bool write) int count, void *buffer, bool write)
{ {
int ret; int ret;
unsigned long start_addr; sector_t start_addr;
int dma_channel = -1; int dma_channel = -1;
bool use_direct_dma; bool use_direct_dma;
int count_per_dma; int count_per_dma;
unsigned long rel_addr; unsigned long rel_addr;
dbgprintf("transfer %d %d %d", card_no, start, count); dbgprintf("transfer %d %lu %d", card_no, start, count);
mutex_lock(&sd_mtx); mutex_lock(&sd_mtx);
enable_controller(true); enable_controller(true);
@ -673,6 +673,7 @@ sd_transfer_retry:
if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS))
start_addr *= SD_BLOCK_SIZE; /* not SDHC */ start_addr *= SD_BLOCK_SIZE; /* not SDHC */
// XXX 64-bit
ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK,
start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | start_addr, MMC_CMD_DCLR | MMC_CMD_DATA |
SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0),
@ -765,7 +766,7 @@ sd_transfer_error:
} }
} }
int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
void* inbuf) void* inbuf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE
@ -774,7 +775,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
return sd_transfer_sectors(card_no, start, incount, inbuf, false); return sd_transfer_sectors(card_no, start, incount, inbuf, false);
} }
int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
const void* outbuf) const void* outbuf)
{ {
#ifndef HAVE_MULTIDRIVE #ifndef HAVE_MULTIDRIVE

View file

@ -209,9 +209,9 @@ int os_opendir_and_fd(const char *osdirname, DIR **osdirpp, int *osfdp)
} }
/* do we really need this in the app? (in the sim, yes) */ /* do we really need this in the app? (in the sim, yes) */
void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
{ {
unsigned long size = 0, free = 0; sector_t size = 0, free = 0;
char volpath[MAX_PATH]; char volpath[MAX_PATH];
struct statfs fs; struct statfs fs;

View file

@ -472,7 +472,7 @@ int os_modtime(const char *path, time_t modtime)
int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize); int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
{ {
ULARGE_INTEGER free = { .QuadPart = 0 }, ULARGE_INTEGER free = { .QuadPart = 0 },
size = { .QuadPart = 0 }; size = { .QuadPart = 0 };

View file

@ -84,7 +84,7 @@ struct nand_param
* *
*/ */
static volatile unsigned long nand_address; static volatile sector_t nand_address;
#define NAND_DATAPORT (nand_address) #define NAND_DATAPORT (nand_address)
#define NAND_ADDRPORT (nand_address+0x10000) #define NAND_ADDRPORT (nand_address+0x10000)
#define NAND_COMMPORT (nand_address+0x08000) #define NAND_COMMPORT (nand_address+0x08000)
@ -111,7 +111,7 @@ static volatile unsigned long nand_address;
static struct nand_info* chip_info = NULL; static struct nand_info* chip_info = NULL;
static struct nand_info* banks[4]; static struct nand_info* banks[4];
static unsigned int nr_banks = 1; static unsigned int nr_banks = 1;
static unsigned long bank_size; static sector_t bank_size;
static struct nand_param internal_param; static struct nand_param internal_param;
static struct mutex nand_mtx; static struct mutex nand_mtx;
#ifdef USE_DMA #ifdef USE_DMA
@ -282,7 +282,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
/* /*
* Read oob * Read oob
*/ */
static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
{ {
struct nand_param *nandp = &internal_param; struct nand_param *nandp = &internal_param;
int page_size, row_cycle, bus_width; 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
* page - page number within a block: 0, 1, 2, ... * page - page number within a block: 0, 1, 2, ...
* dst - pointer to target buffer * dst - pointer to target buffer
*/ */
static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
{ {
struct nand_param *nandp = &internal_param; struct nand_param *nandp = &internal_param;
int page_size, oob_size; int page_size, oob_size;
@ -611,7 +611,7 @@ int nand_init(void)
return res; return res;
} }
static inline int read_sector(unsigned long start, unsigned int count, static inline int read_sector(sector_t start, unsigned int count,
void* buf, unsigned int chip_size) void* buf, unsigned int chip_size)
{ {
register int ret; register int ret;
@ -627,14 +627,14 @@ static inline int read_sector(unsigned long start, unsigned int count,
return ret; return ret;
} }
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
(void)drive; (void)drive;
#endif #endif
int ret = 0; int ret = 0;
unsigned int i, _count, chip_size = chip_info->page_size; unsigned int i, _count, chip_size = chip_info->page_size;
unsigned long _start; sector_t _start;
logf("start"); logf("start");
mutex_lock(&nand_mtx); mutex_lock(&nand_mtx);
@ -670,7 +670,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* bu
} }
/* TODO */ /* TODO */
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
{ {
(void)start; (void)start;
(void)count; (void)count;

View file

@ -110,7 +110,7 @@ struct nand_param {
static struct nand_info* chip_info = NULL; static struct nand_info* chip_info = NULL;
static struct nand_info* bank; static struct nand_info* bank;
static unsigned long nand_size; static sector_t nand_size;
static struct nand_param internal_param; static struct nand_param internal_param;
static struct mutex nand_mtx; static struct mutex nand_mtx;
#ifdef USE_DMA #ifdef USE_DMA
@ -281,7 +281,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
/* /*
* Read oob * Read oob
*/ */
static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
{ {
struct nand_param *nandp = &internal_param; struct nand_param *nandp = &internal_param;
int page_size, row_cycle, bus_width; 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
* page - page number within a block: 0, 1, 2, ... * page - page number within a block: 0, 1, 2, ...
* dst - pointer to target buffer * dst - pointer to target buffer
*/ */
static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
{ {
struct nand_param *nandp = &internal_param; struct nand_param *nandp = &internal_param;
int page_size, oob_size; int page_size, oob_size;
@ -532,7 +532,7 @@ int nand_init(void)
return res; return res;
} }
static inline int read_sector(unsigned long start, unsigned int count, static inline int read_sector(sector_t start, unsigned int count,
void* buf, unsigned int chip_size) void* buf, unsigned int chip_size)
{ {
register int ret; register int ret;
@ -548,7 +548,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
return ret; return ret;
} }
static inline int write_sector(unsigned long start, unsigned int count, static inline int write_sector(sector_t start, unsigned int count,
const void* buf, unsigned int chip_size) const void* buf, unsigned int chip_size)
{ {
int ret = 0; int ret = 0;
@ -563,14 +563,14 @@ static inline int write_sector(unsigned long start, unsigned int count,
return ret; return ret;
} }
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
(void)drive; (void)drive;
#endif #endif
int ret = 0; int ret = 0;
unsigned int _count, chip_size = chip_info->page_size; unsigned int _count, chip_size = chip_info->page_size;
unsigned long _start; sector_t _start;
logf("start"); logf("start");
mutex_lock(&nand_mtx); mutex_lock(&nand_mtx);
@ -590,14 +590,14 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* bu
return ret; return ret;
} }
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
(void)drive; (void)drive;
#endif #endif
int ret = 0; int ret = 0;
unsigned int _count, chip_size = chip_info->page_size; unsigned int _count, chip_size = chip_info->page_size;
unsigned long _start; sector_t _start;
logf("start"); logf("start");
mutex_lock(&nand_mtx); mutex_lock(&nand_mtx);

View file

@ -42,7 +42,6 @@ static struct mutex sd_mtx;
static int use_4bit; static int use_4bit;
static int num_6; static int num_6;
static int sd2_0;
//#define SD_DMA_ENABLE //#define SD_DMA_ENABLE
#define SD_DMA_INTERRUPT 0 #define SD_DMA_INTERRUPT 0
@ -598,7 +597,7 @@ static int jz_sd_transmit_data(struct sd_request *req)
static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) static inline unsigned int jz_sd_calc_clkrt(unsigned int rate)
{ {
unsigned int clkrt; unsigned int clkrt;
unsigned int clk_src = sd2_0 ? SD_CLOCK_HIGH : SD_CLOCK_FAST; unsigned int clk_src = card.sd2plus ? SD_CLOCK_HIGH : SD_CLOCK_FAST;
clkrt = 0; clkrt = 0;
while (rate < clk_src) while (rate < clk_src)
@ -716,7 +715,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
events = SD_EVENT_RX_DATA_DONE; events = SD_EVENT_RX_DATA_DONE;
break; break;
case 6: case SD_SWITCH_FUNC:
if (num_6 < 2) if (num_6 < 2)
{ {
#if defined(SD_DMA_ENABLE) #if defined(SD_DMA_ENABLE)
@ -1086,7 +1085,6 @@ static int sd_init_card_state(struct sd_request *request)
(request->response[3+i*4]<< 8) | request->response[4+i*4]); (request->response[3+i*4]<< 8) | request->response[4+i*4]);
sd_parse_csd(&card); sd_parse_csd(&card);
sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1);
logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]);
DEBUG("SD card is ready"); DEBUG("SD card is ready");
@ -1155,7 +1153,7 @@ static int sd_select_card(void)
if (retval) if (retval)
return retval; return retval;
if (sd2_0) if (card.sd2plus)
{ {
retval = sd_read_switch(&request); retval = sd_read_switch(&request);
if (!retval) if (!retval)
@ -1188,7 +1186,6 @@ static int __sd_init_device(void)
/* Initialise card data as blank */ /* Initialise card data as blank */
memset(&card, 0, sizeof(tCardInfo)); memset(&card, 0, sizeof(tCardInfo));
sd2_0 = 0;
num_6 = 0; num_6 = 0;
use_4bit = 0; use_4bit = 0;
@ -1250,7 +1247,7 @@ static inline void sd_stop_transfer(void)
mutex_unlock(&sd_mtx); mutex_unlock(&sd_mtx);
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
(void)drive; (void)drive;
@ -1276,7 +1273,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
if ((retval = sd_unpack_r1(&request, &r1))) if ((retval = sd_unpack_r1(&request, &r1)))
goto err; goto err;
if (sd2_0) // XXX 64-bit
if (card.sd2plus)
{ {
sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
count, SD_BLOCK_SIZE, RESPONSE_R1, buf); count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
@ -1292,19 +1290,18 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
goto err; goto err;
} }
last_disk_activity = current_tick;
sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
if ((retval = sd_unpack_r1(&request, &r1))) if ((retval = sd_unpack_r1(&request, &r1)))
goto err; goto err;
err: err:
last_disk_activity = current_tick;
sd_stop_transfer(); sd_stop_transfer();
return retval; return retval;
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
{ {
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
(void)drive; (void)drive;
@ -1330,7 +1327,8 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const voi
if ((retval = sd_unpack_r1(&request, &r1))) if ((retval = sd_unpack_r1(&request, &r1)))
goto err; goto err;
if (sd2_0) // XXX 64-bit
if (card.sd2plus)
{ {
sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start, sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start,
count, SD_BLOCK_SIZE, RESPONSE_R1, count, SD_BLOCK_SIZE, RESPONSE_R1,

View file

@ -57,8 +57,6 @@ static struct semaphore sd_wakeup[NUM_DRIVES];
static int use_4bit[NUM_DRIVES]; static int use_4bit[NUM_DRIVES];
static int num_6[NUM_DRIVES]; static int num_6[NUM_DRIVES];
static int sd2_0[NUM_DRIVES];
//#define DEBUG(x...) logf(x) //#define DEBUG(x...) logf(x)
#define DEBUG(x, ...) #define DEBUG(x, ...)
@ -698,7 +696,7 @@ static inline unsigned int jz_sd_calc_clkrt(const int drive, unsigned int rate)
unsigned int clkrt = 0; unsigned int clkrt = 0;
unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */ unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */
if (!sd2_0[drive] && rate > SD_CLOCK_FAST) if (!card[drive].sd2plus && rate > SD_CLOCK_FAST)
rate = SD_CLOCK_FAST; rate = SD_CLOCK_FAST;
while (rate < clk_src) while (rate < clk_src)
@ -1192,7 +1190,6 @@ static int sd_init_card_state(const int drive, struct sd_request *request)
(request->response[3+i*4]<< 8) | request->response[4+i*4]); (request->response[3+i*4]<< 8) | request->response[4+i*4]);
sd_parse_csd(&card[drive]); sd_parse_csd(&card[drive]);
sd2_0[drive] = (card_extract_bits(card[drive].csd, 127, 2) == 1);
logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]); logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]);
DEBUG("SD card is ready"); DEBUG("SD card is ready");
@ -1261,7 +1258,7 @@ static int sd_select_card(const int drive)
if (retval) if (retval)
return retval; return retval;
if (sd2_0[drive]) if (card[drive].sd2plus)
{ {
retval = sd_read_switch(drive, &request); retval = sd_read_switch(drive, &request);
if (!retval) if (!retval)
@ -1292,7 +1289,6 @@ static int __sd_init_device(const int drive)
/* Initialise card data as blank */ /* Initialise card data as blank */
memset(&card[drive], 0, sizeof(tCardInfo)); memset(&card[drive], 0, sizeof(tCardInfo));
sd2_0[drive] = 0;
num_6[drive] = 0; num_6[drive] = 0;
use_4bit[drive] = 0; use_4bit[drive] = 0;
active[drive] = 0; active[drive] = 0;
@ -1402,7 +1398,7 @@ static inline void sd_stop_transfer(const int drive)
mutex_unlock(&sd_mtx[drive]); mutex_unlock(&sd_mtx[drive]);
} }
int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count, void* buf, bool write) int sd_transfer_sectors(IF_MD(const int drive,) sector_t start, int count, void* buf, bool write)
{ {
struct sd_request request; struct sd_request request;
struct sd_response_r1 r1; struct sd_response_r1 r1;
@ -1427,11 +1423,12 @@ int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count,
if ((retval = sd_unpack_r1(&request, &r1))) if ((retval = sd_unpack_r1(&request, &r1)))
goto err; goto err;
// XXX 64-bit
sd_send_cmd(drive, &request, sd_send_cmd(drive, &request,
(count > 1) ? (count > 1) ?
(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) : (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) :
(write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK), (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK),
sd2_0[drive] ? start : (start * SD_BLOCK_SIZE), card[drive].sd2plus ? start : (start * SD_BLOCK_SIZE),
count, SD_BLOCK_SIZE, RESPONSE_R1, buf); count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
if ((retval = sd_unpack_r1(&request, &r1))) if ((retval = sd_unpack_r1(&request, &r1)))
goto err; goto err;
@ -1451,12 +1448,12 @@ err:
return retval; return retval;
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
{ {
return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
{ {
return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
} }

View file

@ -844,7 +844,7 @@ int msc_cmd_send_csd(msc_drv* d)
d->cardinfo.csd[i] = req.response[i]; d->cardinfo.csd[i] = req.response[i];
sd_parse_csd(&d->cardinfo); sd_parse_csd(&d->cardinfo);
if((req.response[0] >> 30) == 1) if(d->cardinfo.sd2plus)
d->driver_flags |= MSC_DF_V2_CARD; d->driver_flags |= MSC_DF_V2_CARD;
return 0; return 0;

View file

@ -51,7 +51,7 @@ static int sd_init_card(msc_drv* d)
} }
static int sd_transfer(msc_drv* d, bool write, static int sd_transfer(msc_drv* d, bool write,
unsigned long start, int count, void* buf) sector_t start, int count, void* buf)
{ {
int status = -1; int status = -1;
@ -114,6 +114,7 @@ static int sd_transfer(msc_drv* d, bool write,
: SD_READ_MULTIPLE_BLOCK; : SD_READ_MULTIPLE_BLOCK;
} }
// XXX 64-bit
if(d->driver_flags & MSC_DF_V2_CARD) if(d->driver_flags & MSC_DF_V2_CARD)
req.argument = start; req.argument = start;
else else
@ -142,14 +143,14 @@ static int sd_transfer(msc_drv* d, bool write,
return status; return status;
} }
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int sd_read_sectors(IF_MD(int drive,) sector_t start,
int count, void* buf) int count, void* buf)
{ {
return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false, return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false,
start, count, buf); start, count, buf);
} }
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int sd_write_sectors(IF_MD(int drive,) sector_t start,
int count, const void* buf) int count, const void* buf)
{ {
return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true, return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true,

View file

@ -114,6 +114,9 @@
#define SCSI_REPORT_LUNS 0xa0 #define SCSI_REPORT_LUNS 0xa0
#define SCSI_WRITE_BUFFER 0x3b #define SCSI_WRITE_BUFFER 0x3b
#define SCSI_READ_16 0x88
#define SCSI_WRITE_16 0x8a
#define UMS_STATUS_GOOD 0x00 #define UMS_STATUS_GOOD 0x00
#define UMS_STATUS_FAIL 0x01 #define UMS_STATUS_FAIL 0x01
@ -273,7 +276,7 @@ static union {
static char *cbw_buffer; static char *cbw_buffer;
static struct { static struct {
unsigned int sector; sector_t sector;
unsigned int count; unsigned int count;
unsigned int orig_count; unsigned int orig_count;
unsigned int cur_cmd; unsigned int cur_cmd;
@ -503,7 +506,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
if(dir==USB_DIR_IN) { if(dir==USB_DIR_IN) {
logf("IN received in RECEIVING"); logf("IN received in RECEIVING");
} }
logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); logf("scsi write %llu %d", cur_cmd.sector, cur_cmd.count);
if(status==0) { if(status==0) {
if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count) if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count)
&& (unsigned int)length!=WRITE_BUFFER_SIZE) { && (unsigned int)length!=WRITE_BUFFER_SIZE) {
@ -511,7 +514,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
break; break;
} }
unsigned int next_sector = cur_cmd.sector + sector_t next_sector = cur_cmd.sector +
(WRITE_BUFFER_SIZE/SECTOR_SIZE); (WRITE_BUFFER_SIZE/SECTOR_SIZE);
unsigned int next_count = cur_cmd.count - unsigned int next_count = cur_cmd.count -
MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE); MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE);
@ -739,12 +742,10 @@ static void send_and_read_next(void)
static void handle_scsi(struct command_block_wrapper* cbw) static void handle_scsi(struct command_block_wrapper* cbw)
{ {
/* USB Mass Storage assumes LBA capability.
TODO: support 48-bit LBA */
struct storage_info info; struct storage_info info;
unsigned int length = cbw->data_transfer_length; unsigned int length = cbw->data_transfer_length;
unsigned int block_size, block_count; sector_t block_count;
unsigned int block_size;
bool lun_present=true; bool lun_present=true;
unsigned char lun = cbw->lun; unsigned char lun = cbw->lun;
unsigned int block_size_mult = 1; unsigned int block_size_mult = 1;
@ -888,6 +889,12 @@ static void handle_scsi(struct command_block_wrapper* cbw)
memset(tb.ms_data_10->block_descriptor.reserved,0,4); memset(tb.ms_data_10->block_descriptor.reserved,0,4);
memset(tb.ms_data_10->block_descriptor.num_blocks,0,8); memset(tb.ms_data_10->block_descriptor.num_blocks,0,8);
#ifdef STORAGE_64BIT_SECTOR
tb.ms_data_10->block_descriptor.num_blocks[2] =
((block_count/block_size_mult) & 0xff00000000ULL)>>40;
tb.ms_data_10->block_descriptor.num_blocks[3] =
((block_count/block_size_mult) & 0x00ff000000ULL)>>32;
#endif
tb.ms_data_10->block_descriptor.num_blocks[4] = tb.ms_data_10->block_descriptor.num_blocks[4] =
((block_count/block_size_mult) & 0xff000000)>>24; ((block_count/block_size_mult) & 0xff000000)>>24;
tb.ms_data_10->block_descriptor.num_blocks[5] = tb.ms_data_10->block_descriptor.num_blocks[5] =
@ -1070,7 +1077,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
cbw->command_block[8]); cbw->command_block[8]);
cur_cmd.orig_count = cur_cmd.count; cur_cmd.orig_count = cur_cmd.count;
//logf("scsi read %d %d", cur_cmd.sector, cur_cmd.count); logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count);
if((cur_cmd.sector + cur_cmd.count) > block_count) { if((cur_cmd.sector + cur_cmd.count) > block_count) {
send_csw(UMS_STATUS_FAIL); send_csw(UMS_STATUS_FAIL);
@ -1092,7 +1099,58 @@ static void handle_scsi(struct command_block_wrapper* cbw)
send_and_read_next(); send_and_read_next();
} }
break; break;
#ifdef STORAGE_64BIT_SECTOR
case SCSI_READ_16:
logf("scsi read16 %d",lun);
if(!lun_present) {
send_command_failed_result();
cur_sense_data.sense_key=SENSE_NOT_READY;
cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
cur_sense_data.ascq=0;
break;
}
cur_cmd.data[0] = tb.transfer_buffer;
cur_cmd.data[1] = &tb.transfer_buffer[READ_BUFFER_SIZE];
cur_cmd.data_select=0;
cur_cmd.sector = block_size_mult *
((uint64_t)cbw->command_block[2] << 56 |
(uint64_t)cbw->command_block[3] << 48 |
(uint64_t)cbw->command_block[4] << 40 |
(uint64_t)cbw->command_block[5] << 32 |
cbw->command_block[6] << 24 |
cbw->command_block[7] << 16 |
cbw->command_block[8] << 8 |
cbw->command_block[9]);
cur_cmd.count = block_size_mult *
(cbw->command_block[10] << 24 |
cbw->command_block[11] << 16 |
cbw->command_block[12] << 8 |
cbw->command_block[13]);
cur_cmd.orig_count = cur_cmd.count;
logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count);
if((cur_cmd.sector + cur_cmd.count) > block_count) {
send_csw(UMS_STATUS_FAIL);
cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
cur_sense_data.ascq=0;
}
else {
#ifdef USB_USE_RAMDISK
memcpy(cur_cmd.data[cur_cmd.data_select],
ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE);
#else
cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,)
cur_cmd.sector,
MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
cur_cmd.data[cur_cmd.data_select]);
#endif
send_and_read_next();
}
break;
#endif
case SCSI_WRITE_10: case SCSI_WRITE_10:
logf("scsi write10 %d",lun); logf("scsi write10 %d",lun);
if(!lun_present) { if(!lun_present) {
@ -1127,6 +1185,48 @@ static void handle_scsi(struct command_block_wrapper* cbw)
MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
} }
break; break;
#ifdef STORAGE_64BIT_SECTOR
case SCSI_WRITE_16:
logf("scsi write16 %d",lun);
if(!lun_present) {
send_csw(UMS_STATUS_FAIL);
cur_sense_data.sense_key=SENSE_NOT_READY;
cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
cur_sense_data.ascq=0;
break;
}
cur_cmd.data[0] = tb.transfer_buffer;
cur_cmd.data[1] = &tb.transfer_buffer[WRITE_BUFFER_SIZE];
cur_cmd.data_select=0;
cur_cmd.sector = block_size_mult *
((uint64_t)cbw->command_block[2] << 56 |
(uint64_t)cbw->command_block[3] << 48 |
(uint64_t)cbw->command_block[4] << 40 |
(uint64_t)cbw->command_block[5] << 32 |
cbw->command_block[6] << 24 |
cbw->command_block[7] << 16 |
cbw->command_block[8] << 8 |
cbw->command_block[9]);
cur_cmd.count = block_size_mult *
(cbw->command_block[10] << 24 |
cbw->command_block[11] << 16 |
cbw->command_block[12] << 8 |
cbw->command_block[13]);
cur_cmd.orig_count = cur_cmd.count;
/* expect data */
if((cur_cmd.sector + cur_cmd.count) > block_count) {
send_csw(UMS_STATUS_FAIL);
cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
cur_sense_data.ascq=0;
}
else {
receive_block_data(cur_cmd.data[0],
MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
}
break;
#endif
#if CONFIG_RTC #if CONFIG_RTC
case SCSI_WRITE_BUFFER: case SCSI_WRITE_BUFFER: