forked from len0rd/rockbox
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
|
|
@ -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