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
));
314 CopyMem (&UsbCbiDev
->BulkOutEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
320 // We parse interrupt endpoint
322 if (EndpointDescriptor
.Attributes
== 0x03) {
323 CopyMem (&UsbCbiDev
->InterruptEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
329 // Double check we have these
335 // After installing Usb-Atapi protocol onto this handle
336 // it will be called by upper layer drivers such as Fat
338 Cbi1ReportStatusCode (
339 UsbCbiDev
->DevicePath
,
341 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
)
344 Status
= gBS
->InstallProtocolInterface (
346 &gEfiUsbAtapiProtocolGuid
,
347 EFI_NATIVE_INTERFACE
,
348 &UsbCbiDev
->UsbAtapiProtocol
351 if (EFI_ERROR (Status
)) {
360 &gEfiUsbIoProtocolGuid
,
361 This
->DriverBindingHandle
,
364 if (UsbCbiDev
!= NULL
) {
365 gBS
->FreePool (UsbCbiDev
);
375 CBI1DriverBindingStop (
376 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
377 IN EFI_HANDLE ControllerHandle
,
378 IN UINTN NumberOfChildren
,
379 IN EFI_HANDLE
*ChildHandleBuffer
384 Stop this driver on ControllerHandle. Support stoping any child handles
385 created by this driver.
388 This - Protocol instance pointer.
389 ControllerHandle - Handle of device to stop driver on
390 NumberOfChildren - Number of Children in the ChildHandleBuffer
391 ChildHandleBuffer - List of handles for the children we need to stop.
394 EFI_SUCCESS - This driver is removed DeviceHandle
395 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol
396 other - This driver was not removed from this device
401 EFI_USB_ATAPI_PROTOCOL
*CBI1AtapiProtocol
;
402 USB_CBI_DEVICE
*UsbCbiDev
;
403 EFI_USB_IO_PROTOCOL
*UsbIo
;
406 // Get our context back.
408 Status
= gBS
->OpenProtocol (
410 &gEfiUsbAtapiProtocolGuid
,
411 (VOID
**) &CBI1AtapiProtocol
,
412 This
->DriverBindingHandle
,
414 EFI_OPEN_PROTOCOL_GET_PROTOCOL
416 if (EFI_ERROR (Status
)) {
417 return EFI_UNSUPPORTED
;
420 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol
);
422 UsbIo
= UsbCbiDev
->UsbIo
;
424 Cbi1ReportStatusCode (
425 UsbCbiDev
->DevicePath
,
427 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
)
430 Status
= gBS
->UninstallProtocolInterface (
432 &gEfiUsbAtapiProtocolGuid
,
433 &UsbCbiDev
->UsbAtapiProtocol
435 if (EFI_ERROR (Status
)) {
439 Status
= gBS
->CloseProtocol (
441 &gEfiUsbIoProtocolGuid
,
442 This
->DriverBindingHandle
,
445 gBS
->FreePool (UsbCbiDev
);
456 IN USB_CBI_DEVICE
*UsbCbiDev
,
458 IN UINT8 CommandSize
,
464 In order to make consistence, CBI transportation protocol does only use
465 the first 3 parameters. Other parameters are not used here.
468 UsbCbiDev - USB_CBI_DEVICE
469 Command - Command to send
470 CommandSize - Command Size
471 Result - Result to return
474 EFI_SUCCESS - This driver is removed DeviceHandle
475 other - This driver was not removed from this device
479 EFI_USB_IO_PROTOCOL
*UsbIo
;
480 EFI_USB_DEVICE_REQUEST Request
;
481 UINT32 TimeOutInMilliSeconds
;
483 UsbIo
= UsbCbiDev
->UsbIo
;
485 ZeroMem (&Request
, sizeof (EFI_USB_DEVICE_REQUEST
));
488 // Device request see CBI specification
490 Request
.RequestType
= 0x21;
491 Request
.Length
= CommandSize
;
493 TimeOutInMilliSeconds
= 1000;
495 Status
= UsbIo
->UsbControlTransfer (
499 TimeOutInMilliSeconds
,
511 IN USB_CBI_DEVICE
*UsbCbiDev
,
513 IN OUT VOID
*DataBuffer
,
514 IN EFI_USB_DATA_DIRECTION Direction
,
526 UsbCbiDev - USB_CBI_DEVICE
528 DataBuffer - Data Buffer
529 Direction - IN/OUT/NODATA
530 Timeout - Time out value in milliseconds
531 Result - Transfer result
535 EFI_SUCCESS - Success
540 EFI_USB_IO_PROTOCOL
*UsbIo
;
547 UsbIo
= UsbCbiDev
->UsbIo
;
550 BufferPtr
= (UINT8
*) DataBuffer
;
553 // retrieve the the max packet length of the given endpoint
555 if (Direction
== EfiUsbDataIn
) {
556 MaxPacketLen
= (UsbCbiDev
->BulkInEndpointDescriptor
).MaxPacketSize
;
557 EndpointAddr
= (UsbCbiDev
->BulkInEndpointDescriptor
).EndpointAddress
;
559 MaxPacketLen
= (UsbCbiDev
->BulkOutEndpointDescriptor
).MaxPacketSize
;
560 EndpointAddr
= (UsbCbiDev
->BulkOutEndpointDescriptor
).EndpointAddress
;
565 // Using 15 packets to aVOID Bitstuff error
567 if (Remain
> 15 * MaxPacketLen
) {
568 Increment
= 15 * MaxPacketLen
;
573 Status
= UsbIo
->UsbBulkTransfer (
582 if (EFI_ERROR (Status
)) {
586 BufferPtr
+= Increment
;
594 if (Direction
== EfiUsbDataIn
) {
595 Cbi1ReportStatusCode (
596 UsbCbiDev
->DevicePath
,
597 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
598 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_INPUT_ERROR
)
601 Cbi1ReportStatusCode (
602 UsbCbiDev
->DevicePath
,
603 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
604 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_OUTPUT_ERROR
)
608 if (((*Result
) & EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
610 // just endpoint stall happens
612 UsbClearEndpointHalt (
622 // CBI1 USB ATAPI Protocol
627 CBI1MassStorageReset (
628 IN EFI_USB_ATAPI_PROTOCOL
*This
,
629 IN BOOLEAN ExtendedVerification
637 This - Protocol instance pointer.
638 ExtendedVerification - TRUE if we need to do strictly reset.
641 EFI_SUCCESS - Command succeeded.
642 EFI_DEVICE_ERROR - Command failed.
646 UINT8 ResetCommand
[12];
648 EFI_USB_IO_PROTOCOL
*UsbIo
;
649 USB_CBI_DEVICE
*UsbCbiDev
;
653 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
654 UsbIo
= UsbCbiDev
->UsbIo
;
656 Cbi1ReportStatusCode (
657 UsbCbiDev
->DevicePath
,
659 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_RESET
)
662 if (ExtendedVerification
) {
663 UsbIo
->UsbPortReset (UsbIo
);
666 // CBI reset command protocol
668 SetMem (ResetCommand
, sizeof (ResetCommand
), 0xff);
669 ResetCommand
[0] = 0x1d;
670 ResetCommand
[1] = 0x04;
672 Status
= CBI1CommandPhase (
680 // clear bulk in endpoint stall feature
682 EndpointAddr
= UsbCbiDev
->BulkInEndpointDescriptor
.EndpointAddress
;
683 UsbClearEndpointHalt (
690 // clear bulk out endpoint stall feature
692 EndpointAddr
= UsbCbiDev
->BulkOutEndpointDescriptor
.EndpointAddress
;
693 UsbClearEndpointHalt (
707 IN EFI_USB_ATAPI_PROTOCOL
*This
,
709 IN UINT8 CommandSize
,
711 IN UINT32 BufferLength
,
712 IN EFI_USB_DATA_DIRECTION Direction
,
713 IN UINT16 TimeOutInMilliSeconds
718 Send ATAPI command using CBI1 protocol.
721 This - Protocol instance pointer.
722 Command - Command buffer
723 CommandSize - Size of Command Buffer
724 DataBuffer - Data buffer
725 BufferLength - Length of Data buffer
726 Direction - Data direction of this command
727 TimeOutInMilliSeconds - Timeout value in ms
730 EFI_SUCCESS - Command succeeded.
731 EFI_DEVICE_ERROR - Command failed.
736 USB_CBI_DEVICE
*UsbCbiDev
;
741 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
745 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
748 // First send ATAPI command through CBI1
750 Status
= CBI1CommandPhase (
756 if (EFI_ERROR (Status
)) {
760 case EFI_USB_NOERROR
:
761 case EFI_USB_ERR_STALL
:
762 case EFI_USB_ERR_SYSTEM
:
763 return EFI_DEVICE_ERROR
;
774 if (Index
== MaxRetryNum
) {
775 return EFI_DEVICE_ERROR
;
778 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
780 // Send/Get Data if there is a Data Stage
786 Status
= CBI1DataPhase (
791 TimeOutInMilliSeconds
,
795 if (EFI_ERROR (Status
)) {
798 case EFI_USB_NOERROR
:
799 case EFI_USB_ERR_STALL
:
800 case EFI_USB_ERR_SYSTEM
:
801 return EFI_DEVICE_ERROR
;
819 // If goes here, means met error.
821 return EFI_DEVICE_ERROR
;
825 Cbi1ReportStatusCode (
826 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
827 IN EFI_STATUS_CODE_TYPE CodeType
,
828 IN EFI_STATUS_CODE_VALUE Value
833 Report Status Code in Usb Cbi1 Driver
836 DevicePath - Use this to get Device Path
837 CodeType - Status Code Type
838 CodeValue - Status Code Value
845 REPORT_STATUS_CODE_WITH_DEVICE_PATH (