+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- BOT.c\r
-\r
-Abstract:\r
-\r
---*/\r
-\r
-#include "bot.h"\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTDebugLevel = EFI_D_INFO;\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTErrorLevel = EFI_D_INFO;\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gUsbBotDriverBinding = {\r
- BotDriverBindingSupported,\r
- BotDriverBindingStart,\r
- BotDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-//\r
-// Bot Protocol\r
-//\r
-STATIC\r
-EFI_STATUS\r
-BotCommandPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- IN VOID *Command,\r
- IN UINT8 CommandSize,\r
- IN UINT32 DataTransferLength,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 Timeout\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-BotDataPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- IN UINTN *DataSize,\r
- IN OUT VOID *DataBuffer,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 Timeout\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-BotStatusPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- OUT UINT32 *DataResidue, \r
- IN UINT16 Timeout\r
- );\r
-//\r
-// USB Atapi protocol prototype\r
-//\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-BotAtapiCommand (\r
- IN EFI_USB_ATAPI_PROTOCOL *This,\r
- IN VOID *Command,\r
- IN UINT8 CommandSize,\r
- IN VOID *DataBuffer,\r
- IN UINT32 BufferLength,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 TimeOutInMilliSeconds\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-BotMassStorageReset (\r
- IN EFI_USB_ATAPI_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- );\r
-\r
-STATIC\r
-VOID\r
-BotReportStatusCode (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value\r
- );\r
-\r
-STATIC EFI_USB_ATAPI_PROTOCOL BotAtapiProtocol = {\r
- BotAtapiCommand,\r
- BotMassStorageReset,\r
- 0\r
-};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
- than contains a BlockIo and DiskIo protocol can be supported.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ControllerHandle - Handle of device to test\r
- RemainingDevicePath - Not used\r
-\r
- Returns:\r
- EFI_SUCCESS - This driver supports this device\r
- EFI_ALREADY_STARTED - This driver is already running on this device\r
- other - This driver does not support this device\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
- EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
-\r
- //\r
- // Check if the Controller supports USB IO protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- (VOID **) &UsbIo,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Get the Default interface descriptor, now we only\r
- // suppose interface 1\r
- //\r
- Status = UsbIo->UsbGetInterfaceDescriptor (\r
- UsbIo,\r
- &InterfaceDescriptor\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
- //\r
- // Check if it is a BOT type Mass Storage Device\r
- //\r
- if ((InterfaceDescriptor.InterfaceClass != MASS_STORAGE_CLASS) ||\r
- (InterfaceDescriptor.InterfaceProtocol != BOT)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Exit;\r
- }\r
-\r
-Exit:\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Start this driver on ControllerHandle by opening a Block IO and Disk IO\r
- protocol, reading Device Path, and creating a child handle with a\r
- Disk IO and device path protocol.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ControllerHandle - Handle of device to bind driver to\r
- RemainingDevicePath - Not used\r
-\r
- Returns:\r
- EFI_SUCCESS - This driver is added to DeviceHandle\r
- EFI_ALREADY_STARTED - This driver is already running on DeviceHandle\r
- EFI_OUT_OF_RESOURCES- Can't allocate the memory resource\r
- other - This driver does not support this device\r
-\r
---*/\r
-{\r
- USB_BOT_DEVICE *UsbBotDev;\r
- UINT8 Index;\r
- EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;\r
- EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor;\r
- EFI_STATUS Status;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
-\r
- //\r
- // Check if the Controller supports USB IO protocol\r
- //\r
- UsbBotDev = NULL;\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- (VOID **) &UsbIo,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- InterfaceDescriptor = AllocateZeroPool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));\r
- if (InterfaceDescriptor == NULL) {\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Get the controller interface descriptor,\r
- //\r
- Status = UsbIo->UsbGetInterfaceDescriptor (\r
- UsbIo,\r
- InterfaceDescriptor\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (InterfaceDescriptor);\r
- goto ErrorExit;\r
- }\r
-\r
- BotAtapiProtocol.CommandProtocol = InterfaceDescriptor->InterfaceSubClass;\r
-\r
- UsbBotDev = AllocateZeroPool (sizeof (USB_BOT_DEVICE));\r
- if (UsbBotDev == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- gBS->FreePool (InterfaceDescriptor);\r
- goto ErrorExit;\r
- }\r
-\r
- UsbBotDev->Signature = USB_BOT_DEVICE_SIGNATURE;\r
- UsbBotDev->UsbIo = UsbIo;\r
- UsbBotDev->InterfaceDescriptor = InterfaceDescriptor;\r
- CopyMem (&UsbBotDev->UsbAtapiProtocol, &BotAtapiProtocol, sizeof (BotAtapiProtocol));\r
-\r
- //\r
- // Get the Device Path Protocol on Controller's handle\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &UsbBotDev->DevicePath,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- for (Index = 0; Index < InterfaceDescriptor->NumEndpoints; Index++) {\r
- EndpointDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));\r
- if (EndpointDescriptor == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- UsbIo->UsbGetEndpointDescriptor (\r
- UsbIo,\r
- Index,\r
- EndpointDescriptor\r
- );\r
-\r
- //\r
- // We parse bulk endpoint\r
- //\r
- if ((EndpointDescriptor->Attributes & 0x03) == 0x02) {\r
- if ((EndpointDescriptor->EndpointAddress & 0x80) != 0) {\r
- UsbBotDev->BulkInEndpointDescriptor = EndpointDescriptor;\r
- } else {\r
- UsbBotDev->BulkOutEndpointDescriptor = EndpointDescriptor;\r
- }\r
-\r
- continue;\r
- }\r
-\r
- gBS->FreePool (EndpointDescriptor);\r
- }\r
- //\r
- // Double check we have these endpoint descriptors\r
- //\r
- if (!(UsbBotDev->BulkInEndpointDescriptor &&\r
- UsbBotDev->BulkOutEndpointDescriptor)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto ErrorExit;\r
- }\r
- //\r
- // After installing Usb-Atapi protocol onto this handle\r
- // it will be called by upper layer drivers such as Fat\r
- //\r
- BotReportStatusCode (\r
- UsbBotDev->DevicePath,\r
- EFI_PROGRESS_CODE,\r
- (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)\r
- );\r
-\r
- //\r
- // Install Usb-Atapi Protocol onto the handle\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &ControllerHandle,\r
- &gEfiUsbAtapiProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &UsbBotDev->UsbAtapiProtocol\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- UsbBotDev->ControllerNameTable = NULL;\r
- AddUnicodeString (\r
- "eng",\r
- gUsbBotComponentName.SupportedLanguages,\r
- &UsbBotDev->ControllerNameTable,\r
- (CHAR16 *) L"Usb Bot Mass Storage"\r
- );\r
-\r
- return EFI_SUCCESS;\r
-\r
-ErrorExit:\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- if (UsbBotDev != NULL) {\r
- if (UsbBotDev->InterfaceDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->InterfaceDescriptor);\r
- }\r
-\r
- if (UsbBotDev->BulkInEndpointDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->BulkInEndpointDescriptor);\r
- }\r
-\r
- if (UsbBotDev->BulkOutEndpointDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->BulkOutEndpointDescriptor);\r
- }\r
-\r
- gBS->FreePool (UsbBotDev);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Stop this driver on ControllerHandle. Support stoping any child handles\r
- created by this driver.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ControllerHandle - Handle of device to stop driver on\r
- NumberOfChildren - Number of Children in the ChildHandleBuffer\r
- ChildHandleBuffer - List of handles for the children we need to stop.\r
-\r
- Returns:\r
- EFI_SUCCESS - This driver is removed DeviceHandle\r
- EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocl\r
- other - This driver was not removed from this device\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_USB_ATAPI_PROTOCOL *BotAtapiProtocol;\r
- USB_BOT_DEVICE *UsbBotDev;\r
-\r
- //\r
- // Get our context back.\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUsbAtapiProtocolGuid,\r
- (VOID **) &BotAtapiProtocol,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- UsbBotDev = USB_BOT_DEVICE_FROM_THIS (BotAtapiProtocol);\r
-\r
- //\r
- // After installing Usb-Atapi protocol onto this handle\r
- // it will be called by upper layer drivers such as Fat\r
- //\r
-\r
- BotReportStatusCode (\r
- UsbBotDev->DevicePath,\r
- EFI_PROGRESS_CODE,\r
- (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)\r
- );\r
-\r
- //\r
- // Uninstall protocol\r
- //\r
- Status = gBS->UninstallProtocolInterface (\r
- ControllerHandle,\r
- &gEfiUsbAtapiProtocolGuid,\r
- &UsbBotDev->UsbAtapiProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUsbIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- //\r
- // Free all allocated resources\r
- //\r
- if (UsbBotDev->InterfaceDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->InterfaceDescriptor);\r
- }\r
-\r
- if (UsbBotDev->BulkInEndpointDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->BulkInEndpointDescriptor);\r
- }\r
-\r
- if (UsbBotDev->BulkOutEndpointDescriptor != NULL) {\r
- gBS->FreePool (UsbBotDev->BulkOutEndpointDescriptor);\r
- }\r
-\r
- if (UsbBotDev->ControllerNameTable) {\r
- FreeUnicodeStringTable (UsbBotDev->ControllerNameTable);\r
- }\r
-\r
- gBS->FreePool (UsbBotDev);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-ClearBulkInPipe (\r
- IN USB_BOT_DEVICE *UsbBotDev\r
- )\r
-{\r
- UINT32 Result;\r
-\r
- return UsbClearEndpointHalt (\r
- UsbBotDev->UsbIo,\r
- UsbBotDev->BulkInEndpointDescriptor->EndpointAddress,\r
- &Result\r
- );\r
-}\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-ClearBulkOutPipe (\r
- IN USB_BOT_DEVICE *UsbBotDev\r
- )\r
-{\r
- UINT32 Result;\r
- return UsbClearEndpointHalt (\r
- UsbBotDev->UsbIo,\r
- UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,\r
- &Result\r
- );\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BotRecoveryReset (\r
- IN USB_BOT_DEVICE *UsbBotDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Bot reset routine\r
-\r
-Arguments:\r
-\r
- UsbBotDev - USB_BOT_DEVICE pointer\r
-\r
-Returns:\r
- EFI_SUCCESS - Success the operation\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_USB_DEVICE_REQUEST Request;\r
- UINT32 Result;\r
- BotReportStatusCode (\r
- UsbBotDev->DevicePath,\r
- EFI_PROGRESS_CODE,\r
- (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)\r
- );\r
-\r
- ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));\r
-\r
- //\r
- // See BOT specification\r
- //\r
- Request.RequestType = 0x21;\r
- Request.Request = 0xFF;\r
-\r
- Status = UsbBotDev->UsbIo->UsbControlTransfer (\r
- UsbBotDev->UsbIo,\r
- &Request,\r
- EfiUsbNoData,\r
- TIMEOUT_VALUE,\r
- NULL,\r
- 0,\r
- &Result\r
- );\r
-\r
- gBS->Stall (100 * 1000);\r
-\r
- ClearBulkInPipe (UsbBotDev);\r
- ClearBulkOutPipe (UsbBotDev);\r
-\r
- return Status;\r
-}\r
-\r
-//\r
-// Bot Protocol Implementation\r
-//\r
-STATIC\r
-EFI_STATUS\r
-BotCommandPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- IN VOID *Command,\r
- IN UINT8 CommandSize,\r
- IN UINT32 DataTransferLength,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 Timeout\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Send ATAPI command through BOT interface.\r
-\r
- Parameters:\r
- UsbBotDev - USB_BOT_DEVICE\r
- Command - command packet\r
- CommandSize - Command size\r
- DataTransferLength - Data Transfer Length\r
- Direction - Data IN/OUT/NODATA\r
- Timeout - Time out value in milliseconds\r
- Return Values:\r
- EFI_SUCCESS\r
- Others\r
-\r
---*/\r
-{\r
- CBW cbw;\r
- EFI_STATUS Status;\r
- UINT32 Result;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
- UINTN DataSize;\r
-\r
- UsbIo = UsbBotDev->UsbIo;\r
-\r
- ZeroMem (&cbw, sizeof (CBW));\r
-\r
- //\r
- // Fill the command block, detailed see BOT spec\r
- //\r
- cbw.dCBWSignature = CBWSIG;\r
- cbw.dCBWTag = 0x01;\r
- cbw.dCBWDataTransferLength = DataTransferLength;\r
- cbw.bmCBWFlags = (UINT8) ((Direction == EfiUsbDataIn) ? 0x80 : 0);\r
- cbw.bCBWCBLength = CommandSize;\r
-\r
- CopyMem (cbw.CBWCB, Command, CommandSize);\r
-\r
- DataSize = sizeof (CBW);\r
-\r
- Status = UsbIo->UsbBulkTransfer (\r
- UsbIo,\r
- UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,\r
- &cbw,\r
- &DataSize,\r
- Timeout,\r
- &Result\r
- );\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BotDataPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- IN UINTN *DataSize,\r
- IN OUT VOID *DataBuffer,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 Timeout\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Get/Send Data through BOT interface\r
-\r
- Parameters:\r
- UsbBotDev - USB_BOT_DEVICE pointer\r
- DataSize - Data size\r
- DataBuffer - Data buffer pointer\r
- Direction - IN/OUT/NODATA\r
- Timeout - Time out value in milliseconds\r
- Return Value:\r
- EFI_SUCCESS\r
- Others\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Result;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
- UINT8 EndpointAddr;\r
- UINT8 *BufferPtr;\r
-\r
- UsbIo = UsbBotDev->UsbIo;\r
- BufferPtr = (UINT8 *) DataBuffer;\r
-\r
- //\r
- // retrieve the the max packet length of the given endpoint\r
- //\r
- if (Direction == EfiUsbDataIn) {\r
- EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;\r
- } else {\r
- EndpointAddr = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;\r
- }\r
-\r
- Status = UsbIo->UsbBulkTransfer (\r
- UsbIo,\r
- EndpointAddr,\r
- BufferPtr,\r
- DataSize,\r
- (UINT16)(Timeout),\r
- &Result\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
- if (Direction == EfiUsbDataIn) {\r
- DEBUG((gBOTErrorLevel, "BOT: Data IN Stall, ClearBulkInPipe\n"));\r
- ClearBulkInPipe (UsbBotDev);\r
- } else {\r
- DEBUG((gBOTErrorLevel, "BOT: Data OUT Stall, ClearBulkInPipe\n"));\r
- ClearBulkOutPipe (UsbBotDev);\r
- }\r
- }\r
- // BotRecoveryReset (UsbBotDev);\r
- }\r
-\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BotStatusPhase (\r
- IN USB_BOT_DEVICE *UsbBotDev,\r
- OUT UINT32 *DataResidue,\r
- IN UINT16 Timeout\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Get transfer status through BOT interface\r
-\r
- Parameters:\r
- UsbBotDev - USB_BOT_DEVICE pointer\r
- Timeout - Time out value in milliseconds\r
- Return Value:\r
- EFI_SUCCESS\r
- Others\r
-\r
---*/\r
-{\r
- CSW csw;\r
- EFI_STATUS Status;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
- UINT8 EndpointAddr;\r
- UINTN DataSize;\r
- UINT32 Result;\r
- UINT8 Index;\r
-\r
- UsbIo = UsbBotDev->UsbIo;\r
- EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;\r
-\r
-\r
- for (Index = 0; Index < 3; Index ++) {\r
- ZeroMem (&csw, sizeof (CSW));\r
- DataSize = sizeof (CSW);\r
- Result = 0;\r
-\r
- Status = UsbIo->UsbBulkTransfer (\r
- UsbIo,\r
- EndpointAddr,\r
- &csw,\r
- &DataSize,\r
- Timeout,\r
- &Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
- DEBUG((gBOTDebugLevel, "BOT: CSW Stall, ClearBulkInPipe\n"));\r
- ClearBulkInPipe (UsbBotDev);\r
- continue;\r
- }\r
- }\r
-\r
- if (csw.dCSWSignature == CSWSIG) {\r
- if (csw.bCSWStatus == 0 || csw.bCSWStatus == 0x01) {\r
- if (DataResidue != NULL) {\r
- *DataResidue = csw.dCSWDataResidue;\r
- }\r
- if (csw.bCSWStatus == 0x01) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- break;\r
- } else if (csw.bCSWStatus == 0x02) {\r
- DEBUG((gBOTErrorLevel, "BOT: Bot Phase error\n"));\r
- BotRecoveryReset (UsbBotDev);\r
- }\r
-\r
- }\r
- }\r
-\r
- if (Index == 3) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Usb Atapi Protocol implementation\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-BotAtapiCommand (\r
- IN EFI_USB_ATAPI_PROTOCOL *This,\r
- IN VOID *Command,\r
- IN UINT8 CommandSize,\r
- IN VOID *DataBuffer,\r
- IN UINT32 BufferLength,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN UINT16 TimeOutInMilliSeconds\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Send ATAPI command using BOT protocol.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Command - Command buffer\r
- CommandSize - Size of Command Buffer\r
- DataBuffer - Data buffer\r
- BufferLength - Length of Data buffer\r
- Direction - Data direction of this command\r
- TimeoutInMilliSeconds - Timeout value in ms\r
-\r
- Returns:\r
- EFI_SUCCESS - Command succeeded.\r
- EFI_DEVICE_ERROR - Command failed.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS BotDataStatus;\r
- USB_BOT_DEVICE *UsbBotDev;\r
- UINTN BufferSize;\r
- UINT8 Index;\r
- UINT32 DataResidue;\r
-\r
- //\r
- // Get the context\r
- //\r
- UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);\r
- BotDataStatus = EFI_SUCCESS;\r
- BufferSize = 0;\r
-\r
- for (Index = 0; Index < 3; Index ++) {\r
- //\r
- // First send ATAPI command through Bot\r
- //\r
- Status = BotCommandPhase (\r
- UsbBotDev,\r
- Command,\r
- CommandSize,\r
- BufferLength,\r
- Direction,\r
- 10 * 1000\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((gBOTErrorLevel, "BotCommandPhase Fail\n"));\r
- return Status;\r
- }\r
- //\r
- // Send/Get Data if there is a Data Stage\r
- //\r
- switch (Direction) {\r
-\r
- case EfiUsbDataIn:\r
- case EfiUsbDataOut:\r
- BufferSize = BufferLength;\r
-\r
- BotDataStatus = BotDataPhase (\r
- UsbBotDev,\r
- &BufferSize,\r
- DataBuffer,\r
- Direction,\r
- (UINT16) (TimeOutInMilliSeconds)\r
- );\r
-\r
-\r
- if (EFI_ERROR (BotDataStatus)) {\r
- DEBUG((gBOTErrorLevel, "BotDataPhase Fail\n"));\r
- }\r
- break;\r
-\r
- case EfiUsbNoData:\r
- break;\r
- }\r
-\r
- DataResidue = 0;\r
- //\r
- // Status Phase\r
- //\r
- Status = BotStatusPhase (\r
- UsbBotDev,\r
- &DataResidue,\r
- 10 * 1000\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((gBOTErrorLevel, "BotStatusPhase Fail\n"));\r
- return Status;\r
- }\r
-\r
- if (!EFI_ERROR (BotDataStatus)) {\r
- break;\r
- }\r
-\r
- }\r
- return BotDataStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotMassStorageReset (\r
- IN EFI_USB_ATAPI_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reset Bot Devices\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - TRUE if we need to do strictly reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - Command succeeded.\r
- EFI_DEVICE_ERROR - Command failed.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- USB_BOT_DEVICE *UsbBotDev;\r
- EFI_USB_IO_PROTOCOL *UsbIo;\r
-\r
- UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);\r
- UsbIo = UsbBotDev->UsbIo;\r
-\r
- if (ExtendedVerification) {\r
- //\r
- // If we need to do strictly reset, reset its parent hub port\r
- //\r
- Status = UsbIo->UsbPortReset (UsbIo);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- Status = BotRecoveryReset (UsbBotDev);\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-VOID\r
-BotReportStatusCode (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Report Status Code in Usb Bot Driver\r
-\r
- Arguments:\r
- DevicePath - Use this to get Device Path\r
- CodeType - Status Code Type\r
- CodeValue - Status Code Value\r
-\r
- Returns:\r
- None\r
-\r
---*/\r
-{\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- CodeType,\r
- Value,\r
- DevicePath\r
- );\r
-}\r