summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-04-01 20:36:51 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-04-01 20:36:51 +0000
commit688f8decf4c1b360bdd1a5ff91cf007eca4d52f9 (patch)
treeb98a38a3fc1569531e2a0995558c8f8afea6bad9
parent92717eb9ed97447e725fb3ac6cb3182589053366 (diff)
downloadrockbox-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
-rw-r--r--firmware/usbstack/usb_storage.c44
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 {
245static void handle_scsi(struct command_block_wrapper* cbw); 245static void handle_scsi(struct command_block_wrapper* cbw);
246static void send_csw(int status); 246static void send_csw(int status);
247static void send_command_result(void *data,int size); 247static void send_command_result(void *data,int size);
248static void send_command_failed_result(void);
248static void send_block_data(void *data,int size); 249static void send_block_data(void *data,int size);
249static void receive_block_data(void *data,int size); 250static void receive_block_data(void *data,int size);
250static void identify2inquiry(int lun); 251static 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
955static void send_command_failed_result(void)
956{
957 usb_drv_send_nonblocking(usb_endpoint, NULL, 0);
958 state = SENDING_FAILED_RESULT;
959}
960
960static void receive_block_data(void *data,int size) 961static 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