ReactOS 0.4.17-dev-1281-g065abb3
XhciController Class Reference

#include <hc.h>

Collaboration diagram for XhciController:

Public Types

enum  : ULONG64 {
  FixFrescoShadow = 0x01 , FixFrescoControl = 0x02 , FixEtronSet = 0x04 , FixEtronClear = 0x08 ,
  FixAsmediaResetDelay = 0x10
}
 
enum class  SystemAction : ULONG {
  Boot = 0 , ResumeFromSleep = 1 , ResumeFromHibernate = 2 , Sleep = 3 ,
  HybridSleep = 4 , Hibernate = 5 , Shutdown = 6 , None = 7
}
 

Public Member Functions

BOOLEAN HasErrata (_In_ XhciErrata Bit) const
 
VOID SetErrata (_In_ XhciErrata Bit)
 
BOOLEAN IsAccessible () const
 
VOID MarkGone ()
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID RaiseControllerFault(_In_ XhciRecovery Action
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) ULONG GetFrameNumber(_In_ ULONG Increment)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID VerifierCheck(_In_ ULONG Flag)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID OnRootHubD0Entry()
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID NotifyPortConnectState(_In_ BOOLEAN AnyConnected)
 
NTSTATUS Initialize (_In_ WDFDEVICE Device, _In_ UCXCONTROLLER Ucx, _In_ const XhciIdentity *Identity)
 
NTSTATUS PrepareHardware (_In_ WDFCMRESLIST Raw, _In_ WDFCMRESLIST Translated)
 
VOID ReleaseHardware ()
 
NTSTATUS D0Entry (_In_ WDF_POWER_DEVICE_STATE PreviousState)
 
NTSTATUS D0EntryPostInterruptsEnabled (_In_ WDF_POWER_DEVICE_STATE PreviousState)
 
VOID D0ExitPreInterruptsDisabled ()
 
VOID D0Exit (_In_ WDF_POWER_DEVICE_STATE TargetState)
 
VOID SelfManagedIoInit ()
 
VOID SelfManagedIoCleanup ()
 
VOID UsageNotification (_In_ WDF_SPECIAL_FILE_TYPE Type, _In_ BOOLEAN InPath)
 
VOID SetPortWake (_In_ BOOLEAN Arm)
 
VOID TrackSystemPowerIrp (_In_ PIO_STACK_LOCATION Stack)
 
VOID WatchdogTick ()
 
VOID RecoveryWorker ()
 
VOID IdleTimeoutWorker ()
 
VOID UcxReset ()
 
NTSTATUS QueryUsbCapability (_In_ const GUID *Capability, _In_ ULONG OutputBufferLength, _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, _Out_ PULONG ResultLength)
 
VOID FdoCleanup ()
 

Static Public Member Functions

static XhciController * FromDevice (_In_ WDFDEVICE Device)
 
static XhciController * FromUcx (_In_ UCXCONTROLLER UcxController)
 

Public Attributes

_In_ ULONG Reason
 
WDFDEVICE m_Device
 
PDEVICE_OBJECT m_WdmDevice
 
UCXCONTROLLER m_Ucx
 
ULONG64 m_Errata
 
ULONG64 m_ErrataWord2
 
XhciRegisters m_Registers
 
XhciCommonBuffer m_Buffers
 
XhciSlotTable m_Slots
 
XhciInterrupters m_Interrupters
 
XhciCommandRing m_Commands
 
XhciRootHub m_RootHub
 
XhciIdentity m_Identity
 
ULONG64 m_InternalFlags
 
BOOLEAN m_ReservedIoArmed
 
WDF_POWER_DEVICE_STATE m_PowerState
 
SystemAction m_SystemAction
 
XhciDmaBuffer * m_SplitPadBuffer
 
BOOLEAN m_WaitWakeQueued
 
BOOLEAN m_TestMode
 

Private Types

enum class  IdleStatus : ULONG { NotConfigured , NoS0Wake , Configured }
 

Private Member Functions

NTSTATUS CreateWdfObjects ()
 
VOID PopulateErrata ()
 
VOID QueryErrataDatabase (_In_ BOOLEAN AtAddDevice)
 
VOID ReadRegistryErrata ()
 
VOID SetInternalFlags ()
 
VOID ReadVerifierFlags ()
 
VOID ConfigureS0Idle ()
 
VOID SetIdleTimeout (_In_ ULONG Milliseconds)
 
VOID EvaluateDsm (_In_ ULONG Function)
 
VOID EvaluatePrmi ()
 
VOID UpdateRegistryCounters ()
 
VOID RunFirmwareCommands ()
 
NTSTATUS StartController ()
 
NTSTATUS RunD0Pass (_In_ BOOLEAN Restore)
 
VOID InitFrameSnapshot ()
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID QueueRecovery(_In_ ULONG Actions
 
VOID BootRecovery (_In_ ULONG Actions)
 
VOID RunRecovery (_In_ ULONG Actions)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID SetGone(_In_ BOOLEAN ReportToPnp)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID DisableController()
 
VOID InternalReset ()
 
ULONG64 NowMs () const
 

Private Attributes

ULONG m_VerifierFlags
 
BOOLEAN m_Gone
 
BOOLEAN m_SaveFailed
 
BOOLEAN m_FrameSnapshotReady
 
LONG64 m_FrameSnapshot
 
ULONG m_TimeIncrement
 
ULONG m_SpecialFiles
 
ULONG m_RestoreFailures
 
ULONG m_RecoveryCount
 
LONG m_ResetCount
 
LONG m_ResetInterval
 
LONG m_ResetLock
 
IdleStatus m_IdleStatus
 
ULONG m_LastIdleTimeout
 
WDFTIMER m_Watchdog
 
WDFWORKITEM m_RecoveryItem
 
WDFWORKITEM m_IdleItem
 
KSPIN_LOCK m_RecoveryLock
 
ULONG m_RecoveryActions
 
KMUTEX m_RecoveryMutex
 
BOOLEAN m_GoneHandled
 
BOOLEAN m_PnpToldRemoved
 

Detailed Description

Lives in the UCXCONTROLLER context and embeds every module object.

Definition at line 47 of file hc.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum : ULONG64

Internal fixes keyed by PCI id, bits of m_InternalFlags.

Enumerator
FixFrescoShadow 
FixFrescoControl 
FixEtronSet 
FixEtronClear 
FixAsmediaResetDelay 

Definition at line 103 of file hc.h.

104 {
105 FixFrescoShadow = 0x01,
106 FixFrescoControl = 0x02,
107 FixEtronSet = 0x04,
108 FixEtronClear = 0x08,
110 };
@ FixFrescoShadow
Definition: hc.h:105
@ FixAsmediaResetDelay
Definition: hc.h:109
@ FixEtronClear
Definition: hc.h:108
@ FixFrescoControl
Definition: hc.h:106
@ FixEtronSet
Definition: hc.h:107

◆ IdleStatus

Enumerator
NotConfigured 
NoS0Wake 
Configured 

Definition at line 207 of file hc.h.

◆ SystemAction

Tracked system power action.

Enumerator
Boot 
ResumeFromSleep 
ResumeFromHibernate 
Sleep 
HybridSleep 
Hibernate 
Shutdown 
None 

Definition at line 120 of file hc.h.

Member Function Documentation

◆ _IRQL_requires_max_() [1/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

32 bit frame number, Increment microframes ahead.

◆ _IRQL_requires_max_() [2/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )
private

◆ _IRQL_requires_max_() [3/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Port connect state for the power engine.

◆ _IRQL_requires_max_() [4/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Root hub PDO reached D0: switch to the short idle timeout.

◆ _IRQL_requires_max_() [5/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )
private

◆ _IRQL_requires_max_() [6/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Any IRQL up to DISPATCH_LEVEL; the work runs on the recovery work item.

◆ _IRQL_requires_max_() [7/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )
private

◆ _IRQL_requires_max_() [8/8]

XhciController::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

DPRINT1 a hardware verifier condition; breaks in when that flag is enabled.

◆ BootRecovery()

VOID XhciController::BootRecovery ( _In_ ULONG  Actions)
private

Definition at line 1971 of file hc.cpp.

1973{
1974 static LONG InlineResets;
1975
1976 /* The branches are exclusive even when several bits are set */
1978 {
1979 KeBugCheckEx(XHCI_BUGCHECK_USB3_DRIVER, 2, (ULONG_PTR)WdfDeviceWdmGetPhysicalDevice(m_Device), 3, 0);
1980 }
1981 else if (Actions & XHCI_RECOVER_INTERNAL_RESET)
1982 {
1984 {
1985 UcxControllerNeedsReset(m_Ucx);
1986 return;
1987 }
1988
1989 /* QUIRK: one counter shared by every controller */
1990 if (InterlockedIncrement(&InlineResets) != 1)
1991 DPRINT1("Boot path internal resets overlap\n");
1992 InternalReset();
1993 InterlockedDecrement(&InlineResets);
1994 }
1995 else if (Actions & XHCI_RECOVER_RESET)
1996 {
1997 UcxControllerNeedsReset(m_Ucx);
1998 }
1999 else
2000 {
2001 DPRINT1("Boot path recovery 0x%lx has no handler\n", Actions);
2002 }
2003}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
VOID InternalReset()
Definition: hc.cpp:2113
WDFDEVICE m_Device
Definition: hc.h:85
UCXCONTROLLER m_Ucx
Definition: hc.h:87
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define XHCI_RECOVER_NO_RESTART
Definition: hc.cpp:43
#define XHCI_RECOVER_INTERNAL_RESET
Definition: hc.cpp:41
#define XHCI_RECOVER_GONE_PNP
Definition: hc.cpp:45
#define XHCI_RECOVER_RESET
Definition: hc.cpp:42
#define XHCI_BUGCHECK_USB3_DRIVER
Definition: hc.cpp:80
#define XHCI_RECOVER_GONE
Definition: hc.cpp:44
long LONG
Definition: pedump.c:60
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ ConfigureS0Idle()

VOID XhciController::ConfigureS0Idle ( )
private

Definition at line 761 of file hc.cpp.

762{
766
767 if (HasErrata(XhciErrata::PwrStayInD0))
768 {
769 DPRINT1("S0 idle disabled by errata\n");
771 return;
772 }
773
774 if (HasErrata(XhciErrata::AcpiDsmAllowD3Cold))
775 EvaluateDsm(3);
776
777 RtlZeroMemory(&D3Cold, sizeof(D3Cold));
778 Status = WdfFdoQueryForInterface(m_Device, &XhciGuidD3ColdSupport, (PINTERFACE)&D3Cold,
779 sizeof(D3Cold), D3COLD_SUPPORT_INTERFACE_VERSION, NULL);
780 if (!NT_SUCCESS(Status))
781 {
782 DPRINT("No D3cold interface 0x%lx, S0 idle off\n", Status);
784 return;
785 }
786
787 if (D3Cold.GetIdleWakeInfo != NULL)
788 {
789 Status = D3Cold.GetIdleWakeInfo(D3Cold.Context, PowerSystemWorking, &Depth);
790 if (!NT_SUCCESS(Status))
791 {
792 DPRINT1("Idle wake information query failed 0x%lx\n", Status);
794 }
795 }
796
797 if (D3Cold.InterfaceDereference != NULL)
798 D3Cold.InterfaceDereference(D3Cold.Context);
799
801 {
802 DPRINT("Controller cannot wake from a Dx state in S0, S0 idle off\n");
804 return;
805 }
806
809
810 /* ReactOS has no runtime power framework */
811 DPRINT("Power framework registration skipped\n");
812}
LONG NTSTATUS
Definition: precomp.h:26
_In_ BOOLEAN _In_ BOOLEAN SetIdleTimeout
Definition: cdrom.h:1429
BOOLEAN HasErrata(_In_ XhciErrata Bit) const
Definition: hc.h:58
IdleStatus m_IdleStatus
Definition: hc.h:273
VOID EvaluateDsm(_In_ ULONG Function)
Definition: hc.cpp:686
UINT Depth
Definition: d3d12.idl:4644
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
#define XHCI_IDLE_TIMEOUT_LONG_MS
Definition: hc.cpp:75
static const GUID XhciGuidD3ColdSupport
Definition: hc.cpp:18
@ PowerSystemWorking
Definition: ntpoapi.h:36
#define DPRINT
Definition: sndvol32.h:73
PVOID Context
Definition: miniport.h:123
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: miniport.h:125
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
enum _DEVICE_WAKE_DEPTH DEVICE_WAKE_DEPTH
#define D3COLD_SUPPORT_INTERFACE_VERSION
@ DeviceWakeDepthD0
Definition: iotypes.h:7496
@ DeviceWakeDepthNotWakeable
Definition: iotypes.h:7495

Referenced by Initialize().

◆ CreateWdfObjects()

NTSTATUS XhciController::CreateWdfObjects ( )
private

Definition at line 850 of file hc.cpp.

851{
852 WDF_TIMER_CONFIG TimerConfig;
853 WDF_WORKITEM_CONFIG WorkConfig;
856
859 TimerConfig.AutomaticSerialization = FALSE;
860
861 /* The UCXCONTROLLER is passive; every watchdog step is fine at DISPATCH */
863 Attributes.ParentObject = m_Ucx;
864 Attributes.ExecutionLevel = WdfExecutionLevelDispatch;
865
866 Status = WdfTimerCreate(&TimerConfig, &Attributes, &m_Watchdog);
867 if (!NT_SUCCESS(Status))
868 {
869 DPRINT1("Watchdog timer creation failed 0x%lx\n", Status);
870 return Status;
871 }
872 XhciGetObjectContext(m_Watchdog)->Controller = this;
873
875 WorkConfig.AutomaticSerialization = FALSE;
877 Attributes.ParentObject = m_Ucx;
878
879 Status = WdfWorkItemCreate(&WorkConfig, &Attributes, &m_IdleItem);
880 if (!NT_SUCCESS(Status))
881 {
882 DPRINT1("Idle timeout work item creation failed 0x%lx\n", Status);
883 return Status;
884 }
885 XhciGetObjectContext(m_IdleItem)->Controller = this;
886
888 WorkConfig.AutomaticSerialization = FALSE;
889
890 Status = WdfWorkItemCreate(&WorkConfig, &Attributes, &m_RecoveryItem);
891 if (!NT_SUCCESS(Status))
892 {
893 DPRINT1("Recovery work item creation failed 0x%lx\n", Status);
894 return Status;
895 }
896 XhciGetObjectContext(m_RecoveryItem)->Controller = this;
897
901 return STATUS_SUCCESS;
902}
KSPIN_LOCK m_RecoveryLock
Definition: hc.h:281
ULONG m_RecoveryActions
Definition: hc.h:282
WDFTIMER m_Watchdog
Definition: hc.h:276
WDFWORKITEM m_IdleItem
Definition: hc.h:278
KMUTEX m_RecoveryMutex
Definition: hc.h:283
WDFWORKITEM m_RecoveryItem
Definition: hc.h:277
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define FALSE
Definition: types.h:117
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
static EVT_WDF_WORKITEM XhciEvtRecoveryWork
Definition: hc.cpp:154
static EVT_WDF_WORKITEM XhciEvtIdleTimeoutWork
Definition: hc.cpp:155
#define XHCI_WATCHDOG_TOLERANCE_MS
Definition: hc.cpp:72
#define XHCI_WATCHDOG_PERIOD_MS
Definition: hc.cpp:71
static EVT_WDF_TIMER XhciEvtWatchdog
Definition: hc.cpp:153
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG TolerableDelay
Definition: wdftimer.h:95
BOOLEAN AutomaticSerialization
Definition: wdftimer.h:90
BOOLEAN AutomaticSerialization
Definition: wdfworkitem.h:79
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
@ WdfExecutionLevelDispatch
Definition: wdfobject.h:55
FORCEINLINE VOID WDF_TIMER_CONFIG_INIT_PERIODIC(_Out_ PWDF_TIMER_CONFIG Config, _In_ PFN_WDF_TIMER EvtTimerFunc, _In_ LONG Period)
Definition: wdftimer.h:126
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85

Referenced by Initialize().

◆ D0Entry()

NTSTATUS XhciController::D0Entry ( _In_ WDF_POWER_DEVICE_STATE  PreviousState)

Definition at line 1357 of file hc.cpp.

1359{
1362 BOOLEAN WasReset = FALSE;
1363 BOOLEAN AllOnes = FALSE;
1364 BOOLEAN Restore;
1366
1368 {
1369 DPRINT1("Controller registers read all ones at D0 entry\n");
1370 AllOnes = TRUE;
1372 goto Exit;
1373 }
1374
1375 if (FromHibernate)
1376 {
1377 /* Without a crash dump stack the firmware owned the controller during resume */
1379 if (!NT_SUCCESS(Status))
1380 {
1381 DPRINT1("BIOS handoff on hibernate resume failed 0x%lx\n", Status);
1382 goto Exit;
1383 }
1384
1386
1388 if (!NT_SUCCESS(Status))
1389 {
1390 DPRINT1("Reset on hibernate resume failed 0x%lx\n", Status);
1391 goto Exit;
1392 }
1393 WasReset = TRUE;
1394 }
1395
1398
1399 if (HasErrata(XhciErrata::AcpiDsmHsicSuspendDetach))
1400 EvaluateDsm(5);
1401
1402 Restore = !HasErrata(XhciErrata::PwrSkipSaveRestore) &&
1403 !m_SaveFailed &&
1405 !FromHibernate;
1406
1407 Status = RunD0Pass(Restore);
1408 if (!NT_SUCCESS(Status))
1409 goto Exit;
1410
1411 if (PreviousState != WdfPowerDeviceD3Final && !FromHibernate)
1412 {
1413 if (Restore)
1414 {
1416 if (!NT_SUCCESS(Status))
1417 {
1418 DPRINT1("Controller state restore failed 0x%lx\n", Status);
1420 VerifierCheck(XHCI_VERIFY_SAVE_RESTORE);
1421 }
1422 }
1423
1424 if (!Restore || !NT_SUCCESS(Status))
1425 {
1427
1429 if (!NT_SUCCESS(Status))
1430 {
1431 DPRINT1("Controller reset at D0 entry failed 0x%lx\n", Status);
1432 goto Exit;
1433 }
1434 WasReset = TRUE;
1435
1437 if (!NT_SUCCESS(Status))
1438 goto Exit;
1439 }
1440 }
1441
1445
1446 if (WasReset)
1447 {
1449 UcxControllerResetComplete(m_Ucx, &ResetInfo);
1450 }
1451
1453
1454Exit:
1455 if (NT_SUCCESS(Status))
1456 {
1458 {
1460
1463 }
1464
1465 return STATUS_SUCCESS;
1466 }
1467
1469 if (AllOnes)
1470 {
1471 SetGone(TRUE);
1472 }
1473 else
1474 {
1476 SetGone(FALSE);
1477 }
1478
1479 return Status;
1480}
unsigned char BOOLEAN
Definition: actypes.h:127
XhciSlotTable m_Slots
Definition: hc.h:93
WDF_POWER_DEVICE_STATE m_PowerState
Definition: hc.h:117
NTSTATUS RunD0Pass(_In_ BOOLEAN Restore)
Definition: hc.cpp:1329
ULONG m_RestoreFailures
Definition: hc.h:268
ULONG m_LastIdleTimeout
Definition: hc.h:274
BOOLEAN m_SaveFailed
Definition: hc.h:263
XhciRootHub m_RootHub
Definition: hc.h:96
BOOLEAN m_FrameSnapshotReady
Definition: hc.h:264
XhciRegisters m_Registers
Definition: hc.h:91
SystemAction m_SystemAction
Definition: hc.h:131
VOID InitFrameSnapshot()
Definition: hc.cpp:1805
ULONG ReadCapability32(_In_ ULONG Offset) const
Definition: mmio.cpp:421
NTSTATUS RestoreState()
Definition: mmio.cpp:984
NTSTATUS Reset()
Definition: mmio.cpp:800
VOID ApplyD0Workarounds()
Definition: mmio.cpp:1052
NTSTATUS BiosHandoff()
Definition: mmio.cpp:712
VOID D0Entry()
Definition: rootports.cpp:844
VOID DiscardState()
Definition: slots.cpp:183
VOID DisableAll()
Definition: slots.cpp:199
#define TRUE
Definition: types.h:120
#define XHCI_REASON_START_FAILED
Definition: hc.cpp:58
#define XHCI_VERIFY_SAVE_RESTORE
Definition: hc.cpp:69
#define XHCI_RECOVER_NONE
Definition: hc.cpp:40
static void Exit(void)
Definition: sock.c:1330
#define MAXULONG
Definition: typedefs.h:251
@ UcxControllerStateLost
Definition: ucxcontroller.h:24
FORCEINLINE VOID NTAPI UCX_CONTROLLER_RESET_COMPLETE_INFO_INIT(_Out_ PUCX_CONTROLLER_RESET_COMPLETE_INFO UcxControllerResetCompleteInfo, _In_ UCX_CONTROLLER_STATE UcxControllerState, _In_ BOOLEAN UcxCoordinated)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
@ WdfPowerDeviceD3Final
Definition: wdfdevice.h:427
@ WdfPowerDeviceD0
Definition: wdfdevice.h:423
#define XHCI_CAP_LENGTH_VERSION
Definition: xhcihw.h:335

Referenced by XhciEvtDeviceD0Entry().

◆ D0EntryPostInterruptsEnabled()

NTSTATUS XhciController::D0EntryPostInterruptsEnabled ( _In_ WDF_POWER_DEVICE_STATE  PreviousState)

Definition at line 1574 of file hc.cpp.

1576{
1578
1580 if (!NT_SUCCESS(Status))
1581 {
1582 DPRINT1("Controller start failed 0x%lx\n", Status);
1583 return Status;
1584 }
1585
1588
1591
1592 if (HasErrata(XhciErrata::HostRefuseToStart))
1593 {
1594 DPRINT1("Controller is marked as not supported\n");
1595 return STATUS_NOT_SUPPORTED;
1596 }
1597
1598 return STATUS_SUCCESS;
1599}
VOID PostInterruptsEntry()
Definition: cmdring.cpp:254
XhciCommandRing m_Commands
Definition: hc.h:95
VOID RunFirmwareCommands()
Definition: hc.cpp:1536
NTSTATUS StartController()
Definition: hc.cpp:1483
VOID PostInterruptsEntry()
Definition: rootports.cpp:867
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48

Referenced by XhciEvtDeviceD0EntryPostInterruptsEnabled().

◆ D0Exit()

VOID XhciController::D0Exit ( _In_ WDF_POWER_DEVICE_STATE  TargetState)

Definition at line 1613 of file hc.cpp.

1615{
1616 POWER_ACTION Action = WdfDeviceGetSystemPowerAction(m_Device);
1617 BOOLEAN Save;
1619
1621
1622 m_Buffers.D0Exit();
1623 m_RootHub.D0Exit();
1624
1625 WdfTimerStop(m_Watchdog, TRUE);
1627 if (!NT_SUCCESS(Status))
1628 DPRINT1("Controller stop at D0 exit failed 0x%lx\n", Status);
1629
1631
1632 Save = !HasErrata(XhciErrata::PwrSkipSaveRestore) &&
1633 !m_SaveFailed &&
1636 if (Save)
1637 {
1639 if (!NT_SUCCESS(Status))
1640 {
1641 /* QUIRK: one failure turns save and restore off for good */
1642 DPRINT("Controller state save failed 0x%lx\n", Status);
1644 VerifierCheck(XHCI_VERIFY_SAVE_RESTORE);
1645 }
1646
1649
1650 if (HasErrata(XhciErrata::AcpiDsmHsicSuspendDetach))
1651 EvaluateDsm(6);
1652 }
1653
1654 if (HasErrata(XhciErrata::PwrResetBeforeShutdown) && Action == PowerActionShutdownReset)
1655 {
1657 if (!NT_SUCCESS(Status))
1658 DPRINT("Reset before restart failed 0x%lx\n", Status);
1659 }
1660
1661 WdfWorkItemFlush(m_RecoveryItem);
1662 WdfWorkItemFlush(m_IdleItem);
1663}
XhciCommonBuffer m_Buffers
Definition: hc.h:92
XhciInterrupters m_Interrupters
Definition: hc.h:94
VOID D0Exit()
Definition: intr.cpp:1380
NTSTATUS Stop()
Definition: mmio.cpp:775
VOID SaveVendorBits()
Definition: mmio.cpp:1019
NTSTATUS ResetController(_In_ BOOLEAN AllowRunning)
Definition: mmio.cpp:806
VOID ProgramSsicPortUnused(_In_ BOOLEAN PowerDown)
Definition: mmio.cpp:1004
NTSTATUS SaveState()
Definition: mmio.cpp:968
VOID D0Exit()
Definition: rootports.cpp:877
POWER_ACTION
Definition: ntpoapi.h:122
@ PowerActionShutdownReset
Definition: ntpoapi.h:128
static int Save(const char **args)
Definition: vfdcmd.c:1851
_In_ WDF_POWER_DEVICE_STATE TargetState
Definition: wdfdevice.h:859
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510

Referenced by XhciEvtDeviceD0Exit().

◆ D0ExitPreInterruptsDisabled()

VOID XhciController::D0ExitPreInterruptsDisabled ( )

Definition at line 1604 of file hc.cpp.

1605{
1606 if (HasErrata(XhciErrata::AcpiNotifyBeforeIntOff))
1607 EvaluatePrmi();
1608
1610}
VOID EvaluatePrmi()
Definition: hc.cpp:723
VOID D0ExitPreInterruptsDisabled()
Definition: intr.cpp:1347

Referenced by XhciEvtDeviceD0ExitPreInterruptsDisabled().

◆ EvaluateDsm()

VOID XhciController::EvaluateDsm ( _In_ ULONG  Function)
private

Definition at line 686 of file hc.cpp.

688{
691 ULONG Size;
692 ULONG Index;
693
694 Size = sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX) + sizeof(GUID) - sizeof(ULONG) +
695 3 * sizeof(ACPI_METHOD_ARGUMENT);
696
698 if (Input == NULL)
699 {
700 DPRINT1("No memory for the _DSM(%lu) call\n", Function);
701 return;
702 }
703
705 Input->MethodNameAsUlong = 'MSD_';
706 Input->Size = Size;
707 Input->ArgumentCount = 4;
708
709 /* UUID, then the function value, then two reserved zeros */
710 Argument = &Input->Argument[0];
712 for (Index = 0; Index < 3; Index++)
713 {
716 }
717
720}
struct _ACPI_EVAL_INPUT_BUFFER_COMPLEX * PACPI_EVAL_INPUT_BUFFER_COMPLEX
#define ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
Definition: acpiioct.h:15
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:80
#define ACPI_METHOD_NEXT_ARGUMENT(Argument)
Definition: acpiioct.h:159
#define ACPI_METHOD_SET_ARGUMENT_INTEGER(MethodArgument, IntData)
Definition: acpiioct.h:164
#define ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, BuffData, BuffLength)
Definition: acpiioct.h:174
struct _ACPI_EVAL_INPUT_BUFFER_COMPLEX ACPI_EVAL_INPUT_BUFFER_COMPLEX
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG _In_ PVOID Argument
Definition: dispmprt.h:1288
#define NonPagedPool
Definition: env_spec_w32.h:307
static VOID NTAPI XhciEvaluateAcpiMethod(_In_ WDFDEVICE Device, _In_reads_bytes_(InputSize) PVOID Input, _In_ ULONG InputSize)
Definition: hc.cpp:663
static const GUID XhciGuidDsm
Definition: hc.cpp:36
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
_In_ ULONG _In_ WDFMEMORY Input
Definition: portacpi.cpp:109
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
#define XHCI_TAG_CONTROLLER
Definition: xhciutil.h:12

Referenced by ConfigureS0Idle(), D0Entry(), and D0Exit().

◆ EvaluatePrmi()

VOID XhciController::EvaluatePrmi ( )
private

Definition at line 723 of file hc.cpp.

724{
726
727 RtlZeroMemory(&Input, sizeof(Input));
729 Input.MethodNameAsUlong = 'IMRP';
730
732}
#define ACPI_EVAL_INPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:12

Referenced by D0ExitPreInterruptsDisabled().

◆ FdoCleanup()

VOID XhciController::FdoCleanup ( )

Definition at line 1229 of file hc.cpp.

1230{
1232
1233 if (Bus->InterfaceDereference != NULL)
1234 Bus->InterfaceDereference(Bus->Context);
1235
1236 RtlZeroMemory(Bus, sizeof(*Bus));
1237}
XhciIdentity m_Identity
Definition: hc.h:100
BUS_INTERFACE_STANDARD PciInterface
Definition: hc.h:43
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: iotypes.h:912

Referenced by XhciEvtFdoCleanup().

◆ FromDevice()

◆ FromUcx()

XhciController * XhciController::FromUcx ( _In_ UCXCONTROLLER  UcxController)
static

◆ HasErrata()

BOOLEAN XhciController::HasErrata ( _In_ XhciErrata  Bit) const
inline

Definition at line 58 of file hc.h.

60 {
61 ULONG Position = static_cast<ULONG>(Bit);
62
63 if (Position >= 64)
64 return (m_ErrataWord2 & (1ULL << (Position - 64))) != 0;
65
66 return (m_Errata & XhciErrataBit(Bit)) != 0;
67 }
ULONG64 m_Errata
Definition: hc.h:88
ULONG64 m_ErrataWord2
Definition: hc.h:89
static COORD Position
Definition: mouse.c:34
FORCEINLINE ULONG64 NTAPI XhciErrataBit(_In_ XhciErrata Bit)
Definition: xhcierrata.h:90

Referenced by XhciRootHub::AcknowledgeResume(), XhciRegisters::ApplyD0Workarounds(), XhciUsbDevice::ApplyUpdate(), XhciRegisters::BiosHandoff(), XhciEndpoint::BuildContext(), XhciTransferRing::BuildLinkTrb(), XhciUsbDevice::BuildSlotContext(), XhciRootHub::ClearUsb20PortFeature(), ConfigureS0Idle(), XhciRegisters::ContiguousFrameId(), XhciRootHub::D0Entry(), D0Entry(), D0EntryPostInterruptsEnabled(), XhciRootHub::D0Exit(), D0Exit(), D0ExitPreInterruptsDisabled(), XhciEndpointMachine::DelaysFirstStop(), XhciEndpoint::DequeueAfterStop(), XhciInterrupters::FilterResourceRequirements(), Initialize(), XhciEndpoint::Initialize(), XhciRootHub::IsHiddenDebugPort(), XhciEndpointMachine::NeedsContextRebuildAfterStop(), XhciEndpointMachine::OnPrimaryInterrupterOnly(), XhciEndpoint::OnTransferEvent(), XhciRegisters::ParseCapabilities(), XhciCommandRing::PlaceLocked(), XhciInterrupters::Prepare(), XhciRegisters::ProgramSsicPortUnused(), XhciRootHub::QueryTunnelState(), QueryUsbCapability(), XhciRegisters::Read64(), XhciUsbDevice::Reset(), XhciEndpoint::ResetStreamTransferLength(), XhciRegisters::RestoreVendorBits(), XhciRootHub::ResuspendResumedPorts(), XhciTransferRing::ReturnSegments(), XhciRegisters::SaveVendorBits(), XhciInterrupters::SecondaryCountFor(), SelfManagedIoInit(), SetPortWake(), XhciRootHub::SetUsb20PortFeature(), XhciRootHub::SetUsb30LinkState(), XhciRootHub::SetWakeEnables(), XhciEndpoint::StreamTransferLength(), XhciUsbDevice::WantsTunnelStateDsm(), and XhciRegisters::Write64().

◆ IdleTimeoutWorker()

VOID XhciController::IdleTimeoutWorker ( )

Definition at line 822 of file hc.cpp.

823{
825}
#define XHCI_IDLE_TIMEOUT_SHORT_MS
Definition: hc.cpp:76

◆ InitFrameSnapshot()

VOID XhciController::InitFrameSnapshot ( )
private

Definition at line 1805 of file hc.cpp.

1806{
1809}
LONG64 m_FrameSnapshot
Definition: hc.h:265
ULONG64 NowMs() const
Definition: hc.cpp:1783
ULONG CurrentFrame(_In_ ULONG Increment) const
Definition: mmio.cpp:679
static LONG64 NTAPI XhciPackFrameSnapshot(_In_ ULONG Frame, _In_ ULONG64 Now)
Definition: hc.cpp:1795
#define InterlockedExchange64
Definition: interlocked.h:186

Referenced by D0Entry().

◆ Initialize()

NTSTATUS XhciController::Initialize ( _In_ WDFDEVICE  Device,
_In_ UCXCONTROLLER  Ucx,
_In_ const XhciIdentity *  Identity 
)

Definition at line 905 of file hc.cpp.

909{
910 WDF_IO_QUEUE_CONFIG QueueConfig;
913
915 m_WdmDevice = WdfDeviceWdmGetDeviceObject(Device);
916 m_Ucx = Ucx;
923
925 {
929 m_Identity.PciBus = 0;
932 }
933 else
934 {
938 }
939
941 if (!NT_SUCCESS(Status))
942 return Status;
943
945 if (HasErrata(XhciErrata::HostRefuseToStart))
946 {
947 DPRINT1("Controller is marked as not supported\n");
949 }
950
953 Status = WdfIoQueueCreate(m_Device, &QueueConfig, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE);
954 if (!NT_SUCCESS(Status))
955 {
956 DPRINT1("Default queue creation failed 0x%lx\n", Status);
957 return Status;
958 }
959
960 Status = m_Buffers.Create(this);
961 if (!NT_SUCCESS(Status))
962 {
963 DPRINT1("Common buffer creation failed 0x%lx\n", Status);
964 return Status;
965 }
966
968 if (!NT_SUCCESS(Status))
969 {
970 DPRINT1("Interrupter creation failed 0x%lx\n", Status);
971 return Status;
972 }
973
974 Status = m_Slots.Create(this);
975 if (!NT_SUCCESS(Status))
976 {
977 DPRINT1("Device slot table creation failed 0x%lx\n", Status);
978 return Status;
979 }
980
981 Status = m_Commands.Create(this);
982 if (!NT_SUCCESS(Status))
983 {
984 DPRINT1("Command ring creation failed 0x%lx\n", Status);
985 return Status;
986 }
987
988 if (HasErrata(XhciErrata::IntelPchBandwidthCap))
989 DPRINT1("Panther Point command filter not implemented, endpoint limit not enforced\n");
990
991 Status = m_RootHub.Create(this);
992 if (!NT_SUCCESS(Status))
993 {
994 DPRINT1("Root hub creation failed 0x%lx\n", Status);
995 return Status;
996 }
997
998 DPRINT("Controller capability WMI block not provided\n");
999
1001
1003 WakeSettings.Enabled = WdfFalse;
1005 WakeSettings.IndicateChildWakeOnParentWake = TRUE;
1007 Status = WdfDeviceAssignSxWakeSettings(m_Device, &WakeSettings);
1008 if (!NT_SUCCESS(Status))
1009 DPRINT1("Sx wake settings refused 0x%lx\n", Status);
1010
1011 return STATUS_SUCCESS;
1012}
NTSTATUS Create(_In_ XhciController *Controller)
Definition: cmdring.cpp:95
NTSTATUS Create(_In_ XhciController *Controller)
PDEVICE_OBJECT m_WdmDevice
Definition: hc.h:86
BOOLEAN m_TestMode
Definition: hc.h:204
VOID PopulateErrata()
Definition: hc.cpp:580
VOID ConfigureS0Idle()
Definition: hc.cpp:761
NTSTATUS CreateWdfObjects()
Definition: hc.cpp:850
ULONG m_TimeIncrement
Definition: hc.h:266
NTSTATUS Create(_In_ XhciController *Controller)
Definition: intr.cpp:831
NTSTATUS Create(_In_ XhciController *Controller)
Definition: rootports.cpp:186
NTSTATUS Create(_In_ XhciController *Controller)
Definition: slots.cpp:17
static GLfloat Identity[16]
Definition: matrix.c:127
static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL XhciEvtIoDeviceControl
Definition: hc.cpp:152
#define XHCI_ACPI_PARENT_ID
Definition: hc.cpp:78
XhciDriverData XhciDriver
Definition: xhcientry.cpp:23
ULONG NTAPI KeQueryTimeIncrement(VOID)
Definition: clock.c:151
BOOLEAN TestMode
Definition: hc.h:293
UCHAR PciRevisionId
Definition: hc.h:29
ULONG PciDeviceId
Definition: hc.h:28
CHAR AcpiRevisionId[MAX_REVISION_ID_STRING_LENGTH]
Definition: hc.h:37
ULONG PciFunction
Definition: hc.h:34
CHAR AcpiDeviceId[MAX_DEVICE_ID_STRING_LENGTH]
Definition: hc.h:36
ULONG PciVendorId
Definition: hc.h:27
CHAR AcpiVendorId[MAX_VENDOR_ID_STRING_LENGTH]
Definition: hc.h:35
ULONG PciDevice
Definition: hc.h:33
UCX_CONTROLLER_PARENT_BUS_TYPE ParentBus
Definition: hc.h:26
ULONG PciBus
Definition: hc.h:32
WDF_POWER_POLICY_SX_WAKE_USER_CONTROL UserControlOfWakeSettings
Definition: wdfdevice.h:1401
PFN_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl
Definition: wdfio.h:405
@ UcxControllerParentBusTypeAcpi
Definition: ucxcontroller.h:18
@ WakeDoNotAllowUserControl
Definition: wdfdevice.h:417
FORCEINLINE VOID WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(_Out_ PWDF_DEVICE_POWER_POLICY_WAKE_SETTINGS Settings)
Definition: wdfdevice.h:1437
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:443
@ WdfIoQueueDispatchSequential
Definition: wdfio.h:78
@ WdfFalse
Definition: wdftypes.h:87
#define WDF_NO_HANDLE
Definition: wdftypes.h:107
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105

◆ InternalReset()

VOID XhciController::InternalReset ( )
private

Definition at line 2113 of file hc.cpp.

2114{
2115 NTSTATUS StopStatus;
2116 NTSTATUS ResetStatus = STATUS_SUCCESS;
2118
2119 /* QUIRK: overlap is only reported */
2121 DPRINT1("Controller %p internal reset entered twice\n", this);
2122
2125
2126 WdfTimerStop(m_Watchdog, TRUE);
2128 m_Slots.PreReset();
2129
2130 KeFlushQueuedDpcs();
2131 StopStatus = m_Registers.Stop();
2132 KeFlushQueuedDpcs();
2133
2134 if (!NT_SUCCESS(StopStatus))
2135 {
2136 DPRINT1("Stop before internal reset failed 0x%lx\n", StopStatus);
2137 DisableController();
2138 }
2139 else
2140 {
2141 ResetStatus = m_Registers.ResetController(TRUE);
2142 }
2143
2146 m_Slots.PostReset();
2148
2149 if (!NT_SUCCESS(StopStatus))
2150 {
2151 VerifierCheck(XHCI_VERIFY_STOP_TIMEOUT);
2153 Status = StopStatus;
2154 }
2155 else
2156 {
2158
2159 if (!NT_SUCCESS(ResetStatus))
2160 {
2161 DPRINT1("Internal reset failed 0x%lx\n", ResetStatus);
2162 VerifierCheck(XHCI_VERIFY_RESET_TIMEOUT);
2164 Status = ResetStatus;
2165 }
2166 else
2167 {
2169 if (!NT_SUCCESS(Status))
2170 {
2171 DPRINT1("Start after internal reset failed 0x%lx\n", Status);
2172 VerifierCheck(XHCI_VERIFY_START_TIMEOUT);
2174 }
2175 }
2176 }
2177
2178 if (NT_SUCCESS(Status))
2179 {
2181 }
2182 else
2183 {
2184 DPRINT1("Controller %p internal reset ended with 0x%lx\n", this, Status);
2186 UcxControllerSetFailed(m_Ucx);
2187 }
2188
2190}
VOID PreReset()
Definition: cmdring.cpp:732
VOID PostResetSuccess()
Definition: cmdring.cpp:762
VOID FailAll()
Definition: cmdring.cpp:807
VOID PostReset()
Definition: cmdring.cpp:743
LONG m_ResetLock
Definition: hc.h:272
ULONG m_RecoveryCount
Definition: hc.h:269
LONG m_ResetCount
Definition: hc.h:270
VOID PostReset()
Definition: intr.cpp:1386
VOID PostReset()
Definition: rootports.cpp:914
#define XHCI_REASON_RESTART_FAILED
Definition: hc.cpp:53
#define XHCI_REASON_RESET_FAILED
Definition: hc.cpp:52
#define XHCI_REASON_STOP_FAILED
Definition: hc.cpp:54
#define XHCI_VERIFY_START_TIMEOUT
Definition: hc.cpp:67
#define XHCI_VERIFY_STOP_TIMEOUT
Definition: hc.cpp:65
#define XHCI_VERIFY_RESET_TIMEOUT
Definition: hc.cpp:66

Referenced by BootRecovery(), RunRecovery(), and UcxReset().

◆ IsAccessible()

◆ MarkGone()

VOID XhciController::MarkGone ( )

Definition at line 1924 of file hc.cpp.

1925{
1926 SetGone(TRUE);
1927}

Referenced by XhciRootHub::CheckRunning(), XhciRootHub::GetPortStatus(), XhciRootHub::InterruptTransfer(), and XhciCommandRing::OnTimer().

◆ NowMs()

ULONG64 XhciController::NowMs ( ) const
private

Definition at line 1783 of file hc.cpp.

1784{
1786
1788 return (ULONG64)Ticks.QuadPart * m_TimeIncrement / 10000;
1789}
LARGE_INTEGER Ticks
Definition: driver.cpp:132
unsigned __int64 ULONG64
Definition: imports.h:198
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by InitFrameSnapshot().

◆ PopulateErrata()

VOID XhciController::PopulateErrata ( )
private

Definition at line 580 of file hc.cpp.

581{
582 m_Errata = XhciErrataBit(XhciErrata::BootTolerateBiosHold);
583 m_ErrataWord2 = 0;
587
588 DPRINT1("Controller %04lx:%04lx rev %02x errata 0x%I64x 0x%I64x internal 0x%I64x\n",
591}
VOID QueryErrataDatabase(_In_ BOOLEAN AtAddDevice)
Definition: hc.cpp:432
ULONG64 m_InternalFlags
Definition: hc.h:111
VOID SetInternalFlags()
Definition: hc.cpp:562
VOID ReadRegistryErrata()
Definition: hc.cpp:522

Referenced by Initialize().

◆ PrepareHardware()

NTSTATUS XhciController::PrepareHardware ( _In_ WDFCMRESLIST  Raw,
_In_ WDFCMRESLIST  Translated 
)

Definition at line 1254 of file hc.cpp.

1257{
1259
1260 Status = m_Registers.Prepare(this, Translated);
1261 if (!NT_SUCCESS(Status))
1262 {
1263 DPRINT1("Register prepare failed 0x%lx\n", Status);
1264 goto Fail;
1265 }
1266
1268 if (!NT_SUCCESS(Status))
1269 {
1270 DPRINT1("Common buffer prepare failed 0x%lx\n", Status);
1271 goto Fail;
1272 }
1273
1274 Status = m_Interrupters.Prepare(Raw, Translated);
1275 if (!NT_SUCCESS(Status))
1276 {
1277 DPRINT1("Interrupter prepare failed 0x%lx\n", Status);
1278 goto Fail;
1279 }
1280
1282 if (!NT_SUCCESS(Status))
1283 {
1284 DPRINT1("Device slot prepare failed 0x%lx\n", Status);
1285 goto Fail;
1286 }
1287
1289 if (!NT_SUCCESS(Status))
1290 {
1291 DPRINT1("Command ring prepare failed 0x%lx\n", Status);
1292 goto Fail;
1293 }
1294
1296 if (!NT_SUCCESS(Status))
1297 {
1298 DPRINT1("Root hub prepare failed 0x%lx\n", Status);
1299 goto Fail;
1300 }
1301
1302 return STATUS_SUCCESS;
1303
1304Fail:
1305 /* Keeps PnP from restarting a controller that cannot start */
1306 DPRINT1("Controller %p failed to prepare hardware 0x%lx\n", this, Status);
1308 return Status;
1309}
NTSTATUS Prepare()
Definition: cmdring.cpp:144
NTSTATUS Prepare()
NTSTATUS Prepare(_In_ WDFCMRESLIST Raw, _In_ WDFCMRESLIST Translated)
Definition: intr.cpp:1104
NTSTATUS Prepare(_In_ XhciController *Controller, _In_ WDFCMRESLIST Translated)
Definition: mmio.cpp:92
NTSTATUS Prepare()
Definition: rootports.cpp:314
NTSTATUS Prepare()
int Fail
Definition: ehthrow.cxx:24
#define XHCI_RECOVER_REPORT_FAILED
Definition: hc.cpp:46
@ Raw
Definition: sacdrv.h:279

Referenced by XhciEvtDevicePrepareHardware().

◆ QueryErrataDatabase()

VOID XhciController::QueryErrataDatabase ( _In_ BOOLEAN  AtAddDevice)
private

Definition at line 432 of file hc.cpp.

434{
435 static const PCWSTR Providers[] = { L"USBXHCI", L"USBXHCI2" };
437 PULONG64 Words[] = { &m_Errata, &m_ErrataWord2 };
438 WCHAR Keys[7][96];
439 ULONG KeyCount;
441 BOOLEAN Any = FALSE;
444 ULONG Index;
445
446 if (Query == NULL)
447 return;
448
449 /* Keys go from the broadest match to the most specific one */
450 RtlStringCchCopyW(Keys[0], RTL_NUMBER_OF(Keys[0]), L"USBXHCI:ALL");
451 if (Pci)
452 {
453 RtlStringCchPrintfW(Keys[1], RTL_NUMBER_OF(Keys[1]), L"USBXHCI:PCI\\VEN_%04X",
455 RtlStringCchPrintfW(Keys[2], RTL_NUMBER_OF(Keys[2]), L"%s&DEV_%04X",
456 Keys[1], m_Identity.PciDeviceId);
457 RtlStringCchPrintfW(Keys[3], RTL_NUMBER_OF(Keys[3]), L"%s&REV_%02X",
458 Keys[2], m_Identity.PciRevisionId);
459 }
460 else
461 {
462 RtlStringCchPrintfW(Keys[1], RTL_NUMBER_OF(Keys[1]), L"USBXHCI:ACPI\\VEN_%S",
464 RtlStringCchPrintfW(Keys[2], RTL_NUMBER_OF(Keys[2]), L"%s&DEV_%S",
465 Keys[1], m_Identity.AcpiDeviceId);
466 RtlStringCchPrintfW(Keys[3], RTL_NUMBER_OF(Keys[3]), L"%s&REV_%S",
467 Keys[2], m_Identity.AcpiRevisionId);
468 }
469 KeyCount = 4;
470
472 {
473 RtlStringCchPrintfW(Keys[KeyCount], RTL_NUMBER_OF(Keys[KeyCount]), L"%s&%I64X",
474 Keys[3], m_Identity.FirmwareVersion);
475 KeyCount++;
476 }
477
478 if (Pci)
479 {
480 RtlStringCchPrintfW(Keys[KeyCount], RTL_NUMBER_OF(Keys[KeyCount]), L"%s&SUBSYS_%04X%04X",
482 RtlStringCchPrintfW(Keys[KeyCount + 1], RTL_NUMBER_OF(Keys[KeyCount + 1]), L"%s&REV_%02X",
483 Keys[KeyCount], m_Identity.PciRevisionId);
484 KeyCount += 2;
485 }
486
487 for (Provider = 0; Provider < RTL_NUMBER_OF(Providers); Provider++)
488 {
489 for (Index = 0; Index < KeyCount; Index++)
490 {
491 Flags = 0;
492 if (!NT_SUCCESS(Query(Keys[Index], Providers[Provider], &Flags)))
493 continue;
494
495 DPRINT("Errata word %lu 0x%I64x from %S\n", Provider + 1, Flags, Keys[Index]);
496 *Words[Provider] |= Flags;
497
498 /* The catch all key does not identify this controller */
499 if (Index != 0)
500 Any = TRUE;
501 }
502 }
503
504 if (!Any)
505 DPRINT("No errata database entry for this controller\n");
506
507 if (HasErrata(XhciErrata::HostRefuseToStart))
508 {
509 /* Skip recovery at AddDevice; that device is about to be deleted */
510 if (!AtAddDevice)
512 }
513 else if (HasErrata(XhciErrata::HostStaleFirmware))
514 {
515 DPRINT1("Controller firmware 0x%I64x is outdated\n", m_Identity.FirmwareVersion);
516 VerifierCheck(XHCI_VERIFY_FIRMWARE_OUTDATED);
518 }
519}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define L(x)
Definition: resources.c:13
NTSTATUS(NTAPI * PFN_XHCI_QUERY_DEVICE_FLAGS)(_In_ PCWSTR DeviceKey, _In_ PCWSTR Category, _Out_ PULONG64 Flags)
Definition: hc.cpp:111
#define XHCI_REASON_OLD_FIRMWARE
Definition: hc.cpp:57
#define XHCI_REASON_NOT_SUPPORTED
Definition: hc.cpp:55
#define XHCI_VERIFY_FIRMWARE_OUTDATED
Definition: hc.cpp:62
#define XHCI_FIRMWARE_UNKNOWN
Definition: hc.h:21
_In_ const GUID _In_ ULONG _In_opt_ PFN_WDF_WMI_INSTANCE_QUERY_INSTANCE Query
Definition: hubwmi.cpp:114
unsigned __int64 * PULONG64
Definition: imports.h:198
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
short WCHAR
Definition: pedump.c:58
PVOID QueryDeviceFlags
Definition: hc.h:292
ULONG64 FirmwareVersion
Definition: hc.h:40
USHORT PciSubsystemId
Definition: hc.h:31
USHORT PciSubsystemVendorId
Definition: hc.h:30
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by PopulateErrata(), and SelfManagedIoInit().

◆ QueryUsbCapability()

NTSTATUS XhciController::QueryUsbCapability ( _In_ const GUID *  Capability,
_In_ ULONG  OutputBufferLength,
_Out_writes_bytes_opt_(OutputBufferLength) PVOID  OutputBuffer,
_Out_ PULONG  ResultLength 
)

Definition at line 2210 of file hc.cpp.

2215{
2216 ULONG Hcc2;
2217
2218 *ResultLength = 0;
2219
2220 if (IsEqualGUID(*Capability, XhciGuidChainedMdls))
2221 return HasErrata(XhciErrata::XferFlattenMdlChain) ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS;
2222
2223 if (IsEqualGUID(*Capability, XhciGuidStaticStreams))
2224 {
2225 *ResultLength = sizeof(USHORT);
2226 if (OutputBufferLength < sizeof(USHORT))
2227 {
2228 DPRINT1("Stream capability buffer of %lu bytes too small\n", OutputBufferLength);
2230 }
2231 if (OutputBuffer == NULL)
2232 {
2233 DPRINT1("Stream capability buffer missing\n");
2235 }
2236
2238 return STATUS_SUCCESS;
2239 }
2240
2241 if (IsEqualGUID(*Capability, XhciGuidFunctionSuspend) ||
2243 {
2244 return STATUS_SUCCESS;
2245 }
2246
2248 return HasErrata(XhciErrata::XferFlushTtOnAbort) ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
2249
2250 if (IsEqualGUID(*Capability, XhciGuidHighBandwidthIsoch))
2251 {
2252 *ResultLength = sizeof(ULONG);
2253 if (OutputBufferLength < sizeof(ULONG))
2254 {
2255 DPRINT1("Isoch capability buffer of %lu bytes too small\n", OutputBufferLength);
2257 }
2258 if (OutputBuffer == NULL)
2259 {
2260 DPRINT1("Isoch capability buffer missing\n");
2262 }
2263
2264 Hcc2 = m_Registers.Hccparams2();
2265 if (!(Hcc2 & XHCI_HCC2_LEC))
2266 return STATUS_NOT_SUPPORTED;
2267
2268 *(PULONG)OutputBuffer = (Hcc2 & XHCI_HCC2_ETC) ? 32 : 4;
2269 return STATUS_SUCCESS;
2270 }
2271
2273}
ULONG SupportedStreams() const
Definition: mmio.cpp:585
ULONG Hccparams2() const
Definition: mmio.cpp:603
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static const GUID XhciGuidStaticStreams
Definition: hc.cpp:26
static const GUID XhciGuidSelectiveSuspend
Definition: hc.cpp:28
static const GUID XhciGuidHighBandwidthIsoch
Definition: hc.cpp:32
static const GUID XhciGuidChainedMdls
Definition: hc.cpp:24
static const GUID XhciGuidClearTtBufferOnCancel
Definition: hc.cpp:34
static const GUID XhciGuidFunctionSuspend
Definition: hc.cpp:30
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
_In_ PGUID _In_ ULONG _Out_ PULONG ResultLength
Definition: ucxcontroller.h:83
_In_ PGUID _In_ ULONG OutputBufferLength
Definition: ucxcontroller.h:81
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
#define XHCI_HCC2_ETC
Definition: xhcihw.h:378
#define XHCI_HCC2_LEC
Definition: xhcihw.h:377

Referenced by XhciEvtControllerQueryUsbCapability().

◆ ReadRegistryErrata()

VOID XhciController::ReadRegistryErrata ( )
private

Definition at line 522 of file hc.cpp.

523{
524 DECLARE_CONST_UNICODE_STRING(ValueName, L"UseStrictBiosHandoff");
525 WDFKEY Keys[2] = { NULL, NULL };
526 ULONG Value;
527 ULONG Index;
529
530 Status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &Keys[0]);
531 if (!NT_SUCCESS(Status))
532 {
533 DPRINT1("Driver parameters key open failed 0x%lx\n", Status);
534 Keys[0] = NULL;
535 }
536
538 if (!NT_SUCCESS(Status))
539 {
540 DPRINT1("Device hardware key open failed 0x%lx\n", Status);
541 Keys[1] = NULL;
542 }
543
544 for (Index = 0; Index < RTL_NUMBER_OF(Keys); Index++)
545 {
546 if (Keys[Index] == NULL)
547 continue;
548
549 if (NT_SUCCESS(WdfRegistryQueryULong(Keys[Index], &ValueName, &Value)))
550 {
551 if (Value == 0)
552 m_Errata &= ~XhciErrataBit(XhciErrata::BootStrictBiosRelease);
553 else if (Value == 1)
554 m_Errata |= XhciErrataBit(XhciErrata::BootStrictBiosRelease);
555 }
556
557 WdfRegistryClose(Keys[Index]);
558 }
559}
WdfRegistryClose(HardwareKey)
return WdfDeviceOpenRegistryKey(Child->m_Pdo->m_Device, PLUGPLAY_REGKEY_DEVICE, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
#define KEY_READ
Definition: nt_native.h:1026
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
FORCEINLINE WDFDRIVER WdfGetDriver(VOID)
Definition: wdfdriver.h:194
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2812

Referenced by PopulateErrata().

◆ ReadVerifierFlags()

VOID XhciController::ReadVerifierFlags ( )
private

Definition at line 596 of file hc.cpp.

597{
598 WCHAR Ids[3][24];
599 WCHAR Path[160];
600 UNICODE_STRING PathString;
602 PCWSTR Version = (m_Registers.VersionMajor() == 0) ? L"xHCI96" : L"xHCI10";
603 ULONG64 Flags = 0;
605 ULONG Type;
606 WDFKEY Key;
607 ULONG Index;
609
611 {
616 }
617 else
618 {
623 }
624 RtlStringCchCopyW(Ids[2], RTL_NUMBER_OF(Ids[2]), L"global");
625
627 {
629 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\usb\\HardwareVerifier\\%s\\%s",
630 Ids[Index], Version);
631 RtlInitUnicodeString(&PathString, Path);
632
634 if (!NT_SUCCESS(Status))
635 continue;
636
639 }
640
641 if (!NT_SUCCESS(Status))
642 {
644 DPRINT1("Hardware verifier settings read failed 0x%lx\n", Status);
645 Flags = 0;
646 }
647
649}
Type
Definition: Type.h:7
ULONG m_VerifierFlags
Definition: hc.h:261
UCHAR VersionMajor() const
Definition: mmio.cpp:615
return WdfRegistryQueryValue(Key, &ValueName, sizeof(*Value), Value, NULL, NULL)
return WdfRegistryOpenKey(NULL, &KeyName, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
_In_ const HubIdStrings * Ids
UNICODE_STRING Path
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469

Referenced by SelfManagedIoInit().

◆ RecoveryWorker()

VOID XhciController::RecoveryWorker ( )

Definition at line 2095 of file hc.cpp.

2096{
2097 ULONG Actions;
2098 KIRQL Irql;
2099
2101
2103 Actions = m_RecoveryActions;
2106
2107 RunRecovery(Actions);
2108
2110}
VOID RunRecovery(_In_ ULONG Actions)
Definition: hc.cpp:2024
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KernelMode
Definition: asm.h:38
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
@ Executive
Definition: ketypes.h:467

◆ ReleaseHardware()

VOID XhciController::ReleaseHardware ( )

Definition at line 1312 of file hc.cpp.

1313{
1314 /* D0 exit did not run when D0 entry failed */
1315 WdfWorkItemFlush(m_RecoveryItem);
1316 WdfWorkItemFlush(m_IdleItem);
1317
1320 m_Slots.Release();
1324}
VOID Release()
Definition: cmdring.cpp:174
VOID Release()
Definition: intr.cpp:1296
VOID Release()
Definition: mmio.cpp:126
VOID Release()
Definition: rootports.cpp:404

Referenced by XhciEvtDeviceReleaseHardware().

◆ RunD0Pass()

NTSTATUS XhciController::RunD0Pass ( _In_ BOOLEAN  Restore)
private

Definition at line 1329 of file hc.cpp.

1331{
1333
1334 if (Restore)
1335 {
1338 }
1339
1340 Status = m_Interrupters.D0Entry(Restore);
1341 if (!NT_SUCCESS(Status))
1342 {
1343 DPRINT1("Interrupter D0 entry failed 0x%lx\n", Status);
1344 return Status;
1345 }
1346
1347 m_Slots.D0Entry();
1348
1350 if (!NT_SUCCESS(Status))
1351 DPRINT1("Command ring D0 entry failed 0x%lx\n", Status);
1352
1353 return Status;
1354}
NTSTATUS D0Entry()
Definition: cmdring.cpp:247
NTSTATUS D0Entry(_In_ BOOLEAN StatePreserved)
Definition: intr.cpp:1326
VOID RestoreVendorBits()
Definition: mmio.cpp:1035
VOID D0Entry()
Definition: slots.cpp:161

Referenced by D0Entry().

◆ RunFirmwareCommands()

VOID XhciController::RunFirmwareCommands ( )
private

Definition at line 1536 of file hc.cpp.

1537{
1539 BOOLEAN Renesas = Pci && (m_Identity.PciVendorId == 0x1033 || m_Identity.PciVendorId == 0x1912);
1540 BOOLEAN Asmedia = Pci && m_Identity.PciVendorId == 0x1B21;
1541 BOOLEAN Nvidia;
1544
1545 Nvidia = !Pci && _strnicmp(m_Identity.AcpiVendorId, "NVDA", 4) == 0;
1546 if (!Renesas && !Asmedia && !Nvidia)
1547 return;
1548
1550
1551 if (Asmedia)
1552 {
1553 if (!XhciSendFirmwareCommand(this, static_cast<ULONG>(XhciTrbType::VendorFirmwareVersionAltSetup), &Parameter))
1554 return;
1555
1557 if (!XhciSendFirmwareCommand(this, static_cast<ULONG>(XhciTrbType::VendorFirmwareVersionAlt), &Parameter))
1558 return;
1559
1561 }
1562 else
1563 {
1564 if (!XhciSendFirmwareCommand(this, static_cast<ULONG>(XhciTrbType::VendorFirmwareVersion), &Parameter))
1565 return;
1566
1568 }
1569
1570 DPRINT1("Controller firmware version 0x%I64x\n", m_Identity.FirmwareVersion);
1571}
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
static BOOLEAN NTAPI XhciSendFirmwareCommand(_In_ XhciController *Controller, _In_ ULONG Type, _Out_ PULONG Parameter)
Definition: hc.cpp:1508
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by D0EntryPostInterruptsEnabled().

◆ RunRecovery()

VOID XhciController::RunRecovery ( _In_ ULONG  Actions)
private

Definition at line 2024 of file hc.cpp.

2026{
2028
2030 {
2031 DPRINT1("Controller reset %ld times in 5 minutes, giving up\n", m_ResetCount);
2032 Actions |= XHCI_RECOVER_NO_RESTART;
2033 }
2034
2035 while (Actions != 0)
2036 {
2037 if (Actions & (XHCI_RECOVER_GONE | XHCI_RECOVER_GONE_PNP))
2038 {
2039 if (!m_GoneHandled)
2040 {
2043 KeFlushQueuedDpcs();
2047 KeFlushQueuedDpcs();
2048 UcxControllerSetFailed(m_Ucx);
2049
2050 if (Actions & XHCI_RECOVER_GONE)
2051 WdfDeviceSetFailed(m_Device, WdfDeviceFailedNoRestart);
2052 }
2053
2054 if ((Actions & XHCI_RECOVER_GONE_PNP) && !m_PnpToldRemoved)
2055 {
2057 State.Removed = WdfTrue;
2058 WdfDeviceSetDeviceState(m_Device, &State);
2060 }
2061
2064 }
2065 else if (Actions & XHCI_RECOVER_NO_RESTART)
2066 {
2067 DisableController();
2068 WdfDeviceSetFailed(m_Device, WdfDeviceFailedNoRestart);
2070 }
2071 else if (Actions & XHCI_RECOVER_INTERNAL_RESET)
2072 {
2073 InternalReset();
2074 Actions &= ~XHCI_RECOVER_INTERNAL_RESET;
2075 }
2076 else if (Actions & XHCI_RECOVER_RESET)
2077 {
2078 UcxControllerNeedsReset(m_Ucx);
2079 Actions &= ~XHCI_RECOVER_RESET;
2080 }
2081 else if (Actions & XHCI_RECOVER_REPORT_FAILED)
2082 {
2083 WdfDeviceSetFailed(m_Device, WdfDeviceFailedNoRestart);
2084 Actions &= ~XHCI_RECOVER_REPORT_FAILED;
2085 }
2086 else
2087 {
2088 DPRINT1("Recovery actions 0x%lx not understood\n", Actions);
2089 break;
2090 }
2091 }
2092}
VOID OnHostLost()
Definition: cmdring.cpp:813
BOOLEAN m_PnpToldRemoved
Definition: hc.h:285
BOOLEAN m_GoneHandled
Definition: hc.h:284
VOID OnHostLost()
Definition: rootports.cpp:921
VOID OnHostLost()
Definition: slots.cpp:247
#define XHCI_RESET_LIMIT
Definition: hc.cpp:73
FORCEINLINE VOID WDF_DEVICE_STATE_INIT(_Out_ PWDF_DEVICE_STATE PnpDeviceState)
Definition: wdfdevice.h:1496
@ WdfDeviceFailedNoRestart
Definition: wdfdevice.h:470
@ WdfTrue
Definition: wdftypes.h:88

Referenced by RecoveryWorker().

◆ SelfManagedIoCleanup()

VOID XhciController::SelfManagedIoCleanup ( )

Definition at line 1722 of file hc.cpp.

1723{
1724 if (m_SplitPadBuffer != NULL)
1725 {
1728 }
1729
1731}
XhciDmaBuffer * m_SplitPadBuffer
Definition: hc.h:134
VOID UpdateRegistryCounters()
Definition: hc.cpp:1689

Referenced by XhciEvtDeviceSelfManagedIoCleanup().

◆ SelfManagedIoInit()

VOID XhciController::SelfManagedIoInit ( )

Definition at line 1668 of file hc.cpp.

1669{
1670 PDEVICE_OBJECT Pdo = WdfDeviceWdmGetPhysicalDevice(m_Device);
1671
1672 if (Pdo->Flags & XHCI_DEVICE_USED_BY_DEBUGGER)
1673 DPRINT1("Controller shared with the kernel debugger; low power epoch tracking unavailable\n");
1674
1675 DPRINT("Friendly name not set\n");
1676
1679
1680 if (HasErrata(XhciErrata::XferPacketAlignChunks) && m_SplitPadBuffer == NULL)
1681 {
1683 if (m_SplitPadBuffer == NULL)
1684 DPRINT1("No split transfer pad buffer, transfers run without it\n");
1685 }
1686}
VOID ReadVerifierFlags()
Definition: hc.cpp:596
#define XHCI_DEVICE_USED_BY_DEBUGGER
Definition: hc.cpp:82
#define XHCI_PAD_BUFFER_SIZE
Definition: hc.cpp:77
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280

Referenced by XhciEvtDeviceSelfManagedIoInit().

◆ SetErrata()

VOID XhciController::SetErrata ( _In_ XhciErrata  Bit)

Only bits 0 and 12 may be set after population.

Definition at line 183 of file hc.cpp.

185{
186 if (Bit != XhciErrata::RegSplit64BitAccess && Bit != XhciErrata::IntPrimaryOnly)
187 DPRINT1("Errata bit %lu set after population\n", static_cast<ULONG>(Bit));
188
189 m_Errata |= XhciErrataBit(Bit);
190}

Referenced by XhciRegisters::ParseCapabilities().

◆ SetIdleTimeout()

VOID XhciController::SetIdleTimeout ( _In_ ULONG  Milliseconds)
private

Definition at line 737 of file hc.cpp.

739{
742
744 Settings.UserControlOfIdleSettings = IdleAllowUserControl;
745 Settings.IdleTimeout = Milliseconds;
747
748 Status = WdfDeviceAssignS0IdleSettings(m_Device, &Settings);
749 if (!NT_SUCCESS(Status))
750 {
751 /* QUIRK: a failure downgrades the idle status after the fact */
752 DPRINT("Idle timeout %lu ms refused 0x%lx\n", Milliseconds, Status);
754 return;
755 }
756
757 m_LastIdleTimeout = Milliseconds;
758}
FORCEINLINE VOID WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(_Out_ PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings, _In_ WDF_POWER_POLICY_S0_IDLE_CAPABILITIES IdleCaps)
Definition: wdfdevice.h:1349
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings
Definition: wdfdevice.h:2601
@ IdleAllowUserControl
Definition: wdfdevice.h:408
@ SystemManagedIdleTimeoutWithHint
Definition: wdfdevice.h:1245
@ IdleCanWakeFromS0
Definition: wdfdevice.h:401

◆ SetInternalFlags()

VOID XhciController::SetInternalFlags ( )
private

Definition at line 562 of file hc.cpp.

563{
566
567 m_InternalFlags = 0;
568
569 if (Vendor == 0x1B73 && Device == 0x1100 && m_Identity.PciRevisionId == 0x10)
571 else if (Vendor == 0x1B73 && Device == 0x1009)
573 else if (Vendor == 0x1B6F && Device == 0x7023)
575 else if (Vendor == 0x1B21 && Device >= 0x1040 && Device <= 0x1042)
577}

Referenced by PopulateErrata().

◆ SetPortWake()

VOID XhciController::SetPortWake ( _In_ BOOLEAN  Arm)

Definition at line 836 of file hc.cpp.

838{
839 m_WaitWakeQueued = Arm;
840
841 if (!Arm && HasErrata(XhciErrata::PortHoldWakeMaskAwake))
842 return;
843
845}
BOOLEAN m_WaitWakeQueued
Definition: hc.h:203
VOID SetWakeEnables(_In_ BOOLEAN Arm)
Definition: rootports.cpp:936

Referenced by XhciEvtDeviceArmWakeFromS0(), and XhciEvtDeviceDisarmWakeFromS0().

◆ StartController()

NTSTATUS XhciController::StartController ( )
private

Definition at line 1483 of file hc.cpp.

1484{
1486
1488 if (!NT_SUCCESS(Status))
1489 return Status;
1490
1492 return STATUS_SUCCESS;
1493}
NTSTATUS Run()
Definition: mmio.cpp:868
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_MS(_In_ ULONGLONG Time)
Definition: wdfcore.h:80

Referenced by D0EntryPostInterruptsEnabled(), and InternalReset().

◆ TrackSystemPowerIrp()

VOID XhciController::TrackSystemPowerIrp ( _In_ PIO_STACK_LOCATION  Stack)

Definition at line 1746 of file hc.cpp.

1748{
1749 SYSTEM_POWER_STATE_CONTEXT Context = Stack->Parameters.Power.SystemPowerStateContext;
1750
1751 switch (Stack->Parameters.Power.State.SystemState)
1752 {
1753 case PowerSystemWorking:
1754 m_SystemAction = (Context.CurrentSystemState == PowerSystemHibernate) ?
1756 break;
1757
1761 m_SystemAction = (Context.EffectiveSystemState == PowerSystemHibernate) ?
1763 break;
1764
1767 break;
1768
1770 m_SystemAction = (Context.EffectiveSystemState == PowerSystemHibernate) ?
1772 break;
1773
1774 default:
1775 DPRINT1("Unexpected system power state %d\n", Stack->Parameters.Power.State.SystemState);
1776 break;
1777 }
1778}
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
@ PowerSystemSleeping1
Definition: ntpoapi.h:37
@ PowerSystemSleeping2
Definition: ntpoapi.h:38
@ PowerSystemSleeping3
Definition: ntpoapi.h:39
@ PowerSystemShutdown
Definition: ntpoapi.h:41
@ PowerSystemHibernate
Definition: ntpoapi.h:40
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

◆ UcxReset()

VOID XhciController::UcxReset ( )

Definition at line 2193 of file hc.cpp.

2194{
2196
2197 if (IsAccessible())
2198 InternalReset();
2199 else
2200 DPRINT1("UCX reset of an inaccessible controller skipped\n");
2201
2202 /* QUIRK: reported even after a failed reset; SetFailed already told UCX */
2204 UcxControllerResetComplete(m_Ucx, &Info);
2205}
BOOLEAN IsAccessible() const
Definition: hc.cpp:193
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by XhciEvtControllerReset().

◆ UpdateRegistryCounters()

VOID XhciController::UpdateRegistryCounters ( )
private

Definition at line 1689 of file hc.cpp.

1690{
1691 DECLARE_CONST_UNICODE_STRING(RestoreName, L"HCRestoreStateFailureCount");
1692 DECLARE_CONST_UNICODE_STRING(RecoveryName, L"HCRecoveryCount");
1693 PCUNICODE_STRING Names[2] = { &RestoreName, &RecoveryName };
1695 WDFKEY Key;
1696 ULONG Value;
1697 ULONG Index;
1699
1702 if (!NT_SUCCESS(Status))
1703 {
1704 DPRINT1("Device key open for the recovery counters failed 0x%lx\n", Status);
1705 return;
1706 }
1707
1708 for (Index = 0; Index < RTL_NUMBER_OF(Names); Index++)
1709 {
1710 if (!NT_SUCCESS(WdfRegistryQueryULong(Key, Names[Index], &Value)))
1711 Value = 0;
1712
1713 Status = WdfRegistryAssignULong(Key, Names[Index], Value + Counts[Index]);
1714 if (!NT_SUCCESS(Status))
1715 DPRINT1("Writing %wZ failed 0x%lx\n", Names[Index], Status);
1716 }
1717
1719}
static COUNTS Counts
Definition: ObType.cpp:60
PWSTR Names[]
#define KEY_WRITE
Definition: nt_native.h:1034

Referenced by SelfManagedIoCleanup().

◆ UsageNotification()

VOID XhciController::UsageNotification ( _In_ WDF_SPECIAL_FILE_TYPE  Type,
_In_ BOOLEAN  InPath 
)

Definition at line 1734 of file hc.cpp.

1737{
1738 /* No pageable code in this driver, so there is nothing to lock down */
1739 if (InPath)
1740 m_SpecialFiles |= 1UL << Type;
1741 else
1742 m_SpecialFiles &= ~(1UL << Type);
1743}
ULONG m_SpecialFiles
Definition: hc.h:267

Referenced by XhciEvtDeviceUsageNotification().

◆ WatchdogTick()

VOID XhciController::WatchdogTick ( )

Definition at line 1848 of file hc.cpp.

1849{
1850 ULONG Usbsts;
1851
1852 if (!IsAccessible())
1853 return;
1854
1856 if (Usbsts == MAXULONG)
1857 {
1858 DPRINT1("Watchdog read all ones, controller gone\n");
1859 SetGone(TRUE);
1860 return;
1861 }
1862
1863 /* QUIRK: neither error is cleared here, so each tick reports it again */
1864 if (Usbsts & XHCI_USBSTS_HSE)
1865 {
1866 DPRINT1("Host System Error, USBSTS 0x%08lx\n", Usbsts);
1867 VerifierCheck(XHCI_VERIFY_HSE);
1869 return;
1870 }
1871
1872 if (Usbsts & XHCI_USBSTS_HCE)
1873 {
1874 DPRINT1("Host Controller Error, USBSTS 0x%08lx\n", Usbsts);
1875 VerifierCheck(XHCI_VERIFY_HCE);
1877 return;
1878 }
1879
1881 {
1884 }
1885
1887}
#define InterlockedExchange
Definition: armddk.h:54
VOID Rebalance()
Definition: dmapool.cpp:655
LONG m_ResetInterval
Definition: hc.h:271
ULONG ReadOperational32(_In_ ULONG Offset) const
Definition: mmio.cpp:431
#define XHCI_VERIFY_HSE
Definition: hc.cpp:63
#define XHCI_RESET_WINDOW_TICKS
Definition: hc.cpp:74
#define XHCI_REASON_HOST_SYSTEM_ERROR
Definition: hc.cpp:50
#define XHCI_REASON_HOST_CONTROLLER_ERROR
Definition: hc.cpp:51
#define XHCI_VERIFY_HCE
Definition: hc.cpp:64
#define XHCI_USBSTS_HCE
Definition: xhcihw.h:409
#define XHCI_OP_USBSTS
Definition: xhcihw.h:382
#define XHCI_USBSTS_HSE
Definition: xhcihw.h:402

Member Data Documentation

◆ m_Buffers

◆ m_Commands

◆ m_Device

◆ m_Errata

ULONG64 XhciController::m_Errata

Definition at line 88 of file hc.h.

Referenced by HasErrata(), PopulateErrata(), QueryErrataDatabase(), ReadRegistryErrata(), and SetErrata().

◆ m_ErrataWord2

ULONG64 XhciController::m_ErrataWord2

Definition at line 89 of file hc.h.

Referenced by HasErrata(), PopulateErrata(), and QueryErrataDatabase().

◆ m_FrameSnapshot

LONG64 XhciController::m_FrameSnapshot
private

Definition at line 265 of file hc.h.

Referenced by InitFrameSnapshot().

◆ m_FrameSnapshotReady

BOOLEAN XhciController::m_FrameSnapshotReady
private

Definition at line 264 of file hc.h.

Referenced by D0Entry(), and InitFrameSnapshot().

◆ m_Gone

BOOLEAN XhciController::m_Gone
private

Definition at line 262 of file hc.h.

Referenced by IsAccessible().

◆ m_GoneHandled

BOOLEAN XhciController::m_GoneHandled
private

Definition at line 284 of file hc.h.

Referenced by RunRecovery().

◆ m_Identity

XhciIdentity XhciController::m_Identity

◆ m_IdleItem

WDFWORKITEM XhciController::m_IdleItem
private

Definition at line 278 of file hc.h.

Referenced by CreateWdfObjects(), D0Exit(), and ReleaseHardware().

◆ m_IdleStatus

IdleStatus XhciController::m_IdleStatus
private

Definition at line 273 of file hc.h.

Referenced by ConfigureS0Idle(), D0Entry(), Initialize(), and SetIdleTimeout().

◆ m_InternalFlags

ULONG64 XhciController::m_InternalFlags

◆ m_Interrupters

◆ m_LastIdleTimeout

ULONG XhciController::m_LastIdleTimeout
private

Definition at line 274 of file hc.h.

Referenced by D0Entry(), and SetIdleTimeout().

◆ m_PnpToldRemoved

BOOLEAN XhciController::m_PnpToldRemoved
private

Definition at line 285 of file hc.h.

Referenced by RunRecovery().

◆ m_PowerState

WDF_POWER_DEVICE_STATE XhciController::m_PowerState

D0 only after a successful D0 entry; the target state from D0 exit start.

Definition at line 117 of file hc.h.

Referenced by D0Entry(), XhciRootHub::D0Exit(), D0Exit(), and Initialize().

◆ m_RecoveryActions

ULONG XhciController::m_RecoveryActions
private

Definition at line 282 of file hc.h.

Referenced by CreateWdfObjects(), and RecoveryWorker().

◆ m_RecoveryCount

ULONG XhciController::m_RecoveryCount
private

Definition at line 269 of file hc.h.

Referenced by InternalReset(), and UpdateRegistryCounters().

◆ m_RecoveryItem

WDFWORKITEM XhciController::m_RecoveryItem
private

Definition at line 277 of file hc.h.

Referenced by CreateWdfObjects(), D0Exit(), and ReleaseHardware().

◆ m_RecoveryLock

KSPIN_LOCK XhciController::m_RecoveryLock
private

Definition at line 281 of file hc.h.

Referenced by CreateWdfObjects(), and RecoveryWorker().

◆ m_RecoveryMutex

KMUTEX XhciController::m_RecoveryMutex
private

Definition at line 283 of file hc.h.

Referenced by CreateWdfObjects(), and RecoveryWorker().

◆ m_Registers

◆ m_ReservedIoArmed

BOOLEAN XhciController::m_ReservedIoArmed

Set by UCX through EvtControllerEnableForwardProgress; read by transfer code.

Definition at line 114 of file hc.h.

Referenced by XhciEvtControllerEnableForwardProgress().

◆ m_ResetCount

LONG XhciController::m_ResetCount
private

Definition at line 270 of file hc.h.

Referenced by InternalReset(), RunRecovery(), and WatchdogTick().

◆ m_ResetInterval

LONG XhciController::m_ResetInterval
private

Definition at line 271 of file hc.h.

Referenced by WatchdogTick().

◆ m_ResetLock

LONG XhciController::m_ResetLock
private

Definition at line 272 of file hc.h.

Referenced by InternalReset().

◆ m_RestoreFailures

ULONG XhciController::m_RestoreFailures
private

Definition at line 268 of file hc.h.

Referenced by D0Entry(), and UpdateRegistryCounters().

◆ m_RootHub

◆ m_SaveFailed

BOOLEAN XhciController::m_SaveFailed
private

Definition at line 263 of file hc.h.

Referenced by D0Entry(), and D0Exit().

◆ m_Slots

◆ m_SpecialFiles

ULONG XhciController::m_SpecialFiles
private

Definition at line 267 of file hc.h.

Referenced by UsageNotification().

◆ m_SplitPadBuffer

XhciDmaBuffer* XhciController::m_SplitPadBuffer

Errata bit 34 pad buffer, NULL when absent.

Definition at line 134 of file hc.h.

Referenced by SelfManagedIoCleanup(), and SelfManagedIoInit().

◆ m_SystemAction

SystemAction XhciController::m_SystemAction

Definition at line 131 of file hc.h.

Referenced by D0Entry(), XhciRootHub::D0Exit(), D0Exit(), Initialize(), and TrackSystemPowerIrp().

◆ m_TestMode

BOOLEAN XhciController::m_TestMode

Definition at line 204 of file hc.h.

Referenced by Initialize().

◆ m_TimeIncrement

ULONG XhciController::m_TimeIncrement
private

Definition at line 266 of file hc.h.

Referenced by Initialize(), and NowMs().

◆ m_Ucx

UCXCONTROLLER XhciController::m_Ucx

◆ m_VerifierFlags

ULONG XhciController::m_VerifierFlags
private

Definition at line 261 of file hc.h.

Referenced by ReadVerifierFlags().

◆ m_WaitWakeQueued

BOOLEAN XhciController::m_WaitWakeQueued

Definition at line 203 of file hc.h.

Referenced by SetPortWake(), XhciEvtDeviceArmWakeFromSx(), and XhciEvtDeviceDisarmWakeFromSx().

◆ m_Watchdog

WDFTIMER XhciController::m_Watchdog
private

Definition at line 276 of file hc.h.

Referenced by CreateWdfObjects(), D0Exit(), InternalReset(), and StartController().

◆ m_WdmDevice

PDEVICE_OBJECT XhciController::m_WdmDevice

Definition at line 86 of file hc.h.

Referenced by XhciControlRing::BuildControlTd(), Initialize(), and XhciEndpoint::SendClearStall().

◆ Reason

_In_ ULONG XhciController::Reason

Definition at line 83 of file hc.h.


The documentation for this class was generated from the following files: