42 OUT VOID **Context OPTIONAL
55 ASSERT (UsbBot !=
NULL);
57 UsbBot->UsbIo = UsbIo;
63 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &UsbBot->Interface);
65 if (EFI_ERROR (Status)) {
69 Interface = &UsbBot->Interface;
72 Status = EFI_UNSUPPORTED;
79 for (Index = 0; Index < Interface->NumEndpoints; Index++) {
80 Status = UsbIo->UsbGetEndpointDescriptor (UsbIo, Index, &EndPoint);
82 if (EFI_ERROR (Status) || !USB_IS_BULK_ENDPOINT (EndPoint.Attributes)) {
86 if (USB_IS_IN_ENDPOINT (EndPoint.EndpointAddress) &&
87 (UsbBot->BulkInEndpoint ==
NULL))
90 CopyMem (UsbBot->BulkInEndpoint, &EndPoint, sizeof (EndPoint));
93 if (USB_IS_OUT_ENDPOINT (EndPoint.EndpointAddress) &&
94 (UsbBot->BulkOutEndpoint ==
NULL))
97 CopyMem (UsbBot->BulkOutEndpoint, &EndPoint, sizeof (EndPoint));
104 if ((UsbBot->BulkInEndpoint ==
NULL) || (UsbBot->BulkOutEndpoint ==
NULL)) {
105 Status = EFI_UNSUPPORTED;
112 UsbBot->CbwTag = 0x01;
114 if (Context !=
NULL) {
168 Cbw.Tag = UsbBot->CbwTag;
170 Cbw.
Flag = (UINT8)((DataDir == EfiUsbDataIn) ? BIT7 : 0);
175 CopyMem (Cbw.CmdBlock, Cmd, CmdLen);
179 Timeout = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;
184 Status = UsbBot->UsbIo->UsbBulkTransfer (
186 UsbBot->BulkOutEndpoint->EndpointAddress,
192 if (EFI_ERROR (Status)) {
193 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL) && (DataDir == EfiUsbDataOut)) {
199 }
else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
200 Status = EFI_NOT_READY;
242 if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
249 if (DataDir == EfiUsbDataIn) {
250 Endpoint = UsbBot->BulkInEndpoint;
252 Endpoint = UsbBot->BulkOutEndpoint;
256 Timeout = Timeout / USB_MASS_1_MILLISECOND;
258 Status = UsbBot->UsbIo->UsbBulkTransfer (
260 Endpoint->EndpointAddress,
266 if (EFI_ERROR (Status)) {
267 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {
268 DEBUG ((DEBUG_INFO,
"UsbBotDataTransfer: (%r)\n", Status));
269 DEBUG ((DEBUG_INFO,
"UsbBotDataTransfer: DataIn Stall\n"));
271 }
else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
272 Status = EFI_NOT_READY;
274 DEBUG ((DEBUG_ERROR,
"UsbBotDataTransfer: (%r)\n", Status));
277 if (Status == EFI_TIMEOUT) {
321 Status = EFI_DEVICE_ERROR;
322 Endpoint = UsbBot->BulkInEndpoint->EndpointAddress;
323 UsbIo = UsbBot->UsbIo;
324 Timeout = USB_BOT_RECV_CSW_TIMEOUT / USB_MASS_1_MILLISECOND;
326 for (Index = 0; Index < USB_BOT_RECV_CSW_RETRY; Index++) {
333 Status = UsbIo->UsbBulkTransfer (
341 if (EFI_ERROR (Status)) {
342 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {
360 *CmdStatus = Csw.CmdStatus;
402 OUT UINT32 *CmdStatus
410 *CmdStatus = USB_MASS_CMD_FAIL;
418 if (EFI_ERROR (Status)) {
419 DEBUG ((DEBUG_ERROR,
"UsbBotExecCommand: UsbBotSendCommand (%r)\n", Status));
428 TransLen = (
UINTN)DataLen;
435 if (EFI_ERROR (Status)) {
436 DEBUG ((DEBUG_ERROR,
"UsbBotExecCommand: UsbBotGetStatus (%r)\n", Status));
441 *CmdStatus = USB_MASS_CMD_SUCCESS;
462 IN BOOLEAN ExtendedVerification
473 if (ExtendedVerification) {
477 Status = UsbBot->UsbIo->UsbPortReset (UsbBot->UsbIo);
478 if (EFI_ERROR (Status)) {
479 return EFI_DEVICE_ERROR;
487 Request.RequestType = 0x21;
490 Request.Index = UsbBot->Interface.InterfaceNumber;
492 Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
494 Status = UsbBot->UsbIo->UsbControlTransfer (
504 if (EFI_ERROR (Status)) {
505 return EFI_DEVICE_ERROR;
513 gBS->Stall (USB_BOT_RESET_DEVICE_STALL);
547 if ((Context ==
NULL) || (MaxLun ==
NULL)) {
548 return EFI_INVALID_PARAMETER;
557 Request.RequestType = 0xA1;
560 Request.Index = UsbBot->Interface.InterfaceNumber;
562 Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
564 Status = UsbBot->UsbIo->UsbControlTransfer (
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define DEBUG(Expression)
#define USB_MASS_STORE_BOT
Bulk-Only Transport.
EFI_STATUS UsbClearEndpointStall(IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT8 EndpointAddr)
EFI_STATUS UsbBotSendCommand(IN USB_BOT_PROTOCOL *UsbBot, IN UINT8 *Cmd, IN UINT8 CmdLen, IN EFI_USB_DATA_DIRECTION DataDir, IN UINT32 TransLen, IN UINT8 Lun)
EFI_STATUS UsbBotExecCommand(IN VOID *Context, IN VOID *Cmd, IN UINT8 CmdLen, IN EFI_USB_DATA_DIRECTION DataDir, IN VOID *Data, IN UINT32 DataLen, IN UINT8 Lun, IN UINT32 Timeout, OUT UINT32 *CmdStatus)
EFI_STATUS UsbBotInit(IN EFI_USB_IO_PROTOCOL *UsbIo, OUT VOID **Context OPTIONAL)
EFI_STATUS UsbBotCleanUp(IN VOID *Context)
EFI_STATUS UsbBotDataTransfer(IN USB_BOT_PROTOCOL *UsbBot, IN EFI_USB_DATA_DIRECTION DataDir, IN OUT UINT8 *Data, IN OUT UINTN *TransLen, IN UINT32 Timeout)
EFI_STATUS UsbBotResetDevice(IN VOID *Context, IN BOOLEAN ExtendedVerification)
EFI_STATUS UsbBotGetStatus(IN USB_BOT_PROTOCOL *UsbBot, IN UINT32 TransLen, OUT UINT8 *CmdStatus)
EFI_STATUS UsbBotGetMaxLun(IN VOID *Context, OUT UINT8 *MaxLun)
#define USB_BOT_COMMAND_ERROR
Phase error, need to reset the device.
#define USB_BOT_RESET_REQUEST
Bulk-Only Mass Storage Reset.
#define USB_BOT_MAX_LUN
Lun number is from 0 to 15.
#define USB_BOT_MAX_CMDLEN
Maximum number of command from command set.
#define USB_BOT_GETLUN_REQUEST
Get Max Lun.
#define USB_BOT_CSW_SIGNATURE
dCSWSignature, tag the packet as CSW
#define USB_BOT_CBW_SIGNATURE
dCBWSignature, tag the packet as CBW
UINT8 CmdLen
Length of the command. Bits 0~4 are used.
UINT8 Flag
Bit 7, 0 ~ Data-Out, 1 ~ Data-In.
UINT32 DataLen
Length of data between CBW and CSW.
UINT8 Lun
Lun number. Bits 0~3 are used.