void MassStorage_t::SCSICmdHandler() { // Uart.Printf("\rSgn=%X; Tag=%X; Len=%u; Flags=%X; LUN=%u; SLen=%u; SCmd=%A", CmdBlock.Signature, CmdBlock.Tag, CmdBlock.DataTransferLen, CmdBlock.Flags, CmdBlock.LUN, CmdBlock.SCSICmdLen, CmdBlock.SCSICmdData, CmdBlock.SCSICmdLen, ' '); // Uart.Printf("\rSCmd=%X", CmdBlock.SCSICmdData[0]); bool CmdOk = false; switch(CmdBlock.SCSICmdData[0]) { case SCSI_CMD_INQUIRY: CmdOk = CmdInquiry(); break; case SCSI_CMD_REQUEST_SENSE: CmdOk = CmdRequestSense(); break; case SCSI_CMD_READ_CAPACITY_10: CmdOk = CmdReadCapacity10(); break; case SCSI_CMD_SEND_DIAGNOSTIC: CmdOk = CmdSendDiagnostic(); break; case SCSI_READ_FORMAT_CAPACITIES: CmdOk = CmdReadFormatCapacities(); break; case SCSI_CMD_WRITE_10: CmdOk = CmdWrite10(); break; case SCSI_CMD_READ_10: CmdOk = CmdRead10(); break; case SCSI_CMD_MODE_SENSE_6: CmdOk = CmdModeSense6(); break; // These commands should just succeed, no handling required case SCSI_CMD_TEST_UNIT_READY: case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: case SCSI_CMD_VERIFY_10: case SCSI_CMD_SYNCHRONIZE_CACHE: case SCSI_CMD_START_STOP_UNIT: CmdOk = true; CmdBlock.DataTransferLen = 0; break; default: Uart.Printf("\rMSCmd %X not supported", CmdBlock.SCSICmdData[0]); // Update the SENSE key to reflect the invalid command SenseData.SenseKey = SCSI_SENSE_KEY_ILLEGAL_REQUEST; SenseData.AdditionalSenseCode = SCSI_ASENSE_INVALID_COMMAND; SenseData.AdditionalSenseQualifier = SCSI_ASENSEQ_NO_QUALIFIER; // Update status //CmdStatus.DataTransferResidue = 0; // 0 or requested length? break; } // switch // Update Sense if command was successfully processed if(CmdOk) { SenseData.SenseKey = SCSI_SENSE_KEY_GOOD; SenseData.AdditionalSenseCode = SCSI_ASENSE_NO_ADDITIONAL_INFORMATION; SenseData.AdditionalSenseQualifier = SCSI_ASENSEQ_NO_QUALIFIER; } // Send status CmdStatus.Status = CmdOk? MS_SCSI_Status_Good : MS_SCSI_Status_Check_Condition; CmdStatus.Signature = MS_CSW_SIGNATURE; CmdStatus.Tag = CmdBlock.Tag; // DataTransferLen decreased at cmd handlers CmdStatus.DataTransferResidue = CmdBlock.DataTransferLen; // Stall if cmd failed and there is data to send bool ShouldSendStatus = true; if(!CmdOk) { Usb.PEpBulkIn->SetStallIn(); ShouldSendStatus = (Usb.PEpBulkIn->WaitUntilReady() == OK); } if(ShouldSendStatus) Usb.PEpBulkIn->StartTransmitBuf((uint8_t*)&CmdStatus, sizeof(MS_CommandStatusWrapper_t)); }
int LineRequestSense(SCSI_HANDLE handle, COMMON_PARAMS common, int argc, char**argv) { if (argc > optind) { help(common); return -1; } { dat = CmdRequestSense(handle, common); } return 0; }