3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 cbi1 transportation protocol implementation files
25 UsbCBI1DriverEntryPoint (
26 IN EFI_HANDLE ImageHandle
,
27 IN EFI_SYSTEM_TABLE
*SystemTable
31 // CBI Function prototypes
36 IN USB_CBI_DEVICE
*UsbCbiDev
,
45 IN USB_CBI_DEVICE
*UsbCbiDev
,
47 IN OUT VOID
*DataBuffer
,
48 IN EFI_USB_DATA_DIRECTION Direction
,
54 // USB Atapi implementation
60 IN EFI_USB_ATAPI_PROTOCOL
*This
,
64 IN UINT32 BufferLength
,
65 IN EFI_USB_DATA_DIRECTION Direction
,
66 IN UINT16 TimeOutInMilliSeconds
72 CBI1MassStorageReset (
73 IN EFI_USB_ATAPI_PROTOCOL
*This
,
74 IN BOOLEAN ExtendedVerification
78 // CBI1 Driver Binding Protocol
83 CBI1DriverBindingSupported (
84 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
85 IN EFI_HANDLE ControllerHandle
,
86 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
92 CBI1DriverBindingStart (
93 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
94 IN EFI_HANDLE ControllerHandle
,
95 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
101 CBI1DriverBindingStop (
102 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
103 IN EFI_HANDLE ControllerHandle
,
104 IN UINTN NumberOfChildren
,
105 IN EFI_HANDLE
*ChildHandleBuffer
109 Cbi1ReportStatusCode (
110 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
111 IN EFI_STATUS_CODE_TYPE CodeType
,
112 IN EFI_STATUS_CODE_VALUE Value
116 EFI_DRIVER_BINDING_PROTOCOL gCBI1DriverBinding
= {
117 CBI1DriverBindingSupported
,
118 CBI1DriverBindingStart
,
119 CBI1DriverBindingStop
,
125 STATIC EFI_USB_ATAPI_PROTOCOL CBI1AtapiProtocol
= {
127 CBI1MassStorageReset
,
132 // CBI1 Driver Binding implementation
137 CBI1DriverBindingSupported (
138 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
139 IN EFI_HANDLE ControllerHandle
,
140 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
145 Test to see if this driver supports ControllerHandle. Any ControllerHandle
146 than contains a BlockIo and DiskIo protocol can be supported.
149 This - Protocol instance pointer.
150 ControllerHandle - Handle of device to test
151 RemainingDevicePath - Not used
154 EFI_SUCCESS - This driver supports this device
155 EFI_ALREADY_STARTED - This driver is already running on this device
156 other - This driver does not support this device
161 EFI_USB_IO_PROTOCOL
*UsbIo
;
162 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
165 // Check if the Controller supports USB IO protocol
167 Status
= gBS
->OpenProtocol (
169 &gEfiUsbIoProtocolGuid
,
171 This
->DriverBindingHandle
,
173 EFI_OPEN_PROTOCOL_BY_DRIVER
175 if (EFI_ERROR (Status
)) {
179 // Get the Controller interface descriptor
181 Status
= UsbIo
->UsbGetInterfaceDescriptor (
185 if (EFI_ERROR (Status
)) {
189 // Bug here: just let Vendor specific CBI protocol get supported
191 if (!((InterfaceDescriptor
.InterfaceClass
== 0xFF) &&
192 (InterfaceDescriptor
.InterfaceProtocol
== 0))) {
193 Status
= EFI_UNSUPPORTED
;
200 &gEfiUsbIoProtocolGuid
,
201 This
->DriverBindingHandle
,
211 CBI1DriverBindingStart (
212 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
213 IN EFI_HANDLE ControllerHandle
,
214 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
219 Start this driver on ControllerHandle by opening a Block IO and Disk IO
220 protocol, reading Device Path, and creating a child handle with a
221 Disk IO and device path protocol.
224 This - Protocol instance pointer.
225 ControllerHandle - Handle of device to bind driver to
226 RemainingDevicePath - Not used
229 EFI_SUCCESS - This driver is added to DeviceHandle
230 EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
231 other - This driver does not support this device
235 USB_CBI_DEVICE
*UsbCbiDev
;
237 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
238 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
240 EFI_USB_IO_PROTOCOL
*UsbIo
;
245 // Check if the Controller supports USB IO protocol
249 Status
= gBS
->OpenProtocol (
251 &gEfiUsbIoProtocolGuid
,
253 This
->DriverBindingHandle
,
255 EFI_OPEN_PROTOCOL_BY_DRIVER
257 if (EFI_ERROR (Status
)) {
261 // Get the controller interface descriptor
263 Status
= UsbIo
->UsbGetInterfaceDescriptor (
267 if (EFI_ERROR (Status
)) {
271 CBI1AtapiProtocol
.CommandProtocol
= InterfaceDescriptor
.InterfaceSubClass
;
273 UsbCbiDev
= AllocateZeroPool (sizeof (USB_CBI_DEVICE
));
274 if (UsbCbiDev
== NULL
) {
275 Status
= EFI_OUT_OF_RESOURCES
;
279 UsbCbiDev
->Signature
= USB_CBI_DEVICE_SIGNATURE
;
280 UsbCbiDev
->UsbIo
= UsbIo
;
281 CopyMem (&UsbCbiDev
->InterfaceDescriptor
, &InterfaceDescriptor
, sizeof (InterfaceDescriptor
));
282 CopyMem (&UsbCbiDev
->UsbAtapiProtocol
, &CBI1AtapiProtocol
, sizeof (CBI1AtapiProtocol
));
285 // Get the Device Path Protocol on Controller's handle
287 Status
= gBS
->OpenProtocol (
289 &gEfiDevicePathProtocolGuid
,
290 (VOID
**) &UsbCbiDev
->DevicePath
,
291 This
->DriverBindingHandle
,
293 EFI_OPEN_PROTOCOL_GET_PROTOCOL
296 if (EFI_ERROR (Status
)) {
300 for (Index
= 0; Index
< InterfaceDescriptor
.NumEndpoints
; Index
++) {
301 UsbIo
->UsbGetEndpointDescriptor (
308 // We parse bulk endpoint
310 if (EndpointDescriptor
.Attributes
== 0x02) {
311 if (EndpointDescriptor
.EndpointAddress
& 0x80) {
312 CopyMem (&UsbCbiDev
->BulkInEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
313 //UsbCbiDev->BulkInEndpointDescriptor = EndpointDescriptor;
315 CopyMem (&UsbCbiDev
->BulkOutEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
316 //UsbCbiDev->BulkOutEndpointDescriptor = EndpointDescriptor;
322 // We parse interrupt endpoint
324 if (EndpointDescriptor
.Attributes
== 0x03) {
325 CopyMem (&UsbCbiDev
->InterruptEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
326 //UsbCbiDev->InterruptEndpointDescriptor = EndpointDescriptor;
332 // Double check we have these
338 // After installing Usb-Atapi protocol onto this handle
339 // it will be called by upper layer drivers such as Fat
341 Cbi1ReportStatusCode (
342 UsbCbiDev
->DevicePath
,
344 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
)
347 Status
= gBS
->InstallProtocolInterface (
349 &gEfiUsbAtapiProtocolGuid
,
350 EFI_NATIVE_INTERFACE
,
351 &UsbCbiDev
->UsbAtapiProtocol
354 if (EFI_ERROR (Status
)) {
363 &gEfiUsbIoProtocolGuid
,
364 This
->DriverBindingHandle
,
367 if (UsbCbiDev
!= NULL
) {
368 gBS
->FreePool (UsbCbiDev
);
378 CBI1DriverBindingStop (
379 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
380 IN EFI_HANDLE ControllerHandle
,
381 IN UINTN NumberOfChildren
,
382 IN EFI_HANDLE
*ChildHandleBuffer
387 Stop this driver on ControllerHandle. Support stoping any child handles
388 created by this driver.
391 This - Protocol instance pointer.
392 ControllerHandle - Handle of device to stop driver on
393 NumberOfChildren - Number of Children in the ChildHandleBuffer
394 ChildHandleBuffer - List of handles for the children we need to stop.
397 EFI_SUCCESS - This driver is removed DeviceHandle
398 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol
399 other - This driver was not removed from this device
404 EFI_USB_ATAPI_PROTOCOL
*CBI1AtapiProtocol
;
405 USB_CBI_DEVICE
*UsbCbiDev
;
406 EFI_USB_IO_PROTOCOL
*UsbIo
;
409 // Get our context back.
411 Status
= gBS
->OpenProtocol (
413 &gEfiUsbAtapiProtocolGuid
,
414 (VOID
**) &CBI1AtapiProtocol
,
415 This
->DriverBindingHandle
,
417 EFI_OPEN_PROTOCOL_GET_PROTOCOL
419 if (EFI_ERROR (Status
)) {
420 return EFI_UNSUPPORTED
;
423 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol
);
425 UsbIo
= UsbCbiDev
->UsbIo
;
427 Cbi1ReportStatusCode (
428 UsbCbiDev
->DevicePath
,
430 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
)
433 Status
= gBS
->UninstallProtocolInterface (
435 &gEfiUsbAtapiProtocolGuid
,
436 &UsbCbiDev
->UsbAtapiProtocol
438 if (EFI_ERROR (Status
)) {
442 Status
= gBS
->CloseProtocol (
444 &gEfiUsbIoProtocolGuid
,
445 This
->DriverBindingHandle
,
448 gBS
->FreePool (UsbCbiDev
);
459 IN USB_CBI_DEVICE
*UsbCbiDev
,
461 IN UINT8 CommandSize
,
467 In order to make consistence, CBI transportation protocol does only use
468 the first 3 parameters. Other parameters are not used here.
471 UsbCbiDev - USB_CBI_DEVICE
472 Command - Command to send
473 CommandSize - Command Size
474 Result - Result to return
477 EFI_SUCCESS - This driver is removed DeviceHandle
478 other - This driver was not removed from this device
482 EFI_USB_IO_PROTOCOL
*UsbIo
;
483 EFI_USB_DEVICE_REQUEST Request
;
484 UINT32 TimeOutInMilliSeconds
;
486 UsbIo
= UsbCbiDev
->UsbIo
;
488 ZeroMem (&Request
, sizeof (EFI_USB_DEVICE_REQUEST
));
491 // Device request see CBI specification
493 Request
.RequestType
= 0x21;
494 Request
.Length
= CommandSize
;
496 TimeOutInMilliSeconds
= 1000;
498 Status
= UsbIo
->UsbControlTransfer (
502 TimeOutInMilliSeconds
,
514 IN USB_CBI_DEVICE
*UsbCbiDev
,
516 IN OUT VOID
*DataBuffer
,
517 IN EFI_USB_DATA_DIRECTION Direction
,
529 UsbCbiDev - USB_CBI_DEVICE
531 DataBuffer - Data Buffer
532 Direction - IN/OUT/NODATA
533 Timeout - Time out value in milliseconds
534 Result - Transfer result
538 EFI_SUCCESS - Success
543 EFI_USB_IO_PROTOCOL
*UsbIo
;
550 UsbIo
= UsbCbiDev
->UsbIo
;
553 BufferPtr
= (UINT8
*) DataBuffer
;
556 // retrieve the the max packet length of the given endpoint
558 if (Direction
== EfiUsbDataIn
) {
559 MaxPacketLen
= (UsbCbiDev
->BulkInEndpointDescriptor
).MaxPacketSize
;
560 EndpointAddr
= (UsbCbiDev
->BulkInEndpointDescriptor
).EndpointAddress
;
562 MaxPacketLen
= (UsbCbiDev
->BulkOutEndpointDescriptor
).MaxPacketSize
;
563 EndpointAddr
= (UsbCbiDev
->BulkOutEndpointDescriptor
).EndpointAddress
;
568 // Using 15 packets to aVOID Bitstuff error
570 if (Remain
> 15 * MaxPacketLen
) {
571 Increment
= 15 * MaxPacketLen
;
576 Status
= UsbIo
->UsbBulkTransfer (
585 if (EFI_ERROR (Status
)) {
589 BufferPtr
+= Increment
;
597 if (Direction
== EfiUsbDataIn
) {
598 Cbi1ReportStatusCode (
599 UsbCbiDev
->DevicePath
,
600 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
601 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_INPUT_ERROR
)
604 Cbi1ReportStatusCode (
605 UsbCbiDev
->DevicePath
,
606 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
607 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_OUTPUT_ERROR
)
611 if (((*Result
) & EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
613 // just endpoint stall happens
615 UsbClearEndpointHalt (
625 // CBI1 USB ATAPI Protocol
630 CBI1MassStorageReset (
631 IN EFI_USB_ATAPI_PROTOCOL
*This
,
632 IN BOOLEAN ExtendedVerification
640 This - Protocol instance pointer.
641 ExtendedVerification - TRUE if we need to do strictly reset.
644 EFI_SUCCESS - Command succeeded.
645 EFI_DEVICE_ERROR - Command failed.
649 UINT8 ResetCommand
[12];
651 EFI_USB_IO_PROTOCOL
*UsbIo
;
652 USB_CBI_DEVICE
*UsbCbiDev
;
656 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
657 UsbIo
= UsbCbiDev
->UsbIo
;
659 Cbi1ReportStatusCode (
660 UsbCbiDev
->DevicePath
,
662 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_RESET
)
665 if (ExtendedVerification
) {
666 UsbIo
->UsbPortReset (UsbIo
);
669 // CBI reset command protocol
671 SetMem (ResetCommand
, sizeof (ResetCommand
), 0xff);
672 ResetCommand
[0] = 0x1d;
673 ResetCommand
[1] = 0x04;
675 Status
= CBI1CommandPhase (
683 // clear bulk in endpoint stall feature
685 EndpointAddr
= UsbCbiDev
->BulkInEndpointDescriptor
.EndpointAddress
;
686 UsbClearEndpointHalt (
693 // clear bulk out endpoint stall feature
695 EndpointAddr
= UsbCbiDev
->BulkOutEndpointDescriptor
.EndpointAddress
;
696 UsbClearEndpointHalt (
710 IN EFI_USB_ATAPI_PROTOCOL
*This
,
712 IN UINT8 CommandSize
,
714 IN UINT32 BufferLength
,
715 IN EFI_USB_DATA_DIRECTION Direction
,
716 IN UINT16 TimeOutInMilliSeconds
721 Send ATAPI command using CBI1 protocol.
724 This - Protocol instance pointer.
725 Command - Command buffer
726 CommandSize - Size of Command Buffer
727 DataBuffer - Data buffer
728 BufferLength - Length of Data buffer
729 Direction - Data direction of this command
730 TimeOutInMilliSeconds - Timeout value in ms
733 EFI_SUCCESS - Command succeeded.
734 EFI_DEVICE_ERROR - Command failed.
739 USB_CBI_DEVICE
*UsbCbiDev
;
744 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
748 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
751 // First send ATAPI command through CBI1
753 Status
= CBI1CommandPhase (
759 if (EFI_ERROR (Status
)) {
763 case EFI_USB_NOERROR
:
764 case EFI_USB_ERR_STALL
:
765 case EFI_USB_ERR_SYSTEM
:
766 return EFI_DEVICE_ERROR
;
777 if (Index
== MaxRetryNum
) {
778 return EFI_DEVICE_ERROR
;
781 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
783 // Send/Get Data if there is a Data Stage
789 Status
= CBI1DataPhase (
794 TimeOutInMilliSeconds
,
798 if (EFI_ERROR (Status
)) {
801 case EFI_USB_NOERROR
:
802 case EFI_USB_ERR_STALL
:
803 case EFI_USB_ERR_SYSTEM
:
804 return EFI_DEVICE_ERROR
;
822 // If goes here, means met error.
824 return EFI_DEVICE_ERROR
;
828 Cbi1ReportStatusCode (
829 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
830 IN EFI_STATUS_CODE_TYPE CodeType
,
831 IN EFI_STATUS_CODE_VALUE Value
836 Report Status Code in Usb Cbi1 Driver
839 DevicePath - Use this to get Device Path
840 CodeType - Status Code Type
841 CodeValue - Status Code Value
848 REPORT_STATUS_CODE_WITH_DEVICE_PATH (