// Process a SCSI command // input: // pdev - pointer to the USB device handle // lun - logical unit number // params - pointer to the buffer with command parameters int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { switch (params[0]) { case SCSI_TEST_UNIT_READY: return SCSI_TestUnitReady(pdev,lun,params); case SCSI_REQUEST_SENSE: return SCSI_RequestSense(pdev,lun,params); case SCSI_INQUIRY: return SCSI_Inquiry(pdev,lun,params); case SCSI_START_STOP_UNIT: return SCSI_StartStopUnit(pdev,lun,params); case SCSI_ALLOW_MEDIUM_REMOVAL: return SCSI_StartStopUnit(pdev,lun,params); case SCSI_MODE_SENSE6: return SCSI_ModeSense6(pdev,lun,params); case SCSI_MODE_SENSE10: return SCSI_ModeSense10(pdev,lun,params); case SCSI_READ_FORMAT_CAPACITIES: return SCSI_ReadFormatCapacity(pdev,lun,params); case SCSI_READ_CAPACITY10: return SCSI_ReadCapacity10(pdev,lun,params); case SCSI_READ10: return SCSI_Read10(pdev,lun,params); case SCSI_WRITE10: return SCSI_Write10(pdev,lun,params); case SCSI_VERIFY10: return SCSI_Verify10(pdev,lun,params); default: SCSI_SenseCode(pdev,lun,ILLEGAL_REQUEST,INVALID_CDB); return -1; } }
/** * @brief SCSI_ProcessCmd * Process SCSI commands * @param pdev: device instance * @param lun: Logical unit number * @param params: Command parameters * @retval status */ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { /* if (params[0] != SCSI_READ10 && params[0] != SCSI_WRITE10) { printf("SCSI_ProcessCmd(lun=%d, params=%x, %x)\n", lun, params[0], params[1]); } */ switch (params[0]) { case SCSI_TEST_UNIT_READY: return SCSI_TestUnitReady(pdev, lun, params); case SCSI_REQUEST_SENSE: return SCSI_RequestSense (pdev, lun, params); case SCSI_INQUIRY: return SCSI_Inquiry(pdev, lun, params); case SCSI_START_STOP_UNIT: return SCSI_StartStopUnit(pdev, lun, params); case SCSI_ALLOW_MEDIUM_REMOVAL: return SCSI_AllowMediumRemoval(pdev, lun, params); case SCSI_MODE_SENSE6: return SCSI_ModeSense6 (pdev, lun, params); case SCSI_MODE_SENSE10: return SCSI_ModeSense10 (pdev, lun, params); case SCSI_SYNCHRONIZE_CACHE10: case SCSI_SYNCHRONIZE_CACHE16: return SCSI_SynchronizeCache(pdev, lun, params); case SCSI_READ_FORMAT_CAPACITIES: return SCSI_ReadFormatCapacity(pdev, lun, params); case SCSI_READ_CAPACITY10: return SCSI_ReadCapacity10(pdev, lun, params); case SCSI_READ10: return SCSI_Read10(pdev, lun, params); case SCSI_WRITE10: return SCSI_Write10(pdev, lun, params); case SCSI_VERIFY10: return SCSI_Verify10(pdev, lun, params); default: SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); return -1; } }
//---------------------------------------------- // function that processes any ACSI command void ACSI_ProcessCommand(void) { unsigned char a,b,i; char FromMaster; //printf("\nCmd: %x %x %x %x %x %x", AcsiCmnd.cmd[0], AcsiCmnd.cmd[1], AcsiCmnd.cmd[2], AcsiCmnd.cmd[3], AcsiCmnd.cmd[4], AcsiCmnd.cmd[5]); SetBit(ACSI_o,ACSI_INT); // INT to H switch(AcsiCmnd.cmd[1] & 0xE0) // check the device # { case 0x00: FromMaster = 1; break; // device # 0 case 0x20: FromMaster = 0; break; // device # 1 default: SCSI_SK = SCSI_E_IllegalRequest; // other devices = error SCSI_ASC = SCSI_ASC_LU_NOT_SUPPORTED; SCSI_ASCQ = SCSI_ASCQ_LU_NOT_SUPPORTED; ACSI_SendStatus(ACSI_S_ERROR,1); printf("\nError: bad device #: %x %x %x %x %x %x", AcsiCmnd.cmd[0], AcsiCmnd.cmd[1], AcsiCmnd.cmd[2], AcsiCmnd.cmd[3], AcsiCmnd.cmd[4], AcsiCmnd.cmd[5]); return; break; } // now check that if the wanted drive is present if((FromMaster && !Master.Present) || (!FromMaster && !Slave.Present)) { SCSI_SK = SCSI_E_IllegalRequest; // the device # is invalid SCSI_ASC = SCSI_ASC_LU_NOT_SUPPORTED; SCSI_ASCQ = SCSI_ASCQ_LU_NOT_SUPPORTED; ACSI_SendStatus(ACSI_S_ERROR,FromMaster); /* printf("\nError: Device not present!"); if(FromMaster) { if(Master.Present) printf("MP"); else printf("MM"); } else { if(Slave.Present) printf("SP"); else printf("SM"); } */ return; } //------------------------------------------ switch((AcsiCmnd.cmd[0] & 0x1f)) // get only the command part of byte { case ACSI_C_DriveReady : if((FromMaster && Master.Ready) || (!FromMaster && Slave.Ready)) { SCSI_SK = SCSI_E_NoSense; SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); } else { SCSI_SK = SCSI_E_NotReady; // drive not ready SCSI_ASC = SCSI_ASC_LU_NOT_READY; SCSI_ASCQ = SCSI_ASCQ_CAUSE_NOT_REPORTABLE; ACSI_SendStatus(ACSI_S_BUSY,FromMaster); } if(DEBUG_TXT) printf("\nDr"); break; //---------------------------------------------------- case ACSI_C_RestoreTo0 : SCSI_SK = SCSI_E_NoSense; // no error SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); break; case ACSI_C_RequestSense: if(AcsiCmnd.cmd[4]==4) // if 4 bytes wanted ACSI_RequestSense(FromMaster); // ACSI RS else SCSI_RequestSense(FromMaster); // SCSI RS if(DEBUG_TXT) printf("\nRs"); break; case ACSI_C_FormatDrive : /* ACSI_LastError = ACSI_E_InvalidCommand; SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; */ // printf("\nFmt"); SCSI_SK = SCSI_E_NoSense; // no error SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); if(FromMaster) // set a flag that we should be formating Master.DoFormat=1; else Slave.DoFormat=1; break; //---------------------------------------------------- case ACSI_C_ReadSector : a = IDE_ReadSector(FromMaster, AcsiCmnd.cmd[4], 0, (AcsiCmnd.cmd[1] & 0x1F), AcsiCmnd.cmd[2], AcsiCmnd.cmd[3]); if(a==0) { printf("\nRok"); SCSI_SK = SCSI_E_NoSense; // no error SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); } else { printf("\nRerr"); SCSI_SK = SCSI_E_AbortedCommand; SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_ERROR,FromMaster); } if(DEBUG_TXT) printf("\nR"); break; //---------------------------------------------------- case ACSI_C_WriteSector : // printf("\nWRITE: %x %x %x %x %x %x", AcsiCmnd.cmd[0], AcsiCmnd.cmd[1], AcsiCmnd.cmd[2], AcsiCmnd.cmd[3], AcsiCmnd.cmd[4], AcsiCmnd.cmd[5]); a = IDE_WriteSector(FromMaster, AcsiCmnd.cmd[4], 0, (AcsiCmnd.cmd[1] & 0x1F), AcsiCmnd.cmd[2], AcsiCmnd.cmd[3]); if(a==0) { printf("\nWok"); SCSI_SK = SCSI_E_NoSense; // no error SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); } else { printf("\nWerr"); SCSI_SK = SCSI_E_AbortedCommand; SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_ERROR,FromMaster); } if(DEBUG_TXT) printf("\nW"); break; //---------------------------------------------------- case ACSI_C_SeekBlock : SCSI_SK = SCSI_E_NoSense; // no error SCSI_ASC = SCSI_ASC_NO_ADDITIONAL_SENSE; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_OK,FromMaster); break; case ACSI_C_ModeSelect : ACSI_ModeSelect(FromMaster); if(DEBUG_TXT) printf("\nMSl"); break; case ACSI_C_ModeSense : a = ACSI_ModeSense(FromMaster); ACSI_SendStatus(a,FromMaster); if(DEBUG_TXT) printf("\nMSnc"); break; case SCSI_C_INQUIRY : SCSI_Inquiry(FromMaster); if(DEBUG_TXT) printf("\nI"); break; default : printf("\nUnkn: %x %x %x %x %x %x", AcsiCmnd.cmd[0], AcsiCmnd.cmd[1], AcsiCmnd.cmd[2], AcsiCmnd.cmd[3], AcsiCmnd.cmd[4], AcsiCmnd.cmd[5]); SCSI_SK = SCSI_E_IllegalRequest; SCSI_ASC = SCSI_ASC_InvalidCommandOperationCode; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_ERROR,FromMaster); break; } }