Esempio n. 1
0
USBH_Status USBH_MSC_Issue_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev)
{
  USBH_Status status = USBH_BUSY;
  USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
  if(HCD_IsDeviceConnected(&USB_OTG_FS_dev))
  {  
    do
    {
      status = USBH_MSC_GETMaxLUN(pdev);
    }
    while((status == USBH_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;
}