diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-04-01 20:36:51 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-04-01 20:36:51 +0000 |
commit | 688f8decf4c1b360bdd1a5ff91cf007eca4d52f9 (patch) | |
tree | b98a38a3fc1569531e2a0995558c8f8afea6bad9 /firmware/usbstack/usb_storage.c | |
parent | 92717eb9ed97447e725fb3ac6cb3182589053366 (diff) | |
download | rockbox-688f8decf4c1b360bdd1a5ff91cf007eca4d52f9.tar.gz rockbox-688f8decf4c1b360bdd1a5ff91cf007eca4d52f9.zip |
Clean up the way empty transfers are sent in error cases.
correctly zero out all data that gets sent to the host
I'm just committing this. The actual work was done by Martin Ritter (thanks)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16922 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/usbstack/usb_storage.c')
-rw-r--r-- | firmware/usbstack/usb_storage.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 0b433764cf..1f7069dfe2 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -245,6 +245,7 @@ static struct { | |||
245 | static void handle_scsi(struct command_block_wrapper* cbw); | 245 | static void handle_scsi(struct command_block_wrapper* cbw); |
246 | static void send_csw(int status); | 246 | static void send_csw(int status); |
247 | static void send_command_result(void *data,int size); | 247 | static void send_command_result(void *data,int size); |
248 | static void send_command_failed_result(void); | ||
248 | static void send_block_data(void *data,int size); | 249 | static void send_block_data(void *data,int size); |
249 | static void receive_block_data(void *data,int size); | 250 | static void receive_block_data(void *data,int size); |
250 | static void identify2inquiry(int lun); | 251 | static void identify2inquiry(int lun); |
@@ -258,6 +259,7 @@ static enum { | |||
258 | WAITING_FOR_COMMAND, | 259 | WAITING_FOR_COMMAND, |
259 | SENDING_BLOCKS, | 260 | SENDING_BLOCKS, |
260 | SENDING_RESULT, | 261 | SENDING_RESULT, |
262 | SENDING_FAILED_RESULT, | ||
261 | RECEIVING_BLOCKS, | 263 | RECEIVING_BLOCKS, |
262 | SENDING_CSW | 264 | SENDING_CSW |
263 | } state = WAITING_FOR_COMMAND; | 265 | } state = WAITING_FOR_COMMAND; |
@@ -468,6 +470,12 @@ void usb_storage_transfer_complete(bool in,int status,int length) | |||
468 | cur_sense_data.ascq=0; | 470 | cur_sense_data.ascq=0; |
469 | } | 471 | } |
470 | break; | 472 | break; |
473 | case SENDING_FAILED_RESULT: | ||
474 | if(in==false) { | ||
475 | logf("OUT received in SENDING"); | ||
476 | } | ||
477 | send_csw(UMS_STATUS_FAIL); | ||
478 | break; | ||
471 | case SENDING_BLOCKS: | 479 | case SENDING_BLOCKS: |
472 | if(in==false) { | 480 | if(in==false) { |
473 | logf("OUT received in SENDING"); | 481 | logf("OUT received in SENDING"); |
@@ -657,6 +665,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
657 | 665 | ||
658 | case SCSI_REQUEST_SENSE: { | 666 | case SCSI_REQUEST_SENSE: { |
659 | tb.sense_data->ResponseCode=0x70;/*current error*/ | 667 | tb.sense_data->ResponseCode=0x70;/*current error*/ |
668 | tb.sense_data->Obsolete=0; | ||
660 | tb.sense_data->fei_sensekey=cur_sense_data.sense_key&0x0f; | 669 | tb.sense_data->fei_sensekey=cur_sense_data.sense_key&0x0f; |
661 | tb.sense_data->Information=cur_sense_data.information; | 670 | tb.sense_data->Information=cur_sense_data.information; |
662 | tb.sense_data->AdditionalSenseLength=10; | 671 | tb.sense_data->AdditionalSenseLength=10; |
@@ -673,9 +682,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
673 | 682 | ||
674 | case SCSI_MODE_SENSE_10: { | 683 | case SCSI_MODE_SENSE_10: { |
675 | if(! lun_present) { | 684 | if(! lun_present) { |
676 | /* Windows expects an empty command result before the csw */ | 685 | send_command_failed_result(); |
677 | usb_drv_send(usb_endpoint, 0, 0); | ||
678 | send_csw(UMS_STATUS_FAIL); | ||
679 | cur_sense_data.sense_key=SENSE_NOT_READY; | 686 | cur_sense_data.sense_key=SENSE_NOT_READY; |
680 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 687 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
681 | cur_sense_data.ascq=0; | 688 | cur_sense_data.ascq=0; |
@@ -719,9 +726,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
719 | MIN(sizeof(struct mode_sense_data_10), length)); | 726 | MIN(sizeof(struct mode_sense_data_10), length)); |
720 | break; | 727 | break; |
721 | default: | 728 | default: |
722 | /* Windows expects an empty command result before the csw */ | 729 | send_command_failed_result(); |
723 | usb_drv_send(usb_endpoint, 0, 0); | ||
724 | send_csw(UMS_STATUS_FAIL); | ||
725 | cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; | 730 | cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; |
726 | cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD; | 731 | cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD; |
727 | cur_sense_data.ascq=0; | 732 | cur_sense_data.ascq=0; |
@@ -731,9 +736,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
731 | } | 736 | } |
732 | case SCSI_MODE_SENSE_6: { | 737 | case SCSI_MODE_SENSE_6: { |
733 | if(! lun_present) { | 738 | if(! lun_present) { |
734 | /* Windows expects an empty command result before the csw */ | 739 | send_command_failed_result(); |
735 | usb_drv_send(usb_endpoint, 0, 0); | ||
736 | send_csw(UMS_STATUS_FAIL); | ||
737 | cur_sense_data.sense_key=SENSE_NOT_READY; | 740 | cur_sense_data.sense_key=SENSE_NOT_READY; |
738 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 741 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
739 | cur_sense_data.ascq=0; | 742 | cur_sense_data.ascq=0; |
@@ -776,9 +779,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
776 | MIN(sizeof(struct mode_sense_data_6), length)); | 779 | MIN(sizeof(struct mode_sense_data_6), length)); |
777 | break; | 780 | break; |
778 | default: | 781 | default: |
779 | /* Windows expects an empty command result before the csw */ | 782 | send_command_failed_result(); |
780 | usb_drv_send(usb_endpoint, 0, 0); | ||
781 | send_csw(UMS_STATUS_FAIL); | ||
782 | cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; | 783 | cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; |
783 | cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD; | 784 | cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD; |
784 | cur_sense_data.ascq=0; | 785 | cur_sense_data.ascq=0; |
@@ -827,9 +828,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
827 | } | 828 | } |
828 | else | 829 | else |
829 | { | 830 | { |
830 | /* Windows expects an empty command result before the csw */ | 831 | send_command_failed_result(); |
831 | usb_drv_send(usb_endpoint, 0, 0); | ||
832 | send_csw(UMS_STATUS_FAIL); | ||
833 | cur_sense_data.sense_key=SENSE_NOT_READY; | 832 | cur_sense_data.sense_key=SENSE_NOT_READY; |
834 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 833 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
835 | cur_sense_data.ascq=0; | 834 | cur_sense_data.ascq=0; |
@@ -851,9 +850,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
851 | } | 850 | } |
852 | else | 851 | else |
853 | { | 852 | { |
854 | /* Windows expects an empty command result before the csw */ | 853 | send_command_failed_result(); |
855 | usb_drv_send(usb_endpoint, 0, 0); | ||
856 | send_csw(UMS_STATUS_FAIL); | ||
857 | cur_sense_data.sense_key=SENSE_NOT_READY; | 854 | cur_sense_data.sense_key=SENSE_NOT_READY; |
858 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 855 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
859 | cur_sense_data.ascq=0; | 856 | cur_sense_data.ascq=0; |
@@ -864,9 +861,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
864 | case SCSI_READ_10: | 861 | case SCSI_READ_10: |
865 | logf("scsi read10 %d",lun); | 862 | logf("scsi read10 %d",lun); |
866 | if(! lun_present) { | 863 | if(! lun_present) { |
867 | /* Windows expects an empty command result before the csw */ | 864 | send_command_failed_result(); |
868 | usb_drv_send(usb_endpoint, 0, 0); | ||
869 | send_csw(UMS_STATUS_FAIL); | ||
870 | cur_sense_data.sense_key=SENSE_NOT_READY; | 865 | cur_sense_data.sense_key=SENSE_NOT_READY; |
871 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 866 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
872 | cur_sense_data.ascq=0; | 867 | cur_sense_data.ascq=0; |
@@ -957,6 +952,12 @@ static void send_command_result(void *data,int size) | |||
957 | state = SENDING_RESULT; | 952 | state = SENDING_RESULT; |
958 | } | 953 | } |
959 | 954 | ||
955 | static void send_command_failed_result(void) | ||
956 | { | ||
957 | usb_drv_send_nonblocking(usb_endpoint, NULL, 0); | ||
958 | state = SENDING_FAILED_RESULT; | ||
959 | } | ||
960 | |||
960 | static void receive_block_data(void *data,int size) | 961 | static void receive_block_data(void *data,int size) |
961 | { | 962 | { |
962 | usb_drv_recv(usb_endpoint, data, size); | 963 | usb_drv_recv(usb_endpoint, data, size); |
@@ -1026,6 +1027,7 @@ static void identify2inquiry(int lun) | |||
1026 | 1027 | ||
1027 | tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE; | 1028 | tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE; |
1028 | tb.inquiry->AdditionalLength = 0x1f; | 1029 | tb.inquiry->AdditionalLength = 0x1f; |
1030 | memset(tb.inquiry->Reserved, 0, 3); | ||
1029 | tb.inquiry->Versions = 4; /* SPC-2 */ | 1031 | tb.inquiry->Versions = 4; /* SPC-2 */ |
1030 | tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ | 1032 | tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ |
1031 | 1033 | ||