Esempio n. 1
0
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));
}
Esempio n. 2
0
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;
}