1
0
Fork 0
forked from len0rd/rockbox

Use different read and write buffer sizes. Due to interaction between common transfer sizes used by most OSes (64k) and the double-buffering system we use for writes, writes need a smaller buffer to make sure that USB and disk I/O can overlap.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20988 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2009-05-19 18:51:03 +00:00
parent 00392020d8
commit 792a7a6086

View file

@ -51,8 +51,14 @@
* enough for efficient mass storage support, as commonly host OSes * enough for efficient mass storage support, as commonly host OSes
* don't do larger SCSI transfers anyway, so larger USB transfers * don't do larger SCSI transfers anyway, so larger USB transfers
* wouldn't buy us anything. * wouldn't buy us anything.
* Due to being the double-buffering system used, using a smaller write buffer
* ends up being more efficient. Measurements have shown that 24k to 28k is
* optimal
*/ */
#define BUFFER_SIZE 65536 #define READ_BUFFER_SIZE (1024*64)
#define WRITE_BUFFER_SIZE (1024*24)
#define ALLOCATE_BUFFER_SIZE (2*MAX(READ_BUFFER_SIZE,WRITE_BUFFER_SIZE))
/* bulk-only class specific requests */ /* bulk-only class specific requests */
#define USB_BULK_RESET_REQUEST 0xff #define USB_BULK_RESET_REQUEST 0xff
@ -399,11 +405,11 @@ void usb_storage_init_connection(void)
#if CONFIG_CPU == IMX31L || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \ #if CONFIG_CPU == IMX31L || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \
defined(BOOTLOADER) || CONFIG_CPU == DM320 defined(BOOTLOADER) || CONFIG_CPU == DM320
static unsigned char _cbw_buffer[BUFFER_SIZE*2] static unsigned char _cbw_buffer[ALLOCATE_BUFFER_SIZE]
USB_DEVBSS_ATTR __attribute__((aligned(32))); USB_DEVBSS_ATTR __attribute__((aligned(32)));
cbw_buffer = (void *)_cbw_buffer; cbw_buffer = (void *)_cbw_buffer;
static unsigned char _transfer_buffer[BUFFER_SIZE*2] static unsigned char _transfer_buffer[ALLOCATE_BUFFER_SIZE]
USB_DEVBSS_ATTR __attribute__((aligned(32))); USB_DEVBSS_ATTR __attribute__((aligned(32)));
tb.transfer_buffer = (void *)_transfer_buffer; tb.transfer_buffer = (void *)_transfer_buffer;
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
@ -420,7 +426,7 @@ void usb_storage_init_connection(void)
tb.transfer_buffer = cbw_buffer + 1024; tb.transfer_buffer = cbw_buffer + 1024;
cpucache_invalidate(); cpucache_invalidate();
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
ramdisk_buffer = tb.transfer_buffer + BUFFER_SIZE*2; ramdisk_buffer = tb.transfer_buffer + ALLOCATE_BUFFER_SIZE;
#endif #endif
#endif #endif
usb_drv_recv(ep_out, cbw_buffer, 1024); usb_drv_recv(ep_out, cbw_buffer, 1024);
@ -460,20 +466,20 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
if(status==0) { if(status==0) {
if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count) if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count)
&& (unsigned int)length!=BUFFER_SIZE) { && (unsigned int)length!=WRITE_BUFFER_SIZE) {
logf("unexpected length :%d",length); logf("unexpected length :%d",length);
} }
unsigned int next_sector = cur_cmd.sector + unsigned int next_sector = cur_cmd.sector +
(BUFFER_SIZE/SECTOR_SIZE); (WRITE_BUFFER_SIZE/SECTOR_SIZE);
unsigned int next_count = cur_cmd.count - unsigned int next_count = cur_cmd.count -
MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE);
int next_select = !cur_cmd.data_select; int next_select = !cur_cmd.data_select;
if(next_count!=0) { if(next_count!=0) {
/* Ask the host to send more, to the other buffer */ /* Ask the host to send more, to the other buffer */
receive_block_data(cur_cmd.data[next_select], receive_block_data(cur_cmd.data[next_select],
MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); MIN(WRITE_BUFFER_SIZE,next_count*SECTOR_SIZE));
} }
/* Now write the data that just came in, while the host is /* Now write the data that just came in, while the host is
@ -481,11 +487,11 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
memcpy(ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, memcpy(ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
cur_cmd.data[cur_cmd.data_select], cur_cmd.data[cur_cmd.data_select],
MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
#else #else
int result = storage_write_sectors(cur_cmd.lun, int result = storage_write_sectors(cur_cmd.lun,
cur_cmd.sector, cur_cmd.sector,
MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
cur_cmd.data[cur_cmd.data_select]); cur_cmd.data[cur_cmd.data_select]);
if(result != 0) { if(result != 0) {
send_csw(UMS_STATUS_FAIL); send_csw(UMS_STATUS_FAIL);
@ -644,13 +650,13 @@ static void send_and_read_next(void)
return; return;
} }
send_block_data(cur_cmd.data[cur_cmd.data_select], send_block_data(cur_cmd.data[cur_cmd.data_select],
MIN(BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE)); MIN(READ_BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE));
/* Switch buffers for the next one */ /* Switch buffers for the next one */
cur_cmd.data_select=!cur_cmd.data_select; cur_cmd.data_select=!cur_cmd.data_select;
cur_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE); cur_cmd.sector+=(READ_BUFFER_SIZE/SECTOR_SIZE);
cur_cmd.count-=MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); cur_cmd.count-=MIN(cur_cmd.count,READ_BUFFER_SIZE/SECTOR_SIZE);
if(cur_cmd.count!=0) { if(cur_cmd.count!=0) {
/* already read the next bit, so we can send it out immediately when the /* already read the next bit, so we can send it out immediately when the
@ -658,11 +664,11 @@ static void send_and_read_next(void)
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
memcpy(cur_cmd.data[cur_cmd.data_select], memcpy(cur_cmd.data[cur_cmd.data_select],
ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
#else #else
cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, cur_cmd.last_result = storage_read_sectors(cur_cmd.lun,
cur_cmd.sector, cur_cmd.sector,
MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
cur_cmd.data[cur_cmd.data_select]); cur_cmd.data[cur_cmd.data_select]);
#endif #endif
} }
@ -977,7 +983,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
break; break;
} }
cur_cmd.data[0] = tb.transfer_buffer; cur_cmd.data[0] = tb.transfer_buffer;
cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; cur_cmd.data[1] = &tb.transfer_buffer[READ_BUFFER_SIZE];
cur_cmd.data_select=0; cur_cmd.data_select=0;
cur_cmd.sector = block_size_mult * cur_cmd.sector = block_size_mult *
(cbw->command_block[2] << 24 | (cbw->command_block[2] << 24 |
@ -1001,11 +1007,11 @@ static void handle_scsi(struct command_block_wrapper* cbw)
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
memcpy(cur_cmd.data[cur_cmd.data_select], memcpy(cur_cmd.data[cur_cmd.data_select],
ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
MIN(BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE);
#else #else
cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, cur_cmd.last_result = storage_read_sectors(cur_cmd.lun,
cur_cmd.sector, cur_cmd.sector,
MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
cur_cmd.data[cur_cmd.data_select]); cur_cmd.data[cur_cmd.data_select]);
#ifdef TOSHIBA_GIGABEAT_S #ifdef TOSHIBA_GIGABEAT_S
@ -1028,7 +1034,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
break; break;
} }
cur_cmd.data[0] = tb.transfer_buffer; cur_cmd.data[0] = tb.transfer_buffer;
cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; cur_cmd.data[1] = &tb.transfer_buffer[WRITE_BUFFER_SIZE];
cur_cmd.data_select=0; cur_cmd.data_select=0;
cur_cmd.sector = block_size_mult * cur_cmd.sector = block_size_mult *
(cbw->command_block[2] << 24 | (cbw->command_block[2] << 24 |
@ -1049,7 +1055,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
} }
else { else {
receive_block_data(cur_cmd.data[0], receive_block_data(cur_cmd.data[0],
MIN(BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
} }
break; break;