/** * @brief USBH_MSC_SCSI_Inquiry * Issue Inquiry command. * @param phost: Host handle * @param lun: Logical Unit Number * @param capacity: pointer to the inquiry structure * @retval USBH Status */ USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost, uint8_t lun, SCSI_StdInquiryDataTypeDef *inquiry) { USBH_StatusTypeDef error = USBH_FAIL ; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; switch(MSC_Handle->hbot.cmd_state) { case BOT_CMD_SEND: /*Prepare the CBW and relevent field*/ MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY; MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH); MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY; MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5); MSC_Handle->hbot.cbw.field.CB[2] = 0; MSC_Handle->hbot.cbw.field.CB[3] = 0; MSC_Handle->hbot.cbw.field.CB[4] = 0x24; MSC_Handle->hbot.cbw.field.CB[5] = 0; MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data; error = USBH_BUSY; break; case BOT_CMD_WAIT: error = USBH_MSC_BOT_Process(phost, lun); if(error == USBH_OK) { USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef)); /*assign Inquiry Data */ inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1F; inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5; inquiry->RemovableMedia = (MSC_Handle->hbot.pbuf[1] & 0x80)== 0x80; USBH_memcpy (inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8); USBH_memcpy (inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16); USBH_memcpy (inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4); } break; default: break; }
/** * @brief USBH_MSC_SCSI_TestUnitReady * Issue TestUnitReady command. * @param phost: Host handle * @param lun: Logical Unit Number * @retval USBH Status */ USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost, uint8_t lun) { USBH_StatusTypeDef error = USBH_FAIL ; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; switch(MSC_Handle->hbot.cmd_state) { case BOT_CMD_SEND: /*Prepare the CBW and relevent field*/ MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY; MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY; MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; error = USBH_BUSY; break; case BOT_CMD_WAIT: error = USBH_MSC_BOT_Process(phost, lun); break; default: break; } return error; }
/** * @brief USBH_MSC_SCSI_ReadCapacity * Issue Read Capacity command. * @param phost: Host handle * @param lun: Logical Unit Number * @param capacity: pointer to the capacity structure * @retval USBH Status */ USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost, uint8_t lun, SCSI_CapacityTypeDef *capacity) { USBH_StatusTypeDef error = USBH_BUSY ; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; switch(MSC_Handle->hbot.cmd_state) { case BOT_CMD_SEND: /*Prepare the CBW and relevent field*/ MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10; MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10; MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data; error = USBH_BUSY; break; case BOT_CMD_WAIT: error = USBH_MSC_BOT_Process(phost, lun); if(error == USBH_OK) { /*assign the capacity*/ capacity->block_nbr = MSC_Handle->hbot.pbuf[3] | (MSC_Handle->hbot.pbuf[2] << 8) |\ (MSC_Handle->hbot.pbuf[1] << 16) | (MSC_Handle->hbot.pbuf[0] << 24); /*assign the page length*/ capacity->block_size = MSC_Handle->hbot.pbuf[7] | (MSC_Handle->hbot.pbuf[6] << 8); } break; default: break; } return error; }
/** * @brief USBH_MSC_InterfaceInit * The function init the MSC class. * @param phost: Host handle * @retval USBH Status */ static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost) { uint8_t interface = 0; USBH_StatusTypeDef status = USBH_FAIL ; MSC_HandleTypeDef *MSC_Handle; interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, MSC_TRANSPARENT, MSC_BOT); if(interface == 0xFF) /* Not Valid Interface */ { USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name); status = USBH_FAIL; } else { USBH_SelectInterface (phost, interface); phost->pActiveClass->pData = (MSC_HandleTypeDef *)USBH_malloc (sizeof(MSC_HandleTypeDef)); MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress & 0x80) { MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress); MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize; } else { MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress); MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize; } if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress & 0x80) { MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress); MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize; } else { MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress); MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize; } MSC_Handle->current_lun = 0; MSC_Handle->rw_lun = 0; MSC_Handle->state = MSC_INIT; MSC_Handle->error = MSC_OK; MSC_Handle->req_state = MSC_REQ_IDLE; MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp); MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp); USBH_MSC_BOT_Init(phost); /* De-Initialize LUNs information */ USBH_memset(MSC_Handle->unit, 0, sizeof(MSC_Handle->unit)); /* Open the new channels */ USBH_OpenPipe (phost, MSC_Handle->OutPipe, MSC_Handle->OutEp, phost->device.address, phost->device.speed, USB_EP_TYPE_BULK, MSC_Handle->OutEpSize); USBH_OpenPipe (phost, MSC_Handle->InPipe, MSC_Handle->InEp, phost->device.address, phost->device.speed, USB_EP_TYPE_BULK, MSC_Handle->InEpSize); USBH_LL_SetToggle (phost, MSC_Handle->InPipe,0); USBH_LL_SetToggle (phost, MSC_Handle->OutPipe,0); status = USBH_OK; } return status; }