3 Provides some data structure definitions used by the XHCI host controller driver.
5 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 #include <Protocol/Usb2HostController.h>
22 #include <Protocol/PciIo.h>
24 #include <Guid/EventGroup.h>
26 #include <Library/BaseLib.h>
27 #include <Library/BaseMemoryLib.h>
28 #include <Library/UefiDriverEntryPoint.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/UefiLib.h>
32 #include <Library/DebugLib.h>
34 #include <IndustryStandard/Pci.h>
36 typedef struct _USB_XHCI_INSTANCE USB_XHCI_INSTANCE
;
37 typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT
;
40 #include "XhciSched.h"
41 #include "ComponentName.h"
44 // Convert millisecond to microsecond.
46 #define XHC_1_MILLISECOND (1000)
48 // XHC generic timeout experience values.
49 // The unit is microsecond, setting it as 10ms.
51 #define XHC_GENERIC_TIMEOUT (10 * 1000)
53 // XHC reset timeout experience values.
54 // The unit is microsecond, setting it as 1s.
56 #define XHC_RESET_TIMEOUT (1000 * 1000)
58 // XHC delay experience value for polling operation.
59 // The unit is microsecond, set it as 1ms.
61 #define XHC_POLL_DELAY (1000)
63 // XHC async transfer timer interval, set by experience.
64 // The unit is 100us, takes 50ms as interval.
66 #define XHC_ASYNC_TIMER_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(50)
69 // XHC raises TPL to TPL_NOTIFY to serialize all its operations
70 // to protect shared data structures.
72 #define XHC_TPL TPL_NOTIFY
74 #define CMD_RING_TRB_NUMBER 0x40
75 #define TR_RING_TRB_NUMBER 0x40
76 #define ERST_NUMBER 0x01
77 #define EVENT_RING_TRB_NUMBER 0x80
83 #define INT_INTER_ASYNC 4
86 // Iterate through the doule linked list. This is delete-safe.
87 // Don't touch NextEntry
89 #define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
90 for (Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\
91 Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink)
93 #define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field)
95 #define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFFFFFFF))
96 #define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINT64)(UINTN)(Addr64), 32) & 0xFFFFFFFF))
97 #define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
99 #define XHC_REG_BIT_IS_SET(Xhc, Offset, Bit) \
100 (XHC_BIT_IS_SET(XhcReadOpReg ((Xhc), (Offset)), (Bit)))
102 #define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80)
104 #define XHCI_INSTANCE_SIG SIGNATURE_32 ('x', 'h', 'c', 'i')
105 #define XHC_FROM_THIS(a) CR(a, USB_XHCI_INSTANCE, Usb2Hc, XHCI_INSTANCE_SIG)
107 #define USB_DESC_TYPE_HUB 0x29
108 #define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a
111 // The RequestType in EFI_USB_DEVICE_REQUEST is composed of
112 // three fields: One bit direction, 2 bit type, and 5 bit
115 #define USB_REQUEST_TYPE(Dir, Type, Target) \
116 ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target)))
119 // Xhci Data and Ctrl Structures
134 UINT8 HubContrCurrent
;
136 } EFI_USB_HUB_DESCRIPTOR
;
139 struct _USB_DEV_CONTEXT
{
141 // Whether this entry in UsbDevContext array is used or not.
145 // The slot id assigned to the new device through XHCI's Enable_Slot cmd.
149 // The route string presented an attached usb device.
151 USB_DEV_ROUTE RouteString
;
153 // The route string of parent device if it exists. Otherwise it's zero.
155 USB_DEV_ROUTE ParentRouteString
;
157 // The actual device address assigned by XHCI through Address_Device command.
161 // The requested device address from UsbBus driver through Set_Address standard usb request.
162 // As XHCI spec replaces this request with Address_Device command, we have to record the
163 // requested device address and establish a mapping relationship with the actual device address.
164 // Then UsbBus driver just need to be aware of the requested device address to access usb device
165 // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual
166 // device address and access the actual device.
170 // The pointer to the input device context.
174 // The pointer to the output device context.
178 // The transfer queue for every endpoint.
180 VOID
*EndpointTransferRing
[31];
182 // The device descriptor which is stored to support XHCI's Evaluate_Context cmd.
184 EFI_USB_DEVICE_DESCRIPTOR DevDesc
;
186 // As a usb device may include multiple configuration descriptors, we dynamically allocate an array
188 // Note that every configuration descriptor stored here includes those lower level descriptors,
189 // such as Interface descriptor, Endpoint descriptor, and so on.
190 // These information is used to support XHCI's Config_Endpoint cmd.
192 EFI_USB_CONFIG_DESCRIPTOR
**ConfDesc
;
195 struct _USB_XHCI_INSTANCE
{
197 EFI_PCI_IO_PROTOCOL
*PciIo
;
198 UINT64 OriginalPciAttributes
;
200 EFI_USB2_HC_PROTOCOL Usb2Hc
;
202 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
205 // ExitBootServicesEvent is used to set OS semaphore and
206 // stop the XHC DMA operation after exit boot service.
208 EFI_EVENT ExitBootServiceEvent
;
210 LIST_ENTRY AsyncIntTransfers
;
212 UINT8 CapLength
; ///< Capability Register Length
213 XHC_HCSPARAMS1 HcSParams1
; ///< Structural Parameters 1
214 XHC_HCSPARAMS2 HcSParams2
; ///< Structural Parameters 2
215 XHC_HCCPARAMS HcCParams
; ///< Capability Parameters
216 UINT32 DBOff
; ///< Doorbell Offset
217 UINT32 RTSOff
; ///< Runtime Register Space Offset
221 UINT32 MaxScratchpadBufs
;
222 UINT32 ExtCapRegBase
;
223 UINT32 UsbLegSupOffset
;
229 TRANSFER_RING CmdRing
;
233 EVENT_RING EventRing
;
237 EFI_UNICODE_STRING_TABLE
*ControllerNameTable
;
240 // Store device contexts managed by XHCI instance
241 // The array supports up to 255 devices, entry 0 is reserved and should not be used.
243 USB_DEV_CONTEXT UsbDevContext
[256];
247 extern EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding
;
248 extern EFI_COMPONENT_NAME_PROTOCOL gXhciComponentName
;
249 extern EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2
;
252 Test to see if this driver supports ControllerHandle. Any
253 ControllerHandle that has Usb2HcProtocol installed will
256 @param This Protocol instance pointer.
257 @param Controller Handle of device to test.
258 @param RemainingDevicePath Not used.
260 @return EFI_SUCCESS This driver supports this device.
261 @return EFI_UNSUPPORTED This driver does not support this device.
266 XhcDriverBindingSupported (
267 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
268 IN EFI_HANDLE Controller
,
269 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
273 Starting the Usb XHCI Driver.
275 @param This Protocol instance pointer.
276 @param Controller Handle of device to test.
277 @param RemainingDevicePath Not used.
279 @return EFI_SUCCESS supports this device.
280 @return EFI_UNSUPPORTED do not support this device.
281 @return EFI_DEVICE_ERROR cannot be started due to device Error.
282 @return EFI_OUT_OF_RESOURCES cannot allocate resources.
287 XhcDriverBindingStart (
288 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
289 IN EFI_HANDLE Controller
,
290 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
294 Stop this driver on ControllerHandle. Support stoping any child handles
295 created by this driver.
297 @param This Protocol instance pointer.
298 @param Controller Handle of device to stop driver on.
299 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
300 @param ChildHandleBuffer List of handles for the children we need to stop.
302 @return EFI_SUCCESS Success.
303 @return EFI_DEVICE_ERROR Fail.
308 XhcDriverBindingStop (
309 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
310 IN EFI_HANDLE Controller
,
311 IN UINTN NumberOfChildren
,
312 IN EFI_HANDLE
*ChildHandleBuffer
316 Retrieves the capability of root hub ports.
318 @param This The EFI_USB2_HC_PROTOCOL instance.
319 @param MaxSpeed Max speed supported by the controller.
320 @param PortNumber Number of the root hub ports.
321 @param Is64BitCapable Whether the controller supports 64-bit memory
324 @retval EFI_SUCCESS Host controller capability were retrieved successfully.
325 @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.
331 IN EFI_USB2_HC_PROTOCOL
*This
,
333 OUT UINT8
*PortNumber
,
334 OUT UINT8
*Is64BitCapable
338 Provides software reset for the USB host controller.
340 @param This This EFI_USB2_HC_PROTOCOL instance.
341 @param Attributes A bit mask of the reset operation to perform.
343 @retval EFI_SUCCESS The reset operation succeeded.
344 @retval EFI_INVALID_PARAMETER Attributes is not valid.
345 @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
346 not currently supported by the host controller.
347 @retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
353 IN EFI_USB2_HC_PROTOCOL
*This
,
358 Retrieve the current state of the USB host controller.
360 @param This This EFI_USB2_HC_PROTOCOL instance.
361 @param State Variable to return the current host controller
364 @retval EFI_SUCCESS Host controller state was returned in State.
365 @retval EFI_INVALID_PARAMETER State is NULL.
366 @retval EFI_DEVICE_ERROR An error was encountered while attempting to
367 retrieve the host controller's current state.
373 IN EFI_USB2_HC_PROTOCOL
*This
,
374 OUT EFI_USB_HC_STATE
*State
378 Sets the USB host controller to a specific state.
380 @param This This EFI_USB2_HC_PROTOCOL instance.
381 @param State The state of the host controller that will be set.
383 @retval EFI_SUCCESS The USB host controller was successfully placed
384 in the state specified by State.
385 @retval EFI_INVALID_PARAMETER State is invalid.
386 @retval EFI_DEVICE_ERROR Failed to set the state due to device error.
392 IN EFI_USB2_HC_PROTOCOL
*This
,
393 IN EFI_USB_HC_STATE State
397 Retrieves the current status of a USB root hub port.
399 @param This This EFI_USB2_HC_PROTOCOL instance.
400 @param PortNumber The root hub port to retrieve the state from.
401 This value is zero-based.
402 @param PortStatus Variable to receive the port state.
404 @retval EFI_SUCCESS The status of the USB root hub port specified.
405 by PortNumber was returned in PortStatus.
406 @retval EFI_INVALID_PARAMETER PortNumber is invalid.
407 @retval EFI_DEVICE_ERROR Can't read register.
412 XhcGetRootHubPortStatus (
413 IN EFI_USB2_HC_PROTOCOL
*This
,
415 OUT EFI_USB_PORT_STATUS
*PortStatus
419 Sets a feature for the specified root hub port.
421 @param This This EFI_USB2_HC_PROTOCOL instance.
422 @param PortNumber Root hub port to set.
423 @param PortFeature Feature to set.
425 @retval EFI_SUCCESS The feature specified by PortFeature was set.
426 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
427 @retval EFI_DEVICE_ERROR Can't read register.
432 XhcSetRootHubPortFeature (
433 IN EFI_USB2_HC_PROTOCOL
*This
,
435 IN EFI_USB_PORT_FEATURE PortFeature
439 Clears a feature for the specified root hub port.
441 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
442 @param PortNumber Specifies the root hub port whose feature is
443 requested to be cleared.
444 @param PortFeature Indicates the feature selector associated with the
445 feature clear request.
447 @retval EFI_SUCCESS The feature specified by PortFeature was cleared
448 for the USB root hub port specified by PortNumber.
449 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
450 @retval EFI_DEVICE_ERROR Can't read register.
455 XhcClearRootHubPortFeature (
456 IN EFI_USB2_HC_PROTOCOL
*This
,
458 IN EFI_USB_PORT_FEATURE PortFeature
462 Submits control transfer to a target USB device.
464 @param This This EFI_USB2_HC_PROTOCOL instance.
465 @param DeviceAddress The target device address.
466 @param DeviceSpeed Target device speed.
467 @param MaximumPacketLength Maximum packet size the default control transfer
468 endpoint is capable of sending or receiving.
469 @param Request USB device request to send.
470 @param TransferDirection Specifies the data direction for the data stage
471 @param Data Data buffer to be transmitted or received from USB
473 @param DataLength The size (in bytes) of the data buffer.
474 @param Timeout Indicates the maximum timeout, in millisecond.
475 @param Translator Transaction translator to be used by this device.
476 @param TransferResult Return the result of this control transfer.
478 @retval EFI_SUCCESS Transfer was completed successfully.
479 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.
480 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
481 @retval EFI_TIMEOUT Transfer failed due to timeout.
482 @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.
488 IN EFI_USB2_HC_PROTOCOL
*This
,
489 IN UINT8 DeviceAddress
,
490 IN UINT8 DeviceSpeed
,
491 IN UINTN MaximumPacketLength
,
492 IN EFI_USB_DEVICE_REQUEST
*Request
,
493 IN EFI_USB_DATA_DIRECTION TransferDirection
,
495 IN OUT UINTN
*DataLength
,
497 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
498 OUT UINT32
*TransferResult
502 Submits bulk transfer to a bulk endpoint of a USB device.
504 @param This This EFI_USB2_HC_PROTOCOL instance.
505 @param DeviceAddress Target device address.
506 @param EndPointAddress Endpoint number and its direction in bit 7.
507 @param DeviceSpeed Device speed, Low speed device doesn't support bulk
509 @param MaximumPacketLength Maximum packet size the endpoint is capable of
510 sending or receiving.
511 @param DataBuffersNumber Number of data buffers prepared for the transfer.
512 @param Data Array of pointers to the buffers of data to transmit
513 from or receive into.
514 @param DataLength The lenght of the data buffer.
515 @param DataToggle On input, the initial data toggle for the transfer;
516 On output, it is updated to to next data toggle to
517 use of the subsequent bulk transfer.
518 @param Timeout Indicates the maximum time, in millisecond, which
519 the transfer is allowed to complete.
520 @param Translator A pointr to the transaction translator data.
521 @param TransferResult A pointer to the detailed result information of the
524 @retval EFI_SUCCESS The transfer was completed successfully.
525 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
526 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
527 @retval EFI_TIMEOUT The transfer failed due to timeout.
528 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
534 IN EFI_USB2_HC_PROTOCOL
*This
,
535 IN UINT8 DeviceAddress
,
536 IN UINT8 EndPointAddress
,
537 IN UINT8 DeviceSpeed
,
538 IN UINTN MaximumPacketLength
,
539 IN UINT8 DataBuffersNumber
,
540 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
541 IN OUT UINTN
*DataLength
,
542 IN OUT UINT8
*DataToggle
,
544 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
545 OUT UINT32
*TransferResult
549 Submits an asynchronous interrupt transfer to an
550 interrupt endpoint of a USB device.
552 @param This This EFI_USB2_HC_PROTOCOL instance.
553 @param DeviceAddress Target device address.
554 @param EndPointAddress Endpoint number and its direction encoded in bit 7
555 @param DeviceSpeed Indicates device speed.
556 @param MaximumPacketLength Maximum packet size the target endpoint is capable
557 @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt
558 transfer If FALSE, to remove the specified
559 asynchronous interrupt.
560 @param DataToggle On input, the initial data toggle to use; on output,
561 it is updated to indicate the next data toggle.
562 @param PollingInterval The he interval, in milliseconds, that the transfer
564 @param DataLength The length of data to receive at the rate specified
566 @param Translator Transaction translator to use.
567 @param CallBackFunction Function to call at the rate specified by
569 @param Context Context to CallBackFunction.
571 @retval EFI_SUCCESS The request has been successfully submitted or canceled.
572 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
573 @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources.
574 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
579 XhcAsyncInterruptTransfer (
580 IN EFI_USB2_HC_PROTOCOL
*This
,
581 IN UINT8 DeviceAddress
,
582 IN UINT8 EndPointAddress
,
583 IN UINT8 DeviceSpeed
,
584 IN UINTN MaximumPacketLength
,
585 IN BOOLEAN IsNewTransfer
,
586 IN OUT UINT8
*DataToggle
,
587 IN UINTN PollingInterval
,
589 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
590 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
591 IN VOID
*Context OPTIONAL
595 Submits synchronous interrupt transfer to an interrupt endpoint
598 @param This This EFI_USB2_HC_PROTOCOL instance.
599 @param DeviceAddress Target device address.
600 @param EndPointAddress Endpoint number and its direction encoded in bit 7
601 @param DeviceSpeed Indicates device speed.
602 @param MaximumPacketLength Maximum packet size the target endpoint is capable
603 of sending or receiving.
604 @param Data Buffer of data that will be transmitted to USB
605 device or received from USB device.
606 @param DataLength On input, the size, in bytes, of the data buffer; On
607 output, the number of bytes transferred.
608 @param DataToggle On input, the initial data toggle to use; on output,
609 it is updated to indicate the next data toggle.
610 @param Timeout Maximum time, in second, to complete.
611 @param Translator Transaction translator to use.
612 @param TransferResult Variable to receive the transfer result.
614 @return EFI_SUCCESS The transfer was completed successfully.
615 @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
616 @return EFI_INVALID_PARAMETER Some parameters are invalid.
617 @return EFI_TIMEOUT The transfer failed due to timeout.
618 @return EFI_DEVICE_ERROR The failed due to host controller or device error
623 XhcSyncInterruptTransfer (
624 IN EFI_USB2_HC_PROTOCOL
*This
,
625 IN UINT8 DeviceAddress
,
626 IN UINT8 EndPointAddress
,
627 IN UINT8 DeviceSpeed
,
628 IN UINTN MaximumPacketLength
,
630 IN OUT UINTN
*DataLength
,
631 IN OUT UINT8
*DataToggle
,
633 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
634 OUT UINT32
*TransferResult
638 Submits isochronous transfer to a target USB device.
640 @param This This EFI_USB2_HC_PROTOCOL instance.
641 @param DeviceAddress Target device address.
642 @param EndPointAddress End point address with its direction.
643 @param DeviceSpeed Device speed, Low speed device doesn't support this
645 @param MaximumPacketLength Maximum packet size that the endpoint is capable of
646 sending or receiving.
647 @param DataBuffersNumber Number of data buffers prepared for the transfer.
648 @param Data Array of pointers to the buffers of data that will
649 be transmitted to USB device or received from USB
651 @param DataLength The size, in bytes, of the data buffer.
652 @param Translator Transaction translator to use.
653 @param TransferResult Variable to receive the transfer result.
655 @return EFI_UNSUPPORTED Isochronous transfer is unsupported.
660 XhcIsochronousTransfer (
661 IN EFI_USB2_HC_PROTOCOL
*This
,
662 IN UINT8 DeviceAddress
,
663 IN UINT8 EndPointAddress
,
664 IN UINT8 DeviceSpeed
,
665 IN UINTN MaximumPacketLength
,
666 IN UINT8 DataBuffersNumber
,
667 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
669 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
670 OUT UINT32
*TransferResult
674 Submits Async isochronous transfer to a target USB device.
676 @param This This EFI_USB2_HC_PROTOCOL instance.
677 @param DeviceAddress Target device address.
678 @param EndPointAddress End point address with its direction.
679 @param DeviceSpeed Device speed, Low speed device doesn't support this
681 @param MaximumPacketLength Maximum packet size that the endpoint is capable of
682 sending or receiving.
683 @param DataBuffersNumber Number of data buffers prepared for the transfer.
684 @param Data Array of pointers to the buffers of data that will
685 be transmitted to USB device or received from USB
687 @param DataLength The size, in bytes, of the data buffer.
688 @param Translator Transaction translator to use.
689 @param IsochronousCallBack Function to be called when the transfer complete.
690 @param Context Context passed to the call back function as
693 @return EFI_UNSUPPORTED Isochronous transfer isn't supported.
698 XhcAsyncIsochronousTransfer (
699 IN EFI_USB2_HC_PROTOCOL
*This
,
700 IN UINT8 DeviceAddress
,
701 IN UINT8 EndPointAddress
,
702 IN UINT8 DeviceSpeed
,
703 IN UINTN MaximumPacketLength
,
704 IN UINT8 DataBuffersNumber
,
705 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
707 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
708 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,