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
24 // CBI Function prototypes
29 IN USB_CBI_DEVICE
*UsbCbiDev
,
38 IN USB_CBI_DEVICE
*UsbCbiDev
,
40 IN OUT VOID
*DataBuffer
,
41 IN EFI_USB_DATA_DIRECTION Direction
,
47 // USB Atapi implementation
53 IN EFI_USB_ATAPI_PROTOCOL
*This
,
57 IN UINT32 BufferLength
,
58 IN EFI_USB_DATA_DIRECTION Direction
,
59 IN UINT16 TimeOutInMilliSeconds
65 CBI1MassStorageReset (
66 IN EFI_USB_ATAPI_PROTOCOL
*This
,
67 IN BOOLEAN ExtendedVerification
71 // CBI1 Driver Binding Protocol
76 CBI1DriverBindingSupported (
77 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
78 IN EFI_HANDLE ControllerHandle
,
79 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
85 CBI1DriverBindingStart (
86 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
87 IN EFI_HANDLE ControllerHandle
,
88 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
94 CBI1DriverBindingStop (
95 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
96 IN EFI_HANDLE ControllerHandle
,
97 IN UINTN NumberOfChildren
,
98 IN EFI_HANDLE
*ChildHandleBuffer
103 Cbi1ReportStatusCode (
104 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
105 IN EFI_STATUS_CODE_TYPE CodeType
,
106 IN EFI_STATUS_CODE_VALUE Value
110 EFI_DRIVER_BINDING_PROTOCOL gUsbCbi1DriverBinding
= {
111 CBI1DriverBindingSupported
,
112 CBI1DriverBindingStart
,
113 CBI1DriverBindingStop
,
119 STATIC EFI_USB_ATAPI_PROTOCOL CBI1AtapiProtocol
= {
121 CBI1MassStorageReset
,
126 // CBI1 Driver Binding implementation
131 CBI1DriverBindingSupported (
132 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
133 IN EFI_HANDLE ControllerHandle
,
134 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
139 Test to see if this driver supports ControllerHandle. Any ControllerHandle
140 than contains a BlockIo and DiskIo protocol can be supported.
143 This - Protocol instance pointer.
144 ControllerHandle - Handle of device to test
145 RemainingDevicePath - Not used
148 EFI_SUCCESS - This driver supports this device
149 EFI_ALREADY_STARTED - This driver is already running on this device
150 other - This driver does not support this device
155 EFI_USB_IO_PROTOCOL
*UsbIo
;
156 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
159 // Check if the Controller supports USB IO protocol
161 Status
= gBS
->OpenProtocol (
163 &gEfiUsbIoProtocolGuid
,
165 This
->DriverBindingHandle
,
167 EFI_OPEN_PROTOCOL_BY_DRIVER
169 if (EFI_ERROR (Status
)) {
173 // Get the Controller interface descriptor
175 Status
= UsbIo
->UsbGetInterfaceDescriptor (
179 if (EFI_ERROR (Status
)) {
183 // Bug here: just let Vendor specific CBI protocol get supported
185 if (!((InterfaceDescriptor
.InterfaceClass
== 0xFF) &&
186 (InterfaceDescriptor
.InterfaceProtocol
== 0))) {
187 Status
= EFI_UNSUPPORTED
;
194 &gEfiUsbIoProtocolGuid
,
195 This
->DriverBindingHandle
,
205 CBI1DriverBindingStart (
206 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
207 IN EFI_HANDLE ControllerHandle
,
208 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
213 Start this driver on ControllerHandle by opening a Block IO and Disk IO
214 protocol, reading Device Path, and creating a child handle with a
215 Disk IO and device path protocol.
218 This - Protocol instance pointer.
219 ControllerHandle - Handle of device to bind driver to
220 RemainingDevicePath - Not used
223 EFI_SUCCESS - This driver is added to DeviceHandle
224 EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
225 other - This driver does not support this device
229 USB_CBI_DEVICE
*UsbCbiDev
;
231 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
232 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
234 EFI_USB_IO_PROTOCOL
*UsbIo
;
239 // Check if the Controller supports USB IO protocol
243 Status
= gBS
->OpenProtocol (
245 &gEfiUsbIoProtocolGuid
,
247 This
->DriverBindingHandle
,
249 EFI_OPEN_PROTOCOL_BY_DRIVER
251 if (EFI_ERROR (Status
)) {
255 // Get the controller interface descriptor
257 Status
= UsbIo
->UsbGetInterfaceDescriptor (
261 if (EFI_ERROR (Status
)) {
265 CBI1AtapiProtocol
.CommandProtocol
= InterfaceDescriptor
.InterfaceSubClass
;
267 UsbCbiDev
= AllocateZeroPool (sizeof (USB_CBI_DEVICE
));
268 if (UsbCbiDev
== NULL
) {
269 Status
= EFI_OUT_OF_RESOURCES
;
273 UsbCbiDev
->Signature
= USB_CBI_DEVICE_SIGNATURE
;
274 UsbCbiDev
->UsbIo
= UsbIo
;
275 CopyMem (&UsbCbiDev
->InterfaceDescriptor
, &InterfaceDescriptor
, sizeof (InterfaceDescriptor
));
276 CopyMem (&UsbCbiDev
->UsbAtapiProtocol
, &CBI1AtapiProtocol
, sizeof (CBI1AtapiProtocol
));
279 // Get the Device Path Protocol on Controller's handle
281 Status
= gBS
->OpenProtocol (
283 &gEfiDevicePathProtocolGuid
,
284 (VOID
**) &UsbCbiDev
->DevicePath
,
285 This
->DriverBindingHandle
,
287 EFI_OPEN_PROTOCOL_GET_PROTOCOL
290 if (EFI_ERROR (Status
)) {
294 for (Index
= 0; Index
< InterfaceDescriptor
.NumEndpoints
; Index
++) {
295 UsbIo
->UsbGetEndpointDescriptor (
302 // We parse bulk endpoint
304 if (EndpointDescriptor
.Attributes
== 0x02) {
305 if (EndpointDescriptor
.EndpointAddress
& 0x80) {
306 CopyMem (&UsbCbiDev
->BulkInEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
308 CopyMem (&UsbCbiDev
->BulkOutEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
314 // We parse interrupt endpoint
316 if (EndpointDescriptor
.Attributes
== 0x03) {
317 CopyMem (&UsbCbiDev
->InterruptEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
323 // Double check we have these
329 // After installing Usb-Atapi protocol onto this handle
330 // it will be called by upper layer drivers such as Fat
332 Cbi1ReportStatusCode (
333 UsbCbiDev
->DevicePath
,
335 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
)
338 Status
= gBS
->InstallProtocolInterface (
340 &gEfiUsbAtapiProtocolGuid
,
341 EFI_NATIVE_INTERFACE
,
342 &UsbCbiDev
->UsbAtapiProtocol
345 if (EFI_ERROR (Status
)) {
349 UsbCbiDev
->ControllerNameTable
= NULL
;
352 gUsbCbi1ComponentName
.SupportedLanguages
,
353 &UsbCbiDev
->ControllerNameTable
,
354 (CHAR16
*) L
"Usb Cbi1 Mass Storage"
362 &gEfiUsbIoProtocolGuid
,
363 This
->DriverBindingHandle
,
366 if (UsbCbiDev
!= NULL
) {
367 gBS
->FreePool (UsbCbiDev
);
377 CBI1DriverBindingStop (
378 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
379 IN EFI_HANDLE ControllerHandle
,
380 IN UINTN NumberOfChildren
,
381 IN EFI_HANDLE
*ChildHandleBuffer
386 Stop this driver on ControllerHandle. Support stoping any child handles
387 created by this driver.
390 This - Protocol instance pointer.
391 ControllerHandle - Handle of device to stop driver on
392 NumberOfChildren - Number of Children in the ChildHandleBuffer
393 ChildHandleBuffer - List of handles for the children we need to stop.
396 EFI_SUCCESS - This driver is removed DeviceHandle
397 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol
398 other - This driver was not removed from this device
403 EFI_USB_ATAPI_PROTOCOL
*CBI1AtapiProtocol
;
404 USB_CBI_DEVICE
*UsbCbiDev
;
407 // Get our context back.
409 Status
= gBS
->OpenProtocol (
411 &gEfiUsbAtapiProtocolGuid
,
412 (VOID
**) &CBI1AtapiProtocol
,
413 This
->DriverBindingHandle
,
415 EFI_OPEN_PROTOCOL_GET_PROTOCOL
417 if (EFI_ERROR (Status
)) {
418 return EFI_UNSUPPORTED
;
421 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol
);
423 Cbi1ReportStatusCode (
424 UsbCbiDev
->DevicePath
,
426 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
)
429 Status
= gBS
->UninstallProtocolInterface (
431 &gEfiUsbAtapiProtocolGuid
,
432 &UsbCbiDev
->UsbAtapiProtocol
434 if (EFI_ERROR (Status
)) {
438 Status
= gBS
->CloseProtocol (
440 &gEfiUsbIoProtocolGuid
,
441 This
->DriverBindingHandle
,
444 gBS
->FreePool (UsbCbiDev
);
455 IN USB_CBI_DEVICE
*UsbCbiDev
,
457 IN UINT8 CommandSize
,
463 In order to make consistence, CBI transportation protocol does only use
464 the first 3 parameters. Other parameters are not used here.
467 UsbCbiDev - USB_CBI_DEVICE
468 Command - Command to send
469 CommandSize - Command Size
470 Result - Result to return
473 EFI_SUCCESS - This driver is removed DeviceHandle
474 other - This driver was not removed from this device
478 EFI_USB_IO_PROTOCOL
*UsbIo
;
479 EFI_USB_DEVICE_REQUEST Request
;
480 UINT32 TimeOutInMilliSeconds
;
482 UsbIo
= UsbCbiDev
->UsbIo
;
484 ZeroMem (&Request
, sizeof (EFI_USB_DEVICE_REQUEST
));
487 // Device request see CBI specification
489 Request
.RequestType
= 0x21;
490 Request
.Length
= CommandSize
;
492 TimeOutInMilliSeconds
= 1000;
494 Status
= UsbIo
->UsbControlTransfer (
498 TimeOutInMilliSeconds
,
510 IN USB_CBI_DEVICE
*UsbCbiDev
,
512 IN OUT VOID
*DataBuffer
,
513 IN EFI_USB_DATA_DIRECTION Direction
,
525 UsbCbiDev - USB_CBI_DEVICE
527 DataBuffer - Data Buffer
528 Direction - IN/OUT/NODATA
529 Timeout - Time out value in milliseconds
530 Result - Transfer result
534 EFI_SUCCESS - Success
539 EFI_USB_IO_PROTOCOL
*UsbIo
;
546 UsbIo
= UsbCbiDev
->UsbIo
;
549 BufferPtr
= (UINT8
*) DataBuffer
;
552 // retrieve the the max packet length of the given endpoint
554 if (Direction
== EfiUsbDataIn
) {
555 MaxPacketLen
= (UsbCbiDev
->BulkInEndpointDescriptor
).MaxPacketSize
;
556 EndpointAddr
= (UsbCbiDev
->BulkInEndpointDescriptor
).EndpointAddress
;
558 MaxPacketLen
= (UsbCbiDev
->BulkOutEndpointDescriptor
).MaxPacketSize
;
559 EndpointAddr
= (UsbCbiDev
->BulkOutEndpointDescriptor
).EndpointAddress
;
564 // Using 15 packets to aVOID Bitstuff error
566 if (Remain
> 15 * MaxPacketLen
) {
567 Increment
= 15 * MaxPacketLen
;
572 Status
= UsbIo
->UsbBulkTransfer (
581 if (EFI_ERROR (Status
)) {
585 BufferPtr
+= Increment
;
593 if (Direction
== EfiUsbDataIn
) {
594 Cbi1ReportStatusCode (
595 UsbCbiDev
->DevicePath
,
596 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
597 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_INPUT_ERROR
)
600 Cbi1ReportStatusCode (
601 UsbCbiDev
->DevicePath
,
602 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
603 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_OUTPUT_ERROR
)
607 if (((*Result
) & EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
609 // just endpoint stall happens
611 UsbClearEndpointHalt (
621 // CBI1 USB ATAPI Protocol
626 CBI1MassStorageReset (
627 IN EFI_USB_ATAPI_PROTOCOL
*This
,
628 IN BOOLEAN ExtendedVerification
636 This - Protocol instance pointer.
637 ExtendedVerification - TRUE if we need to do strictly reset.
640 EFI_SUCCESS - Command succeeded.
641 EFI_DEVICE_ERROR - Command failed.
645 UINT8 ResetCommand
[12];
646 EFI_USB_IO_PROTOCOL
*UsbIo
;
647 USB_CBI_DEVICE
*UsbCbiDev
;
651 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
652 UsbIo
= UsbCbiDev
->UsbIo
;
654 Cbi1ReportStatusCode (
655 UsbCbiDev
->DevicePath
,
657 (EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_RESET
)
660 if (ExtendedVerification
) {
661 UsbIo
->UsbPortReset (UsbIo
);
664 // CBI reset command protocol
666 SetMem (ResetCommand
, sizeof (ResetCommand
), 0xff);
667 ResetCommand
[0] = 0x1d;
668 ResetCommand
[1] = 0x04;
678 // clear bulk in endpoint stall feature
680 EndpointAddr
= UsbCbiDev
->BulkInEndpointDescriptor
.EndpointAddress
;
681 UsbClearEndpointHalt (
688 // clear bulk out endpoint stall feature
690 EndpointAddr
= UsbCbiDev
->BulkOutEndpointDescriptor
.EndpointAddress
;
691 UsbClearEndpointHalt (
705 IN EFI_USB_ATAPI_PROTOCOL
*This
,
707 IN UINT8 CommandSize
,
709 IN UINT32 BufferLength
,
710 IN EFI_USB_DATA_DIRECTION Direction
,
711 IN UINT16 TimeOutInMilliSeconds
716 Send ATAPI command using CBI1 protocol.
719 This - Protocol instance pointer.
720 Command - Command buffer
721 CommandSize - Size of Command Buffer
722 DataBuffer - Data buffer
723 BufferLength - Length of Data buffer
724 Direction - Data direction of this command
725 TimeOutInMilliSeconds - Timeout value in ms
728 EFI_SUCCESS - Command succeeded.
729 EFI_DEVICE_ERROR - Command failed.
734 USB_CBI_DEVICE
*UsbCbiDev
;
739 UsbCbiDev
= USB_CBI_DEVICE_FROM_THIS (This
);
743 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
746 // First send ATAPI command through CBI1
748 Status
= CBI1CommandPhase (
754 if (EFI_ERROR (Status
)) {
758 case EFI_USB_NOERROR
:
759 case EFI_USB_ERR_STALL
:
760 case EFI_USB_ERR_SYSTEM
:
761 return EFI_DEVICE_ERROR
;
772 if (Index
== MaxRetryNum
) {
773 return EFI_DEVICE_ERROR
;
776 for (Index
= 0; Index
< MaxRetryNum
; Index
++) {
778 // Send/Get Data if there is a Data Stage
784 Status
= CBI1DataPhase (
789 TimeOutInMilliSeconds
,
793 if (EFI_ERROR (Status
)) {
796 case EFI_USB_NOERROR
:
797 case EFI_USB_ERR_STALL
:
798 case EFI_USB_ERR_SYSTEM
:
799 return EFI_DEVICE_ERROR
;
817 // If goes here, means met error.
819 return EFI_DEVICE_ERROR
;
824 Cbi1ReportStatusCode (
825 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
826 IN EFI_STATUS_CODE_TYPE CodeType
,
827 IN EFI_STATUS_CODE_VALUE Value
832 Report Status Code in Usb Cbi1 Driver
835 DevicePath - Use this to get Device Path
836 CodeType - Status Code Type
837 CodeValue - Status Code Value
844 REPORT_STATUS_CODE_WITH_DEVICE_PATH (