3 Provides some data structure definitions used by the XHCI host controller driver.
5 Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
6 Copyright (c) Microsoft Corporation.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include <Protocol/Usb2HostController.h>
17 #include <Protocol/PciIo.h>
19 #include <Guid/EventGroup.h>
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/UefiDriverEntryPoint.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/UefiLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/ReportStatusCodeLib.h>
30 #include <IndustryStandard/Pci.h>
32 typedef struct _USB_XHCI_INSTANCE USB_XHCI_INSTANCE
;
33 typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT
;
36 #include "XhciSched.h"
37 #include "ComponentName.h"
41 // The unit is microsecond, setting it as 1us.
43 #define XHC_1_MICROSECOND (1)
45 // The unit is microsecond, setting it as 1ms.
47 #define XHC_1_MILLISECOND (1000)
49 // XHC generic timeout experience values.
50 // The unit is millisecond, setting it as 10s.
52 #define XHC_GENERIC_TIMEOUT (10 * 1000)
54 // XHC reset timeout experience values.
55 // The unit is millisecond, setting it as 1s.
57 #define XHC_RESET_TIMEOUT (1000)
59 // TRSTRCY delay requirement in usb 2.0 spec chapter 7.1.7.5.
60 // The unit is microsecond, setting it as 10ms.
62 #define XHC_RESET_RECOVERY_DELAY (10 * 1000)
64 // XHC async transfer timer interval, set by experience.
65 // The unit is 100us, takes 1ms as interval.
67 #define XHC_ASYNC_TIMER_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(1)
70 // XHC raises TPL to TPL_NOTIFY to serialize all its operations
71 // to protect shared data structures.
73 #define XHC_TPL TPL_NOTIFY
75 #define CMD_RING_TRB_NUMBER 0x100
76 #define TR_RING_TRB_NUMBER 0x100
77 #define ERST_NUMBER 0x01
78 #define EVENT_RING_TRB_NUMBER 0x200
84 #define INT_INTER_ASYNC 4
86 #define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field)
88 #define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFFFFFFF))
89 #define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINT64)(UINTN)(Addr64), 32) & 0xFFFFFFFF))
90 #define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
92 #define XHC_REG_BIT_IS_SET(Xhc, Offset, Bit) \
93 (XHC_BIT_IS_SET(XhcReadOpReg ((Xhc), (Offset)), (Bit)))
95 #define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80)
97 #define XHCI_INSTANCE_SIG SIGNATURE_32 ('x', 'h', 'c', 'i')
98 #define XHC_FROM_THIS(a) CR(a, USB_XHCI_INSTANCE, Usb2Hc, XHCI_INSTANCE_SIG)
100 #define USB_DESC_TYPE_HUB 0x29
101 #define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a
104 // The RequestType in EFI_USB_DEVICE_REQUEST is composed of
105 // three fields: One bit direction, 2 bit type, and 5 bit
108 #define USB_REQUEST_TYPE(Dir, Type, Target) \
109 ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target)))
112 // Xhci Data and Ctrl Structures
127 UINT8 HubContrCurrent
;
129 } EFI_USB_HUB_DESCRIPTOR
;
132 struct _USB_DEV_CONTEXT
{
134 // Whether this entry in UsbDevContext array is used or not.
138 // The slot id assigned to the new device through XHCI's Enable_Slot cmd.
142 // The route string presented an attached usb device.
144 USB_DEV_ROUTE RouteString
;
146 // The route string of parent device if it exists. Otherwise it's zero.
148 USB_DEV_ROUTE ParentRouteString
;
150 // The actual device address assigned by XHCI through Address_Device command.
154 // The requested device address from UsbBus driver through Set_Address standard usb request.
155 // As XHCI spec replaces this request with Address_Device command, we have to record the
156 // requested device address and establish a mapping relationship with the actual device address.
157 // Then UsbBus driver just need to be aware of the requested device address to access usb device
158 // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual
159 // device address and access the actual device.
163 // The pointer to the input device context.
167 // The pointer to the output device context.
171 // The transfer queue for every endpoint.
173 VOID
*EndpointTransferRing
[31];
175 // The device descriptor which is stored to support XHCI's Evaluate_Context cmd.
177 EFI_USB_DEVICE_DESCRIPTOR DevDesc
;
179 // As a usb device may include multiple configuration descriptors, we dynamically allocate an array
181 // Note that every configuration descriptor stored here includes those lower level descriptors,
182 // such as Interface descriptor, Endpoint descriptor, and so on.
183 // These information is used to support XHCI's Config_Endpoint cmd.
185 EFI_USB_CONFIG_DESCRIPTOR
**ConfDesc
;
187 // A device has an active Configuration.
189 UINT8 ActiveConfiguration
;
191 // Every interface has an active AlternateSetting.
193 UINT8
*ActiveAlternateSetting
;
196 struct _USB_XHCI_INSTANCE
{
198 EFI_PCI_IO_PROTOCOL
*PciIo
;
199 UINT64 OriginalPciAttributes
;
200 USBHC_MEM_POOL
*MemPool
;
202 EFI_USB2_HC_PROTOCOL Usb2Hc
;
204 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
207 // ExitBootServicesEvent is used to set OS semaphore and
208 // stop the XHC DMA operation after exit boot service.
210 EFI_EVENT ExitBootServiceEvent
;
212 LIST_ENTRY AsyncIntTransfers
;
214 UINT8 CapLength
; ///< Capability Register Length
215 XHC_HCSPARAMS1 HcSParams1
; ///< Structural Parameters 1
216 XHC_HCSPARAMS2 HcSParams2
; ///< Structural Parameters 2
217 XHC_HCCPARAMS HcCParams
; ///< Capability Parameters
218 UINT32 DBOff
; ///< Doorbell Offset
219 UINT32 RTSOff
; ///< Runtime Register Space Offset
224 UINT32 MaxScratchpadBufs
;
225 UINT64
*ScratchEntry
;
226 UINTN
*ScratchEntryMap
;
227 UINT32 ExtCapRegBase
;
228 UINT32 UsbLegSupOffset
;
229 UINT32 DebugCapSupOffset
;
230 UINT32 Usb2SupOffset
;
231 UINT32 Usb3SupOffset
;
239 TRANSFER_RING CmdRing
;
243 EVENT_RING EventRing
;
247 EFI_UNICODE_STRING_TABLE
*ControllerNameTable
;
250 // Store device contexts managed by XHCI instance
251 // The array supports up to 255 devices, entry 0 is reserved and should not be used.
253 USB_DEV_CONTEXT UsbDevContext
[256];
255 BOOLEAN Support64BitDma
; // Whether 64 bit DMA may be used with this device
258 extern EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding
;
259 extern EFI_COMPONENT_NAME_PROTOCOL gXhciComponentName
;
260 extern EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2
;
263 Test to see if this driver supports ControllerHandle. Any
264 ControllerHandle that has Usb2HcProtocol installed will
267 @param This Protocol instance pointer.
268 @param Controller Handle of device to test.
269 @param RemainingDevicePath Not used.
271 @return EFI_SUCCESS This driver supports this device.
272 @return EFI_UNSUPPORTED This driver does not support this device.
277 XhcDriverBindingSupported (
278 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
279 IN EFI_HANDLE Controller
,
280 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
284 Starting the Usb XHCI Driver.
286 @param This Protocol instance pointer.
287 @param Controller Handle of device to test.
288 @param RemainingDevicePath Not used.
290 @return EFI_SUCCESS supports this device.
291 @return EFI_UNSUPPORTED do not support this device.
292 @return EFI_DEVICE_ERROR cannot be started due to device Error.
293 @return EFI_OUT_OF_RESOURCES cannot allocate resources.
298 XhcDriverBindingStart (
299 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
300 IN EFI_HANDLE Controller
,
301 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
305 Stop this driver on ControllerHandle. Support stopping any child handles
306 created by this driver.
308 @param This Protocol instance pointer.
309 @param Controller Handle of device to stop driver on.
310 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
311 @param ChildHandleBuffer List of handles for the children we need to stop.
313 @return EFI_SUCCESS Success.
314 @return EFI_DEVICE_ERROR Fail.
319 XhcDriverBindingStop (
320 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
321 IN EFI_HANDLE Controller
,
322 IN UINTN NumberOfChildren
,
323 IN EFI_HANDLE
*ChildHandleBuffer
327 Retrieves the capability of root hub ports.
329 @param This The EFI_USB2_HC_PROTOCOL instance.
330 @param MaxSpeed Max speed supported by the controller.
331 @param PortNumber Number of the root hub ports.
332 @param Is64BitCapable Whether the controller supports 64-bit memory
335 @retval EFI_SUCCESS Host controller capability were retrieved successfully.
336 @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.
342 IN EFI_USB2_HC_PROTOCOL
*This
,
344 OUT UINT8
*PortNumber
,
345 OUT UINT8
*Is64BitCapable
349 Provides software reset for the USB host controller.
351 @param This This EFI_USB2_HC_PROTOCOL instance.
352 @param Attributes A bit mask of the reset operation to perform.
354 @retval EFI_SUCCESS The reset operation succeeded.
355 @retval EFI_INVALID_PARAMETER Attributes is not valid.
356 @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
357 not currently supported by the host controller.
358 @retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
364 IN EFI_USB2_HC_PROTOCOL
*This
,
369 Retrieve the current state of the USB host controller.
371 @param This This EFI_USB2_HC_PROTOCOL instance.
372 @param State Variable to return the current host controller
375 @retval EFI_SUCCESS Host controller state was returned in State.
376 @retval EFI_INVALID_PARAMETER State is NULL.
377 @retval EFI_DEVICE_ERROR An error was encountered while attempting to
378 retrieve the host controller's current state.
384 IN EFI_USB2_HC_PROTOCOL
*This
,
385 OUT EFI_USB_HC_STATE
*State
389 Sets the USB host controller to a specific state.
391 @param This This EFI_USB2_HC_PROTOCOL instance.
392 @param State The state of the host controller that will be set.
394 @retval EFI_SUCCESS The USB host controller was successfully placed
395 in the state specified by State.
396 @retval EFI_INVALID_PARAMETER State is invalid.
397 @retval EFI_DEVICE_ERROR Failed to set the state due to device error.
403 IN EFI_USB2_HC_PROTOCOL
*This
,
404 IN EFI_USB_HC_STATE State
408 Retrieves the current status of a USB root hub port.
410 @param This This EFI_USB2_HC_PROTOCOL instance.
411 @param PortNumber The root hub port to retrieve the state from.
412 This value is zero-based.
413 @param PortStatus Variable to receive the port state.
415 @retval EFI_SUCCESS The status of the USB root hub port specified.
416 by PortNumber was returned in PortStatus.
417 @retval EFI_INVALID_PARAMETER PortNumber is invalid.
418 @retval EFI_DEVICE_ERROR Can't read register.
423 XhcGetRootHubPortStatus (
424 IN EFI_USB2_HC_PROTOCOL
*This
,
426 OUT EFI_USB_PORT_STATUS
*PortStatus
430 Sets a feature for the specified root hub port.
432 @param This This EFI_USB2_HC_PROTOCOL instance.
433 @param PortNumber Root hub port to set.
434 @param PortFeature Feature to set.
436 @retval EFI_SUCCESS The feature specified by PortFeature was set.
437 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
438 @retval EFI_DEVICE_ERROR Can't read register.
443 XhcSetRootHubPortFeature (
444 IN EFI_USB2_HC_PROTOCOL
*This
,
446 IN EFI_USB_PORT_FEATURE PortFeature
450 Clears a feature for the specified root hub port.
452 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
453 @param PortNumber Specifies the root hub port whose feature is
454 requested to be cleared.
455 @param PortFeature Indicates the feature selector associated with the
456 feature clear request.
458 @retval EFI_SUCCESS The feature specified by PortFeature was cleared
459 for the USB root hub port specified by PortNumber.
460 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
461 @retval EFI_DEVICE_ERROR Can't read register.
466 XhcClearRootHubPortFeature (
467 IN EFI_USB2_HC_PROTOCOL
*This
,
469 IN EFI_USB_PORT_FEATURE PortFeature
473 Submits control transfer to a target USB device.
475 @param This This EFI_USB2_HC_PROTOCOL instance.
476 @param DeviceAddress The target device address.
477 @param DeviceSpeed Target device speed.
478 @param MaximumPacketLength Maximum packet size the default control transfer
479 endpoint is capable of sending or receiving.
480 @param Request USB device request to send.
481 @param TransferDirection Specifies the data direction for the data stage
482 @param Data Data buffer to be transmitted or received from USB
484 @param DataLength The size (in bytes) of the data buffer.
485 @param Timeout Indicates the maximum timeout, in millisecond.
486 @param Translator Transaction translator to be used by this device.
487 @param TransferResult Return the result of this control transfer.
489 @retval EFI_SUCCESS Transfer was completed successfully.
490 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.
491 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
492 @retval EFI_TIMEOUT Transfer failed due to timeout.
493 @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.
499 IN EFI_USB2_HC_PROTOCOL
*This
,
500 IN UINT8 DeviceAddress
,
501 IN UINT8 DeviceSpeed
,
502 IN UINTN MaximumPacketLength
,
503 IN EFI_USB_DEVICE_REQUEST
*Request
,
504 IN EFI_USB_DATA_DIRECTION TransferDirection
,
506 IN OUT UINTN
*DataLength
,
508 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
509 OUT UINT32
*TransferResult
513 Submits bulk transfer to a bulk endpoint of a USB device.
515 @param This This EFI_USB2_HC_PROTOCOL instance.
516 @param DeviceAddress Target device address.
517 @param EndPointAddress Endpoint number and its direction in bit 7.
518 @param DeviceSpeed Device speed, Low speed device doesn't support bulk
520 @param MaximumPacketLength Maximum packet size the endpoint is capable of
521 sending or receiving.
522 @param DataBuffersNumber Number of data buffers prepared for the transfer.
523 @param Data Array of pointers to the buffers of data to transmit
524 from or receive into.
525 @param DataLength The lenght of the data buffer.
526 @param DataToggle On input, the initial data toggle for the transfer;
527 On output, it is updated to to next data toggle to
528 use of the subsequent bulk transfer.
529 @param Timeout Indicates the maximum time, in millisecond, which
530 the transfer is allowed to complete.
531 @param Translator A pointr to the transaction translator data.
532 @param TransferResult A pointer to the detailed result information of the
535 @retval EFI_SUCCESS The transfer was completed successfully.
536 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
537 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
538 @retval EFI_TIMEOUT The transfer failed due to timeout.
539 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
545 IN EFI_USB2_HC_PROTOCOL
*This
,
546 IN UINT8 DeviceAddress
,
547 IN UINT8 EndPointAddress
,
548 IN UINT8 DeviceSpeed
,
549 IN UINTN MaximumPacketLength
,
550 IN UINT8 DataBuffersNumber
,
551 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
552 IN OUT UINTN
*DataLength
,
553 IN OUT UINT8
*DataToggle
,
555 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
556 OUT UINT32
*TransferResult
560 Submits an asynchronous interrupt transfer to an
561 interrupt endpoint of a USB device.
563 @param This This EFI_USB2_HC_PROTOCOL instance.
564 @param DeviceAddress Target device address.
565 @param EndPointAddress Endpoint number and its direction encoded in bit 7
566 @param DeviceSpeed Indicates device speed.
567 @param MaximumPacketLength Maximum packet size the target endpoint is capable
568 @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt
569 transfer If FALSE, to remove the specified
570 asynchronous interrupt.
571 @param DataToggle On input, the initial data toggle to use; on output,
572 it is updated to indicate the next data toggle.
573 @param PollingInterval The he interval, in milliseconds, that the transfer
575 @param DataLength The length of data to receive at the rate specified
577 @param Translator Transaction translator to use.
578 @param CallBackFunction Function to call at the rate specified by
580 @param Context Context to CallBackFunction.
582 @retval EFI_SUCCESS The request has been successfully submitted or canceled.
583 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
584 @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources.
585 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
590 XhcAsyncInterruptTransfer (
591 IN EFI_USB2_HC_PROTOCOL
*This
,
592 IN UINT8 DeviceAddress
,
593 IN UINT8 EndPointAddress
,
594 IN UINT8 DeviceSpeed
,
595 IN UINTN MaximumPacketLength
,
596 IN BOOLEAN IsNewTransfer
,
597 IN OUT UINT8
*DataToggle
,
598 IN UINTN PollingInterval
,
600 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
601 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
602 IN VOID
*Context OPTIONAL
606 Submits synchronous interrupt transfer to an interrupt endpoint
609 @param This This EFI_USB2_HC_PROTOCOL instance.
610 @param DeviceAddress Target device address.
611 @param EndPointAddress Endpoint number and its direction encoded in bit 7
612 @param DeviceSpeed Indicates device speed.
613 @param MaximumPacketLength Maximum packet size the target endpoint is capable
614 of sending or receiving.
615 @param Data Buffer of data that will be transmitted to USB
616 device or received from USB device.
617 @param DataLength On input, the size, in bytes, of the data buffer; On
618 output, the number of bytes transferred.
619 @param DataToggle On input, the initial data toggle to use; on output,
620 it is updated to indicate the next data toggle.
621 @param Timeout Maximum time, in second, to complete.
622 @param Translator Transaction translator to use.
623 @param TransferResult Variable to receive the transfer result.
625 @return EFI_SUCCESS The transfer was completed successfully.
626 @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
627 @return EFI_INVALID_PARAMETER Some parameters are invalid.
628 @return EFI_TIMEOUT The transfer failed due to timeout.
629 @return EFI_DEVICE_ERROR The failed due to host controller or device error
634 XhcSyncInterruptTransfer (
635 IN EFI_USB2_HC_PROTOCOL
*This
,
636 IN UINT8 DeviceAddress
,
637 IN UINT8 EndPointAddress
,
638 IN UINT8 DeviceSpeed
,
639 IN UINTN MaximumPacketLength
,
641 IN OUT UINTN
*DataLength
,
642 IN OUT UINT8
*DataToggle
,
644 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
645 OUT UINT32
*TransferResult
649 Submits isochronous transfer to a target USB device.
651 @param This This EFI_USB2_HC_PROTOCOL instance.
652 @param DeviceAddress Target device address.
653 @param EndPointAddress End point address with its direction.
654 @param DeviceSpeed Device speed, Low speed device doesn't support this
656 @param MaximumPacketLength Maximum packet size that the endpoint is capable of
657 sending or receiving.
658 @param DataBuffersNumber Number of data buffers prepared for the transfer.
659 @param Data Array of pointers to the buffers of data that will
660 be transmitted to USB device or received from USB
662 @param DataLength The size, in bytes, of the data buffer.
663 @param Translator Transaction translator to use.
664 @param TransferResult Variable to receive the transfer result.
666 @return EFI_UNSUPPORTED Isochronous transfer is unsupported.
671 XhcIsochronousTransfer (
672 IN EFI_USB2_HC_PROTOCOL
*This
,
673 IN UINT8 DeviceAddress
,
674 IN UINT8 EndPointAddress
,
675 IN UINT8 DeviceSpeed
,
676 IN UINTN MaximumPacketLength
,
677 IN UINT8 DataBuffersNumber
,
678 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
680 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
681 OUT UINT32
*TransferResult
685 Submits Async isochronous transfer to a target USB device.
687 @param This This EFI_USB2_HC_PROTOCOL instance.
688 @param DeviceAddress Target device address.
689 @param EndPointAddress End point address with its direction.
690 @param DeviceSpeed Device speed, Low speed device doesn't support this
692 @param MaximumPacketLength Maximum packet size that the endpoint is capable of
693 sending or receiving.
694 @param DataBuffersNumber Number of data buffers prepared for the transfer.
695 @param Data Array of pointers to the buffers of data that will
696 be transmitted to USB device or received from USB
698 @param DataLength The size, in bytes, of the data buffer.
699 @param Translator Transaction translator to use.
700 @param IsochronousCallBack Function to be called when the transfer complete.
701 @param Context Context passed to the call back function as
704 @return EFI_UNSUPPORTED Isochronous transfer isn't supported.
709 XhcAsyncIsochronousTransfer (
710 IN EFI_USB2_HC_PROTOCOL
*This
,
711 IN UINT8 DeviceAddress
,
712 IN UINT8 EndPointAddress
,
713 IN UINT8 DeviceSpeed
,
714 IN UINTN MaximumPacketLength
,
715 IN UINT8 DataBuffersNumber
,
716 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
718 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
719 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,