// 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; } }
//--------------------------------------------- void SCSI_ProcessCommand(char length) { unsigned char a,b,i; char FromMaster; SetBit(ACSI_o,ACSI_INT); // INT to H, should do nothing, but just to be shure //printf("1->"); switch(AcsiCmnd.cmd[2] & 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); // AcsiCmnd.Active = 0; // deactivate; a sign that we processed the command 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); // AcsiCmnd.Active = 0; // deactivate; a sign that we processed the command return; } //------------------------------------------ switch(AcsiCmnd.cmd[1]) { case SCSI_C_READ_CAPACITY: SCSI_ReadCapacity(FromMaster); break; case SCSI_C_INQUIRY: ICD_SCSI6_to_ACSI(); SCSI_Inquiry(FromMaster); break; //------------------------------ // commands with length 6 bytes /* case SCSI_C_WRITE6: case SCSI_C_READ6: case SCSI_C_START_STOP_UNIT: case SCSI_C_FORMAT_UNIT: case SCSI_C_REQUEST_SENSE: case SCSI_C_TEST_UNIT_READY: */ //------------------------------ // commands with length 10 bytes /* case SCSI_C_WRITE10: case SCSI_C_READ10: case SCSI_C_WRITE_LONG: case SCSI_C_READ_LONG: case SCSI_C_READ_CAPACITY: */ //------------------------------ default: printf("\nICD (%d): ", length); printf("%x %x %x %x ", AcsiCmnd.cmd[0], AcsiCmnd.cmd[1], AcsiCmnd.cmd[2], AcsiCmnd.cmd[3]); printf("%x %x %x %x ", AcsiCmnd.cmd[4], AcsiCmnd.cmd[5], AcsiCmnd.cmd[6], AcsiCmnd.cmd[7]); printf("%x %x %x", AcsiCmnd.cmd[8], AcsiCmnd.cmd[9], AcsiCmnd.cmd[10]); SCSI_SK = SCSI_E_IllegalRequest; SCSI_ASC = SCSI_ASC_InvalidCommandOperationCode; SCSI_ASCQ = SCSI_ASCQ_NO_ADDITIONAL_SENSE; ACSI_SendStatus(ACSI_S_ERROR,FromMaster); break; } //AcsiCmnd.Active = 0; }
int SCSI_OpenDevice(int ip) { int DeviceFD; int i; extern OpenFiles_T *pDev; if (pDev[ip].inqdone == 0) { pDev[ip].inqdone = 1; /* * Check if it is an gsc (generic SCSI device) */ if (strncmp("/dev/gsc", pDev[ip].dev, 8) == 0) { pDev[ip].flags = AIX_USE_GSC; DeviceFD = open(pDev[ip].dev, 0); } else { DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC); } if (DeviceFD >= 0) { pDev[ip].avail = 1; pDev[ip].fd = DeviceFD; pDev[ip].SCSI = 0; pDev[ip].devopen = 1; pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE); if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0) { if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER) { for (i=0;i < 16;i++) pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i]; for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]) ; i--) { pDev[ip].ident[i] = '\0'; } pDev[ip].SCSI = 1; if (pDev[ip].inquiry->type == TYPE_TAPE) { pDev[ip].type = stralloc("tape"); } if (pDev[ip].inquiry->type == TYPE_CHANGER) { pDev[ip].type = stralloc("changer"); } PrintInquiry(pDev[ip].inquiry); return(1); } else { close(DeviceFD); free(pDev[ip].inquiry); return(0); } } free(pDev[ip].inquiry); pDev[ip].inquiry = NULL; return(1); } else { dbprintf(_("SCSI_OpenDevice %s failed\n"), pDev[ip].dev); return(0); } } else { if ((DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC)) >= 0) { pDev[ip].fd = DeviceFD; pDev[ip].devopen = 1; return(1); } } return(0); }