int8_t if_RequestSense(void) { int8_t status = EFS_ERROR; if(HCD_IsDeviceConnected(&USB_OTG_FS_dev)) { do { status = USBH_MSC_RequestSense(); USBH_MSC_HandleBOTXfer(); } while((status == USBH_MSC_BUSY ) && \ (HCD_IsDeviceConnected(&USB_OTG_FS_dev))); } return(status); }
static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , void *phost) { USBH_HOST *pphost = phost; USBH_Status status = USBH_BUSY; uint8_t mscStatus = USBH_MSC_BUSY; uint8_t appliStatus = 0; static uint8_t maxLunExceed = FALSE; if(HCD_IsDeviceConnected(pdev)) { //static uint8_t MSCState_old = -1; //if (USBH_MSC_BOTXferParam.MSCState != MSCState_old){ // USBH_SetState(1, USBH_MSC_BOTXferParam.MSCState); // MSCState_old = USBH_MSC_BOTXferParam.MSCState; //} switch(USBH_MSC_BOTXferParam.MSCState) { case USBH_MSC_BOT_INIT_STATE: USBH_MSC_Init(pdev); USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET; break; case USBH_MSC_BOT_RESET: /* Issue BOT RESET request */ status = USBH_MSC_BOTReset(pdev, phost); if(status == USBH_OK ) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN; } if(status == USBH_NOT_SUPPORTED ) { /* If the Command has failed, then we need to move to Next State, after STALL condition is cleared by Control-Transfer */ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN; /* a Clear Feature should be issued here */ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; } break; case USBH_MSC_GET_MAX_LUN: /* Issue GetMaxLUN request */ status = USBH_MSC_GETMaxLUN(pdev, phost); if(status == USBH_OK ) { MSC_Machine.maxLun = *(MSC_Machine.buff) ; /* If device has more that one logical unit then it is not supported */ if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE)) { maxLunExceed = TRUE; pphost->usr_cb->DeviceNotSupported(); break; } USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY; } if(status == USBH_NOT_SUPPORTED ) { /* If the Command has failed, then we need to move to Next State, after STALL condition is cleared by Control-Transfer */ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY; /* a Clear Feature should be issued here */ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; } break; case USBH_MSC_CTRL_ERROR_STATE: /* Issue Clearfeature request */ status = USBH_ClrFeature(pdev, phost, 0x00, pphost->Control.hc_num_out); if(status == USBH_OK ) { /* If GetMaxLun Request not support, assume Single LUN configuration */ MSC_Machine.maxLun = 0; USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; } break; case USBH_MSC_TEST_UNIT_READY: /* Issue SCSI command TestUnitReady */ mscStatus = USBH_MSC_TestUnitReady(pdev); if(mscStatus == USBH_MSC_OK ) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10; MSCErrorCount = 0; status = USBH_OK; } else { USBH_MSC_ErrorHandle(mscStatus); } break; case USBH_MSC_READ_CAPACITY10: /* Issue READ_CAPACITY10 SCSI command */ mscStatus = USBH_MSC_ReadCapacity10(pdev); if(mscStatus == USBH_MSC_OK ) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6; MSCErrorCount = 0; status = USBH_OK; } else { USBH_MSC_ErrorHandle(mscStatus); } break; case USBH_MSC_MODE_SENSE6: /* Issue ModeSense6 SCSI command for detecting if device is write-protected */ mscStatus = USBH_MSC_ModeSense6(pdev); if(mscStatus == USBH_MSC_OK ) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; MSCErrorCount = 0; status = USBH_OK; } else { USBH_MSC_ErrorHandle(mscStatus); } break; case USBH_MSC_REQUEST_SENSE: /* Issue RequestSense SCSI command for retreiving error code */ mscStatus = USBH_MSC_RequestSense(pdev); if(mscStatus == USBH_MSC_OK ) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; status = USBH_OK; } else { USBH_MSC_ErrorHandle(mscStatus); } break; case USBH_MSC_BOT_USB_TRANSFERS: /* Process the BOT state machine */ USBH_MSC_HandleBOTXfer(pdev , phost); break; case USBH_MSC_DEFAULT_APPLI_STATE: /* Process Application callback for MSC */ appliStatus = pphost->usr_cb->UserApplication(); if(appliStatus == 0) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; } else if (appliStatus == 1) { /* De-init requested from application layer */ status = USBH_APPLY_DEINIT; } break; case USBH_MSC_UNRECOVERED_STATE: status = USBH_UNRECOVERED_ERROR; break; default: break; } } return status; }