mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 10:07:38 -04:00
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:
parent
9ff308a589
commit
15e5237469
49 changed files with 629 additions and 435 deletions
|
@ -557,14 +557,16 @@ static const char* dbg_partitions_getname(int selected_item, void *data,
|
|||
if (!disk_partinfo(partition, &p))
|
||||
return buffer;
|
||||
|
||||
// XXX fix this up to use logical sector size
|
||||
// XXX and if mounted, show free info...
|
||||
if (selected_item%2)
|
||||
{
|
||||
snprintf(buffer, buffer_len, " T:%x %ld MB", p.type,
|
||||
p.size / ( 2048 / ( SECTOR_SIZE / 512 )));
|
||||
snprintf(buffer, buffer_len, " T:%x %llu MB", p.type,
|
||||
(uint64_t)(p.size / ( 2048 / ( SECTOR_SIZE / 512 ))));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -572,7 +574,7 @@ static const char* dbg_partitions_getname(int selected_item, void *data,
|
|||
static bool dbg_partitions(void)
|
||||
{
|
||||
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.scroll_all = true;
|
||||
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);
|
||||
#if (CONFIG_STORAGE & STORAGE_SD)
|
||||
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 */
|
||||
#endif
|
||||
{
|
||||
|
@ -1407,15 +1425,41 @@ static int disk_callback(int btn, struct gui_synclist *lists)
|
|||
buf[8]=0;
|
||||
simplelist_addline(
|
||||
"Firmware: %s", buf);
|
||||
snprintf(buf, sizeof buf, "%ld MB",
|
||||
((unsigned long)identify_info[61] << 16 |
|
||||
(unsigned long)identify_info[60]) / 2048 );
|
||||
|
||||
uint64_t total_sectors = identify_info[60] | (identify_info[61] << 16);
|
||||
#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(
|
||||
"Size: %s", buf);
|
||||
unsigned long free;
|
||||
"Physical sector size: %d B", sector_size);
|
||||
|
||||
#ifndef HAVE_MULTIVOLUME
|
||||
// XXX this needs to be fixed for multi-volume setups
|
||||
sector_t free;
|
||||
volume_size( IF_MV(0,) NULL, &free );
|
||||
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(
|
||||
"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(
|
||||
"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
|
||||
if (identify_info[63] & (1<<0)) {
|
||||
simplelist_addline(
|
||||
|
@ -1751,8 +1791,8 @@ static int disk_callback(int btn, struct gui_synclist *lists)
|
|||
simplelist_addline("Model: %s", info.product);
|
||||
simplelist_addline("Firmware: %s", info.revision);
|
||||
simplelist_addline(
|
||||
"Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
|
||||
unsigned long free;
|
||||
"Size: %lld MB", (uint64_t)(info.num_sectors*(info.sector_size/512)/2048));
|
||||
storage_t free;
|
||||
volume_size( IF_MV(0,) NULL, &free );
|
||||
simplelist_addline(
|
||||
"Free: %ld MB", free / 1024);
|
||||
|
@ -1771,13 +1811,13 @@ static bool dbg_identify_info(void)
|
|||
const unsigned short *identify_info = ata_get_identify();
|
||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
||||
/* 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]);
|
||||
write(fd, &word, 2);
|
||||
}
|
||||
#else
|
||||
write(fd, identify_info, SECTOR_SIZE);
|
||||
write(fd, identify_info, ATA_IDENTIFY_WORDS*2);
|
||||
#endif
|
||||
close(fd);
|
||||
}
|
||||
|
|
|
@ -134,8 +134,8 @@ static int show_legal(void)
|
|||
struct info_data
|
||||
|
||||
{
|
||||
unsigned long size[NUM_VOLUMES];
|
||||
unsigned long free[NUM_VOLUMES];
|
||||
sector_t size[NUM_VOLUMES];
|
||||
sector_t free[NUM_VOLUMES];
|
||||
unsigned long name[NUM_VOLUMES];
|
||||
bool new_data;
|
||||
};
|
||||
|
@ -162,16 +162,19 @@ enum infoscreenorder
|
|||
*/
|
||||
static int refresh_data(struct info_data *info)
|
||||
{
|
||||
int i = 0;
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
int drive;
|
||||
int max = -1;
|
||||
|
||||
#endif
|
||||
int drive = 0;
|
||||
int i = 0;
|
||||
for (i = 0 ; CHECK_VOL(i) ; i++) {
|
||||
#endif
|
||||
volume_size(IF_MV(i,) &info->size[i], &info->free[i]);
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
drive = volume_drive(i);
|
||||
#endif
|
||||
if (drive > 0 || info->size[i] == 0)
|
||||
info->name[i] = LANG_DISK_NAME_MMC;
|
||||
else
|
||||
|
@ -182,9 +185,12 @@ static int refresh_data(struct info_data *info)
|
|||
max = drive;
|
||||
else if (drive < max)
|
||||
break;
|
||||
#elif defined(HAVE_MULTIVOLUME)
|
||||
if (volume_partition(i) == -1)
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
}
|
||||
#else
|
||||
i++;
|
||||
#endif
|
||||
|
||||
info->new_data = false;
|
||||
|
|
13
apps/misc.c
13
apps/misc.c
|
@ -139,7 +139,7 @@ const unsigned char * const unit_strings_core[] =
|
|||
* voiced.*/
|
||||
char *output_dyn_value(char *buf,
|
||||
int buf_size,
|
||||
int value,
|
||||
int64_t value,
|
||||
const unsigned char * const *units,
|
||||
unsigned int unit_count,
|
||||
bool binary_scale)
|
||||
|
@ -147,8 +147,9 @@ char *output_dyn_value(char *buf,
|
|||
unsigned int scale = binary_scale ? 1024 : 1000;
|
||||
unsigned int fraction = 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];
|
||||
int value2;
|
||||
|
||||
while (value_abs >= scale && unit_no < (unit_count - 1))
|
||||
{
|
||||
|
@ -157,7 +158,7 @@ char *output_dyn_value(char *buf,
|
|||
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;
|
||||
|
||||
if (value_abs >= 100 || fraction >= 100 || !unit_no)
|
||||
|
@ -170,10 +171,10 @@ char *output_dyn_value(char *buf,
|
|||
if (buf)
|
||||
{
|
||||
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]));
|
||||
else
|
||||
snprintf(buf, buf_size, "%d%s", value, P2STR(units[unit_no]));
|
||||
snprintf(buf, buf_size, "%d%s", value2, P2STR(units[unit_no]));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1851,7 +1852,7 @@ enum current_activity get_current_activity(void)
|
|||
* ** Extended error info truth table **
|
||||
* [ Handle ][buf_reqd]
|
||||
* [ > 0 ][ > 0 ] buf_reqd indicates how many bytes were used
|
||||
* [ALOC_ERR][ > 0 ] buf_reqd indicates how many bytes are needed
|
||||
* [ALOC_ERR][ > 0 ] buf_reqd indicates how many bytes are needed
|
||||
* [ALOC_ERR][READ_ERR] there was an error reading the file or it is empty
|
||||
*/
|
||||
int core_load_bmp(const char * filename, struct bitmap *bm, const int bmformat,
|
||||
|
|
21
apps/misc.h
21
apps/misc.h
|
@ -1,10 +1,10 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Daniel Stenberg
|
||||
|
@ -22,6 +22,7 @@
|
|||
#define MISC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include "config.h"
|
||||
#include "screen_access.h"
|
||||
|
@ -36,7 +37,7 @@ extern const unsigned char * const unit_strings_core[];
|
|||
* voiced.*/
|
||||
char *output_dyn_value(char *buf,
|
||||
int buf_size,
|
||||
int value,
|
||||
int64_t value,
|
||||
const unsigned char * const *units,
|
||||
unsigned int unit_count,
|
||||
bool binary_scale);
|
||||
|
@ -113,9 +114,9 @@ bool warn_on_pl_erase(void);
|
|||
bool show_search_progress(bool init, int count, int current, int total);
|
||||
|
||||
/* Read (up to) a line of text from fd into buffer and return number of bytes
|
||||
* read (which may be larger than the number of bytes stored in buffer). If
|
||||
* an error occurs, -1 is returned (and buffer contains whatever could be
|
||||
* read). A line is terminated by a LF char. Neither LF nor CR chars are
|
||||
* read (which may be larger than the number of bytes stored in buffer). If
|
||||
* an error occurs, -1 is returned (and buffer contains whatever could be
|
||||
* read). A line is terminated by a LF char. Neither LF nor CR chars are
|
||||
* stored in buffer.
|
||||
*/
|
||||
int read_line(int fd, char* buffer, int buffer_size);
|
||||
|
|
|
@ -649,7 +649,7 @@ struct plugin_api {
|
|||
int (*memcmp)(const void *s1, const void *s2, size_t n);
|
||||
char *(*strcasestr) (const char* phaystack, const char* pneedle);
|
||||
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,
|
||||
unsigned int unit_count, bool binary_scale);
|
||||
/* unicode stuff */
|
||||
|
|
|
@ -172,6 +172,8 @@ bool disk_init(IF_MD_NONVOID(int drive))
|
|||
}
|
||||
}
|
||||
|
||||
// XXX backup GPT header at final LBA of drive...
|
||||
|
||||
while (is_gpt) {
|
||||
/* Re-start partition parsing using GPT */
|
||||
uint64_t part_lba;
|
||||
|
@ -243,20 +245,24 @@ reload:
|
|||
goto skip; /* Any flag makes us ignore this */
|
||||
}
|
||||
tmp = BYTES2INT64(pptr, 32); /* FIRST LBA */
|
||||
if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo!
|
||||
DEBUGF("GPT: partition starts after 2GiB mark\n");
|
||||
#ifndef STORAGE_64BIT_SECTOR
|
||||
if (tmp > UINT32_MAX) {
|
||||
DEBUGF("GPT: partition starts after 2TiB mark\n");
|
||||
goto skip;
|
||||
}
|
||||
#endif
|
||||
if (tmp < 34) {
|
||||
DEBUGF("GPT: Invalid start LBA\n");
|
||||
goto skip;
|
||||
}
|
||||
pinfo[part].start = tmp;
|
||||
tmp = BYTES2INT64(pptr, 40); /* LAST LBA */
|
||||
if (tmp > UINT32_MAX) { // XXX revisit when we resize struct partinfo!
|
||||
DEBUGF("GPT: partition ends after 2GiB mark\n");
|
||||
#ifndef STORAGE_64BIT_SECTOR
|
||||
if (tmp > UINT32_MAX) {
|
||||
DEBUGF("GPT: partition ends after 2TiB mark\n");
|
||||
goto skip;
|
||||
}
|
||||
#endif
|
||||
if (tmp <= pinfo[part].start) {
|
||||
DEBUGF("GPT: Invalid end LBA\n");
|
||||
goto skip;
|
||||
|
@ -264,7 +270,7 @@ reload:
|
|||
pinfo[part].size = tmp - pinfo[part].start + 1;
|
||||
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++;
|
||||
|
||||
|
@ -499,13 +505,13 @@ unsigned int volume_get_cluster_size(IF_MV_NONVOID(int volume))
|
|||
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();
|
||||
|
||||
if (!CHECK_VOL(volume) || !fat_size(IF_MV(volume,) sizep, freep))
|
||||
{
|
||||
if (freep) *sizep = 0;
|
||||
if (sizep) *sizep = 0;
|
||||
if (freep) *freep = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,12 +71,12 @@ struct disk_cache_entry
|
|||
#ifdef HAVE_MULTIVOLUME
|
||||
unsigned char volume; /* volume of sector */
|
||||
#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)
|
||||
|
||||
static inline unsigned int map_sector(unsigned long sector)
|
||||
static inline unsigned int map_sector(sector_t sector)
|
||||
{
|
||||
/* keep sector hash simple for now */
|
||||
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
|
||||
to the specified sector, if it exists, or a new/evicted entry that must
|
||||
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 mapnum = map_sector(sector);
|
||||
|
@ -200,7 +200,7 @@ void * dc_cache_probe(IF_MV(int volume,) unsigned long sector,
|
|||
if (old_flags)
|
||||
{
|
||||
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);
|
||||
|
||||
if (old_flags & DCE_DIRTY)
|
||||
|
|
|
@ -109,15 +109,15 @@ static long last_disk_activity = -1;
|
|||
static long power_off_tick = 0;
|
||||
#endif
|
||||
|
||||
static unsigned long total_sectors;
|
||||
static sector_t total_sectors;
|
||||
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
|
||||
|
||||
struct sector_cache_entry {
|
||||
bool inuse;
|
||||
unsigned long sectornum; /* logical sector */
|
||||
sector_t sectornum; /* logical sector */
|
||||
unsigned char data[MAX_PHYS_SECTOR_SIZE];
|
||||
};
|
||||
/* 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 */
|
||||
|
||||
static int ata_transfer_sectors(unsigned long start,
|
||||
static int ata_transfer_sectors(uint64_t start,
|
||||
int incount,
|
||||
void* inbuf,
|
||||
int write)
|
||||
|
@ -443,9 +443,9 @@ static int ata_transfer_sectors(unsigned long start,
|
|||
ATA_OUT8(ATA_NSECTOR, count & 0xff);
|
||||
ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
|
||||
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_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_SELECT, SELECT_LBA | ata_device);
|
||||
#ifdef HAVE_ATA_DMA
|
||||
|
@ -592,7 +592,7 @@ static int ata_transfer_sectors(unsigned long start,
|
|||
|
||||
#ifndef MAX_PHYS_SECTOR_SIZE
|
||||
int ata_read_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int incount,
|
||||
void* inbuf)
|
||||
{
|
||||
|
@ -607,7 +607,7 @@ int ata_read_sectors(IF_MD(int drive,)
|
|||
}
|
||||
|
||||
int ata_write_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int count,
|
||||
const void* buf)
|
||||
{
|
||||
|
@ -623,7 +623,7 @@ int ata_write_sectors(IF_MD(int drive,)
|
|||
#endif /* ndef 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;
|
||||
|
||||
|
@ -652,7 +652,7 @@ static inline int flush_current_sector(void)
|
|||
}
|
||||
|
||||
int ata_read_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int incount,
|
||||
void* inbuf)
|
||||
{
|
||||
|
@ -718,7 +718,7 @@ int ata_read_sectors(IF_MD(int drive,)
|
|||
}
|
||||
|
||||
int ata_write_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int count,
|
||||
const void* buf)
|
||||
{
|
||||
|
@ -916,7 +916,7 @@ static int identify(void)
|
|||
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
|
||||
this info differently that normal sector 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 */
|
||||
&& total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */
|
||||
{ /* (needs BigLBA addressing) */
|
||||
if (identify_info[102] || identify_info[103])
|
||||
panicf("Unsupported disk size: >= 2^32 sectors");
|
||||
total_sectors = identify_info[100] | (identify_info[101] << 16) | ((uint64_t)identify_info[102] << 32) | ((uint64_t)identify_info[103] << 48);
|
||||
|
||||
total_sectors = identify_info[100] | (identify_info[101] << 16);
|
||||
lba48 = true; /* use BigLBA */
|
||||
}
|
||||
#endif /* HAVE_LBA48 */
|
||||
|
@ -1360,7 +1358,13 @@ void ata_get_info(IF_MD(int drive,)struct storage_info *info)
|
|||
(void)drive; /* unused for now */
|
||||
#endif
|
||||
int i;
|
||||
info->sector_size = SECTOR_SIZE;
|
||||
|
||||
/* 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->num_sectors = total_sectors;
|
||||
|
||||
src = (unsigned short*)&identify_info[27];
|
||||
|
|
|
@ -173,9 +173,9 @@ union raw_dirent
|
|||
|
||||
struct fsinfo
|
||||
{
|
||||
unsigned long freecount; /* last known free cluster count */
|
||||
unsigned long nextfree; /* first cluster to start looking for free
|
||||
clusters, or 0xffffffff for no hint */
|
||||
sector_t freecount; /* last known free cluster count */
|
||||
sector_t nextfree; /* first cluster to start looking for free
|
||||
clusters, or 0xffffffff for no hint */
|
||||
};
|
||||
/* fsinfo offsets */
|
||||
#define FSINFO_SIGNATURE 0
|
||||
|
@ -233,7 +233,7 @@ static struct bpb
|
|||
unsigned long totalsectors;
|
||||
unsigned long rootdirsector;
|
||||
unsigned long firstdatasector;
|
||||
unsigned long startsector;
|
||||
sector_t startsector;
|
||||
unsigned long dataclusters;
|
||||
unsigned long fatrgnstart;
|
||||
unsigned long fatrgnend;
|
||||
|
@ -241,8 +241,8 @@ static struct bpb
|
|||
#ifdef HAVE_FAT16SUPPORT
|
||||
unsigned int bpb_rootentcnt; /* Number of dir entries in the root */
|
||||
/* internals for FAT16 support */
|
||||
unsigned long rootdirsectornum; /* sector offset of root dir relative to start
|
||||
* of first pseudo cluster */
|
||||
sector_t rootdirsectornum; /* sector offset of root dir relative to start
|
||||
* of first pseudo cluster */
|
||||
#endif /* HAVE_FAT16SUPPORT */
|
||||
|
||||
/** Additional information kept for each volume **/
|
||||
|
@ -329,7 +329,7 @@ static void cache_discard(IF_MV_NONVOID(struct bpb *fat_bpb))
|
|||
}
|
||||
|
||||
/* 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;
|
||||
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);
|
||||
if (UNLIKELY(rc < 0))
|
||||
{
|
||||
DEBUGF("%s() - Could not read sector %ld"
|
||||
" (error %d)\n", __func__, secnum, rc);
|
||||
DEBUGF("%s() - Could not read sector %llu"
|
||||
" (error %d)\n", __func__, (uint64_t)secnum, rc);
|
||||
dc_discard_buf(buf);
|
||||
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
|
||||
* a sector's contents in order to avoid a fill */
|
||||
static void * cache_sector_buffer(IF_MV(struct bpb *fat_bpb,)
|
||||
unsigned long secnum)
|
||||
sector_t secnum)
|
||||
{
|
||||
unsigned int flags;
|
||||
return dc_cache_probe(IF_MV(fat_bpb->volume,) secnum, &flags);
|
||||
}
|
||||
|
||||
/* 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)];
|
||||
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);
|
||||
if (rc < 0)
|
||||
{
|
||||
panicf("%s() - Could not write sector %ld"
|
||||
" (error %d)\n", __func__, sector, rc);
|
||||
panicf("%s() - Could not write sector %llu"
|
||||
" (error %d)\n", __func__, (uint64_t)sector, rc);
|
||||
}
|
||||
|
||||
if (--copies == 0)
|
||||
|
@ -2397,12 +2397,12 @@ unsigned long fat_query_sectornum(const struct fat_filestr *filestr)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (write)
|
||||
|
@ -2416,12 +2416,12 @@ static long transfer(struct bpb *fat_bpb, unsigned long start, long count,
|
|||
firstallowed = fat_bpb->firstdatasector;
|
||||
|
||||
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)
|
||||
{
|
||||
panicf("Write %ld after data\n",
|
||||
start + count - fat_bpb->totalsectors);
|
||||
panicf("Write %llu after data\n",
|
||||
(uint64_t)(start + count - fat_bpb->totalsectors));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2487,14 +2487,14 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
|
|||
long rc;
|
||||
|
||||
long cluster = filestr->lastcluster;
|
||||
unsigned long sector = filestr->lastsector;
|
||||
sector_t sector = filestr->lastsector;
|
||||
long clusternum = filestr->clusternum;
|
||||
unsigned long sectornum = filestr->sectornum;
|
||||
|
||||
DEBUGF("%s(file:%lx,count:0x%lx,buf:%lx,%s)\n", __func__,
|
||||
file->firstcluster, sectorcount, (long)buf,
|
||||
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);
|
||||
|
||||
eof = false;
|
||||
|
@ -2534,7 +2534,7 @@ long fat_readwrite(struct fat_filestr *filestr, unsigned long sectorcount,
|
|||
|
||||
unsigned long transferred = 0;
|
||||
unsigned long count = 0;
|
||||
unsigned long last = sector;
|
||||
sector_t last = sector;
|
||||
|
||||
while (transferred + count < sectorcount)
|
||||
{
|
||||
|
@ -2961,7 +2961,7 @@ void fat_recalc_free(IF_MV_NONVOID(int volume))
|
|||
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);
|
||||
if (!fat_bpb)
|
||||
|
|
|
@ -32,7 +32,7 @@ static unsigned char ramdisk[SECTOR_SIZE * NUM_SECTORS];
|
|||
static long last_disk_activity = -1;
|
||||
|
||||
int ramdisk_read_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int count,
|
||||
void* buf)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ int ramdisk_read_sectors(IF_MD(int drive,)
|
|||
}
|
||||
|
||||
int ramdisk_write_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
sector_t start,
|
||||
int count,
|
||||
const void* buf)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ int ramdisk_num_drives(int first_drive)
|
|||
{
|
||||
/* We don't care which logical drive number(s) we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,13 @@ void sd_parse_csd(tCardInfo *card)
|
|||
c_size = card_extract_bits(card->csd, 69, 22) + 1;
|
||||
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 */
|
||||
|
||||
|
@ -62,7 +69,9 @@ void sd_parse_csd(tCardInfo *card)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -99,4 +108,3 @@ void sd_get_info(IF_MD(int drive,) struct storage_info *info)
|
|||
info->revision="0.00";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -140,8 +140,8 @@ bool ata_disk_is_active(void);
|
|||
int ata_soft_reset(void);
|
||||
int ata_init(void) STORAGE_INIT_ATTR;
|
||||
void ata_close(void);
|
||||
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_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
|
||||
int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
|
||||
void ata_spin(void);
|
||||
#if (CONFIG_LED == LED_REAL)
|
||||
void ata_set_led_enabled(bool enabled);
|
||||
|
@ -233,4 +233,6 @@ int ata_read_smart(struct ata_smart_values*);
|
|||
#define STORAGE_CLOSE
|
||||
#endif
|
||||
|
||||
#define ATA_IDENTIFY_WORDS 256
|
||||
|
||||
#endif /* __ATA_H__ */
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
struct partinfo
|
||||
{
|
||||
unsigned long start; /* first sector (LBA) */
|
||||
unsigned long size; /* number of sectors */
|
||||
sector_t start; /* first sector (LBA) */
|
||||
sector_t size; /* number of sectors */
|
||||
unsigned char type;
|
||||
};
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ struct fat_filestr
|
|||
{
|
||||
struct fat_file *fatfilep; /* common file information */
|
||||
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 */
|
||||
unsigned long sectornum; /* sector number within current cluster */
|
||||
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 */
|
||||
unsigned int fat_get_cluster_size(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. **/
|
||||
void fat_empty_fat_direntry(struct fat_direntry *entry);
|
||||
|
|
|
@ -36,8 +36,8 @@ bool mmc_disk_is_active(void);
|
|||
int mmc_soft_reset(void);
|
||||
int mmc_init(void) STORAGE_INIT_ATTR;
|
||||
void mmc_close(void);
|
||||
int mmc_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf);
|
||||
int mmc_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
void mmc_spin(void);
|
||||
int mmc_spinup_time(void);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define __MV_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
/* FixMe: These macros are a bit nasty and perhaps misplaced here.
|
||||
|
@ -40,6 +41,19 @@
|
|||
#define IF_MD_DRV(d) 0
|
||||
#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 */
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
#define IF_MV(x...) x /* valist contents or empty */
|
||||
|
@ -113,7 +127,7 @@ struct volumeinfo
|
|||
/* Volume-centric functions (in disk.c) */
|
||||
void volume_recalc_free(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
|
||||
bool volume_ismounted(IF_MV_NONVOID(int volume));
|
||||
#endif
|
||||
|
|
|
@ -36,8 +36,8 @@ bool nand_disk_is_active(void);
|
|||
int nand_soft_reset(void);
|
||||
int nand_init(void) STORAGE_INIT_ATTR;
|
||||
void nand_close(void);
|
||||
int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf);
|
||||
int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
#ifdef HAVE_STORAGE_FLUSH
|
||||
int nand_flush(void);
|
||||
#endif
|
||||
|
|
|
@ -35,8 +35,8 @@ bool ramdisk_disk_is_active(void);
|
|||
int ramdisk_soft_reset(void);
|
||||
int ramdisk_init(void) STORAGE_INIT_ATTR;
|
||||
void ramdisk_close(void);
|
||||
int ramdisk_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf);
|
||||
int ramdisk_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
void ramdisk_spin(void);
|
||||
void ramdisk_sleepnow(void);
|
||||
int ramdisk_spinup_time(void);
|
||||
|
|
|
@ -42,8 +42,8 @@ bool sd_disk_is_active(void);
|
|||
int sd_soft_reset(void);
|
||||
int sd_init(void) STORAGE_INIT_ATTR;
|
||||
void sd_close(void);
|
||||
int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf);
|
||||
int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
void sd_spin(void);
|
||||
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_MULTIPLE_BLOCK 18
|
||||
#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_WRITE_BLOCK 24
|
||||
#define SD_WRITE_MULTIPLE_BLOCK 25
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
#define __SDMMC_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <mv.h> /* for sector_t */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
bool initialized;
|
||||
|
||||
unsigned long read_timeout; /* n * 8 clock cycles */
|
||||
|
@ -37,7 +39,7 @@ typedef struct
|
|||
unsigned int nsac; /* clock cycles */
|
||||
unsigned long taac; /* n * 0.1 ns */
|
||||
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 long rca; /* RCA register */
|
||||
|
||||
|
@ -48,6 +50,8 @@ typedef struct
|
|||
#if (CONFIG_STORAGE & STORAGE_SD)
|
||||
unsigned int current_bank;
|
||||
#endif
|
||||
|
||||
unsigned int sd2plus; /* SD 2.0 or better */
|
||||
} tCardInfo;
|
||||
|
||||
#if (CONFIG_STORAGE & STORAGE_SD)
|
||||
|
|
|
@ -107,7 +107,7 @@ int ramdisk_event(long id, intptr_t data);
|
|||
struct storage_info
|
||||
{
|
||||
unsigned int sector_size;
|
||||
unsigned int num_sectors;
|
||||
sector_t num_sectors;
|
||||
char *vendor;
|
||||
char *product;
|
||||
char *revision;
|
||||
|
@ -318,6 +318,6 @@ int storage_driver_type(int drive);
|
|||
|
||||
#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_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,7 @@ static inline void dc_unlock_cache(void)
|
|||
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);
|
||||
void dc_dirty_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;
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ int storage_init(void)
|
|||
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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#ifdef CONFIG_STORAGE_MULTI
|
||||
|
|
|
@ -446,7 +446,7 @@ static int sd_init_card(const int drive)
|
|||
sd_parse_csd(&card_info[drive]);
|
||||
|
||||
#if defined(HAVE_MULTIDRIVE)
|
||||
hs_card = (card_info[drive].speed == 50000000);
|
||||
hs_card = (card_info[drive].speed >= 50000000);
|
||||
#endif
|
||||
|
||||
/* Boost MCICLK to operating speed */
|
||||
|
@ -455,7 +455,7 @@ static int sd_init_card(const int drive)
|
|||
#if defined(HAVE_MULTIDRIVE)
|
||||
else
|
||||
/* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/
|
||||
MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) |
|
||||
MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) |
|
||||
MCI_CLOCK_POWERSAVE; /* SD supports powersave */
|
||||
#endif
|
||||
|
||||
|
@ -680,7 +680,7 @@ static int sd_select_bank(signed char bank)
|
|||
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)
|
||||
{
|
||||
#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 */
|
||||
void *dma_buf;
|
||||
|
||||
unsigned long bank_start = start;
|
||||
sector_t bank_start = start;
|
||||
// XXX 64-bit sectors?
|
||||
|
||||
/* Only switch banks for internal storage */
|
||||
if(drive == INTERNAL_AS3525)
|
||||
|
@ -869,7 +870,7 @@ sd_transfer_error_nodma:
|
|||
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)
|
||||
{
|
||||
int ret;
|
||||
|
@ -881,11 +882,11 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
|
|||
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)
|
||||
{
|
||||
#ifdef VERIFY_WRITE
|
||||
unsigned long saved_start = start;
|
||||
sector_t saved_start = start;
|
||||
int saved_count = count;
|
||||
void *saved_buf = (void*)buf;
|
||||
#endif
|
||||
|
|
|
@ -677,7 +677,7 @@ int sd_init(void)
|
|||
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)
|
||||
{
|
||||
unsigned long response;
|
||||
|
@ -776,7 +776,7 @@ retry_with_reinit:
|
|||
|
||||
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 */
|
||||
arg *= SD_BLOCK_SIZE;
|
||||
|
||||
|
@ -858,13 +858,13 @@ exit:
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
|
||||
|
|
|
@ -179,7 +179,7 @@ static int phys_segment_to_page_addr(int phys_segment, int page_in_seg)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
page_addr += (page_in_seg / nand_data->planes);
|
||||
|
||||
return page_addr;
|
||||
|
@ -222,7 +222,7 @@ static void nand_chip_select(int bank)
|
|||
static void nand_read_id(int bank, unsigned char* id_buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
/* Enable NFC bus clock */
|
||||
BCLKCTR |= DEV_NAND;
|
||||
|
||||
|
@ -358,7 +358,7 @@ static void nand_setup_read(int bank, int row, int column)
|
|||
static void nand_end_read(void)
|
||||
{
|
||||
nand_chip_select(-1);
|
||||
|
||||
|
||||
/* Disable NFC bus clock */
|
||||
BCLKCTR &= ~DEV_NAND;
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ static void nand_end_read(void)
|
|||
static void nand_read_raw(int bank, int row, int column, int size, void* buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
nand_setup_read(bank, row, column);
|
||||
|
||||
/* Read data into page buffer */
|
||||
|
@ -388,7 +388,7 @@ static void nand_read_raw(int bank, int row, int column, int size, void* buf)
|
|||
((unsigned int*)buf)[i] = NFC_WDATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nand_end_read();
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,7 @@ static void nand_get_chip_info(void)
|
|||
sectors_per_page = nand_data->page_size / SECTOR_SIZE;
|
||||
|
||||
sectors_per_segment = bytes_per_segment / SECTOR_SIZE;
|
||||
|
||||
|
||||
pages_per_segment = sectors_per_segment / sectors_per_page;
|
||||
|
||||
/* Establish how many banks are present */
|
||||
|
@ -494,7 +494,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
|
|||
|
||||
#ifdef USE_ECC_CORRECTION
|
||||
unsigned long spare_buf[4];
|
||||
|
||||
|
||||
/* Set up the ECC controller to monitor reads from NFC_WDATA */
|
||||
BCLKCTR |= DEV_ECC;
|
||||
ECC_BASE = (unsigned long)&NFC_WDATA;
|
||||
|
@ -514,27 +514,27 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
|
|||
This way, reads are always done through NFC_WDATA - otherwise they
|
||||
would not be 'seen' by the ECC controller. */
|
||||
static char temp_buf[SECTOR_SIZE];
|
||||
|
||||
|
||||
unsigned int* ptr = (unsigned int*) temp_buf;
|
||||
|
||||
|
||||
for (i = 0; i < (SECTOR_SIZE/4); i++)
|
||||
{
|
||||
*ptr++ = NFC_WDATA;
|
||||
}
|
||||
|
||||
|
||||
memcpy(buf, temp_buf, SECTOR_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use straight word copy as buffer and size are both word-aligned */
|
||||
unsigned int* ptr = (unsigned int*) buf;
|
||||
|
||||
|
||||
for (i = 0; i < (SECTOR_SIZE/4); i++)
|
||||
{
|
||||
*ptr++ = NFC_WDATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ECC_CORRECTION
|
||||
/* Stop monitoring before we read the OOB data */
|
||||
ECC_CTRL &= ~ECC_M4EN;
|
||||
|
@ -549,29 +549,29 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
|
|||
/* Calculate MLC4 ECC using bytes 0,1,8-15 */
|
||||
BCLKCTR |= DEV_ECC;
|
||||
ECC_CTRL |= ECC_M4EN;
|
||||
|
||||
|
||||
MLC_ECC0W = *(unsigned short*)spare_buf;
|
||||
MLC_ECC1W = spare_buf[2];
|
||||
MLC_ECC2W = spare_buf[3];
|
||||
|
||||
|
||||
while (!(ECC_CTRL & ECC_READY)) {};
|
||||
|
||||
int errors = ECC_ERR_NUM & 7;
|
||||
|
||||
|
||||
switch (errors)
|
||||
{
|
||||
case 4: /* nothing to correct */
|
||||
break;
|
||||
|
||||
|
||||
case 7: /* fail, can't correct */
|
||||
ret = false;
|
||||
break;
|
||||
|
||||
|
||||
default: /* between 1 and 4 errors */
|
||||
{
|
||||
int i;
|
||||
unsigned char* char_buf = (unsigned char*)buf;
|
||||
|
||||
|
||||
for (i = 0; i < errors + 1; i++)
|
||||
{
|
||||
int offset = 0x207 - ECC_ERRADDR(i);
|
||||
|
@ -584,7 +584,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
|
|||
ECC_CTRL &= ~ECC_M4EN;
|
||||
BCLKCTR &= ~DEV_ECC;
|
||||
#endif
|
||||
|
||||
|
||||
nand_end_read();
|
||||
|
||||
return ret;
|
||||
|
@ -619,7 +619,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
|
|||
|
||||
int cache_num = 0;
|
||||
bool found = false;
|
||||
|
||||
|
||||
while (!found && cache_num < write_caches_in_use)
|
||||
{
|
||||
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,
|
|||
{
|
||||
/* data is located in random pages cache */
|
||||
found = true;
|
||||
|
||||
|
||||
bank = write_caches[cache_num].random_bank;
|
||||
phys_segment = write_caches[cache_num].random_phys_segment;
|
||||
|
||||
|
||||
page_in_segment =
|
||||
write_caches[cache_num].page_map[page_in_segment];
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
|
|||
{
|
||||
/* data is located in in-place pages cache */
|
||||
found = true;
|
||||
|
||||
|
||||
bank = write_caches[cache_num].inplace_bank;
|
||||
phys_segment = write_caches[cache_num].inplace_phys_segment;
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ static inline unsigned char get_sector_type(char* spare_buf)
|
|||
static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf)
|
||||
{
|
||||
(void)phys_seg;
|
||||
|
||||
|
||||
return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
||||
spare_buf[OFF_LOG_SEG_LOBYTE])
|
||||
#if defined(FTL_V1)
|
||||
|
@ -702,7 +702,7 @@ static void read_random_writes_cache(int bank, int phys_segment)
|
|||
16, spare_buf);
|
||||
|
||||
log_segment = get_log_segment_id(phys_segment, spare_buf);
|
||||
|
||||
|
||||
if (log_segment == -1)
|
||||
return;
|
||||
|
||||
|
@ -734,13 +734,13 @@ static void read_random_writes_cache(int bank, int phys_segment)
|
|||
page++)
|
||||
{
|
||||
unsigned short cached_page;
|
||||
|
||||
|
||||
nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page),
|
||||
SECTOR_SIZE, /* offset to first sector's spare */
|
||||
16, spare_buf);
|
||||
|
||||
cached_page = get_cached_page_id(spare_buf);
|
||||
|
||||
|
||||
if (cached_page != 0xFFFF)
|
||||
write_caches[cache_no].page_map[cached_page] = page;
|
||||
}
|
||||
|
@ -759,10 +759,10 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
|
|||
16, spare_buf);
|
||||
|
||||
log_segment = get_log_segment_id(phys_segment, spare_buf);
|
||||
|
||||
|
||||
if (log_segment == -1)
|
||||
return;
|
||||
|
||||
|
||||
/* Find which cache this is related to */
|
||||
int cache_no = find_write_cache(log_segment);
|
||||
|
||||
|
@ -780,7 +780,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
|
|||
}
|
||||
|
||||
write_caches[cache_no].log_segment = log_segment;
|
||||
|
||||
|
||||
/* Find how many pages have been written to the new segment */
|
||||
while (log_segment != -1 &&
|
||||
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)
|
|||
|
||||
log_segment = get_log_segment_id(phys_segment, spare_buf);
|
||||
}
|
||||
|
||||
|
||||
if (page != 0)
|
||||
{
|
||||
write_caches[cache_no].inplace_bank = bank;
|
||||
|
@ -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)
|
||||
{
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
|
@ -809,15 +809,15 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
|
|||
#endif
|
||||
|
||||
int ret = 0;
|
||||
|
||||
|
||||
mutex_lock(&ata_mtx);
|
||||
|
||||
|
||||
led(true);
|
||||
|
||||
while (incount > 0)
|
||||
{
|
||||
int done = 0;
|
||||
int segment = start / sectors_per_segment;
|
||||
sector_t segment = start / sectors_per_segment;
|
||||
int secmod = start % sectors_per_segment;
|
||||
|
||||
while (incount > 0 && secmod < sectors_per_segment)
|
||||
|
@ -839,7 +839,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
|
|||
secmod++;
|
||||
done++;
|
||||
}
|
||||
|
||||
|
||||
if (done < 0)
|
||||
{
|
||||
ret = -1;
|
||||
|
@ -852,11 +852,11 @@ nand_read_error:
|
|||
|
||||
mutex_unlock(&ata_mtx);
|
||||
led(false);
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
|
@ -903,7 +903,7 @@ int nand_init(void)
|
|||
unsigned char spare_buf[16];
|
||||
|
||||
if (initialized) return 0;
|
||||
|
||||
|
||||
mutex_init(&ata_mtx);
|
||||
|
||||
/* Set GPIO direction for chip select & write protect */
|
||||
|
@ -924,7 +924,7 @@ int nand_init(void)
|
|||
|
||||
memset(lpt_lookup, 0xff, lptbuf_size);
|
||||
memset(write_caches, 0xff, sizeof(write_caches));
|
||||
|
||||
|
||||
write_caches_in_use = 0;
|
||||
|
||||
/* Scan banks to build up block translation table */
|
||||
|
@ -936,7 +936,7 @@ int nand_init(void)
|
|||
nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0),
|
||||
SECTOR_SIZE, /* offset */
|
||||
16, spare_buf);
|
||||
|
||||
|
||||
int type = get_sector_type(spare_buf);
|
||||
|
||||
#ifdef FTL_V2
|
||||
|
@ -948,7 +948,7 @@ int nand_init(void)
|
|||
nand_read_raw(bank, phys_segment_to_page_addr
|
||||
(phys_segment, pages_per_segment - 1),
|
||||
SECTOR_SIZE, 16, spare_buf);
|
||||
|
||||
|
||||
if (get_sector_type(spare_buf) != 0xff)
|
||||
{
|
||||
type = SECTYPE_MAIN_DATA;
|
||||
|
@ -982,14 +982,14 @@ int nand_init(void)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SECTYPE_MAIN_RANDOM_CACHE:
|
||||
{
|
||||
/* Newly-written random page data (Main data area) */
|
||||
read_random_writes_cache(bank, phys_segment);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SECTYPE_MAIN_INPLACE_CACHE:
|
||||
{
|
||||
/* Newly-written sequential page data (Main data area) */
|
||||
|
@ -999,7 +999,7 @@ int nand_init(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
initialized = true;
|
||||
|
||||
return 0;
|
||||
|
@ -1029,7 +1029,7 @@ int nand_num_drives(int first_drive)
|
|||
{
|
||||
/* We don't care which logical drive number we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@ int nand_init(void)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return -1;
|
||||
|
|
|
@ -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,
|
||||
enum imx233_part_t part, unsigned *start, unsigned *end)
|
||||
enum imx233_part_t part, sector_t *start, unsigned *end)
|
||||
{
|
||||
uint8_t mblk[512];
|
||||
int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk);
|
||||
|
|
|
@ -45,7 +45,7 @@ enum imx233_part_t
|
|||
/** 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
|
||||
* 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
|
||||
* Freescale/Creative convention */
|
||||
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
|
||||
* called */
|
||||
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__ */
|
||||
|
|
|
@ -648,7 +648,7 @@ int mmc_event(long id, intptr_t data)
|
|||
#endif /* CONFIG_STORAGE & STORAGE_MMC */
|
||||
|
||||
/* 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;
|
||||
int ret = 0;
|
||||
|
@ -660,7 +660,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
|
|||
need_stop = false;
|
||||
/* Set bank_start to the correct unit (blocks or bytes).
|
||||
* 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 */
|
||||
bank_start *= SD_BLOCK_SIZE;
|
||||
/* issue read/write
|
||||
|
@ -686,7 +686,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
|
|||
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;
|
||||
/* 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 */
|
||||
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);
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ void sd_enable(bool 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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
int sd_drive = 0;
|
||||
|
@ -1039,7 +1039,7 @@ int mmc_spinup_time(void)
|
|||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
int mmc_drive = 0;
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
#define STAT_TIME_OUT_RES (1 << 1)
|
||||
#define STAT_TIME_OUT_READ (1)
|
||||
#define STAT_ERROR_BITS (0x3f)
|
||||
|
||||
|
||||
/* MMC_CMDAT bits */
|
||||
/* Some of the bits used by the OF don't make much sense with these */
|
||||
/* definitions. So they're probably different between PXA and PP502x */
|
||||
|
@ -101,7 +101,7 @@
|
|||
#define CMDAT_RES_TYPE3 (3)
|
||||
#define CMDAT_RES_TYPE2 (2)
|
||||
#define CMDAT_RES_TYPE1 (1)
|
||||
|
||||
|
||||
/* MMC_I_MASK bits */
|
||||
/* PP502x apparently only has bits 0-3 */
|
||||
#define I_MASK_SDIO_SUSPEND_ACK (1 << 12)
|
||||
|
@ -499,18 +499,18 @@ static inline void copy_write_sectors(const unsigned char** buf)
|
|||
{
|
||||
asm volatile (
|
||||
"ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov r10, r9, lsr #16 \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov r10, r9, lsr #16 \r\n"
|
||||
"stmia %[data], { r3-r10 } \r\n"
|
||||
"ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov %[t], r9, lsr #16 \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov %[t], r9, lsr #16 \r\n"
|
||||
"stmia %[data], { r3-r9 } \r\n"
|
||||
: [buf]"+&r"(*buf), [t]"=&r"(t)
|
||||
: [buf]"+&r"(*buf), [t]"=&r"(t)
|
||||
: [data]"r"(&MMC_DATA_FIFO)
|
||||
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
|
||||
);
|
||||
|
@ -760,7 +760,7 @@ static void sd_init_device(int card_no)
|
|||
currcard->csd[i] = temp_reg[3-i];
|
||||
|
||||
sd_parse_csd(currcard);
|
||||
|
||||
|
||||
MMC_CLKRT = 0; /* switch to highest clock rate */
|
||||
|
||||
ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
|
||||
|
@ -849,7 +849,7 @@ static void sd_select_device(int card_no)
|
|||
|
||||
/* 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)
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
|
@ -857,8 +857,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
|
|||
#endif
|
||||
int ret;
|
||||
unsigned char *buf, *buf_end;
|
||||
unsigned int bank;
|
||||
|
||||
sector_t bank;
|
||||
|
||||
/* TODO: Add DMA support. */
|
||||
|
||||
mutex_lock(&sd_mtx);
|
||||
|
@ -894,7 +894,7 @@ sd_read_retry:
|
|||
if (ret < 0)
|
||||
goto sd_read_error;
|
||||
}
|
||||
|
||||
|
||||
start -= bank * BLOCKS_PER_BANK;
|
||||
}
|
||||
|
||||
|
@ -904,6 +904,8 @@ sd_read_retry:
|
|||
|
||||
MMC_NUMBLK = incount;
|
||||
|
||||
// XXX 64-bit addresses..
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
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)
|
||||
{
|
||||
/* Write support is not finished yet */
|
||||
|
@ -1010,7 +1012,7 @@ sd_write_retry:
|
|||
if (ret < 0)
|
||||
goto sd_write_error;
|
||||
}
|
||||
|
||||
|
||||
start -= bank * BLOCKS_PER_BANK;
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1252,7 @@ int sd_num_drives(int first_drive)
|
|||
#else
|
||||
(void)first_drive;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
return 2;
|
||||
#else
|
||||
|
|
|
@ -31,18 +31,18 @@
|
|||
|
||||
/* This file provides only STUBS for now */
|
||||
|
||||
/** static, private data **/
|
||||
/** static, private data **/
|
||||
static bool initialized = false;
|
||||
|
||||
/* 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)drive;
|
||||
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)
|
||||
{
|
||||
(void)drive;
|
||||
|
@ -112,7 +112,7 @@ int nand_num_drives(int first_drive)
|
|||
{
|
||||
/* We don't care which logical drive number(s) we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -453,7 +453,7 @@ static inline void write_sd_data(unsigned char **src)
|
|||
*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)
|
||||
{
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
|
@ -498,6 +498,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
|
|||
DATA_XFER_MULTI;
|
||||
}
|
||||
|
||||
// XXX 64-bit
|
||||
|
||||
/* issue read command to the card */
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
#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 */
|
||||
|
||||
// XXX 64-bit
|
||||
if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
|
||||
{
|
||||
ret = -3;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
//#define SD_DEBUG
|
||||
|
||||
#include "system.h"
|
||||
|
@ -33,7 +33,7 @@
|
|||
#include "sdmmc.h"
|
||||
#endif
|
||||
#include "storage.h"
|
||||
#include "dma-target.h"
|
||||
#include "dma-target.h"
|
||||
#include "system-target.h"
|
||||
#include "led-mini2440.h"
|
||||
|
||||
|
@ -83,7 +83,7 @@ struct sd_card_status
|
|||
int retry_max;
|
||||
};
|
||||
|
||||
/** static, private data **/
|
||||
/** static, private data **/
|
||||
|
||||
/* for compatibility */
|
||||
static long last_disk_activity = -1;
|
||||
|
@ -117,13 +117,13 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
|
|||
static struct semaphore transfer_completion_signal;
|
||||
static volatile unsigned int transfer_error[NUM_DRIVES];
|
||||
/* align on cache line size */
|
||||
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
|
||||
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
|
||||
__attribute__((aligned(32)));
|
||||
static unsigned char * uncached_buffer;
|
||||
|
||||
static inline void mci_delay(void)
|
||||
{
|
||||
int i = 0xffff;
|
||||
static inline void mci_delay(void)
|
||||
{
|
||||
int i = 0xffff;
|
||||
while (i--)
|
||||
asm volatile ("nop\n");
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ static void get_regs (unsigned *regs)
|
|||
{
|
||||
unsigned j;
|
||||
volatile unsigned long *sdi_reg = &SDICON;
|
||||
|
||||
|
||||
for (j=0; j < 16;j++)
|
||||
{
|
||||
*regs++ = *sdi_reg++;
|
||||
|
@ -158,7 +158,7 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
|
|||
unsigned j;
|
||||
volatile unsigned long*sdi_reg = &SDICON;
|
||||
unsigned long diff;
|
||||
|
||||
|
||||
for (j=0; j < 16;j++)
|
||||
{
|
||||
diff = *regs1 ^ *regs2;
|
||||
|
@ -174,23 +174,23 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
|
|||
static void debug_r1(int cmd)
|
||||
{
|
||||
#if defined(SD_DEBUG)
|
||||
dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n",
|
||||
cmd,
|
||||
SDICSTA,
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ',
|
||||
|
||||
(SDICSTA & 0x40) ? 'P' : ' ',
|
||||
(SDICSTA & 0x20) ? 'A' : ' ',
|
||||
(SDICSTA & 0x10) ? 'E' : ' ',
|
||||
(SDICSTA & 0x08) ? 'C' : ' ',
|
||||
(SDICSTA & 0x04) ? 'I' : ' ',
|
||||
(SDICSTA & 0x02) ? 'R' : ' ',
|
||||
(SDICSTA & 0x01) ? 'Z' : ' ',
|
||||
|
||||
dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n",
|
||||
cmd,
|
||||
SDICSTA,
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ',
|
||||
(SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ',
|
||||
|
||||
(SDICSTA & 0x40) ? 'P' : ' ',
|
||||
(SDICSTA & 0x20) ? 'A' : ' ',
|
||||
(SDICSTA & 0x10) ? 'E' : ' ',
|
||||
(SDICSTA & 0x08) ? 'C' : ' ',
|
||||
(SDICSTA & 0x04) ? 'I' : ' ',
|
||||
(SDICSTA & 0x02) ? 'R' : ' ',
|
||||
(SDICSTA & 0x01) ? 'Z' : ' ',
|
||||
|
||||
SDIRSP0,
|
||||
SD_R1_CURRENT_STATE(SDIRSP0),
|
||||
(SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " "
|
||||
|
@ -205,8 +205,8 @@ void SDI (void)
|
|||
int status = SDIDSTA;
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
const int curr_card = 0;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
transfer_error[curr_card] = status
|
||||
#if 0
|
||||
& ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL |
|
||||
|
@ -217,7 +217,7 @@ void SDI (void)
|
|||
SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
|
||||
|
||||
dbgprintf ("SDI %x\n", transfer_error[curr_card]);
|
||||
|
||||
|
||||
semaphore_release(&transfer_completion_signal);
|
||||
|
||||
/* Ack the interrupt */
|
||||
|
@ -229,13 +229,13 @@ void SDI (void)
|
|||
void dma_callback (void)
|
||||
{
|
||||
const int status = SDIDSTA;
|
||||
|
||||
|
||||
transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL |
|
||||
S3C2410_SDIDSTA_RXCRCFAIL |
|
||||
S3C2410_SDIDSTA_DATATIMEOUT );
|
||||
|
||||
SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
|
||||
|
||||
|
||||
dbgprintf ("dma_cb\n");
|
||||
semaphore_release(&transfer_completion_signal);
|
||||
}
|
||||
|
@ -248,14 +248,14 @@ static void init_sdi_controller(const int card_no)
|
|||
/*****************************************************************************/
|
||||
#ifdef MINI2440
|
||||
/* Specific to Mini2440 */
|
||||
|
||||
|
||||
/* Enable pullups on SDCMD and SDDAT pins */
|
||||
S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE);
|
||||
S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE);
|
||||
S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE);
|
||||
S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE);
|
||||
S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE);
|
||||
|
||||
|
||||
/* Enable special function for SDCMD, SDCLK and SDDAT pins */
|
||||
S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION);
|
||||
S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION);
|
||||
|
@ -263,15 +263,15 @@ static void init_sdi_controller(const int card_no)
|
|||
S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION);
|
||||
S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION);
|
||||
S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION);
|
||||
|
||||
|
||||
/* Card Detect input */
|
||||
S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT);
|
||||
/* enable external irq 8-23 on the internal interrupt controller */
|
||||
INTMSK &= ~1<<5;
|
||||
/* enable GPG8 IRQ on the external interrupt controller */
|
||||
EINTMASK &= ~(1<<16);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Write Protect input */
|
||||
S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT);
|
||||
/*****************************************************************************/
|
||||
|
@ -279,11 +279,11 @@ static void init_sdi_controller(const int card_no)
|
|||
#error Unsupported target
|
||||
#endif
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
/* About 400KHz for initial comms with card */
|
||||
SDIPRE = PCLK / INITIAL_CLK - 1;
|
||||
/* Byte order=Type A (Little Endian), clock enable */
|
||||
SDICON = S3C2410_SDICON_CLOCKTYPE;
|
||||
SDICON = S3C2410_SDICON_CLOCKTYPE;
|
||||
SDIFSTA |= S3C2440_SDIFSTA_FIFORESET;
|
||||
SDIBSIZE = SD_BLOCK_SIZE;
|
||||
SDIDTIMER= 0x7fffff; /* Set timeout count - max value */
|
||||
|
@ -297,11 +297,11 @@ static void init_sdi_controller(const int card_no)
|
|||
/* Enable interrupt in controller */
|
||||
bitclr32(&INTMOD, SDI_MASK);
|
||||
bitclr32(&INTMSK, SDI_MASK);
|
||||
|
||||
SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH
|
||||
|
||||
SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH
|
||||
| S3C2410_SDIIMSK_DATATIMEOUT
|
||||
| S3C2410_SDIIMSK_DATACRC
|
||||
| S3C2410_SDIIMSK_CRCSTATUS
|
||||
| S3C2410_SDIIMSK_DATACRC
|
||||
| S3C2410_SDIIMSK_CRCSTATUS
|
||||
| S3C2410_SDIIMSK_FIFOFAIL
|
||||
;
|
||||
#endif
|
||||
|
@ -325,18 +325,18 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
|
|||
get_regs (reg_copy2);
|
||||
dump_regs (reg_copy, reg_copy2);
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
while (SDICSTA & S3C2410_SDICMDSTAT_XFERING)
|
||||
; /* wait ?? */
|
||||
#endif
|
||||
#endif
|
||||
/* set up new command */
|
||||
|
||||
|
||||
if (flags & MCI_ARG)
|
||||
SDICARG = arg;
|
||||
else
|
||||
SDICARG = 0;
|
||||
|
||||
|
||||
val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST;
|
||||
if(flags & MCI_RESP)
|
||||
{
|
||||
|
@ -344,27 +344,27 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
|
|||
if(flags & MCI_LONG_RESP)
|
||||
val |= S3C2410_SDICMDCON_LONGRSP;
|
||||
}
|
||||
|
||||
|
||||
/* Clear command/data status flags */
|
||||
SDICSTA |= 0x0f << 9;
|
||||
SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS;
|
||||
|
||||
|
||||
/* Initiate the command */
|
||||
SDICCON = val;
|
||||
|
||||
|
||||
if (flags & MCI_RESP)
|
||||
{
|
||||
/* wait for response or timeout */
|
||||
do
|
||||
do
|
||||
{
|
||||
status = SDICSTA;
|
||||
} while ( (status & (S3C2410_SDICMDSTAT_RSPFIN |
|
||||
} while ( (status & (S3C2410_SDICMDSTAT_RSPFIN |
|
||||
S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0);
|
||||
debug_r1(cmd);
|
||||
if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT)
|
||||
ret = false;
|
||||
else if (status & (S3C2410_SDICMDSTAT_RSPFIN))
|
||||
{
|
||||
{
|
||||
/* resp received */
|
||||
if(flags & MCI_LONG_RESP)
|
||||
{
|
||||
|
@ -381,10 +381,10 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
|
|||
else
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* wait for command completion or timeout */
|
||||
do
|
||||
do
|
||||
{
|
||||
status = SDICSTA;
|
||||
} while ( (status & (S3C2410_SDICMDSTAT_CMDSENT |
|
||||
|
@ -395,12 +395,12 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
|
|||
else
|
||||
ret = true;
|
||||
}
|
||||
|
||||
|
||||
/* Clear Command status flags */
|
||||
SDICSTA |= 0x0f << 9;
|
||||
|
||||
|
||||
mci_delay();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -558,7 +558,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
|
|||
const int card_no = 0;
|
||||
#endif
|
||||
(void)card_no;
|
||||
|
||||
|
||||
/* not applicable */
|
||||
dbgprintf ("sd_remov");
|
||||
return false;
|
||||
|
@ -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 ret = EC_OK;
|
||||
|
@ -636,7 +636,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
void *dma_buf;
|
||||
const int cmd =
|
||||
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
|
||||
unsigned long start_addr = start;
|
||||
sector_t start_addr = start;
|
||||
|
||||
dma_buf = aligned_buffer;
|
||||
if(transfer > UNALIGNED_NUM_SECTORS)
|
||||
|
@ -650,10 +650,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
|
||||
/* TODO? */
|
||||
SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET;
|
||||
SDIDCON = S3C2440_SDIDCON_DS_WORD |
|
||||
SDIDCON = S3C2440_SDIDCON_DS_WORD |
|
||||
S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS |
|
||||
S3C2410_SDIDCON_DMAEN |
|
||||
S3C2440_SDIDCON_DATSTART |
|
||||
S3C2440_SDIDCON_DATSTART |
|
||||
( transfer << 0);
|
||||
if (write)
|
||||
SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART;
|
||||
|
@ -665,6 +665,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
INTPND = SDI_MASK;
|
||||
|
||||
/* Initiate read/write command */
|
||||
// XXX 64-bit
|
||||
if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL))
|
||||
{
|
||||
ret -= 3*20;
|
||||
|
@ -674,32 +675,32 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
if(write)
|
||||
{
|
||||
request.source_addr = dma_buf;
|
||||
request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
|
||||
request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
|
||||
request.dest_addr = &SDIDAT_LLE;
|
||||
request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
|
||||
request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
|
||||
request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
|
||||
request.source_map = DMA_SRC_MAP_SDI;
|
||||
request.control = DCON_DMD_HS | DCON_SYNC_APB |
|
||||
request.control = DCON_DMD_HS | DCON_SYNC_APB |
|
||||
DCON_HW_SEL |
|
||||
DCON_NO_RELOAD | DCON_DSZ_WORD;
|
||||
request.callback = NULL;
|
||||
|
||||
request.callback = NULL;
|
||||
|
||||
dma_enable_channel(0, &request);
|
||||
}
|
||||
else
|
||||
{
|
||||
request.source_addr = &SDIDAT_LLE;
|
||||
request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
|
||||
request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
|
||||
request.dest_addr = dma_buf;
|
||||
request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
|
||||
request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
|
||||
request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
|
||||
request.source_map = DMA_SRC_MAP_SDI;
|
||||
request.control = DCON_DMD_HS | DCON_SYNC_APB |
|
||||
request.control = DCON_DMD_HS | DCON_SYNC_APB |
|
||||
DCON_HW_SEL |
|
||||
DCON_NO_RELOAD | DCON_DSZ_WORD;
|
||||
request.callback = NULL;
|
||||
|
||||
dma_enable_channel(0, &request);
|
||||
request.callback = NULL;
|
||||
|
||||
dma_enable_channel(0, &request);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -716,12 +717,12 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
#endif
|
||||
|
||||
semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
|
||||
|
||||
|
||||
/* wait for DMA to finish */
|
||||
while (DSTAT0 & DSTAT_STAT_BUSY)
|
||||
;
|
||||
|
||||
#if 0
|
||||
|
||||
#if 0
|
||||
status = SDIDSTA;
|
||||
while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0)
|
||||
{
|
||||
|
@ -738,10 +739,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
|
|||
count -= transfer;
|
||||
loops = 0; /* reset errors counter */
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]);
|
||||
|
||||
|
||||
if(loops++ > MAX_TRANSFER_ERRORS)
|
||||
{
|
||||
led_flash(LED1|LED2, LED3|LED4);
|
||||
|
@ -783,11 +784,11 @@ sd_transfer_error:
|
|||
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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
dbgprintf ("sd_read %d %x %d\n", card_no, start, incount);
|
||||
#else
|
||||
|
@ -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)
|
||||
{
|
||||
#ifdef BOOTLOADER /* we don't need write support in bootloader */
|
||||
|
@ -835,7 +836,7 @@ void sd_enable(bool on)
|
|||
{
|
||||
dbgprintf ("sd_enable %d\n", on);
|
||||
/* TODO: enable/disable SDI clock */
|
||||
|
||||
|
||||
if (sd_enabled == on)
|
||||
return; /* nothing to do */
|
||||
if (on)
|
||||
|
@ -847,14 +848,14 @@ void sd_enable(bool on)
|
|||
sd_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sd_init(void)
|
||||
{
|
||||
int ret = EC_OK;
|
||||
dbgprintf ("\n==============================\n");
|
||||
dbgprintf (" sd_init\n");
|
||||
dbgprintf ("==============================\n");
|
||||
|
||||
|
||||
init_sdi_controller (0);
|
||||
#ifndef BOOTLOADER
|
||||
sd_enabled = true;
|
||||
|
@ -893,7 +894,7 @@ long sd_last_disk_activity(void)
|
|||
}
|
||||
|
||||
tCardInfo *card_get_info_target(int card_no)
|
||||
{
|
||||
{
|
||||
return &card_info[card_no];
|
||||
}
|
||||
|
||||
|
|
|
@ -29,17 +29,17 @@
|
|||
#include "ftl-target.h"
|
||||
#include "nand-target.h"
|
||||
|
||||
/** static, private data **/
|
||||
/** static, private data **/
|
||||
static bool initialized = false;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return ftl_write(start, count, outbuf);
|
||||
|
@ -106,7 +106,7 @@ int nand_num_drives(int first_drive)
|
|||
{
|
||||
/* We don't care which logical drive number(s) we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -58,10 +58,9 @@
|
|||
#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
|
||||
#define CEATA_MMC_RCA 1
|
||||
|
||||
|
||||
/** static, private data **/
|
||||
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 ata_lba48;
|
||||
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_CSD, CMD_IDENTIFY);
|
||||
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;
|
||||
}
|
||||
|
@ -701,7 +700,7 @@ static int ata_power_up(void)
|
|||
| (((uint64_t)ata_identify_data[103]) << 48);
|
||||
else
|
||||
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_set_active();
|
||||
return 0;
|
||||
|
@ -966,7 +965,7 @@ static int ata_reset(void)
|
|||
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)
|
||||
{
|
||||
mutex_lock(&ata_mutex);
|
||||
|
@ -975,7 +974,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
|
|||
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)
|
||||
{
|
||||
mutex_lock(&ata_mutex);
|
||||
|
|
|
@ -104,19 +104,19 @@ static bool sd_poll_status(unsigned int trigger, long timeout)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int sd_command(unsigned int cmd, unsigned int arg,
|
||||
static int sd_command(unsigned int cmd, unsigned int arg,
|
||||
unsigned long* response, unsigned int resp_type)
|
||||
{
|
||||
int sdi_cmd = cmd;
|
||||
|
||||
|
||||
sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */
|
||||
|
||||
|
||||
if (resp_type)
|
||||
{
|
||||
/* response type & response required flag */
|
||||
sdi_cmd |= (resp_type<<7) | (1<<6);
|
||||
}
|
||||
|
||||
|
||||
if (cmd == SD_READ_SINGLE_BLOCK ||
|
||||
cmd == SD_READ_MULTIPLE_BLOCK ||
|
||||
cmd == SD_WRITE_BLOCK ||
|
||||
|
@ -124,18 +124,18 @@ static int sd_command(unsigned int cmd, unsigned int arg,
|
|||
{
|
||||
sdi_cmd |= (1<<10); /* request data transfer */
|
||||
}
|
||||
|
||||
|
||||
if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
|
||||
return -EC_COMMAND;
|
||||
|
||||
|
||||
SDIARGU = arg;
|
||||
SDICMD = sdi_cmd;
|
||||
|
||||
|
||||
udelay(10);
|
||||
|
||||
|
||||
if (response == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000))
|
||||
return -EC_COMMAND;
|
||||
|
||||
|
@ -150,7 +150,7 @@ static int sd_command(unsigned int cmd, unsigned int arg,
|
|||
{
|
||||
response[0] = SDIRSPARGU0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ static int sd1_oneshot_callback(struct timeout *tmo)
|
|||
void EXT0(void)
|
||||
{
|
||||
static struct timeout sd1_oneshot;
|
||||
|
||||
|
||||
timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
|
|||
const int card_no = 0;
|
||||
#endif
|
||||
(void)card_no;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ static void sd_init_device(int card_no)
|
|||
{
|
||||
int ret;
|
||||
unsigned long response;
|
||||
|
||||
|
||||
/* Initialise card data as blank */
|
||||
memset(currcard, 0, sizeof(*currcard));
|
||||
|
||||
|
@ -282,7 +282,7 @@ static void sd_init_device(int card_no)
|
|||
#endif
|
||||
|
||||
ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
|
@ -290,30 +290,30 @@ static void sd_init_device(int card_no)
|
|||
SDICLK = (1<<12) | 59;
|
||||
|
||||
sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3);
|
||||
|
||||
|
||||
if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
|
||||
goto card_init_error;
|
||||
|
||||
|
||||
currcard->ocr = 0;
|
||||
|
||||
|
||||
long start_tick = current_tick;
|
||||
|
||||
|
||||
while ((currcard->ocr & (1<<31)) == 0
|
||||
&& TIME_BEFORE(current_tick, start_tick + HZ))
|
||||
{
|
||||
udelay(100);
|
||||
sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0);
|
||||
sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3);
|
||||
}
|
||||
|
||||
|
||||
if ((currcard->ocr & (1<<31)) == 0)
|
||||
{
|
||||
ret = -EC_POWER_UP;
|
||||
goto card_init_error;
|
||||
}
|
||||
|
||||
|
||||
ret = sd_command
|
||||
(SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2);
|
||||
|
||||
|
@ -322,39 +322,39 @@ static void sd_init_device(int card_no)
|
|||
|
||||
ret = sd_command
|
||||
(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
|
||||
ret = sd_command
|
||||
(SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
|
||||
sd_parse_csd(currcard);
|
||||
|
||||
ret = sd_command
|
||||
(SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
ret = sd_command
|
||||
(SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
ret = sd_command /* 4 bit */
|
||||
(SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
ret = sd_command
|
||||
(SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto card_init_error;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
|
@ -416,23 +416,24 @@ sd_read_retry:
|
|||
ret = currcard->initialized;
|
||||
goto sd_read_error;
|
||||
}
|
||||
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto sd_read_error;
|
||||
|
||||
|
||||
/* Use full SD clock for data transfer (PCK_SDMMC) */
|
||||
SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
|
||||
|
||||
|
||||
/* Block count | FIFO count | Block size (2^9) | 4-bit bus */
|
||||
SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2);
|
||||
SDIDCTRL |= (1<<12); /* nReset */
|
||||
|
||||
|
||||
SDIDCTRL2 = (1<<2); /* multi block, read */
|
||||
|
||||
// XXX 64-bit
|
||||
if (currcard->ocr & (1<<30))
|
||||
ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
|
||||
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)
|
||||
{
|
||||
/* Write support is not finished yet */
|
||||
|
@ -538,21 +539,22 @@ sd_write_retry:
|
|||
ret = currcard->initialized;
|
||||
goto sd_write_error;
|
||||
}
|
||||
|
||||
|
||||
ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
goto sd_write_error;
|
||||
|
||||
/* Use full SD clock for data transfer (PCK_SDMMC) */
|
||||
SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
|
||||
|
||||
|
||||
/* Block count | FIFO count | Block size (2^9) | 4-bit bus */
|
||||
SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2);
|
||||
SDIDCTRL |= (1<<12); /* nReset */
|
||||
|
||||
|
||||
SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */
|
||||
|
||||
// XXX 64-bit
|
||||
if (currcard->ocr & (1<<30))
|
||||
ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
|
||||
else
|
||||
|
@ -578,7 +580,7 @@ sd_write_retry:
|
|||
else
|
||||
{
|
||||
int tmp_buf[4];
|
||||
|
||||
|
||||
memcpy(tmp_buf, outbuf, 16);
|
||||
|
||||
SDIWDATA = tmp_buf[0];
|
||||
|
@ -646,12 +648,12 @@ void sd_enable(bool on)
|
|||
PCLK_SDMMC &= ~PCK_EN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sd_init(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
if (!initialized)
|
||||
mutex_init(&sd_mtx);
|
||||
|
||||
|
@ -678,7 +680,7 @@ int sd_init(void)
|
|||
GPIOC_DIR |= (1<<24);
|
||||
|
||||
sleep(HZ/10);
|
||||
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
/* Configure interrupts for the card slot */
|
||||
TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */
|
||||
|
@ -696,7 +698,7 @@ long sd_last_disk_activity(void)
|
|||
}
|
||||
|
||||
tCardInfo *card_get_info_target(int card_no)
|
||||
{
|
||||
{
|
||||
return &card_info[card_no];
|
||||
}
|
||||
|
||||
|
@ -706,7 +708,7 @@ int sd_num_drives(int first_drive)
|
|||
{
|
||||
/* Store which logical drive number(s) we have been assigned */
|
||||
sd_first_drive = first_drive;
|
||||
|
||||
|
||||
#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
|
||||
return 2;
|
||||
#else
|
||||
|
|
|
@ -126,8 +126,10 @@ void GIO2(void)
|
|||
|
||||
#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_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) 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
|
||||
{
|
||||
|
@ -253,9 +255,9 @@ static void cfs_init(void)
|
|||
/* Read root inode */
|
||||
_ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, §or2);
|
||||
root_inode = (struct cfs_inode*)§or2;
|
||||
|
||||
|
||||
logf("Root inode = 0x%x", root_inode);
|
||||
|
||||
|
||||
logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]);
|
||||
|
||||
/* Read root inode's first sector */
|
||||
|
@ -277,9 +279,9 @@ static void cfs_init(void)
|
|||
vfat_inode_nr = root_direntry_items[i].inode_number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logf("VFAT inode = 0x%x", vfat_inode_nr);
|
||||
|
||||
|
||||
if(vfat_inode_nr != 0)
|
||||
{
|
||||
/* Read VFAT inode */
|
||||
|
@ -384,19 +386,19 @@ static void cfs_init(void)
|
|||
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
|
||||
* FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes.
|
||||
*/
|
||||
#ifndef BOOTLOADER
|
||||
unsigned long *sectors = core_get_data(sectors_handle);
|
||||
sector_t *sectors = core_get_data(sectors_handle);
|
||||
#endif
|
||||
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)
|
||||
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)
|
||||
cfs_init();
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
/* Nasty hack, but Creative is nasty... */
|
||||
#define ata_read_sectors _ata_read_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_write_sectors(IF_MD(int drive,) unsigned long start, int count, const 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,) sector_t start, int count, const void* buf);
|
||||
|
||||
/* General purpose memory region #1 */
|
||||
#define ATA_IOBASE 0x50FEE000
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "system.h"
|
||||
#include <string.h>
|
||||
#include "gcc_extensions.h"
|
||||
|
@ -97,7 +97,7 @@ struct sd_card_status
|
|||
int retry_max;
|
||||
};
|
||||
|
||||
/** static, private data **/
|
||||
/** static, private data **/
|
||||
|
||||
/* for compatibility */
|
||||
static long last_disk_activity = -1;
|
||||
|
@ -123,7 +123,7 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
|
|||
static struct semaphore data_done SHAREDBSS_ATTR;
|
||||
static volatile unsigned int transfer_error[NUM_DRIVES];
|
||||
/* align on cache line size */
|
||||
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
|
||||
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
|
||||
__attribute__((aligned(32)));
|
||||
|
||||
static void sd_card_mux(int card_no)
|
||||
|
@ -397,7 +397,7 @@ static int sd_init_card(const int card_no)
|
|||
SDHC_RESP_FMT_1, &currcard->rca);
|
||||
if (ret < 0)
|
||||
{
|
||||
dbgprintf("SD_SEND_RELATIVE_ADDR failed");
|
||||
dbgprintf("SD_SEND_RELATIVE_ADDR failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -559,7 +559,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
|
|||
#ifdef HAVE_MULTIDRIVE
|
||||
(void)card_no;
|
||||
#endif
|
||||
|
||||
|
||||
/* not applicable */
|
||||
return false;
|
||||
}
|
||||
|
@ -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 ret;
|
||||
unsigned long start_addr;
|
||||
sector_t start_addr;
|
||||
int dma_channel = -1;
|
||||
bool use_direct_dma;
|
||||
int count_per_dma;
|
||||
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);
|
||||
enable_controller(true);
|
||||
|
||||
|
@ -673,6 +673,7 @@ sd_transfer_retry:
|
|||
if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS))
|
||||
start_addr *= SD_BLOCK_SIZE; /* not SDHC */
|
||||
|
||||
// XXX 64-bit
|
||||
ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK,
|
||||
start_addr, MMC_CMD_DCLR | MMC_CMD_DATA |
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
|
@ -862,7 +863,7 @@ long sd_last_disk_activity(void)
|
|||
}
|
||||
|
||||
tCardInfo *card_get_info_target(int card_no)
|
||||
{
|
||||
{
|
||||
return &card_info[card_no];
|
||||
}
|
||||
|
||||
|
|
|
@ -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) */
|
||||
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];
|
||||
struct statfs fs;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
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 },
|
||||
size = { .QuadPart = 0 };
|
||||
|
|
|
@ -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_ADDRPORT (nand_address+0x10000)
|
||||
#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* banks[4];
|
||||
static unsigned int nr_banks = 1;
|
||||
static unsigned long bank_size;
|
||||
static sector_t bank_size;
|
||||
static struct nand_param internal_param;
|
||||
static struct mutex nand_mtx;
|
||||
#ifdef USE_DMA
|
||||
|
@ -282,7 +282,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
|||
/*
|
||||
* 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;
|
||||
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, ...
|
||||
* 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;
|
||||
int page_size, oob_size;
|
||||
|
@ -611,7 +611,7 @@ int nand_init(void)
|
|||
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)
|
||||
{
|
||||
register int ret;
|
||||
|
@ -627,14 +627,14 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
|||
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
|
||||
(void)drive;
|
||||
#endif
|
||||
int ret = 0;
|
||||
unsigned int i, _count, chip_size = chip_info->page_size;
|
||||
unsigned long _start;
|
||||
sector_t _start;
|
||||
|
||||
logf("start");
|
||||
mutex_lock(&nand_mtx);
|
||||
|
@ -670,7 +670,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* bu
|
|||
}
|
||||
|
||||
/* 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)count;
|
||||
|
|
|
@ -110,7 +110,7 @@ struct nand_param {
|
|||
|
||||
static struct nand_info* chip_info = NULL;
|
||||
static struct nand_info* bank;
|
||||
static unsigned long nand_size;
|
||||
static sector_t nand_size;
|
||||
static struct nand_param internal_param;
|
||||
static struct mutex nand_mtx;
|
||||
#ifdef USE_DMA
|
||||
|
@ -281,7 +281,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
|||
/*
|
||||
* 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;
|
||||
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, ...
|
||||
* 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;
|
||||
int page_size, oob_size;
|
||||
|
@ -532,7 +532,7 @@ int nand_init(void)
|
|||
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)
|
||||
{
|
||||
register int ret;
|
||||
|
@ -548,7 +548,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
|||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -563,14 +563,14 @@ static inline int write_sector(unsigned long start, unsigned int count,
|
|||
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
|
||||
(void)drive;
|
||||
#endif
|
||||
int ret = 0;
|
||||
unsigned int _count, chip_size = chip_info->page_size;
|
||||
unsigned long _start;
|
||||
sector_t _start;
|
||||
|
||||
logf("start");
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
(void)drive;
|
||||
#endif
|
||||
int ret = 0;
|
||||
unsigned int _count, chip_size = chip_info->page_size;
|
||||
unsigned long _start;
|
||||
sector_t _start;
|
||||
|
||||
logf("start");
|
||||
mutex_lock(&nand_mtx);
|
||||
|
|
|
@ -42,7 +42,6 @@ static struct mutex sd_mtx;
|
|||
|
||||
static int use_4bit;
|
||||
static int num_6;
|
||||
static int sd2_0;
|
||||
|
||||
//#define SD_DMA_ENABLE
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
while (rate < clk_src)
|
||||
|
@ -716,7 +715,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
|
|||
events = SD_EVENT_RX_DATA_DONE;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case SD_SWITCH_FUNC:
|
||||
if (num_6 < 2)
|
||||
{
|
||||
#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]);
|
||||
|
||||
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]);
|
||||
DEBUG("SD card is ready");
|
||||
|
@ -1155,7 +1153,7 @@ static int sd_select_card(void)
|
|||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (sd2_0)
|
||||
if (card.sd2plus)
|
||||
{
|
||||
retval = sd_read_switch(&request);
|
||||
if (!retval)
|
||||
|
@ -1188,7 +1186,6 @@ static int __sd_init_device(void)
|
|||
/* Initialise card data as blank */
|
||||
memset(&card, 0, sizeof(tCardInfo));
|
||||
|
||||
sd2_0 = 0;
|
||||
num_6 = 0;
|
||||
use_4bit = 0;
|
||||
|
||||
|
@ -1250,7 +1247,7 @@ static inline void sd_stop_transfer(void)
|
|||
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
|
||||
(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)))
|
||||
goto err;
|
||||
|
||||
if (sd2_0)
|
||||
// XXX 64-bit
|
||||
if (card.sd2plus)
|
||||
{
|
||||
sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
|
||||
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;
|
||||
}
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
goto err;
|
||||
|
||||
err:
|
||||
last_disk_activity = current_tick;
|
||||
sd_stop_transfer();
|
||||
|
||||
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
|
||||
(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)))
|
||||
goto err;
|
||||
|
||||
if (sd2_0)
|
||||
// XXX 64-bit
|
||||
if (card.sd2plus)
|
||||
{
|
||||
sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start,
|
||||
count, SD_BLOCK_SIZE, RESPONSE_R1,
|
||||
|
|
|
@ -57,8 +57,6 @@ static struct semaphore sd_wakeup[NUM_DRIVES];
|
|||
|
||||
static int use_4bit[NUM_DRIVES];
|
||||
static int num_6[NUM_DRIVES];
|
||||
static int sd2_0[NUM_DRIVES];
|
||||
|
||||
|
||||
//#define DEBUG(x...) logf(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 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;
|
||||
|
||||
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]);
|
||||
|
||||
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]);
|
||||
DEBUG("SD card is ready");
|
||||
|
@ -1261,7 +1258,7 @@ static int sd_select_card(const int drive)
|
|||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (sd2_0[drive])
|
||||
if (card[drive].sd2plus)
|
||||
{
|
||||
retval = sd_read_switch(drive, &request);
|
||||
if (!retval)
|
||||
|
@ -1292,7 +1289,6 @@ static int __sd_init_device(const int drive)
|
|||
/* Initialise card data as blank */
|
||||
memset(&card[drive], 0, sizeof(tCardInfo));
|
||||
|
||||
sd2_0[drive] = 0;
|
||||
num_6[drive] = 0;
|
||||
use_4bit[drive] = 0;
|
||||
active[drive] = 0;
|
||||
|
@ -1402,7 +1398,7 @@ static inline void sd_stop_transfer(const int 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_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)))
|
||||
goto err;
|
||||
|
||||
// XXX 64-bit
|
||||
sd_send_cmd(drive, &request,
|
||||
(count > 1) ?
|
||||
(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_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);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
goto err;
|
||||
|
@ -1451,12 +1448,12 @@ err:
|
|||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -844,7 +844,7 @@ int msc_cmd_send_csd(msc_drv* d)
|
|||
d->cardinfo.csd[i] = req.response[i];
|
||||
sd_parse_csd(&d->cardinfo);
|
||||
|
||||
if((req.response[0] >> 30) == 1)
|
||||
if(d->cardinfo.sd2plus)
|
||||
d->driver_flags |= MSC_DF_V2_CARD;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -51,7 +51,7 @@ static int sd_init_card(msc_drv* d)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -114,6 +114,7 @@ static int sd_transfer(msc_drv* d, bool write,
|
|||
: SD_READ_MULTIPLE_BLOCK;
|
||||
}
|
||||
|
||||
// XXX 64-bit
|
||||
if(d->driver_flags & MSC_DF_V2_CARD)
|
||||
req.argument = start;
|
||||
else
|
||||
|
@ -142,14 +143,14 @@ static int sd_transfer(msc_drv* d, bool write,
|
|||
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)
|
||||
{
|
||||
return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false,
|
||||
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)
|
||||
{
|
||||
return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true,
|
||||
|
|
|
@ -114,6 +114,9 @@
|
|||
#define SCSI_REPORT_LUNS 0xa0
|
||||
#define SCSI_WRITE_BUFFER 0x3b
|
||||
|
||||
#define SCSI_READ_16 0x88
|
||||
#define SCSI_WRITE_16 0x8a
|
||||
|
||||
#define UMS_STATUS_GOOD 0x00
|
||||
#define UMS_STATUS_FAIL 0x01
|
||||
|
||||
|
@ -273,7 +276,7 @@ static union {
|
|||
static char *cbw_buffer;
|
||||
|
||||
static struct {
|
||||
unsigned int sector;
|
||||
sector_t sector;
|
||||
unsigned int count;
|
||||
unsigned int orig_count;
|
||||
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) {
|
||||
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((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count)
|
||||
&& (unsigned int)length!=WRITE_BUFFER_SIZE) {
|
||||
|
@ -511,7 +514,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
|
|||
break;
|
||||
}
|
||||
|
||||
unsigned int next_sector = cur_cmd.sector +
|
||||
sector_t next_sector = cur_cmd.sector +
|
||||
(WRITE_BUFFER_SIZE/SECTOR_SIZE);
|
||||
unsigned int next_count = cur_cmd.count -
|
||||
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)
|
||||
{
|
||||
/* USB Mass Storage assumes LBA capability.
|
||||
TODO: support 48-bit LBA */
|
||||
|
||||
struct storage_info info;
|
||||
unsigned int length = cbw->data_transfer_length;
|
||||
unsigned int block_size, block_count;
|
||||
sector_t block_count;
|
||||
unsigned int block_size;
|
||||
bool lun_present=true;
|
||||
unsigned char lun = cbw->lun;
|
||||
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.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] =
|
||||
((block_count/block_size_mult) & 0xff000000)>>24;
|
||||
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]);
|
||||
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) {
|
||||
send_csw(UMS_STATUS_FAIL);
|
||||
|
@ -1092,7 +1099,58 @@ static void handle_scsi(struct command_block_wrapper* cbw)
|
|||
send_and_read_next();
|
||||
}
|
||||
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:
|
||||
logf("scsi write10 %d",lun);
|
||||
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));
|
||||
}
|
||||
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
|
||||
case SCSI_WRITE_BUFFER:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue