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
23 extern EFI_COMPONENT_NAME_PROTOCOL gUsbCbi1ComponentName
;
27 UsbCBI1DriverEntryPoint (
28 IN EFI_HANDLE ImageHandle
,
29 IN EFI_SYSTEM_TABLE
*SystemTable
33 // CBI Function prototypes
38 IN USB_CBI_DEVICE
*UsbCbiDev
,
47 IN USB_CBI_DEVICE
*UsbCbiDev
,
49 IN OUT VOID
*DataBuffer
,
50 IN EFI_USB_DATA_DIRECTION Direction
,
56 // USB Atapi implementation
62 IN EFI_USB_ATAPI_PROTOCOL
*This
,
66 IN UINT32 BufferLength
,
67 IN EFI_USB_DATA_DIRECTION Direction
,
68 IN UINT16 TimeOutInMilliSeconds
74 CBI1MassStorageReset (
75 IN EFI_USB_ATAPI_PROTOCOL
*This
,
76 IN BOOLEAN ExtendedVerification
80 // CBI1 Driver Binding Protocol
85 CBI1DriverBindingSupported (
86 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
87 IN EFI_HANDLE ControllerHandle
,
88 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
94 CBI1DriverBindingStart (
95 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
96 IN EFI_HANDLE ControllerHandle
,
97 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
103 CBI1DriverBindingStop (
104 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
105 IN EFI_HANDLE ControllerHandle
,
106 IN UINTN NumberOfChildren
,
107 IN EFI_HANDLE
*ChildHandleBuffer
111 Cbi1ReportStatusCode (
112 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
113 IN EFI_STATUS_CODE_TYPE CodeType
,
114 IN EFI_STATUS_CODE_VALUE Value
118 EFI_DRIVER_BINDING_PROTOCOL gUsbCbi1DriverBinding
= {
119 CBI1DriverBindingSupported
,
120 CBI1DriverBindingStart
,
121 CBI1DriverBindingStop
,
127 STATIC EFI_USB_ATAPI_PROTOCOL CBI1AtapiProtocol
= {
129 CBI1MassStorageReset
,
134 // CBI1 Driver Binding implementation
139 CBI1DriverBindingSupported (
140 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
141 IN EFI_HANDLE ControllerHandle
,
142 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
147 Test to see if this driver supports ControllerHandle. Any ControllerHandle
148 than contains a BlockIo and DiskIo protocol can be supported.
151 This - Protocol instance pointer.
152 ControllerHandle - Handle of device to test
153 RemainingDevicePath - Not used
156 EFI_SUCCESS - This driver supports this device
157 EFI_ALREADY_STARTED - This driver is already running on this device
158 other - This driver does not support this device
163 EFI_USB_IO_PROTOCOL
*UsbIo
;
164 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
167 // Check if the Controller supports USB IO protocol
169 Status
= gBS
->OpenProtocol (
171 &gEfiUsbIoProtocolGuid
,
173 This
->DriverBindingHandle
,
175 EFI_OPEN_PROTOCOL_BY_DRIVER
177 if (EFI_ERROR (Status
)) {
181 // Get the Controller interface descriptor
183 Status
= UsbIo
->UsbGetInterfaceDescriptor (
187 if (EFI_ERROR (Status
)) {
191 // Bug here: just let Vendor specific CBI protocol get supported
193 if (!((InterfaceDescriptor
.InterfaceClass
== 0xFF) &&
194 (InterfaceDescriptor
.InterfaceProtocol
== 0))) {
195 Status
= EFI_UNSUPPORTED
;
202 &gEfiUsbIoProtocolGuid
,
203 This
->DriverBindingHandle
,
213 CBI1DriverBindingStart (
214 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
215 IN EFI_HANDLE ControllerHandle
,
216 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
221 Start this driver on ControllerHandle by opening a Block IO and Disk IO
222 protocol, reading Device Path, and creating a child handle with a
223 Disk IO and device path protocol.
226 This - Protocol instance pointer.
227 ControllerHandle - Handle of device to bind driver to
228 RemainingDevicePath - Not used
231 EFI_SUCCESS - This driver is added to DeviceHandle
232 EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
233 other - This driver does not support this device
237 USB_CBI_DEVICE
*UsbCbiDev
;
239 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
240 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
242 EFI_USB_IO_PROTOCOL
*UsbIo
;
247 // Check if the Controller supports USB IO protocol
251 Status
= gBS
->OpenProtocol (
253 &gEfiUsbIoProtocolGuid
,
255 This
->DriverBindingHandle
,
257 EFI_OPEN_PROTOCOL_BY_DRIVER
259 if (EFI_ERROR (Status
)) {
263 // Get the controller interface descriptor
265 Status
= UsbIo
->UsbGetInterfaceDescriptor (
269 if (EFI_ERROR (Status
)) {
273 CBI1AtapiProtocol
.CommandProtocol
= InterfaceDescriptor
.InterfaceSubClass
;
275 UsbCbiDev
= AllocateZeroPool (sizeof (USB_CBI_DEVICE
));
276 if (UsbCbiDev
== NULL
) {
277 Status
= EFI_OUT_OF_RESOURCES
;
281 UsbCbiDev
->Signature
= USB_CBI_DEVICE_SIGNATURE
;
282 UsbCbiDev
->UsbIo
= UsbIo
;
283 CopyMem (&UsbCbiDev
->InterfaceDescriptor
, &InterfaceDescriptor
, sizeof (InterfaceDescriptor
));
284 CopyMem (&UsbCbiDev
->UsbAtapiProtocol
, &CBI1AtapiProtocol
, sizeof (CBI1AtapiProtocol
));
287 // Get the Device Path Protocol on Controller's handle
289 Status
= gBS
->OpenProtocol (
291 &gEfiDevicePathProtocolGuid
,
292 (VOID
**) &UsbCbiDev
->DevicePath
,
293 This
->DriverBindingHandle
,
295 EFI_OPEN_PROTOCOL_GET_PROTOCOL
298 if (EFI_ERROR (Status
)) {
302 for (Index
= 0; Index
< InterfaceDescriptor
.NumEndpoints
; Index
++) {
303 UsbIo
->UsbGetEndpointDescriptor (
310 // We parse bulk endpoint
312 if (EndpointDescriptor
.Attributes
== 0x02) {
313 if (EndpointDescriptor
.EndpointAddress
& 0x80) {
314 CopyMem (&UsbCbiDev
->BulkInEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
316 CopyMem (&UsbCbiDev
->BulkOutEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
322 // We parse interrupt endpoint
324 if (EndpointDescriptor
.Attributes
== 0x03) {
325 CopyMem (&UsbCbiDev
->InterruptEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
331 // Double check we have these
337 // After installing Usb-Atapi protocol onto this handle
338 // it will be called by upper layer drivers such as Fat
340 Cbi1ReportStatusCode (
341 UsbCbiDev
->DevicePath
,
343 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
)
346 Status
= gBS
->InstallProtocolInterface (
348 &gEfiUsbAtapiProtocolGuid
,
349 EFI_NATIVE_INTERFACE
,
350 &UsbCbiDev
->UsbAtapiProtocol
353 if (EFI_ERROR (Status
)) {
357 UsbCbiDev
->ControllerNameTable
= NULL
;
360 gUsbCbi1ComponentName
.SupportedLanguages
,
361 &UsbCbiDev
->ControllerNameTable
,
362 (CHAR16
*) L
"Usb Cbi1 Mass Storage"
370 &gEfiUsbIoProtocolGuid
,
371 This
->DriverBindingHandle
,
374 if (UsbCbiDev
!= NULL
) {
375 gBS
->FreePool (UsbCbiDev
);
385 CBI1DriverBindingStop (
386 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
387 IN EFI_HANDLE ControllerHandle
,
388 IN UINTN NumberOfChildren
,
389 IN EFI_HANDLE
*ChildHandleBuffer
394 Stop this driver on ControllerHandle. Support stoping any child handles
395 created by this driver.
398 This - Protocol instance pointer.
399 ControllerHandle - Handle of device to stop driver on
400 NumberOfChildren - Number of Children in the ChildHandleBuffer
401 ChildHandleBuffer - List of handles for the children we need to stop.
404 EFI_SUCCESS - This driver is removed DeviceHandle
405 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol
406 other - This driver was not removed from this device
411 EFI_USB_ATAPI_PROTOCOL
*CBI1AtapiProtocol
;
412 USB_CBI_DEVICE
*UsbCbiDev
;
415 // Get our context back.
417 Status
= gBS
->OpenProtocol (
419 &gEfiUsbAtapiProtocolGuid
,
420 (VOID
**) &CBI1AtapiProtocol
,
421 This
->DriverBindingHandle
,
423 EFI_OPEN_PROTOCOL_GET_PROTOCOL
425 if (EFI_ERROR (Status
)) {
426 return EFI_UNSUPPORTED
;
429 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol
);
431 Cbi1ReportStatusCode (
432 UsbCbiDev
->DevicePath
,
434 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
)
437 Status
= gBS
->UninstallProtocolInterface (
439 &gEfiUsbAtapiProtocolGuid
,
440 &UsbCbiDev
->UsbAtapiProtocol
442 if (EFI_ERROR (Status
)) {
446 Status
= gBS
->CloseProtocol (
448 &gEfiUsbIoProtocolGuid
,
449 This
->DriverBindingHandle
,
452 gBS
->FreePool (UsbCbiDev
);
463 IN USB_CBI_DEVICE
*UsbCbiDev
,
465 IN UINT8 CommandSize
,
471 In order to make consistence, CBI transportation protocol does only use
472 the first 3 parameters. Other parameters are not used here.
475 UsbCbiDev - USB_CBI_DEVICE
476 Command - Command to send
477 CommandSize - Command Size
478 Result - Result to return
481 EFI_SUCCESS - This driver is removed DeviceHandle
482 other - This driver was not removed from this device
486 EFI_USB_IO_PROTOCOL
*UsbIo
;
487 EFI_USB_DEVICE_REQUEST Request
;
488 UINT32 TimeOutInMilliSeconds
;
490 UsbIo
= UsbCbiDev
->UsbIo
;
492 ZeroMem (&Request
, sizeof (EFI_USB_DEVICE_REQUEST
));
495 // Device request see CBI specification
497 Request
.RequestType
= 0x21;
498 Request
.Length
= CommandSize
;
500 TimeOutInMilliSeconds
= 1000;
502 Status
= UsbIo
->UsbControlTransfer (
506 TimeOutInMilliSeconds
,
518 IN USB_CBI_DEVICE
*UsbCbiDev
,
520 IN OUT VOID
*DataBuffer
,
521 IN EFI_USB_DATA_DIRECTION Direction
,
533 UsbCbiDev - USB_CBI_DEVICE
535 DataBuffer - Data Buffer
536 Direction - IN/OUT/NODATA
537 Timeout - Time out value in milliseconds
538 Result - Transfer result
542 EFI_SUCCESS - Success
547 EFI_USB_IO_PROTOCOL
*UsbIo
;
554 UsbIo
= UsbCbiDev
->UsbIo
;
557 BufferPtr
= (UINT8
*) DataBuffer
;
560 // retrieve the the max packet length of the given endpoint
562 if (Direction
== EfiUsbDataIn
) {
563 MaxPacketLen
= (UsbCbiDev
->BulkInEndpointDescriptor
).MaxPacketSize
;
564 EndpointAddr
= (UsbCbiDev
->BulkInEndpointDescriptor
).EndpointAddress
;
566 MaxPacketLen
= (UsbCbiDev
->BulkOutEndpointDescriptor
).MaxPacketSize
;
567 EndpointAddr
= (UsbCbiDev
->BulkOutEndpointDescriptor
).EndpointAddress
;
572 // Using 15 packets to aVOID Bitstuff error
574 if (Remain
> 15 * MaxPacketLen
) {
575 Increment
= 15 * MaxPacketLen
;
580 Status
= UsbIo
->UsbBulkTransfer (
589 if (EFI_ERROR (Status
)) {
593 BufferPtr
+= Increment
;
601 if (Direction
== EfiUsbDataIn
) {
602 Cbi1ReportStatusCode (
603 UsbCbiDev
->DevicePath
,
604 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
605 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_INPUT_ERROR
)
608 Cbi1ReportStatusCode (
609 UsbCbiDev
->DevicePath
,
610 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
611 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_OUTPUT_ERROR
)
615 if (((*Result
) & EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
617 // just endpoint stall happens
619 UsbClearEndpointHalt (
629 // CBI1 USB ATAPI Protocol
634 CBI1MassStorageReset (
635 IN EFI_USB_ATAPI_PROTOCOL
*This
,
636 IN BOOLEAN ExtendedVerification
644 This - Protocol instance pointer.
645 ExtendedVerification - TRUE if we need to do strictly reset.
648 EFI_SUCCESS - Command succeeded.
649 EFI_DEVICE_ERROR - Command failed.
653 UINT8 ResetCommand
[12];
654 EFI_USB_IO_PROTOCOL
*UsbIo
;
655 USB_CBI_DEVICE
*UsbCbiDev
;
659 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
660 UsbIo
= UsbCbiDev
->UsbIo
;
662 Cbi1ReportStatusCode (
663 UsbCbiDev
->DevicePath
,
665 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_RESET
)
668 if (ExtendedVerification
) {
669 UsbIo
->UsbPortReset (UsbIo
);
672 // CBI reset command protocol
674 SetMem (ResetCommand
, sizeof (ResetCommand
), 0xff);
675 ResetCommand
[0] = 0x1d;
676 ResetCommand
[1] = 0x04;
686 // clear bulk in endpoint stall feature
688 EndpointAddr
= UsbCbiDev
->BulkInEndpointDescriptor
.EndpointAddress
;
689 UsbClearEndpointHalt (
696 // clear bulk out endpoint stall feature
698 EndpointAddr
= UsbCbiDev
->BulkOutEndpointDescriptor
.EndpointAddress
;
699 UsbClearEndpointHalt (
713 IN EFI_USB_ATAPI_PROTOCOL
*This
,
715 IN UINT8 CommandSize
,
717 IN UINT32 BufferLength
,
718 IN EFI_USB_DATA_DIRECTION Direction
,
719 IN UINT16 TimeOutInMilliSeconds
724 Send ATAPI command using CBI1 protocol.
727 This - Protocol instance pointer.
728 Command - Command buffer
729 CommandSize - Size of Command Buffer
730 DataBuffer - Data buffer
731 BufferLength - Length of Data buffer
732 Direction - Data direction of this command
733 TimeOutInMilliSeconds - Timeout value in ms
736 EFI_SUCCESS - Command succeeded.
737 EFI_DEVICE_ERROR - Command failed.
742 USB_CBI_DEVICE
*UsbCbiDev
;
747 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
751 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
754 // First send ATAPI command through CBI1
756 Status
= CBI1CommandPhase (
762 if (EFI_ERROR (Status
)) {
766 case EFI_USB_NOERROR
:
767 case EFI_USB_ERR_STALL
:
768 case EFI_USB_ERR_SYSTEM
:
769 return EFI_DEVICE_ERROR
;
780 if (Index
== MaxRetryNum
) {
781 return EFI_DEVICE_ERROR
;
784 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
786 // Send/Get Data if there is a Data Stage
792 Status
= CBI1DataPhase (
797 TimeOutInMilliSeconds
,
801 if (EFI_ERROR (Status
)) {
804 case EFI_USB_NOERROR
:
805 case EFI_USB_ERR_STALL
:
806 case EFI_USB_ERR_SYSTEM
:
807 return EFI_DEVICE_ERROR
;
825 // If goes here, means met error.
827 return EFI_DEVICE_ERROR
;
831 Cbi1ReportStatusCode (
832 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
833 IN EFI_STATUS_CODE_TYPE CodeType
,
834 IN EFI_STATUS_CODE_VALUE Value
839 Report Status Code in Usb Cbi1 Driver
842 DevicePath - Use this to get Device Path
843 CodeType - Status Code Type
844 CodeValue - Status Code Value
851 REPORT_STATUS_CODE_WITH_DEVICE_PATH (