summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/usb_storage.c')
-rw-r--r--firmware/usbstack/usb_storage.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 9ee58f8d90..0d06221750 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -51,8 +51,14 @@
51 * enough for efficient mass storage support, as commonly host OSes 51 * enough for efficient mass storage support, as commonly host OSes
52 * don't do larger SCSI transfers anyway, so larger USB transfers 52 * don't do larger SCSI transfers anyway, so larger USB transfers
53 * wouldn't buy us anything. 53 * wouldn't buy us anything.
54 * Due to being the double-buffering system used, using a smaller write buffer
55 * ends up being more efficient. Measurements have shown that 24k to 28k is
56 * optimal
54 */ 57 */
55#define BUFFER_SIZE 65536 58#define READ_BUFFER_SIZE (1024*64)
59#define WRITE_BUFFER_SIZE (1024*24)
60
61#define ALLOCATE_BUFFER_SIZE (2*MAX(READ_BUFFER_SIZE,WRITE_BUFFER_SIZE))
56 62
57/* bulk-only class specific requests */ 63/* bulk-only class specific requests */
58#define USB_BULK_RESET_REQUEST 0xff 64#define USB_BULK_RESET_REQUEST 0xff
@@ -399,11 +405,11 @@ void usb_storage_init_connection(void)
399 405
400#if CONFIG_CPU == IMX31L || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \ 406#if CONFIG_CPU == IMX31L || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \
401 defined(BOOTLOADER) || CONFIG_CPU == DM320 407 defined(BOOTLOADER) || CONFIG_CPU == DM320
402 static unsigned char _cbw_buffer[BUFFER_SIZE*2] 408 static unsigned char _cbw_buffer[ALLOCATE_BUFFER_SIZE]
403 USB_DEVBSS_ATTR __attribute__((aligned(32))); 409 USB_DEVBSS_ATTR __attribute__((aligned(32)));
404 cbw_buffer = (void *)_cbw_buffer; 410 cbw_buffer = (void *)_cbw_buffer;
405 411
406 static unsigned char _transfer_buffer[BUFFER_SIZE*2] 412 static unsigned char _transfer_buffer[ALLOCATE_BUFFER_SIZE]
407 USB_DEVBSS_ATTR __attribute__((aligned(32))); 413 USB_DEVBSS_ATTR __attribute__((aligned(32)));
408 tb.transfer_buffer = (void *)_transfer_buffer; 414 tb.transfer_buffer = (void *)_transfer_buffer;
409#ifdef USB_USE_RAMDISK 415#ifdef USB_USE_RAMDISK
@@ -420,7 +426,7 @@ void usb_storage_init_connection(void)
420 tb.transfer_buffer = cbw_buffer + 1024; 426 tb.transfer_buffer = cbw_buffer + 1024;
421 cpucache_invalidate(); 427 cpucache_invalidate();
422#ifdef USB_USE_RAMDISK 428#ifdef USB_USE_RAMDISK
423 ramdisk_buffer = tb.transfer_buffer + BUFFER_SIZE*2; 429 ramdisk_buffer = tb.transfer_buffer + ALLOCATE_BUFFER_SIZE;
424#endif 430#endif
425#endif 431#endif
426 usb_drv_recv(ep_out, cbw_buffer, 1024); 432 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)
460 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); 466 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
461 if(status==0) { 467 if(status==0) {
462 if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count) 468 if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count)
463 && (unsigned int)length!=BUFFER_SIZE) { 469 && (unsigned int)length!=WRITE_BUFFER_SIZE) {
464 logf("unexpected length :%d",length); 470 logf("unexpected length :%d",length);
465 } 471 }
466 472
467 unsigned int next_sector = cur_cmd.sector + 473 unsigned int next_sector = cur_cmd.sector +
468 (BUFFER_SIZE/SECTOR_SIZE); 474 (WRITE_BUFFER_SIZE/SECTOR_SIZE);
469 unsigned int next_count = cur_cmd.count - 475 unsigned int next_count = cur_cmd.count -
470 MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); 476 MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE);
471 int next_select = !cur_cmd.data_select; 477 int next_select = !cur_cmd.data_select;
472 478
473 if(next_count!=0) { 479 if(next_count!=0) {
474 /* Ask the host to send more, to the other buffer */ 480 /* Ask the host to send more, to the other buffer */
475 receive_block_data(cur_cmd.data[next_select], 481 receive_block_data(cur_cmd.data[next_select],
476 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); 482 MIN(WRITE_BUFFER_SIZE,next_count*SECTOR_SIZE));
477 } 483 }
478 484
479 /* Now write the data that just came in, while the host is 485 /* 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)
481#ifdef USB_USE_RAMDISK 487#ifdef USB_USE_RAMDISK
482 memcpy(ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 488 memcpy(ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
483 cur_cmd.data[cur_cmd.data_select], 489 cur_cmd.data[cur_cmd.data_select],
484 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 490 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
485#else 491#else
486 int result = storage_write_sectors(cur_cmd.lun, 492 int result = storage_write_sectors(cur_cmd.lun,
487 cur_cmd.sector, 493 cur_cmd.sector,
488 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 494 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
489 cur_cmd.data[cur_cmd.data_select]); 495 cur_cmd.data[cur_cmd.data_select]);
490 if(result != 0) { 496 if(result != 0) {
491 send_csw(UMS_STATUS_FAIL); 497 send_csw(UMS_STATUS_FAIL);
@@ -644,13 +650,13 @@ static void send_and_read_next(void)
644 return; 650 return;
645 } 651 }
646 send_block_data(cur_cmd.data[cur_cmd.data_select], 652 send_block_data(cur_cmd.data[cur_cmd.data_select],
647 MIN(BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE)); 653 MIN(READ_BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE));
648 654
649 /* Switch buffers for the next one */ 655 /* Switch buffers for the next one */
650 cur_cmd.data_select=!cur_cmd.data_select; 656 cur_cmd.data_select=!cur_cmd.data_select;
651 657
652 cur_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE); 658 cur_cmd.sector+=(READ_BUFFER_SIZE/SECTOR_SIZE);
653 cur_cmd.count-=MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); 659 cur_cmd.count-=MIN(cur_cmd.count,READ_BUFFER_SIZE/SECTOR_SIZE);
654 660
655 if(cur_cmd.count!=0) { 661 if(cur_cmd.count!=0) {
656 /* already read the next bit, so we can send it out immediately when the 662 /* 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)
658#ifdef USB_USE_RAMDISK 664#ifdef USB_USE_RAMDISK
659 memcpy(cur_cmd.data[cur_cmd.data_select], 665 memcpy(cur_cmd.data[cur_cmd.data_select],
660 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 666 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
661 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 667 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
662#else 668#else
663 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, 669 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun,
664 cur_cmd.sector, 670 cur_cmd.sector,
665 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 671 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
666 cur_cmd.data[cur_cmd.data_select]); 672 cur_cmd.data[cur_cmd.data_select]);
667#endif 673#endif
668 } 674 }
@@ -977,7 +983,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
977 break; 983 break;
978 } 984 }
979 cur_cmd.data[0] = tb.transfer_buffer; 985 cur_cmd.data[0] = tb.transfer_buffer;
980 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; 986 cur_cmd.data[1] = &tb.transfer_buffer[READ_BUFFER_SIZE];
981 cur_cmd.data_select=0; 987 cur_cmd.data_select=0;
982 cur_cmd.sector = block_size_mult * 988 cur_cmd.sector = block_size_mult *
983 (cbw->command_block[2] << 24 | 989 (cbw->command_block[2] << 24 |
@@ -1001,11 +1007,11 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1001#ifdef USB_USE_RAMDISK 1007#ifdef USB_USE_RAMDISK
1002 memcpy(cur_cmd.data[cur_cmd.data_select], 1008 memcpy(cur_cmd.data[cur_cmd.data_select],
1003 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 1009 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
1004 MIN(BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); 1010 MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE);
1005#else 1011#else
1006 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun, 1012 cur_cmd.last_result = storage_read_sectors(cur_cmd.lun,
1007 cur_cmd.sector, 1013 cur_cmd.sector,
1008 MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 1014 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
1009 cur_cmd.data[cur_cmd.data_select]); 1015 cur_cmd.data[cur_cmd.data_select]);
1010 1016
1011#ifdef TOSHIBA_GIGABEAT_S 1017#ifdef TOSHIBA_GIGABEAT_S
@@ -1028,7 +1034,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1028 break; 1034 break;
1029 } 1035 }
1030 cur_cmd.data[0] = tb.transfer_buffer; 1036 cur_cmd.data[0] = tb.transfer_buffer;
1031 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; 1037 cur_cmd.data[1] = &tb.transfer_buffer[WRITE_BUFFER_SIZE];
1032 cur_cmd.data_select=0; 1038 cur_cmd.data_select=0;
1033 cur_cmd.sector = block_size_mult * 1039 cur_cmd.sector = block_size_mult *
1034 (cbw->command_block[2] << 24 | 1040 (cbw->command_block[2] << 24 |
@@ -1049,7 +1055,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1049 } 1055 }
1050 else { 1056 else {
1051 receive_block_data(cur_cmd.data[0], 1057 receive_block_data(cur_cmd.data[0],
1052 MIN(BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); 1058 MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE));
1053 } 1059 }
1054 break; 1060 break;
1055 1061