diff options
Diffstat (limited to 'firmware/usbstack')
-rw-r--r-- | firmware/usbstack/usb_storage.c | 217 |
1 files changed, 147 insertions, 70 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index e226c15f99..617988b19f 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -106,8 +106,9 @@ | |||
106 | #define SCSI_MODE_SENSE_10 0x5a | 106 | #define SCSI_MODE_SENSE_10 0x5a |
107 | #define SCSI_REQUEST_SENSE 0x03 | 107 | #define SCSI_REQUEST_SENSE 0x03 |
108 | #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e | 108 | #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e |
109 | #define SCSI_READ_CAPACITY 0x25 | 109 | #define SCSI_READ_CAPACITY_10 0x25 |
110 | #define SCSI_READ_FORMAT_CAPACITY 0x23 | 110 | #define SCSI_READ_CAPACITY_16 0x9e |
111 | #define USB_UFI_READ_FORMAT_CAPACITY 0x23 | ||
111 | #define SCSI_READ_10 0x28 | 112 | #define SCSI_READ_10 0x28 |
112 | #define SCSI_WRITE_10 0x2a | 113 | #define SCSI_WRITE_10 0x2a |
113 | #define SCSI_START_STOP_UNIT 0x1b | 114 | #define SCSI_START_STOP_UNIT 0x1b |
@@ -248,9 +249,16 @@ struct command_status_wrapper { | |||
248 | unsigned char status; | 249 | unsigned char status; |
249 | } __attribute__ ((packed)); | 250 | } __attribute__ ((packed)); |
250 | 251 | ||
251 | struct capacity { | 252 | struct capacity_10 { |
252 | unsigned int block_count; | 253 | unsigned char block_count[4]; |
253 | unsigned int block_size; | 254 | unsigned char block_size[4]; |
255 | } __attribute__ ((packed)); | ||
256 | |||
257 | struct capacity_16 { | ||
258 | unsigned char block_count[8]; | ||
259 | unsigned char block_size[4]; | ||
260 | unsigned char flags[2]; | ||
261 | unsigned char lowest_aligned_lba[2]; | ||
254 | } __attribute__ ((packed)); | 262 | } __attribute__ ((packed)); |
255 | 263 | ||
256 | struct format_capacity { | 264 | struct format_capacity { |
@@ -263,7 +271,8 @@ struct format_capacity { | |||
263 | static union { | 271 | static union { |
264 | unsigned char* transfer_buffer; | 272 | unsigned char* transfer_buffer; |
265 | struct inquiry_data* inquiry; | 273 | struct inquiry_data* inquiry; |
266 | struct capacity* capacity_data; | 274 | struct capacity_10* capacity_data_10; |
275 | struct capacity_16* capacity_data_16; | ||
267 | struct format_capacity* format_capacity_data; | 276 | struct format_capacity* format_capacity_data; |
268 | struct sense_data *sense_data; | 277 | struct sense_data *sense_data; |
269 | struct mode_sense_data_6 *ms_data_6; | 278 | struct mode_sense_data_6 *ms_data_6; |
@@ -278,8 +287,8 @@ static char *cbw_buffer; | |||
278 | static struct { | 287 | static struct { |
279 | sector_t sector; | 288 | sector_t sector; |
280 | unsigned int count; | 289 | unsigned int count; |
281 | unsigned int orig_count; | ||
282 | unsigned int cur_cmd; | 290 | unsigned int cur_cmd; |
291 | unsigned int block_size; | ||
283 | unsigned int tag; | 292 | unsigned int tag; |
284 | unsigned int lun; | 293 | unsigned int lun; |
285 | unsigned char *data[2]; | 294 | unsigned char *data[2]; |
@@ -501,6 +510,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length) | |||
501 | #endif | 510 | #endif |
502 | 511 | ||
503 | logf("transfer result for ep %d/%d %X %d", ep,dir,status, length); | 512 | logf("transfer result for ep %d/%d %X %d", ep,dir,status, length); |
513 | |||
504 | switch(state) { | 514 | switch(state) { |
505 | case RECEIVING_BLOCKS: | 515 | case RECEIVING_BLOCKS: |
506 | if(dir==USB_DIR_IN) { | 516 | if(dir==USB_DIR_IN) { |
@@ -508,37 +518,37 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length) | |||
508 | } | 518 | } |
509 | logf("scsi write %llu %d", cur_cmd.sector, cur_cmd.count); | 519 | logf("scsi write %llu %d", cur_cmd.sector, cur_cmd.count); |
510 | if(status==0) { | 520 | if(status==0) { |
511 | if((unsigned int)length!=(SECTOR_SIZE* cur_cmd.count) | 521 | if((unsigned int)length!=(cur_cmd.block_size* cur_cmd.count) |
512 | && (unsigned int)length!=WRITE_BUFFER_SIZE) { | 522 | && (unsigned int)length!=WRITE_BUFFER_SIZE) { |
513 | logf("unexpected length :%d",length); | 523 | logf("unexpected length :%d",length); |
514 | break; | 524 | break; |
515 | } | 525 | } |
516 | 526 | ||
517 | sector_t next_sector = cur_cmd.sector + | 527 | sector_t next_sector = cur_cmd.sector + |
518 | (WRITE_BUFFER_SIZE/SECTOR_SIZE); | 528 | (WRITE_BUFFER_SIZE/cur_cmd.block_size); |
519 | unsigned int next_count = cur_cmd.count - | 529 | unsigned int next_count = cur_cmd.count - |
520 | MIN(cur_cmd.count,WRITE_BUFFER_SIZE/SECTOR_SIZE); | 530 | MIN(cur_cmd.count,WRITE_BUFFER_SIZE/cur_cmd.block_size); |
521 | int next_select = !cur_cmd.data_select; | 531 | int next_select = !cur_cmd.data_select; |
522 | 532 | ||
523 | if(next_count!=0) { | 533 | if(next_count!=0) { |
524 | /* Ask the host to send more, to the other buffer */ | 534 | /* Ask the host to send more, to the other buffer */ |
525 | receive_block_data(cur_cmd.data[next_select], | 535 | receive_block_data(cur_cmd.data[next_select], |
526 | MIN(WRITE_BUFFER_SIZE,next_count*SECTOR_SIZE)); | 536 | MIN(WRITE_BUFFER_SIZE,next_count*cur_cmd.block_size)); |
527 | } | 537 | } |
528 | 538 | ||
529 | /* Now write the data that just came in, while the host is | 539 | /* Now write the data that just came in, while the host is |
530 | sending the next bit */ | 540 | sending the next bit */ |
531 | #ifdef USB_USE_RAMDISK | 541 | #ifdef USB_USE_RAMDISK |
532 | memcpy(ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, | 542 | memcpy(ramdisk_buffer + cur_cmd.sector*cur_cmd.block_size, |
533 | cur_cmd.data[cur_cmd.data_select], | 543 | cur_cmd.data[cur_cmd.data_select], |
534 | MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); | 544 | MIN(WRITE_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count)*cur_cmd.block_size); |
535 | #else | 545 | #else |
536 | int result = USBSTOR_WRITE_SECTORS_FILTER(); | 546 | int result = USBSTOR_WRITE_SECTORS_FILTER(); |
537 | 547 | ||
538 | if (result == 0) { | 548 | if (result == 0) { |
539 | result = storage_write_sectors(IF_MD(cur_cmd.lun,) | 549 | result = storage_write_sectors(IF_MD(cur_cmd.lun,) |
540 | cur_cmd.sector, | 550 | cur_cmd.sector, |
541 | MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), | 551 | MIN(WRITE_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count), |
542 | cur_cmd.data[cur_cmd.data_select]); | 552 | cur_cmd.data[cur_cmd.data_select]); |
543 | } | 553 | } |
544 | 554 | ||
@@ -712,25 +722,25 @@ static void send_and_read_next(void) | |||
712 | cur_cmd.last_result = result; | 722 | cur_cmd.last_result = result; |
713 | 723 | ||
714 | send_block_data(cur_cmd.data[cur_cmd.data_select], | 724 | send_block_data(cur_cmd.data[cur_cmd.data_select], |
715 | MIN(READ_BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE)); | 725 | MIN(READ_BUFFER_SIZE,cur_cmd.count*cur_cmd.block_size)); |
716 | 726 | ||
717 | /* Switch buffers for the next one */ | 727 | /* Switch buffers for the next one */ |
718 | cur_cmd.data_select=!cur_cmd.data_select; | 728 | cur_cmd.data_select=!cur_cmd.data_select; |
719 | 729 | ||
720 | cur_cmd.sector+=(READ_BUFFER_SIZE/SECTOR_SIZE); | 730 | cur_cmd.sector+=(READ_BUFFER_SIZE/cur_cmd.block_size); |
721 | cur_cmd.count-=MIN(cur_cmd.count,READ_BUFFER_SIZE/SECTOR_SIZE); | 731 | cur_cmd.count-=MIN(cur_cmd.count,READ_BUFFER_SIZE/cur_cmd.block_size); |
722 | 732 | ||
723 | if(cur_cmd.count!=0) { | 733 | if(cur_cmd.count!=0) { |
724 | /* already read the next bit, so we can send it out immediately when the | 734 | /* already read the next bit, so we can send it out immediately when the |
725 | * current transfer completes. */ | 735 | * current transfer completes. */ |
726 | #ifdef USB_USE_RAMDISK | 736 | #ifdef USB_USE_RAMDISK |
727 | memcpy(cur_cmd.data[cur_cmd.data_select], | 737 | memcpy(cur_cmd.data[cur_cmd.data_select], |
728 | ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, | 738 | ramdisk_buffer + cur_cmd.sector*cur_cmd.block_size, |
729 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); | 739 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count)*cur_cmd.block_size); |
730 | #else | 740 | #else |
731 | result = storage_read_sectors(IF_MD(cur_cmd.lun,) | 741 | result = storage_read_sectors(IF_MD(cur_cmd.lun,) |
732 | cur_cmd.sector, | 742 | cur_cmd.sector, |
733 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), | 743 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count), |
734 | cur_cmd.data[cur_cmd.data_select]); | 744 | cur_cmd.data[cur_cmd.data_select]); |
735 | if(cur_cmd.last_result == 0) | 745 | if(cur_cmd.last_result == 0) |
736 | cur_cmd.last_result = result; | 746 | cur_cmd.last_result = result; |
@@ -748,7 +758,6 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
748 | unsigned int block_size; | 758 | unsigned int block_size; |
749 | bool lun_present=true; | 759 | bool lun_present=true; |
750 | unsigned char lun = cbw->lun; | 760 | unsigned char lun = cbw->lun; |
751 | unsigned int block_size_mult = 1; | ||
752 | 761 | ||
753 | if(letoh32(cbw->signature) != CBW_SIGNATURE) { | 762 | if(letoh32(cbw->signature) != CBW_SIGNATURE) { |
754 | logf("ums: bad cbw signature (%x)", cbw->signature); | 763 | logf("ums: bad cbw signature (%x)", cbw->signature); |
@@ -783,10 +792,14 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
783 | if(ejected[lun]) | 792 | if(ejected[lun]) |
784 | lun_present = false; | 793 | lun_present = false; |
785 | 794 | ||
795 | unsigned int block_size_mult = 1; /* Number of LOGICAL storage device blocks in each USB block */ | ||
786 | #ifdef MAX_LOG_SECTOR_SIZE | 796 | #ifdef MAX_LOG_SECTOR_SIZE |
787 | block_size_mult = disk_get_sector_multiplier(IF_MD(lun)); | 797 | block_size_mult = disk_get_sector_multiplier(IF_MD(lun)); |
788 | #endif | 798 | #endif |
789 | 799 | ||
800 | uint32_t bsize = block_size*block_size_mult; | ||
801 | sector_t bcount = block_count/block_size_mult; | ||
802 | |||
790 | cur_cmd.tag = cbw->tag; | 803 | cur_cmd.tag = cbw->tag; |
791 | cur_cmd.lun = lun; | 804 | cur_cmd.lun = lun; |
792 | cur_cmd.cur_cmd = cbw->command_block[0]; | 805 | cur_cmd.cur_cmd = cbw->command_block[0]; |
@@ -887,31 +900,33 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
887 | htobe16(sizeof(struct mode_sense_bdesc_longlba)); | 900 | htobe16(sizeof(struct mode_sense_bdesc_longlba)); |
888 | 901 | ||
889 | memset(tb.ms_data_10->block_descriptor.reserved,0,4); | 902 | memset(tb.ms_data_10->block_descriptor.reserved,0,4); |
890 | memset(tb.ms_data_10->block_descriptor.num_blocks,0,8); | ||
891 | 903 | ||
892 | #ifdef STORAGE_64BIT_SECTOR | 904 | #ifdef STORAGE_64BIT_SECTOR |
893 | tb.ms_data_10->block_descriptor.num_blocks[2] = | 905 | tb.ms_data_10->block_descriptor.num_blocks[2] = |
894 | ((block_count/block_size_mult) & 0xff00000000ULL)>>40; | 906 | (bcount & 0xff00000000ULL)>>40; |
895 | tb.ms_data_10->block_descriptor.num_blocks[3] = | 907 | tb.ms_data_10->block_descriptor.num_blocks[3] = |
896 | ((block_count/block_size_mult) & 0x00ff000000ULL)>>32; | 908 | (bcount & 0x00ff000000ULL)>>32; |
909 | #else | ||
910 | tb.ms_data_10->block_descriptor.num_blocks[2] = 0; | ||
911 | tb.ms_data_10->block_descriptor.num_blocks[3] = 0; | ||
897 | #endif | 912 | #endif |
898 | tb.ms_data_10->block_descriptor.num_blocks[4] = | 913 | tb.ms_data_10->block_descriptor.num_blocks[4] = |
899 | ((block_count/block_size_mult) & 0xff000000)>>24; | 914 | (bcount & 0xff000000)>>24; |
900 | tb.ms_data_10->block_descriptor.num_blocks[5] = | 915 | tb.ms_data_10->block_descriptor.num_blocks[5] = |
901 | ((block_count/block_size_mult) & 0x00ff0000)>>16; | 916 | (bcount & 0x00ff0000)>>16; |
902 | tb.ms_data_10->block_descriptor.num_blocks[6] = | 917 | tb.ms_data_10->block_descriptor.num_blocks[6] = |
903 | ((block_count/block_size_mult) & 0x0000ff00)>>8; | 918 | (bcount & 0x0000ff00)>>8; |
904 | tb.ms_data_10->block_descriptor.num_blocks[7] = | 919 | tb.ms_data_10->block_descriptor.num_blocks[7] = |
905 | ((block_count/block_size_mult) & 0x000000ff); | 920 | (bcount & 0x000000ff); |
906 | 921 | ||
907 | tb.ms_data_10->block_descriptor.block_size[0] = | 922 | tb.ms_data_10->block_descriptor.block_size[0] = |
908 | ((block_size*block_size_mult) & 0xff000000)>>24; | 923 | (bsize & 0xff000000)>>24; |
909 | tb.ms_data_10->block_descriptor.block_size[1] = | 924 | tb.ms_data_10->block_descriptor.block_size[1] = |
910 | ((block_size*block_size_mult) & 0x00ff0000)>>16; | 925 | (bsize & 0x00ff0000)>>16; |
911 | tb.ms_data_10->block_descriptor.block_size[2] = | 926 | tb.ms_data_10->block_descriptor.block_size[2] = |
912 | ((block_size*block_size_mult) & 0x0000ff00)>>8; | 927 | (bsize & 0x0000ff00)>>8; |
913 | tb.ms_data_10->block_descriptor.block_size[3] = | 928 | tb.ms_data_10->block_descriptor.block_size[3] = |
914 | ((block_size*block_size_mult) & 0x000000ff); | 929 | (bsize & 0x000000ff); |
915 | send_command_result(tb.ms_data_10, | 930 | send_command_result(tb.ms_data_10, |
916 | MIN(sizeof(struct mode_sense_data_10), length)); | 931 | MIN(sizeof(struct mode_sense_data_10), length)); |
917 | break; | 932 | break; |
@@ -947,25 +962,24 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
947 | sizeof(struct mode_sense_bdesc_shortlba); | 962 | sizeof(struct mode_sense_bdesc_shortlba); |
948 | tb.ms_data_6->block_descriptor.density_code = 0; | 963 | tb.ms_data_6->block_descriptor.density_code = 0; |
949 | tb.ms_data_6->block_descriptor.reserved = 0; | 964 | tb.ms_data_6->block_descriptor.reserved = 0; |
950 | if(block_count/block_size_mult > 0xffffff) { | 965 | if(bcount > 0xffffff) { |
951 | tb.ms_data_6->block_descriptor.num_blocks[0] = 0xff; | 966 | tb.ms_data_6->block_descriptor.num_blocks[0] = 0xff; |
952 | tb.ms_data_6->block_descriptor.num_blocks[1] = 0xff; | 967 | tb.ms_data_6->block_descriptor.num_blocks[1] = 0xff; |
953 | tb.ms_data_6->block_descriptor.num_blocks[2] = 0xff; | 968 | tb.ms_data_6->block_descriptor.num_blocks[2] = 0xff; |
954 | } | 969 | } else { |
955 | else { | ||
956 | tb.ms_data_6->block_descriptor.num_blocks[0] = | 970 | tb.ms_data_6->block_descriptor.num_blocks[0] = |
957 | ((block_count/block_size_mult) & 0xff0000)>>16; | 971 | (bcount & 0xff0000)>>16; |
958 | tb.ms_data_6->block_descriptor.num_blocks[1] = | 972 | tb.ms_data_6->block_descriptor.num_blocks[1] = |
959 | ((block_count/block_size_mult) & 0x00ff00)>>8; | 973 | (bcount & 0x00ff00)>>8; |
960 | tb.ms_data_6->block_descriptor.num_blocks[2] = | 974 | tb.ms_data_6->block_descriptor.num_blocks[2] = |
961 | ((block_count/block_size_mult) & 0x0000ff); | 975 | (bcount & 0x0000ff); |
962 | } | 976 | } |
963 | tb.ms_data_6->block_descriptor.block_size[0] = | 977 | tb.ms_data_6->block_descriptor.block_size[0] = |
964 | ((block_size*block_size_mult) & 0xff0000)>>16; | 978 | (bsize & 0xff0000)>>16; |
965 | tb.ms_data_6->block_descriptor.block_size[1] = | 979 | tb.ms_data_6->block_descriptor.block_size[1] = |
966 | ((block_size*block_size_mult) & 0x00ff00)>>8; | 980 | (bsize & 0x00ff00)>>8; |
967 | tb.ms_data_6->block_descriptor.block_size[2] = | 981 | tb.ms_data_6->block_descriptor.block_size[2] = |
968 | ((block_size*block_size_mult) & 0x0000ff); | 982 | (bsize & 0x0000ff); |
969 | send_command_result(tb.ms_data_6, | 983 | send_command_result(tb.ms_data_6, |
970 | MIN(sizeof(struct mode_sense_data_6), length)); | 984 | MIN(sizeof(struct mode_sense_data_6), length)); |
971 | break; | 985 | break; |
@@ -1009,15 +1023,16 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1009 | send_csw(UMS_STATUS_GOOD); | 1023 | send_csw(UMS_STATUS_GOOD); |
1010 | break; | 1024 | break; |
1011 | 1025 | ||
1012 | case SCSI_READ_FORMAT_CAPACITY: { | 1026 | case USB_UFI_READ_FORMAT_CAPACITY: { |
1013 | logf("scsi read_format_capacity %d",lun); | 1027 | logf("usb ufi read_format_capacity %d",lun); |
1014 | if(lun_present) { | 1028 | if(lun_present) { |
1015 | tb.format_capacity_data->following_length=htobe32(8); | 1029 | tb.format_capacity_data->following_length=htobe32(8); |
1016 | /* "block count" actually means "number of last block" */ | 1030 | /* "block count" actually means "number of last block" */ |
1017 | tb.format_capacity_data->block_count = | 1031 | if (bcount > 0xffffffff) |
1018 | htobe32(block_count/block_size_mult - 1); | 1032 | tb.format_capacity_data->block_count = 0xffffffff; |
1019 | tb.format_capacity_data->block_size = | 1033 | else |
1020 | htobe32(block_size*block_size_mult); | 1034 | tb.format_capacity_data->block_count = htobe32(bcount - 1); |
1035 | tb.format_capacity_data->block_size = htobe32(bsize); | ||
1021 | tb.format_capacity_data->block_size |= | 1036 | tb.format_capacity_data->block_size |= |
1022 | htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA); | 1037 | htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA); |
1023 | 1038 | ||
@@ -1033,20 +1048,30 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1033 | break; | 1048 | break; |
1034 | } | 1049 | } |
1035 | 1050 | ||
1036 | case SCSI_READ_CAPACITY: { | 1051 | case SCSI_READ_CAPACITY_10: { |
1037 | logf("scsi read_capacity %d",lun); | 1052 | logf("scsi read_capacity10 %d",lun); |
1038 | 1053 | ||
1039 | if(lun_present) { | 1054 | if(lun_present) { |
1040 | /* "block count" actually means "number of last block" */ | 1055 | /* "block count" actually means "number of last block" */ |
1041 | tb.capacity_data->block_count = | 1056 | if (bcount >= 0xffffffff) { |
1042 | htobe32(block_count/block_size_mult - 1); | 1057 | tb.capacity_data_10->block_count[0] = 0xff; |
1043 | tb.capacity_data->block_size = | 1058 | tb.capacity_data_10->block_count[1] = 0xff; |
1044 | htobe32(block_size*block_size_mult); | 1059 | tb.capacity_data_10->block_count[2] = 0xff; |
1045 | 1060 | tb.capacity_data_10->block_count[3] = 0xff; | |
1046 | send_command_result(tb.capacity_data, | 1061 | } else { |
1047 | MIN(sizeof(struct capacity), length)); | 1062 | tb.capacity_data_10->block_count[0] = ((bcount-1) & 0xff000000)>>24; |
1048 | } | 1063 | tb.capacity_data_10->block_count[1] = ((bcount-1) & 0x00ff0000)>>16; |
1049 | else { | 1064 | tb.capacity_data_10->block_count[2] = ((bcount-1) & 0x0000ff00)>>8; |
1065 | tb.capacity_data_10->block_count[3] = ((bcount-1) & 0x000000ff); | ||
1066 | } | ||
1067 | tb.capacity_data_10->block_size[0] = (bsize & 0xff000000)>>24; | ||
1068 | tb.capacity_data_10->block_size[1] = (bsize & 0x00ff0000)>>16; | ||
1069 | tb.capacity_data_10->block_size[2] = (bsize & 0x0000ff00)>>8; | ||
1070 | tb.capacity_data_10->block_size[3] = (bsize & 0x000000ff); | ||
1071 | |||
1072 | send_command_result(tb.capacity_data_10, | ||
1073 | MIN(sizeof(struct capacity_10), length)); | ||
1074 | } else { | ||
1050 | send_command_failed_result(); | 1075 | send_command_failed_result(); |
1051 | cur_sense_data.sense_key=SENSE_NOT_READY; | 1076 | cur_sense_data.sense_key=SENSE_NOT_READY; |
1052 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 1077 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
@@ -1054,7 +1079,59 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1054 | } | 1079 | } |
1055 | break; | 1080 | break; |
1056 | } | 1081 | } |
1082 | case SCSI_READ_CAPACITY_16: { | ||
1083 | logf("scsi read_capacity16 %d",lun); | ||
1057 | 1084 | ||
1085 | if(lun_present) { | ||
1086 | /* "block count" actually means "number of last block" */ | ||
1087 | #ifdef STORAGE_64BIT_SECTOR | ||
1088 | tb.capacity_data_16->block_count[2] = | ||
1089 | ((bcount-1) & 0xff00000000ULL)>>40; | ||
1090 | tb.capacity_data_16->block_count[3] = | ||
1091 | ((bcount-1) & 0x00ff000000ULL)>>32; | ||
1092 | #else | ||
1093 | tb.capacity_data_16->block_count[2] = 0; | ||
1094 | tb.capacity_data_16->block_count[3] = 0; | ||
1095 | #endif | ||
1096 | tb.capacity_data_16->block_count[4] = | ||
1097 | ((bcount-1) & 0xff000000)>>24; | ||
1098 | tb.capacity_data_16->block_count[5] = | ||
1099 | ((bcount-1) & 0x00ff0000)>>16; | ||
1100 | tb.capacity_data_16->block_count[6] = | ||
1101 | ((bcount-1) & 0x0000ff00)>>8; | ||
1102 | tb.capacity_data_16->block_count[7] = | ||
1103 | ((bcount-1) & 0x000000ff); | ||
1104 | |||
1105 | tb.ms_data_10->block_descriptor.block_size[0] = | ||
1106 | (bsize & 0xff000000)>>24; | ||
1107 | tb.ms_data_10->block_descriptor.block_size[1] = | ||
1108 | (bsize & 0x00ff0000)>>16; | ||
1109 | tb.ms_data_10->block_descriptor.block_size[2] = | ||
1110 | (bsize & 0x0000ff00)>>8; | ||
1111 | tb.ms_data_10->block_descriptor.block_size[3] = | ||
1112 | (bsize & 0x000000ff); | ||
1113 | |||
1114 | tb.capacity_data_16->block_size[0] = (bsize & 0xff000000)>>24; | ||
1115 | tb.capacity_data_16->block_size[1] = (bsize & 0x00ff0000)>>16; | ||
1116 | tb.capacity_data_16->block_size[2] = (bsize & 0x0000ff00)>>8; | ||
1117 | tb.capacity_data_16->block_size[3] = (bsize & 0x000000ff); | ||
1118 | |||
1119 | uint16_t flags = htobe16((1<<12) | find_first_set_bit(block_size_mult)); | ||
1120 | memcpy(tb.capacity_data_16->flags, &flags, sizeof(flags)); | ||
1121 | |||
1122 | tb.capacity_data_16->lowest_aligned_lba[0] = 0; | ||
1123 | tb.capacity_data_16->lowest_aligned_lba[1] = 1; | ||
1124 | |||
1125 | send_command_result(tb.capacity_data_16, | ||
1126 | MIN(sizeof(struct capacity_16), length)); | ||
1127 | } else { | ||
1128 | send_command_failed_result(); | ||
1129 | cur_sense_data.sense_key=SENSE_NOT_READY; | ||
1130 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | ||
1131 | cur_sense_data.ascq=0; | ||
1132 | } | ||
1133 | break; | ||
1134 | } | ||
1058 | case SCSI_READ_10: | 1135 | case SCSI_READ_10: |
1059 | logf("scsi read10 %d",lun); | 1136 | logf("scsi read10 %d",lun); |
1060 | if(!lun_present) { | 1137 | if(!lun_present) { |
@@ -1075,7 +1152,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1075 | cur_cmd.count = block_size_mult * | 1152 | cur_cmd.count = block_size_mult * |
1076 | (cbw->command_block[7] << 8 | | 1153 | (cbw->command_block[7] << 8 | |
1077 | cbw->command_block[8]); | 1154 | cbw->command_block[8]); |
1078 | cur_cmd.orig_count = cur_cmd.count; | 1155 | cur_cmd.block_size = block_size; |
1079 | 1156 | ||
1080 | logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count); | 1157 | logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count); |
1081 | 1158 | ||
@@ -1088,12 +1165,12 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1088 | else { | 1165 | else { |
1089 | #ifdef USB_USE_RAMDISK | 1166 | #ifdef USB_USE_RAMDISK |
1090 | memcpy(cur_cmd.data[cur_cmd.data_select], | 1167 | memcpy(cur_cmd.data[cur_cmd.data_select], |
1091 | ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, | 1168 | ramdisk_buffer + cur_cmd.sector*cur_cmd.block_size, |
1092 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); | 1169 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size,cur_cmd.count)*cur_cmd.block_size); |
1093 | #else | 1170 | #else |
1094 | cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,) | 1171 | cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,) |
1095 | cur_cmd.sector, | 1172 | cur_cmd.sector, |
1096 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), | 1173 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count), |
1097 | cur_cmd.data[cur_cmd.data_select]); | 1174 | cur_cmd.data[cur_cmd.data_select]); |
1098 | #endif | 1175 | #endif |
1099 | send_and_read_next(); | 1176 | send_and_read_next(); |
@@ -1126,7 +1203,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1126 | cbw->command_block[11] << 16 | | 1203 | cbw->command_block[11] << 16 | |
1127 | cbw->command_block[12] << 8 | | 1204 | cbw->command_block[12] << 8 | |
1128 | cbw->command_block[13]); | 1205 | cbw->command_block[13]); |
1129 | cur_cmd.orig_count = cur_cmd.count; | 1206 | cur_cmd.block_size = block_size; |
1130 | 1207 | ||
1131 | logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count); | 1208 | logf("scsi read %llu %d", cur_cmd.sector, cur_cmd.count); |
1132 | 1209 | ||
@@ -1139,12 +1216,12 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1139 | else { | 1216 | else { |
1140 | #ifdef USB_USE_RAMDISK | 1217 | #ifdef USB_USE_RAMDISK |
1141 | memcpy(cur_cmd.data[cur_cmd.data_select], | 1218 | memcpy(cur_cmd.data[cur_cmd.data_select], |
1142 | ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, | 1219 | ramdisk_buffer + cur_cmd.sector*cur_cmd.block_size, |
1143 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE,cur_cmd.count)*SECTOR_SIZE); | 1220 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size,cur_cmd.count)*cur_cmd.block_size); |
1144 | #else | 1221 | #else |
1145 | cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,) | 1222 | cur_cmd.last_result = storage_read_sectors(IF_MD(cur_cmd.lun,) |
1146 | cur_cmd.sector, | 1223 | cur_cmd.sector, |
1147 | MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), | 1224 | MIN(READ_BUFFER_SIZE/cur_cmd.block_size, cur_cmd.count), |
1148 | cur_cmd.data[cur_cmd.data_select]); | 1225 | cur_cmd.data[cur_cmd.data_select]); |
1149 | #endif | 1226 | #endif |
1150 | send_and_read_next(); | 1227 | send_and_read_next(); |
@@ -1171,7 +1248,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1171 | cur_cmd.count = block_size_mult * | 1248 | cur_cmd.count = block_size_mult * |
1172 | (cbw->command_block[7] << 8 | | 1249 | (cbw->command_block[7] << 8 | |
1173 | cbw->command_block[8]); | 1250 | cbw->command_block[8]); |
1174 | cur_cmd.orig_count = cur_cmd.count; | 1251 | cur_cmd.block_size = block_size; |
1175 | 1252 | ||
1176 | /* expect data */ | 1253 | /* expect data */ |
1177 | if((cur_cmd.sector + cur_cmd.count) > block_count) { | 1254 | if((cur_cmd.sector + cur_cmd.count) > block_count) { |
@@ -1182,7 +1259,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1182 | } | 1259 | } |
1183 | else { | 1260 | else { |
1184 | receive_block_data(cur_cmd.data[0], | 1261 | receive_block_data(cur_cmd.data[0], |
1185 | MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); | 1262 | MIN(WRITE_BUFFER_SIZE, cur_cmd.count*cur_cmd.block_size)); |
1186 | } | 1263 | } |
1187 | break; | 1264 | break; |
1188 | #ifdef STORAGE_64BIT_SECTOR | 1265 | #ifdef STORAGE_64BIT_SECTOR |
@@ -1212,7 +1289,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1212 | cbw->command_block[11] << 16 | | 1289 | cbw->command_block[11] << 16 | |
1213 | cbw->command_block[12] << 8 | | 1290 | cbw->command_block[12] << 8 | |
1214 | cbw->command_block[13]); | 1291 | cbw->command_block[13]); |
1215 | cur_cmd.orig_count = cur_cmd.count; | 1292 | cur_cmd.block_size = block_size; |
1216 | 1293 | ||
1217 | /* expect data */ | 1294 | /* expect data */ |
1218 | if((cur_cmd.sector + cur_cmd.count) > block_count) { | 1295 | if((cur_cmd.sector + cur_cmd.count) > block_count) { |
@@ -1223,7 +1300,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
1223 | } | 1300 | } |
1224 | else { | 1301 | else { |
1225 | receive_block_data(cur_cmd.data[0], | 1302 | receive_block_data(cur_cmd.data[0], |
1226 | MIN(WRITE_BUFFER_SIZE, cur_cmd.count*SECTOR_SIZE)); | 1303 | MIN(WRITE_BUFFER_SIZE, cur_cmd.count*cur_cmd.block_size)); |
1227 | } | 1304 | } |
1228 | break; | 1305 | break; |
1229 | #endif | 1306 | #endif |