ReactOS 0.4.17-dev-1281-g065abb3
XhciUsbDevice Class Reference

#include <slotdev.h>

Collaboration diagram for XhciUsbDevice:

Classes

struct  ReconfigureWaiter
 

Public Member Functions

PVOID InputContext (_In_ ULONG Index) const
 
PVOID OutputContext (_In_ ULONG Dci) const
 
ULONG64 InputContextAddress () const
 
VOID ZeroInputContext ()
 
VOID BuildSlotContext (_Out_writes_bytes_(ContextSize) PVOID SlotContext, _In_ ULONG ContextSize) const
 
ULONG ContextEntries () const
 
ULONG SlotId () const
 
USB_DEVICE_SPEED Speed () const
 
UCXUSBDEVICE Handle () const
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID RingDoorbell(_In_ ULONG Dci
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) XhciEndpoint *EndpointAt(_In_ ULONG Dci) const
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID AddEndpoint(_In_ XhciEndpoint *Endpoint)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID RemoveEndpoint(_In_ XhciEndpoint *Endpoint)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID ReconfigureEndpoint(_In_ XhciEndpoint *Endpoint
 
_In_ VOID (NTAPI *Done)(_In_ PVOID Context
 
VOID OnTransferEvent (_In_ const XHCI_TRB *Event)
 
VOID OnDeviceNotificationEvent (_In_ const XHCI_TRB *Event)
 
VOID ControllerResetStarting ()
 
 _IRQL_requires_ (PASSIVE_LEVEL) VOID ControllerResetDone()
 
VOID OnHostLost ()
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID SetDisabled()
 
XhciController * Controller () const
 
BOOLEAN IsSlotEnabled () const
 
const USB_DEVICE_DESCRIPTOR * DeviceDescriptor () const
 
const USB_DEVICE_PORT_PATH * PortPath () const
 
ULONG ContextSize () const
 
ULONG EndpointState (_In_ ULONG Dci) const
 
ULONG64 HardwareDequeuePointer (_In_ ULONG Dci) const
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS Initialize(_In_ XhciController *Controller
 
VOID Cleanup (_In_ WDFOBJECT Object)
 
VOID Enable (_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_ENABLE Payload)
 
VOID Address (_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_ADDRESS Payload)
 
VOID Update (_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_UPDATE Payload)
 
VOID HubInfo (_In_ WDFREQUEST Request, _In_ const USBDEVICE_HUB_INFO *Payload)
 
VOID EndpointsConfigure (_In_ WDFREQUEST Request, _Inout_ PENDPOINTS_CONFIGURE Payload)
 
VOID Disable (_In_ WDFREQUEST Request)
 
VOID Reset (_In_ WDFREQUEST Request)
 

Static Public Member Functions

static XhciUsbDevice * FromUcx (_In_ UCXUSBDEVICE UsbDevice)
 

Public Attributes

_In_ ULONG StreamId
 
_In_ _In_ NTSTATUS Status
 
_In_ _In_ NTSTATUS _In_ PVOID Context
 
_In_ UCXUSBDEVICE UsbDevice
 
_In_ UCXUSBDEVICE _In_ const UCXUSBDEVICE_INFO * Info
 

Private Types

enum class  PendingKind : ULONG {
  None , Enable , Address , Update ,
  Configure , Disable , Reset
}
 
enum class  AfterDisable : ULONG { CompleteSuccess , CompleteFailure , EnableSlot }
 
typedef VOID(NTAPI * PFN_RECONFIGURE_DONE) (_In_ PVOID Context, _In_ NTSTATUS Status)
 

Private Member Functions

VOID SetPending (_In_ WDFREQUEST Request, _In_ PVOID Payload, _In_ PendingKind Kind, _In_ BOOLEAN MustSucceed)
 
WDFREQUEST TakePending ()
 
VOID CompletePending (_In_ NTSTATUS Status)
 
NTSTATUS LostSlotStatus () const
 
VOID PrepareCommand (_In_ ULONG Type)
 
VOID SubmitEnableSlot ()
 
NTSTATUS SubmitAddressDevice (_In_ BOOLEAN BlockSetAddress)
 
VOID SubmitDisableSlot (_In_ AfterDisable Next)
 
VOID SubmitSecondConfigure ()
 
VOID OnEnableSlotDone (_In_ const XhciCommand *Command)
 
VOID OnAddressDeviceDone (_In_ const XhciCommand *Command)
 
VOID OnEvaluateContextDone (_In_ const XhciCommand *Command)
 
VOID OnConfigureEndpointDone (_In_ const XhciCommand *Command)
 
VOID OnDisableSlotDone (_In_ const XhciCommand *Command)
 
VOID OnResetDeviceDone (_In_ const XhciCommand *Command)
 
NTSTATUS BuildAddressContext ()
 
VOID ApplyUpdate (_Inout_ PUSBDEVICE_UPDATE Payload)
 
BOOLEAN WantsTunnelStateDsm (_In_ const USBDEVICE_UPDATE *Payload) const
 
BOOLEAN QueueTunnelStateDsm (_Inout_ PUSBDEVICE_UPDATE Payload)
 
 _IRQL_requires_ (PASSIVE_LEVEL) VOID RunTunnelStateDsm(_Inout_ PUSBDEVICE_UPDATE Payload)
 
VOID DisableDefaultEndpoint ()
 
VOID DisableConfiguredEndpoints (_In_ BOOLEAN ClearTable)
 
VOID DisableEndpointList (_In_ ULONG Count, _In_reads_(Count) UCXENDPOINT *Endpoints)
 
VOID RecordEnabledEndpoints (_In_ const ENDPOINTS_CONFIGURE *Payload)
 
VOID ForgetSlot ()
 
VOID StartReconfigure (_In_ const ReconfigureWaiter *Waiter)
 
VOID FinishReconfigure (_In_ NTSTATUS Status)
 
PXHCI_INPUT_CONTROL_CONTEXT InputControl () const
 
PXHCI_SLOT_CONTEXT InputSlot () const
 
const XHCI_SLOT_CONTEXT * OutputSlot () const
 
XhciUsbDevice * TtHub () const
 

Static Private Member Functions

static VOID NTAPI CommandDone (_In_ XhciCommand *Command)
 
static VOID NTAPI ReconfigureCommandDone (_In_ XhciCommand *Command)
 

Private Attributes

UCXUSBDEVICE m_Handle
 
XhciController * m_Controller
 
UCXUSBDEVICE_INFO m_Info
 
ULONG m_ContextSize
 
XhciDmaBuffer * m_Output
 
XhciDmaBuffer * m_Input
 
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
 
BOOLEAN m_SlotEnabled
 
ULONG m_SlotId
 
BOOLEAN m_IsHub
 
ULONG m_NumberOfPorts
 
ULONG m_NumberOfTTs
 
ULONG m_TTThinkTime
 
BOOLEAN m_LpmEnabled
 
BOOLEAN m_ResumeTimeSet
 
ULONG m_ContextMask
 
XhciEndpoint * m_Endpoints [XHCI_MAX_DCI+1]
 
volatile LONG m_EndpointCount
 
XhciCommand m_Command
 
WDFREQUEST m_PendingRequest
 
PVOID m_PendingPayload
 
PendingKind m_PendingKind
 
BOOLEAN m_MustSucceed
 
AfterDisable m_AfterDisable
 
KSPIN_LOCK m_ReconfigureLock
 
BOOLEAN m_ReconfigureBusy
 
ULONG m_ReconfigureQueued
 
ReconfigureWaiter m_ReconfigureWaiters [XHCI_MAX_DCI+1]
 
ReconfigureWaiter m_ReconfigureCurrent
 
XhciCommand m_ReconfigureCommand
 
XhciDmaBuffer * m_ReconfigureInput
 

Static Private Attributes

static EVT_WDF_WORKITEM TunnelDsmWorker
 

Detailed Description

One USB device and its xHCI slot. Lives in the UCXUSBDEVICE context.

Definition at line 17 of file slotdev.h.

Member Typedef Documentation

◆ PFN_RECONFIGURE_DONE

typedef VOID(NTAPI * XhciUsbDevice::PFN_RECONFIGURE_DONE) (_In_ PVOID Context, _In_ NTSTATUS Status)
private

Definition at line 150 of file slotdev.h.

Member Enumeration Documentation

◆ AfterDisable

What a successful Disable Slot does next.

Enumerator
CompleteSuccess 
CompleteFailure 
EnableSlot 

Definition at line 165 of file slotdev.h.

◆ PendingKind

Which device request owns the device command block.

Enumerator
None 
Enable 
Address 
Update 
Configure 
Disable 
Reset 

Definition at line 153 of file slotdev.h.

Member Function Documentation

◆ _IRQL_requires_() [1/3]

XhciUsbDevice::_IRQL_requires_ ( PASSIVE_LEVEL  )

◆ _IRQL_requires_() [2/3]

XhciUsbDevice::_IRQL_requires_ ( PASSIVE_LEVEL  )

◆ _IRQL_requires_() [3/3]

XhciUsbDevice::_IRQL_requires_ ( PASSIVE_LEVEL  )
private

◆ _IRQL_requires_max_() [1/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [2/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Configure Endpoint for one endpoint (drop and add) on its own command block and input context, serialized per device, for static streams enable and disable. Done runs once with the result.

◆ _IRQL_requires_max_() [3/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [4/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [5/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

The slot was lost without a Disable Slot: drop it and finish any pending request.

◆ _IRQL_requires_max_() [6/6]

XhciUsbDevice::_IRQL_requires_max_ ( DISPATCH_LEVEL  ) const

◆ Address()

VOID XhciUsbDevice::Address ( _In_ WDFREQUEST  Request,
_Inout_ PUSBDEVICE_ADDRESS  Payload 
)

Definition at line 839 of file slotdev.cpp.

842{
844
845 if (!m_SlotEnabled)
846 {
847 DPRINT1("ADDRESS for device %p without a slot\n", this);
848 WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
849 return;
850 }
851
853 {
854 DPRINT1("ADDRESS for device %p with the controller gone\n", this);
855 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
856 return;
857 }
858
860
862 if (!NT_SUCCESS(Status))
863 {
864 DPRINT1("Address Device for slot %lu not built: 0x%lx\n", m_SlotId, Status);
866 }
867}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsAccessible() const
Definition: hc.cpp:193
VOID CompletePending(_In_ NTSTATUS Status)
Definition: slotdev.cpp:541
NTSTATUS SubmitAddressDevice(_In_ BOOLEAN BlockSetAddress)
Definition: slotdev.cpp:710
ULONG m_SlotId
Definition: slotdev.h:286
XhciController * m_Controller
Definition: slotdev.h:278
VOID SetPending(_In_ WDFREQUEST Request, _In_ PVOID Payload, _In_ PendingKind Kind, _In_ BOOLEAN MustSucceed)
Definition: slotdev.cpp:519
BOOLEAN m_SlotEnabled
Definition: slotdev.h:285
_In_ _In_ NTSTATUS Status
Definition: slotdev.h:77
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by XhciEvtUsbDeviceAddress().

◆ ApplyUpdate()

VOID XhciUsbDevice::ApplyUpdate ( _Inout_ PUSBDEVICE_UPDATE  Payload)
private

Definition at line 918 of file slotdev.cpp.

920{
921 ULONG RootPort = m_Info.PortPath.PortPath[0];
923
924 /* QUIRK: a device never stops being a hub */
925 if (Payload->Flags.UpdateIsHub && Payload->IsHub)
926 m_IsHub = TRUE;
927
928 if (Payload->Flags.UpdateDeviceDescriptor && Payload->DeviceDescriptor != NULL)
929 RtlCopyMemory(&m_DeviceDescriptor, Payload->DeviceDescriptor, sizeof(m_DeviceDescriptor));
930
931 if (Payload->Flags.Update20HardwareLpmParameters)
932 {
933 ASSERT(!m_IsHub);
934 m_LpmEnabled = (BOOLEAN)Payload->Usb20HardwareLpmParameters.HardwareLpmEnable;
935 m_Controller->m_RootHub.Update20HardwareLpm(RootPort, m_SlotId, &Payload->Usb20HardwareLpmParameters);
936 }
937
938 if (Payload->Flags.UpdateRootPortResumeTime)
939 {
940 m_Controller->m_RootHub.ArmPortResumeTimer(RootPort, Payload->RootPortResumeTime);
942 }
943
944 /* The ACPI path fills the answer before it gets here */
945 if (Payload->Flags.UpdateTunnelState && !m_Controller->HasErrata(XhciErrata::Usb4TunnelFromAcpiDsm))
946 {
947 Answer = UcxHubUpdateTunnelAnswer(Payload);
951 }
952}
BOOLEAN HasErrata(_In_ XhciErrata Bit) const
Definition: hc.h:58
XhciRootHub m_RootHub
Definition: hc.h:96
VOID Update20HardwareLpm(_In_ ULONG PortNumber, _In_ ULONG SlotId, _In_ const USBDEVICE_UPDATE_20_HARDWARE_LPM_PARAMETERS *Parameters)
Definition: rootports.cpp:1075
VOID ArmPortResumeTimer(_In_ ULONG PortNumber, _In_ ULONG Milliseconds)
Definition: rootports.cpp:1140
UCHAR QueryTunnelState(_In_ ULONG PortNumber) const
Definition: rootports.cpp:1005
BOOLEAN m_LpmEnabled
Definition: slotdev.h:291
BOOLEAN m_IsHub
Definition: slotdev.h:287
UCXUSBDEVICE_INFO m_Info
Definition: slotdev.h:279
BOOLEAN m_ResumeTimeSet
Definition: slotdev.h:292
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
Definition: slotdev.h:284
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define UCXHUB_TUNNEL_STATE_TUNNELED
Definition: hubucx.h:539
#define UCXHUB_TUNNEL_STATE_UNKNOWN
Definition: hubucx.h:541
FORCEINLINE PUCXHUB_UPDATE_TUNNEL_ANSWER NTAPI UcxHubUpdateTunnelAnswer(_In_ PUSBDEVICE_UPDATE Update)
Definition: hubucx.h:556
#define ASSERT(a)
Definition: mode.c:44
#define BOOLEAN
Definition: pedump.c:73
USB_DEVICE_PORT_PATH PortPath
Definition: ucxusbdevice.h:178
ULONG PortPath[MAX_USB_DEVICE_DEPTH]
Definition: ucxusbdevice.h:170
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59

Referenced by OnEvaluateContextDone(), and Update().

◆ BuildAddressContext()

NTSTATUS XhciUsbDevice::BuildAddressContext ( )
private

Definition at line 651 of file slotdev.cpp.

652{
656 ULONG Speed;
657 ULONG Route;
658 ULONG Tier;
659
660 switch (m_Info.DeviceSpeed)
661 {
662 case UsbLowSpeed:
664 break;
665 case UsbFullSpeed:
667 break;
668 case UsbHighSpeed:
670 break;
671 case UsbSuperSpeed:
673 break;
674 default:
675 DPRINT1("Device %p has speed %d, which a slot cannot describe\n", this, m_Info.DeviceSpeed);
677 }
678
682
683 /* The root port is not part of the route string (USB 3.2 8.9) */
684 Route = 0;
685 for (Tier = 1; Tier < Path->PortPathDepth && Tier < MAX_USB_DEVICE_DEPTH; Tier++)
686 Route |= min(Path->PortPath[Tier], (ULONG)XHCI_ROUTE_TIER_MAX) << ((Tier - 1) * XHCI_ROUTE_TIER_BITS);
687
688 Slot = InputSlot();
689 Slot->RouteString = Route;
690 Slot->Speed = Speed;
691 Slot->ContextEntries = 1;
692 Slot->RootHubPortNumber = Path->PortPath[0];
693
694 Hub = TtHub();
695 if (Hub != NULL)
696 {
697 Slot->MultiTT = (Hub->m_NumberOfTTs > 1);
698 Slot->TTHubSlotId = Hub->m_SlotId;
699 }
700
701 if (Path->TTHubDepth != 0 && Path->TTHubDepth < MAX_USB_DEVICE_DEPTH)
702 Slot->TTPortNumber = Path->PortPath[Path->TTHubDepth];
703
704 /* QUIRK: Average TRB Length stays 0 for EP0 */
706 return STATUS_SUCCESS;
707}
HubFdo * Hub
Definition: bootdev.cpp:261
VOID BuildContext(_Out_writes_bytes_(ContextSize) PVOID EndpointContext, _In_ ULONG ContextSize) const
Definition: epctx.cpp:754
PXHCI_SLOT_CONTEXT InputSlot() const
Definition: slotdev.cpp:295
XhciUsbDevice * TtHub() const
Definition: slotdev.cpp:383
PVOID InputContext(_In_ ULONG Index) const
Definition: slotdev.cpp:261
USB_DEVICE_SPEED Speed() const
Definition: slotdev.cpp:341
VOID ZeroInputContext()
Definition: slotdev.cpp:283
XhciEndpoint * m_Endpoints[XHCI_MAX_DCI+1]
Definition: slotdev.h:297
ULONG m_ContextSize
Definition: slotdev.h:280
PXHCI_INPUT_CONTROL_CONTEXT InputControl() const
Definition: slotdev.cpp:289
ULONG m_ContextMask
Definition: slotdev.h:295
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
UNICODE_STRING Path
#define min(a, b)
Definition: monoChain.cc:55
#define STATUS_SUCCESS
Definition: shellext.h:65
#define XHCI_ROUTE_TIER_MAX
Definition: slotdev.cpp:59
#define XHCI_ROUTE_TIER_BITS
Definition: slotdev.cpp:60
#define XHCI_DEFAULT_CONTEXT_MASK
Definition: slotdev.cpp:57
USB_DEVICE_SPEED DeviceSpeed
Definition: ucxusbdevice.h:176
#define MAX_USB_DEVICE_DEPTH
Definition: ucxusbdevice.h:163
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
#define XHCI_SPEED_LOW
Definition: xhcihw.h:242
#define XHCI_SPEED_SUPER
Definition: xhcihw.h:244
#define XHCI_SPEED_HIGH
Definition: xhcihw.h:243
#define XHCI_SPEED_FULL
Definition: xhcihw.h:241

Referenced by SubmitAddressDevice().

◆ BuildSlotContext()

VOID XhciUsbDevice::BuildSlotContext ( _Out_writes_bytes_(ContextSize) PVOID  SlotContext,
_In_ ULONG  ContextSize 
) const

Fills the hub fields of an input slot context and applies the multi TT errata rule.

Definition at line 1159 of file slotdev.cpp.

1162{
1165
1166 /* Only the hub fields; the caller zeroed the context and owns Context Entries */
1167 ASSERT(ContextSize >= sizeof(*Slot));
1169
1170 if (m_IsHub)
1171 {
1172 Slot->Hub = 1;
1173 Slot->NumberOfPorts = m_NumberOfPorts;
1174
1176 {
1177 Slot->MultiTT = (m_NumberOfTTs > 1);
1178 Slot->TTThinkTime = m_TTThinkTime;
1179 }
1180 }
1181
1182 /* Some controllers need MTT repeated for LS and FS devices behind a multi TT hub */
1183 if (m_Controller->HasErrata(XhciErrata::CfgMultiTtFromHubData) &&
1184 !m_IsHub &&
1186 {
1187 Hub = TtHub();
1188 if (Hub != NULL && Hub->m_NumberOfTTs > 1)
1189 Slot->MultiTT = 1;
1190 }
1191}
ULONG ContextSize() const
Definition: slotdev.cpp:377
ULONG m_NumberOfTTs
Definition: slotdev.h:289
ULONG m_NumberOfPorts
Definition: slotdev.h:288
ULONG m_TTThinkTime
Definition: slotdev.h:290
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
struct _XHCI_SLOT_CONTEXT * PXHCI_SLOT_CONTEXT

Referenced by EndpointsConfigure(), StartReconfigure(), and SubmitSecondConfigure().

◆ Cleanup()

VOID XhciUsbDevice::Cleanup ( _In_ WDFOBJECT  Object)

Definition at line 221 of file slotdev.cpp.

223{
224 /* Creation never got far enough to own anything */
225 if (m_Handle != (UCXUSBDEVICE)Object)
226 return;
227
228 ASSERT(m_SlotId == 0);
229
230 if (m_Output != NULL)
231 {
233 m_Output = NULL;
234 }
235
236 if (m_Input != NULL)
237 {
239 m_Input = NULL;
240 }
241
243 {
246 }
247}
XhciCommonBuffer m_Buffers
Definition: hc.h:92
XhciDmaBuffer * m_ReconfigureInput
Definition: slotdev.h:315
XhciDmaBuffer * m_Output
Definition: slotdev.h:281
XhciDmaBuffer * m_Input
Definition: slotdev.h:282
UCXUSBDEVICE m_Handle
Definition: slotdev.h:277
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

◆ CommandDone()

VOID NTAPI XhciUsbDevice::CommandDone ( _In_ XhciCommand *  Command)
staticprivate

Definition at line 568 of file slotdev.cpp.

570{
571 XhciUsbDevice* Device = static_cast<XhciUsbDevice*>(Command->Context);
572
573 /* Controller gone or a lost slot already finished the request */
574 if (Device->m_PendingRequest == NULL)
575 {
576 DPRINT("Device %p command type %lu completed with no request left\n",
577 Device, XhciTrbType(&Command->Trb));
578 return;
579 }
580
581 switch (XhciTrbType(&Command->Trb))
582 {
583 case static_cast<ULONG>(XhciTrbType::EnableSlot):
584 Device->OnEnableSlotDone(Command);
585 break;
586
587 case static_cast<ULONG>(XhciTrbType::AddressDevice):
588 Device->OnAddressDeviceDone(Command);
589 break;
590
591 case static_cast<ULONG>(XhciTrbType::EvaluateContext):
592 Device->OnEvaluateContextDone(Command);
593 break;
594
595 case static_cast<ULONG>(XhciTrbType::ConfigureEndpoint):
596 Device->OnConfigureEndpointDone(Command);
597 break;
598
599 case static_cast<ULONG>(XhciTrbType::DisableSlot):
600 Device->OnDisableSlotDone(Command);
601 break;
602
603 case static_cast<ULONG>(XhciTrbType::ResetDevice):
604 Device->OnResetDeviceDone(Command);
605 break;
606
607 default:
608 ASSERT(FALSE);
609 break;
610 }
611}
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define DPRINT
Definition: sndvol32.h:73
Definition: shell.h:41
XhciTrbType
Definition: xhcihw.h:68

Referenced by PrepareCommand(), and Reset().

◆ CompletePending()

VOID XhciUsbDevice::CompletePending ( _In_ NTSTATUS  Status)
private

Definition at line 541 of file slotdev.cpp.

543{
544 WDFREQUEST Request = TakePending();
545
546 if (Request != NULL)
547 WdfRequestComplete(Request, Status);
548}
WDFREQUEST TakePending()
Definition: slotdev.cpp:535

Referenced by Address(), EndpointsConfigure(), OnAddressDeviceDone(), OnConfigureEndpointDone(), OnDisableSlotDone(), OnEnableSlotDone(), OnEvaluateContextDone(), and OnResetDeviceDone().

◆ ContextEntries()

ULONG XhciUsbDevice::ContextEntries ( ) const

Highest DCI the HCD considers configured (Context Entries).

Definition at line 321 of file slotdev.cpp.

322{
324 ULONG Highest = 0;
325
326 ASSERT(Mask != 0);
327
328 while ((Mask >>= 1) != 0)
329 Highest++;
330
331 return Highest;
332}
unsigned int Mask
Definition: fpcontrol.c:82

Referenced by XhciEndpoint::BuildEndpointConfigure(), EndpointsConfigure(), and StartReconfigure().

◆ ContextSize()

ULONG XhciUsbDevice::ContextSize ( ) const

Definition at line 377 of file slotdev.cpp.

378{
379 return m_ContextSize;
380}

Referenced by BuildSlotContext().

◆ Controller()

XhciController * XhciUsbDevice::Controller ( ) const

Definition at line 353 of file slotdev.cpp.

354{
355 return m_Controller;
356}

Referenced by _IRQL_requires_().

◆ ControllerResetStarting()

VOID XhciUsbDevice::ControllerResetStarting ( )

Definition at line 1746 of file slotdev.cpp.

1747{
1748 ULONG Dci;
1749
1750 for (Dci = 1; Dci <= XHCI_MAX_DCI; Dci++)
1751 {
1752 if (m_Endpoints[Dci] != NULL)
1754 }
1755}
VOID ControllerResetStarting()
Definition: epctx.cpp:1253
#define XHCI_MAX_DCI
Definition: slotdev.h:14

◆ DeviceDescriptor()

const USB_DEVICE_DESCRIPTOR * XhciUsbDevice::DeviceDescriptor ( ) const

Definition at line 365 of file slotdev.cpp.

366{
367 return &m_DeviceDescriptor;
368}

Referenced by XhciEndpoint::BuildContext().

◆ Disable()

VOID XhciUsbDevice::Disable ( _In_ WDFREQUEST  Request)

Definition at line 1421 of file slotdev.cpp.

1423{
1424 ULONG RootPort = m_Info.PortPath.PortPath[0];
1425
1426 if (!m_SlotEnabled)
1427 {
1430 WdfRequestComplete(Request, STATUS_SUCCESS);
1431 return;
1432 }
1433
1434 /* QUIRK: neither flag is cleared afterwards */
1435 if (m_LpmEnabled)
1437 if (m_ResumeTimeSet)
1439
1440 if (!m_Controller->IsAccessible())
1441 {
1442 DPRINT("DISABLE for device %p with the controller gone\n", this);
1443 SetDisabled();
1444 WdfRequestComplete(Request, STATUS_SUCCESS);
1445 return;
1446 }
1447
1450}
VOID DisableLpmForSlot(_In_ ULONG PortNumber, _In_ ULONG SlotId)
Definition: rootports.cpp:1118
VOID DisarmPortResumeTimer(_In_ ULONG PortNumber)
Definition: rootports.cpp:1156
VOID DisableDefaultEndpoint()
Definition: slotdev.cpp:456
VOID DisableConfiguredEndpoints(_In_ BOOLEAN ClearTable)
Definition: slotdev.cpp:463
VOID SubmitDisableSlot(_In_ AfterDisable Next)
Definition: slotdev.cpp:1412

Referenced by XhciEvtUsbDeviceDisable().

◆ DisableConfiguredEndpoints()

VOID XhciUsbDevice::DisableConfiguredEndpoints ( _In_ BOOLEAN  ClearTable)
private

Definition at line 463 of file slotdev.cpp.

465{
466 ULONG Dci;
467
468 for (Dci = 2; Dci <= XHCI_MAX_DCI; Dci++)
469 {
470 if (m_Endpoints[Dci] == NULL)
471 continue;
472
473 m_Endpoints[Dci]->Disable(ClearTable);
474 if (ClearTable)
475 m_Endpoints[Dci] = NULL;
476 }
477}

Referenced by Disable(), OnDisableSlotDone(), OnResetDeviceDone(), and Reset().

◆ DisableDefaultEndpoint()

VOID XhciUsbDevice::DisableDefaultEndpoint ( )
private

Definition at line 456 of file slotdev.cpp.

457{
458 if (m_Endpoints[1] != NULL)
459 m_Endpoints[1]->Disable(TRUE);
460}

Referenced by Disable(), Enable(), OnDisableSlotDone(), and OnEnableSlotDone().

◆ DisableEndpointList()

VOID XhciUsbDevice::DisableEndpointList ( _In_ ULONG  Count,
_In_reads_(Count) UCXENDPOINT *  Endpoints 
)
private

Definition at line 480 of file slotdev.cpp.

483{
484 ULONG Index;
485
486 for (Index = 0; Index < Count; Index++)
487 XhciEndpoint::FromUcx(Endpoints[Index])->Disable();
488}
static XhciEndpoint * FromUcx(_In_ UCXENDPOINT Endpoint)
Definition: epctx.cpp:232
USHORT Count
Definition: userreq.cpp:200
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by EndpointsConfigure(), OnConfigureEndpointDone(), and SubmitSecondConfigure().

◆ Enable()

VOID XhciUsbDevice::Enable ( _In_ WDFREQUEST  Request,
_Inout_ PUSBDEVICE_ENABLE  Payload 
)

Definition at line 731 of file slotdev.cpp.

734{
736
737 if (m_Endpoints[1] == NULL)
738 {
739 DPRINT1("ENABLE for device %p before its default endpoint exists\n", this);
740 WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
741 return;
742 }
743
744 Status = m_Endpoints[1]->Enable();
745 if (!NT_SUCCESS(Status))
746 {
747 DPRINT1("Default endpoint of device %p failed to enable: 0x%lx\n", this, Status);
748 WdfRequestComplete(Request, Status);
749 return;
750 }
751
753 {
754 DPRINT1("ENABLE for device %p with the controller gone\n", this);
756 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
757 return;
758 }
759
762}
VOID SubmitEnableSlot()
Definition: slotdev.cpp:641

Referenced by XhciEvtUsbDeviceEnable().

◆ EndpointsConfigure()

VOID XhciUsbDevice::EndpointsConfigure ( _In_ WDFREQUEST  Request,
_Inout_ PENDPOINTS_CONFIGURE  Payload 
)

Definition at line 1194 of file slotdev.cpp.

1197{
1198 XhciRequestData* Data = XhciGetRequestData(Request);
1201 ULONG EnableCount = Payload->EndpointsToEnableCount;
1202 ULONG DisableCount = Payload->EndpointsToDisableCount;
1203 ULONG64 InputAddress;
1204 ULONG AddFlags;
1205 ULONG DropFlags;
1206 ULONG Index;
1208
1209 if (Data == NULL)
1210 {
1211 DPRINT1("ENDPOINTS_CONFIGURE for device %p carries no request context\n", this);
1212 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE);
1213 return;
1214 }
1215
1216 Data->EndpointsConfigure.EnableFailed = FALSE;
1217 Data->EndpointsConfigure.FirstCommandFailed = FALSE;
1218
1219 /* Nothing is disabled here: the endpoints to drop never reached the hardware */
1220 if (!m_SlotEnabled)
1221 {
1222 DPRINT1("ENDPOINTS_CONFIGURE for device %p without a slot\n", this);
1223 WdfRequestComplete(Request, EnableCount != 0 ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
1224 return;
1225 }
1226
1227 if (!m_Controller->IsAccessible())
1228 {
1229 DPRINT1("ENDPOINTS_CONFIGURE for device %p with the controller gone\n", this);
1230 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1231 WdfRequestComplete(Request, EnableCount != 0 ? STATUS_NO_SUCH_DEVICE : STATUS_SUCCESS);
1232 return;
1233 }
1234
1235 SetPending(Request, Payload, PendingKind::Configure, EnableCount == 0);
1236
1239
1240 for (Index = 0; Index < EnableCount; Index++)
1241 {
1242 Status = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index])->Enable();
1243 if (NT_SUCCESS(Status))
1244 continue;
1245
1246 DPRINT1("Endpoint %lu of %lu for device %p failed to enable: 0x%lx\n",
1247 Index, EnableCount, this, Status);
1248
1249 while (Index-- > 0)
1250 XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index])->Disable();
1251
1252 if (DisableCount == 0)
1253 {
1255 return;
1256 }
1257
1258 /* The drops still have to reach the controller */
1259 Data->EndpointsConfigure.EnableFailed = TRUE;
1260 break;
1261 }
1262
1263 AddFlags = 1;
1264 if (!Data->EndpointsConfigure.EnableFailed)
1265 {
1266 for (Index = 0; Index < EnableCount; Index++)
1267 {
1268 Endpoint = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index]);
1269 Endpoint->BuildContext(InputContext(Endpoint->Dci() + 1), m_ContextSize);
1270 AddFlags |= 1UL << Endpoint->Dci();
1271 }
1272 }
1273
1274 DropFlags = 0;
1275 for (Index = 0; Index < DisableCount; Index++)
1276 DropFlags |= 1UL << XhciEndpoint::FromUcx(Payload->EndpointsToDisable[Index])->Dci();
1277
1279 Control->AddFlags = AddFlags;
1280 Control->DropFlags = DropFlags;
1281
1282 /* QUIRK: updated before the command result is known and never rolled back */
1283 m_ContextMask = (m_ContextMask & ~DropFlags) | AddFlags;
1285
1286 InputAddress = InputContextAddress();
1287 PrepareCommand(static_cast<ULONG>(XhciTrbType::ConfigureEndpoint));
1288 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1289 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1291}
XhciCommandRing m_Commands
Definition: hc.h:95
ULONG Dci() const
Definition: epctx.cpp:257
VOID PrepareCommand(_In_ ULONG Type)
Definition: slotdev.cpp:557
ULONG64 InputContextAddress() const
Definition: slotdev.cpp:277
VOID BuildSlotContext(_Out_writes_bytes_(ContextSize) PVOID SlotContext, _In_ ULONG ContextSize) const
Definition: slotdev.cpp:1159
XhciCommand m_Command
Definition: slotdev.h:301
VOID DisableEndpointList(_In_ ULONG Count, _In_reads_(Count) UCXENDPOINT *Endpoints)
Definition: slotdev.cpp:480
ULONG ContextEntries() const
Definition: slotdev.cpp:321
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
unsigned __int64 ULONG64
Definition: imports.h:198
XHCI_TRB Trb
Definition: cmdring.h:21
ULONG ContextEntries
Definition: xhcihw.h:460
ULONG Dword[4]
Definition: xhcihw.h:17
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by XhciEvtUsbDeviceEndpointsConfigure().

◆ EndpointState()

ULONG XhciUsbDevice::EndpointState ( _In_ ULONG  Dci) const

Definition at line 307 of file slotdev.cpp.

309{
310 return ((const XHCI_ENDPOINT_CONTEXT*)OutputContext(Dci))->EndpointState;
311}
PVOID OutputContext(_In_ ULONG Dci) const
Definition: slotdev.cpp:269

Referenced by OnResetDeviceDone().

◆ FinishReconfigure()

VOID XhciUsbDevice::FinishReconfigure ( _In_ NTSTATUS  Status)
private

Definition at line 1671 of file slotdev.cpp.

1673{
1674 ReconfigureWaiter Finished = m_ReconfigureCurrent;
1675 ReconfigureWaiter Next;
1676 BOOLEAN HaveNext = FALSE;
1677 KIRQL OldIrql;
1678 ULONG Dci;
1679
1681 Finished.Done(Finished.Context, Status);
1682
1684 if (m_ReconfigureQueued != 0)
1685 {
1686 Dci = 0;
1687 while ((m_ReconfigureQueued & (1UL << Dci)) == 0)
1688 Dci++;
1689
1691 m_ReconfigureQueued &= ~(1UL << Dci);
1692 HaveNext = TRUE;
1693 }
1694 else
1695 {
1697 }
1699
1700 if (HaveNext)
1702}
unsigned char BOOLEAN
Definition: actypes.h:127
BOOLEAN m_ReconfigureBusy
Definition: slotdev.h:310
ULONG m_ReconfigureQueued
Definition: slotdev.h:311
KSPIN_LOCK m_ReconfigureLock
Definition: slotdev.h:309
ReconfigureWaiter m_ReconfigureWaiters[XHCI_MAX_DCI+1]
Definition: slotdev.h:312
VOID StartReconfigure(_In_ const ReconfigureWaiter *Waiter)
Definition: slotdev.cpp:1600
ReconfigureWaiter m_ReconfigureCurrent
Definition: slotdev.h:313
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
PACPI_METHOD_ARGUMENT Next
Definition: slotdev.cpp:96
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by StartReconfigure().

◆ ForgetSlot()

VOID XhciUsbDevice::ForgetSlot ( )
private

Definition at line 614 of file slotdev.cpp.

615{
616 if (m_SlotId != 0 && m_Controller->m_Slots.LookupSlot(m_SlotId) == this)
617 m_Controller->m_Slots.SetSlot(m_SlotId, this, 0);
618
620 m_SlotId = 0;
621}
XhciSlotTable m_Slots
Definition: hc.h:93

Referenced by OnDisableSlotDone().

◆ FromUcx()

XhciUsbDevice * XhciUsbDevice::FromUcx ( _In_ UCXUSBDEVICE  UsbDevice)
static

◆ Handle()

UCXUSBDEVICE XhciUsbDevice::Handle ( ) const

Definition at line 347 of file slotdev.cpp.

348{
349 return m_Handle;
350}

◆ HardwareDequeuePointer()

ULONG64 XhciUsbDevice::HardwareDequeuePointer ( _In_ ULONG  Dci) const

Definition at line 314 of file slotdev.cpp.

316{
317 return ((const XHCI_ENDPOINT_CONTEXT*)OutputContext(Dci))->TRDequeuePointer;
318}

◆ HubInfo()

VOID XhciUsbDevice::HubInfo ( _In_ WDFREQUEST  Request,
_In_ const USBDEVICE_HUB_INFO *  Payload 
)

Definition at line 1142 of file slotdev.cpp.

1145{
1146 /* QUIRK: accepted whether or not the device is a hub */
1147 m_NumberOfPorts = Payload->NumberOfPorts;
1148 m_NumberOfTTs = Payload->NumberOfTTs;
1149 m_TTThinkTime = Payload->TTThinkTime;
1150
1151 DPRINT("Hub %p: %lu ports, %lu TTs, think time %lu\n",
1153 WdfRequestComplete(Request, STATUS_SUCCESS);
1154}

Referenced by XhciEvtUsbDeviceHubInfo().

◆ InputContext()

PVOID XhciUsbDevice::InputContext ( _In_ ULONG  Index) const

Definition at line 261 of file slotdev.cpp.

263{
266}
PVOID VirtualAddress
Definition: dmapool.h:16
unsigned char * PUCHAR
Definition: typedefs.h:53
#define XHCI_INPUT_CONTEXT_COUNT
Definition: xhcihw.h:450

Referenced by BuildAddressContext(), EndpointsConfigure(), InputControl(), and InputSlot().

◆ InputContextAddress()

ULONG64 XhciUsbDevice::InputContextAddress ( ) const

Definition at line 277 of file slotdev.cpp.

278{
280}
PHYSICAL_ADDRESS LogicalAddress
Definition: dmapool.h:17
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by EndpointsConfigure(), SubmitAddressDevice(), SubmitSecondConfigure(), and Update().

◆ InputControl()

PXHCI_INPUT_CONTROL_CONTEXT XhciUsbDevice::InputControl ( ) const
private

Definition at line 289 of file slotdev.cpp.

290{
292}

Referenced by BuildAddressContext(), EndpointsConfigure(), SubmitSecondConfigure(), and Update().

◆ InputSlot()

PXHCI_SLOT_CONTEXT XhciUsbDevice::InputSlot ( ) const
private

Definition at line 295 of file slotdev.cpp.

296{
298}

Referenced by BuildAddressContext(), EndpointsConfigure(), SubmitSecondConfigure(), and Update().

◆ IsSlotEnabled()

BOOLEAN XhciUsbDevice::IsSlotEnabled ( ) const

Definition at line 359 of file slotdev.cpp.

360{
361 return m_SlotEnabled;
362}

◆ LostSlotStatus()

NTSTATUS XhciUsbDevice::LostSlotStatus ( ) const
private

Definition at line 551 of file slotdev.cpp.

552{
554}
BOOLEAN m_MustSucceed
Definition: slotdev.h:305

Referenced by OnAddressDeviceDone(), and OnEnableSlotDone().

◆ OnAddressDeviceDone()

VOID XhciUsbDevice::OnAddressDeviceDone ( _In_ const XhciCommand *  Command)
private

Definition at line 870 of file slotdev.cpp.

872{
873 BOOLEAN BlockSetAddress = (Command->Trb.Dword[3] & XHCI_CMD_BLOCK_SET_ADDRESS) != 0;
874
875 if (Command->Status == STATUS_NO_SUCH_DEVICE)
876 {
877 if (BlockSetAddress)
878 SetDisabled();
879 else
881 return;
882 }
883
884 if (Command->Code == XhciCompletionCode::Success)
885 {
886 if (!BlockSetAddress && m_PendingKind == PendingKind::Address)
888
889 DPRINT("Slot %lu addressed (BSR %u), USB address %u\n",
890 m_SlotId, BlockSetAddress, OutputSlot()->UsbDeviceAddress);
892 return;
893 }
894
895 DPRINT1("Address Device (BSR %u) for slot %lu failed with completion code %lu\n",
896 BlockSetAddress, m_SlotId, static_cast<ULONG>(Command->Code));
897
898 /* The slot stays enabled until the hub sends DISABLE */
899 if (!BlockSetAddress)
900 {
902 return;
903 }
904
905 if (m_MustSucceed)
906 {
908 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalAddressDefault);
909 return;
910 }
911
913}
const XHCI_SLOT_CONTEXT * OutputSlot() const
Definition: slotdev.cpp:301
NTSTATUS LostSlotStatus() const
Definition: slotdev.cpp:551
PendingKind m_PendingKind
Definition: slotdev.h:304
PVOID m_PendingPayload
Definition: slotdev.h:303
@ XhciDeviceFatalAddressDefault
Definition: slotdev.cpp:39
@ XhciDeviceCheckAddressDefault
Definition: slotdev.cpp:50
ULONG UsbDeviceAddress
Definition: xhcihw.h:472
struct _USBDEVICE_ADDRESS * PUSBDEVICE_ADDRESS
#define XHCI_CMD_BLOCK_SET_ADDRESS
Definition: xhcihw.h:572

◆ OnConfigureEndpointDone()

VOID XhciUsbDevice::OnConfigureEndpointDone ( _In_ const XhciCommand *  Command)
private

Definition at line 1324 of file slotdev.cpp.

1326{
1328 XhciRequestData* Data = XhciGetRequestData(m_PendingRequest);
1329 ULONG EnableCount = Payload->EndpointsToEnableCount;
1330 ULONG DisableCount = Payload->EndpointsToDisableCount;
1331 ULONG Parameter = Command->Completion.Dword[2] & XHCI_COMPLETION_PARAMETER_MASK;
1332 BOOLEAN EarlierFailure;
1333 BOOLEAN SlotLost;
1334
1335 EarlierFailure = Data->EndpointsConfigure.EnableFailed || Data->EndpointsConfigure.FirstCommandFailed;
1336
1337 if (Command->Status != STATUS_NO_SUCH_DEVICE && Command->Code == XhciCompletionCode::Success)
1338 {
1339 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1340 if (!EarlierFailure)
1341 RecordEnabledEndpoints(Payload);
1342
1343 Payload->ExitLatencyDelta = Parameter;
1345 return;
1346 }
1347
1348 SlotLost = (Command->Status == STATUS_NO_SUCH_DEVICE ||
1349 Command->Code == XhciCompletionCode::SlotNotEnabled);
1350
1351 if (Command->Status != STATUS_NO_SUCH_DEVICE)
1352 {
1353 DPRINT1("Configure Endpoint for slot %lu failed with completion code %lu (enable %lu, disable %lu)\n",
1354 m_SlotId, static_cast<ULONG>(Command->Code), EnableCount, DisableCount);
1355
1356 if (!SlotLost && EnableCount != 0)
1357 {
1358 switch (Command->Code)
1359 {
1360 case XhciCompletionCode::BandwidthError:
1361 case XhciCompletionCode::SecondaryBandwidthError:
1363 break;
1364 case XhciCompletionCode::ResourceError:
1366 break;
1367 case XhciCompletionCode::MaxExitLatencyTooLarge:
1369 break;
1370 default:
1371 break;
1372 }
1373 }
1374
1375 if (Command->Code == XhciCompletionCode::MaxExitLatencyTooLarge)
1376 Payload->ExitLatencyDelta = Parameter;
1377 }
1378
1379 /* Endpoints to enable that an earlier failure already disabled are not disabled again */
1380 if (SlotLost)
1381 {
1382 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1383 if (EnableCount != 0 && !EarlierFailure)
1384 DisableEndpointList(EnableCount, Payload->EndpointsToEnable);
1385
1387 return;
1388 }
1389
1390 /* QUIRK: with nothing to enable or disable this fails although UCX expects success */
1391 if (DisableCount == 0)
1392 {
1393 DisableEndpointList(EnableCount, Payload->EndpointsToEnable);
1395 return;
1396 }
1397
1398 if (EnableCount == 0 || EarlierFailure)
1399 {
1401 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalDeconfigure);
1402 return;
1403 }
1404
1405 /* The enables failed in hardware; drop the endpoints to disable on their own */
1407}
WDFREQUEST m_PendingRequest
Definition: slotdev.h:302
VOID SubmitSecondConfigure()
Definition: slotdev.cpp:1294
VOID RecordEnabledEndpoints(_In_ const ENDPOINTS_CONFIGURE *Payload)
Definition: slotdev.cpp:491
@ XhciDeviceFatalDeconfigure
Definition: slotdev.cpp:41
@ XhciDeviceCheckDeconfigure
Definition: slotdev.cpp:51
ULONG EndpointsToDisableCount
Definition: ucxendpoint.h:32
ENDPOINTS_CONFIGURE_FAILURE_FLAGS FailureFlags
Definition: ucxendpoint.h:36
ULONG EndpointsToEnableCount
Definition: ucxendpoint.h:30
struct _ENDPOINTS_CONFIGURE * PENDPOINTS_CONFIGURE
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336
#define XHCI_COMPLETION_PARAMETER_MASK
Definition: xhcihw.h:576

◆ OnDeviceNotificationEvent()

VOID XhciUsbDevice::OnDeviceNotificationEvent ( _In_ const XHCI_TRB *  Event)

Definition at line 1728 of file slotdev.cpp.

1730{
1733
1735 {
1736 DPRINT("Device notification type %lu for slot %lu ignored\n", Type, m_SlotId);
1737 return;
1738 }
1739
1741 DPRINT("Function wake from interface %lu of slot %lu\n", Interface, m_SlotId);
1742 UcxUsbDeviceRemoteWakeNotification(m_Handle, Interface);
1743}
Type
Definition: Type.h:7
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define XHCI_NOTIFICATION_DATA_MASK
Definition: xhcihw.h:581
#define XHCI_NOTIFICATION_TYPE_MASK
Definition: xhcihw.h:198
#define XHCI_NOTIFICATION_DATA_SHIFT
Definition: xhcihw.h:580
#define XHCI_NOTIFICATION_FUNCTION_WAKE
Definition: xhcihw.h:579
#define XHCI_NOTIFICATION_TYPE_SHIFT
Definition: xhcihw.h:197

Referenced by XhciSlotTable::OnDeviceNotificationEvent().

◆ OnDisableSlotDone()

VOID XhciUsbDevice::OnDisableSlotDone ( _In_ const XhciCommand *  Command)
private

Definition at line 1453 of file slotdev.cpp.

1455{
1457
1458 if (Command->Status == STATUS_NO_SUCH_DEVICE)
1459 {
1460 SetDisabled();
1461 return;
1462 }
1463
1464 if (Command->Code != XhciCompletionCode::Success)
1465 {
1466 DPRINT1("Disable Slot %lu completed with code %lu\n", m_SlotId, static_cast<ULONG>(Command->Code));
1467
1468 if (Command->Code != XhciCompletionCode::SlotNotEnabled)
1469 {
1471 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalDisableSlot);
1472 return;
1473 }
1474 }
1475
1476 /* The default endpoint keeps its table entry; a re-enable follows for RESET */
1479
1481 ForgetSlot();
1482
1484 {
1486 return;
1487 }
1488
1490}
VOID ForgetSlot()
Definition: slotdev.cpp:614
AfterDisable m_AfterDisable
Definition: slotdev.h:306
@ XhciDeviceFatalDisableSlot
Definition: slotdev.cpp:42
@ XhciDeviceCheckDisableSlot
Definition: slotdev.cpp:52

◆ OnEnableSlotDone()

VOID XhciUsbDevice::OnEnableSlotDone ( _In_ const XhciCommand *  Command)
private

Definition at line 765 of file slotdev.cpp.

767{
768 ULONG Code = static_cast<ULONG>(Command->Code);
769 ULONG SlotId = XhciTrbSlotId(&Command->Completion);
771
772 if (Command->Status == STATUS_NO_SUCH_DEVICE)
773 {
776 return;
777 }
778
779 if (Command->Code != XhciCompletionCode::Success)
780 {
781 DPRINT1("Enable Slot for device %p failed with completion code %lu\n", this, Code);
782
783 /* A RESET payload has no failure flags, only ENABLE does */
784 if (Command->Code == XhciCompletionCode::NoSlotsAvailable && m_PendingKind == PendingKind::Enable)
785 ((PUSBDEVICE_ENABLE)m_PendingPayload)->FailureFlags.InsufficientHardwareResourcesForDevice = 1;
786
788
789 if (m_MustSucceed)
790 {
791 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalEnableSlot);
792
793 /* Complete the RESET here; the device holds no slot, so no reset walk will */
795 return;
796 }
797
799 return;
800 }
801
804
806
808 if (!NT_SUCCESS(Status))
809 {
810 DPRINT1("Enable Slot gave device %p slot %lu, which is already in use (0x%lx)\n",
811 this, SlotId, Status);
813 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalSlotInUse);
814
815 /* Undo the slot state and complete the request, since nothing else would */
817 m_SlotId = 0;
820 return;
821 }
822
823 DPRINT("Device %p got slot %lu\n", this, SlotId);
824
826 if (!NT_SUCCESS(Status))
827 {
828 DPRINT1("Address Device for slot %lu not built: 0x%lx\n", SlotId, Status);
830
831 if (m_MustSucceed)
832 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalAddressDefault);
833 else
835 }
836}
ULONG SlotId() const
Definition: slotdev.cpp:335
@ XhciDeviceFatalSlotInUse
Definition: slotdev.cpp:38
@ XhciDeviceFatalEnableSlot
Definition: slotdev.cpp:40
@ XhciDeviceCheckSlotInUse
Definition: slotdev.cpp:49
struct _USBDEVICE_ENABLE * PUSBDEVICE_ENABLE
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707
#define XHCI_DEVICE_CONTEXT_COUNT
Definition: xhcihw.h:449
FORCEINLINE ULONG NTAPI XhciTrbSlotId(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:51

◆ OnEvaluateContextDone()

VOID XhciUsbDevice::OnEvaluateContextDone ( _In_ const XhciCommand *  Command)
private

Definition at line 1108 of file slotdev.cpp.

1110{
1113
1114 if (Command->Status == STATUS_NO_SUCH_DEVICE)
1115 {
1117 }
1118 else if (Command->Code == XhciCompletionCode::Success)
1119 {
1120 /* The work item completes the request */
1121 if (WantsTunnelStateDsm(Payload) && QueueTunnelStateDsm(Payload))
1122 return;
1123
1124 ApplyUpdate(Payload);
1126 }
1127 else
1128 {
1129 DPRINT1("Max Exit Latency %lu for slot %lu rejected with completion code %lu\n",
1130 Payload->MaxExitLatency, m_SlotId, static_cast<ULONG>(Command->Code));
1131
1132 if (Command->Code == XhciCompletionCode::MaxExitLatencyTooLarge)
1134
1136 }
1137
1139}
BOOLEAN QueueTunnelStateDsm(_Inout_ PUSBDEVICE_UPDATE Payload)
Definition: slotdev.cpp:963
BOOLEAN WantsTunnelStateDsm(_In_ const USBDEVICE_UPDATE *Payload) const
Definition: slotdev.cpp:955
VOID ApplyUpdate(_Inout_ PUSBDEVICE_UPDATE Payload)
Definition: slotdev.cpp:918
USBDEVICE_UPDATE_FAILURE_FLAGS FailureFlags
Definition: ucxusbdevice.h:126
struct _USBDEVICE_UPDATE * PUSBDEVICE_UPDATE

◆ OnHostLost()

VOID XhciUsbDevice::OnHostLost ( )

Definition at line 1773 of file slotdev.cpp.

1774{
1775 WDFREQUEST Request;
1776 ULONG Dci;
1777
1778 for (Dci = 1; Dci <= XHCI_MAX_DCI; Dci++)
1779 {
1780 if (m_Endpoints[Dci] != NULL)
1782 }
1783
1784 Request = TakePending();
1785 if (Request != NULL)
1787}
VOID ControllerRemoved()
Definition: epctx.cpp:1270
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559

Referenced by XhciSlotTable::OnHostLost().

◆ OnResetDeviceDone()

VOID XhciUsbDevice::OnResetDeviceDone ( _In_ const XhciCommand *  Command)
private

Definition at line 1541 of file slotdev.cpp.

1543{
1544 if (Command->Status != STATUS_NO_SUCH_DEVICE)
1545 {
1546 if (Command->Code != XhciCompletionCode::Success)
1547 {
1548 DPRINT1("Reset Device for slot %lu failed with completion code %lu\n",
1549 m_SlotId, static_cast<ULONG>(Command->Code));
1551 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalResetDevice);
1552 return;
1553 }
1554
1556 DPRINT1("Reset Device for slot %lu left the default endpoint disabled\n", m_SlotId);
1557 }
1558
1559 /* The table keeps the endpoints; the hub configures them again */
1563}
ULONG EndpointState(_In_ ULONG Dci) const
Definition: slotdev.cpp:307
@ XhciDeviceFatalResetDevice
Definition: slotdev.cpp:43
@ XhciDeviceCheckResetDevice
Definition: slotdev.cpp:53
#define XHCI_ENDPOINT_STATE_DISABLED
Definition: xhcihw.h:533

◆ OnTransferEvent()

VOID XhciUsbDevice::OnTransferEvent ( _In_ const XHCI_TRB *  Event)

Definition at line 1707 of file slotdev.cpp.

1709{
1711 XhciEndpoint* Endpoint = EndpointAt(Dci);
1712
1713 if (Endpoint != NULL)
1714 {
1715 Endpoint->OnTransferEvent(Event);
1716 return;
1717 }
1718
1719 /* QUIRK: isochronous leftovers after a deconfigure are dropped without a word */
1721 {
1722 DPRINT1("Transfer event for slot %lu DCI %lu code %lu has no endpoint, dropped\n",
1724 }
1725}
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
#define XHCI_TRB_ENDPOINT_MASK
Definition: xhcihw.h:27
#define XHCI_TRB_ENDPOINT_SHIFT
Definition: xhcihw.h:26
#define XHCI_EVENT_DATA_TYPE_MASK
Definition: xhcihw.h:324
FORCEINLINE ULONG NTAPI XhciTrbCompletionCode(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:42

◆ OutputContext()

◆ OutputSlot()

const XHCI_SLOT_CONTEXT * XhciUsbDevice::OutputSlot ( ) const
private

Definition at line 301 of file slotdev.cpp.

302{
303 return (const XHCI_SLOT_CONTEXT*)OutputContext(0);
304}

Referenced by OnAddressDeviceDone(), and Reset().

◆ PortPath()

const USB_DEVICE_PORT_PATH * XhciUsbDevice::PortPath ( ) const

Definition at line 371 of file slotdev.cpp.

372{
373 return &m_Info.PortPath;
374}

Referenced by XhciEndpoint::BuildContext().

◆ PrepareCommand()

VOID XhciUsbDevice::PrepareCommand ( _In_ ULONG  Type)
private

Definition at line 557 of file slotdev.cpp.

559{
563 m_Command.Context = this;
564}
static VOID NTAPI CommandDone(_In_ XhciCommand *Command)
Definition: slotdev.cpp:568
PFN_XHCI_COMMAND_DONE Done
Definition: cmdring.h:22
PVOID Context
Definition: cmdring.h:23
#define XHCI_TRB_TYPE_SHIFT
Definition: xhcihw.h:23
#define XHCI_TRB_SLOT_SHIFT
Definition: xhcihw.h:25

Referenced by EndpointsConfigure(), SubmitAddressDevice(), SubmitDisableSlot(), SubmitEnableSlot(), SubmitSecondConfigure(), and Update().

◆ QueueTunnelStateDsm()

BOOLEAN XhciUsbDevice::QueueTunnelStateDsm ( _Inout_ PUSBDEVICE_UPDATE  Payload)
private

FALSE when the work item could not be created; the caller then completes the request itself.

Definition at line 963 of file slotdev.cpp.

965{
969 WDFWORKITEM Item;
971
973
974 /* QUIRK: the controller device has no synchronization scope, so this serializes nothing */
975 Config.AutomaticSerialization = TRUE;
976
978 Attributes.ParentObject = m_Controller->m_Device;
979
980 Status = WdfWorkItemCreate(&Config, &Attributes, &Item);
981 if (!NT_SUCCESS(Status))
982 {
983 DPRINT1("No tunnel state work item for root port %lu, 0x%lx\n", m_Info.PortPath.PortPath[0], Status);
984
985 /* QUIRK: the native link flag keeps the hub's value */
987 return FALSE;
988 }
989
990 /* Keeps this context alive even if a removal completes the request first */
992
993 Work = XhciGetTunnelDsmWork(Item);
994 Work->Device = this;
995 Work->Payload = Payload;
997 return TRUE;
998}
WDFDEVICE m_Device
Definition: hc.h:85
static EVT_WDF_WORKITEM TunnelDsmWorker
Definition: slotdev.h:239
_In_ ULONG Attributes
Definition: dispmprt.h:1077
WdfWorkItemEnqueue(WorkItem)
PUSBDEVICE_UPDATE Payload
Definition: slotdev.cpp:30
XhciUsbDevice * Device
Definition: slotdev.cpp:29
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85

Referenced by OnEvaluateContextDone(), and Update().

◆ ReconfigureCommandDone()

VOID NTAPI XhciUsbDevice::ReconfigureCommandDone ( _In_ XhciCommand *  Command)
staticprivate

Definition at line 1653 of file slotdev.cpp.

1655{
1656 XhciUsbDevice* Device = static_cast<XhciUsbDevice*>(Command->Context);
1658
1660 {
1661 DPRINT1("Reconfigure of DCI %lu on slot %lu failed: status 0x%lx, code %lu\n",
1662 Device->m_ReconfigureCurrent.Endpoint->Dci(), Device->m_SlotId,
1663 Command->Status, static_cast<ULONG>(Command->Code));
1665 }
1666
1667 Device->FinishReconfigure(Status);
1668}
static BOOLEAN NTAPI XhciCommandSucceeded(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:168

Referenced by StartReconfigure().

◆ RecordEnabledEndpoints()

VOID XhciUsbDevice::RecordEnabledEndpoints ( _In_ const ENDPOINTS_CONFIGURE *  Payload)
private

Definition at line 491 of file slotdev.cpp.

493{
496 ULONG Index;
497 ULONG Dci;
498
499 for (Index = 0; Index < Payload->EndpointsToEnableCount; Index++)
500 {
501 Endpoint = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index]);
502 Dci = Endpoint->Dci();
503
504 Previous = m_Endpoints[Dci];
505 if (Previous != NULL && Previous != Endpoint)
506 {
507 DPRINT("DCI %lu of device %p moves from endpoint %p to %p\n", Dci, this, Previous, Endpoint);
508 Previous->Disable(TRUE);
509 m_Endpoints[Dci] = NULL;
510 }
511
512 m_Endpoints[Dci] = Endpoint;
513 }
514}
Previous

Referenced by OnConfigureEndpointDone().

◆ Reset()

VOID XhciUsbDevice::Reset ( _In_ WDFREQUEST  Request)

Definition at line 1493 of file slotdev.cpp.

1495{
1496 ULONG Type;
1497
1498 if (!m_SlotEnabled)
1499 {
1500 WdfRequestComplete(Request, STATUS_SUCCESS);
1501 return;
1502 }
1503
1504 /* Enabled or Default: nothing to reset */
1505 if (OutputSlot()->SlotState <= XHCI_SLOT_STATE_DEFAULT)
1506 {
1507 WdfRequestComplete(Request, STATUS_SUCCESS);
1508 return;
1509 }
1510
1511 if (!m_Controller->IsAccessible())
1512 {
1513 DPRINT("RESET for device %p with the controller gone\n", this);
1516 WdfRequestComplete(Request, STATUS_SUCCESS);
1517 return;
1518 }
1519
1521
1522 if (m_Controller->HasErrata(XhciErrata::EpResetViaSlotCycle))
1523 {
1524 Type = static_cast<ULONG>(XhciTrbType::DisableSlot);
1526 }
1527 else
1528 {
1529 Type = static_cast<ULONG>(XhciTrbType::ResetDevice);
1530 }
1531
1532 /* QUIRK: the block is not cleared, so the reserved TRB fields keep the last command's bits */
1536 m_Command.Context = this;
1538}
#define XHCI_SLOT_STATE_DEFAULT
Definition: xhcihw.h:491
#define XHCI_TRB_TYPE_MASK
Definition: xhcihw.h:24

Referenced by XhciEvtUsbDeviceReset().

◆ SetPending()

VOID XhciUsbDevice::SetPending ( _In_ WDFREQUEST  Request,
_In_ PVOID  Payload,
_In_ PendingKind  Kind,
_In_ BOOLEAN  MustSucceed 
)
private

Definition at line 519 of file slotdev.cpp.

524{
525 /* UCX and the hub send one device management request at a time */
527
528 m_PendingPayload = Payload;
529 m_PendingKind = Kind;
530 m_MustSucceed = MustSucceed;
532}

Referenced by Address(), Disable(), Enable(), EndpointsConfigure(), Reset(), and Update().

◆ SlotId()

◆ Speed()

USB_DEVICE_SPEED XhciUsbDevice::Speed ( ) const

◆ StartReconfigure()

VOID XhciUsbDevice::StartReconfigure ( _In_ const ReconfigureWaiter *  Waiter)
private

Definition at line 1600 of file slotdev.cpp.

1602{
1606 PUCHAR Base;
1607 ULONG64 InputAddress;
1608 ULONG Dci;
1609
1610 m_ReconfigureCurrent = *Waiter;
1612 Dci = Endpoint->Dci();
1613
1614 if (m_ReconfigureInput == NULL)
1615 {
1617 if (m_ReconfigureInput == NULL)
1618 {
1619 DPRINT1("No input context to reconfigure DCI %lu of slot %lu\n", Dci, m_SlotId);
1621 return;
1622 }
1623 }
1624
1627
1630
1632 Endpoint->BuildContext(Base + (Dci + 1) * m_ContextSize, m_ContextSize);
1633 Slot->ContextEntries = ContextEntries();
1634
1635 /* Drop and add of the same DCI reconfigures it in place (xHCI 4.6.6) */
1636 Control->AddFlags = 1 | (1UL << Dci);
1637 Control->DropFlags = 1UL << Dci;
1638
1641 m_ReconfigureCommand.Trb.Dword[0] = (ULONG)InputAddress;
1642 m_ReconfigureCommand.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1644 (static_cast<ULONG>(XhciTrbType::ConfigureEndpoint) << XHCI_TRB_TYPE_SHIFT) |
1649}
static VOID NTAPI ReconfigureCommandDone(_In_ XhciCommand *Command)
Definition: slotdev.cpp:1653
VOID FinishReconfigure(_In_ NTSTATUS Status)
Definition: slotdev.cpp:1671
XhciCommand m_ReconfigureCommand
Definition: slotdev.h:314
Walk Base
Definition: desccheck.cpp:2270
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _XHCI_INPUT_CONTROL_CONTEXT * PXHCI_INPUT_CONTROL_CONTEXT

Referenced by FinishReconfigure().

◆ SubmitAddressDevice()

NTSTATUS XhciUsbDevice::SubmitAddressDevice ( _In_ BOOLEAN  BlockSetAddress)
private

Definition at line 710 of file slotdev.cpp.

712{
713 ULONG64 InputAddress = InputContextAddress();
715
717 if (!NT_SUCCESS(Status))
718 return Status;
719
720 PrepareCommand(static_cast<ULONG>(XhciTrbType::AddressDevice));
721 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
722 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
723 if (BlockSetAddress)
725
727 return STATUS_SUCCESS;
728}
NTSTATUS BuildAddressContext()
Definition: slotdev.cpp:651

Referenced by Address(), and OnEnableSlotDone().

◆ SubmitDisableSlot()

VOID XhciUsbDevice::SubmitDisableSlot ( _In_ AfterDisable  Next)
private

Definition at line 1412 of file slotdev.cpp.

1414{
1416 PrepareCommand(static_cast<ULONG>(XhciTrbType::DisableSlot));
1418}

Referenced by Disable(), OnAddressDeviceDone(), and OnEnableSlotDone().

◆ SubmitEnableSlot()

VOID XhciUsbDevice::SubmitEnableSlot ( )
private

Definition at line 641 of file slotdev.cpp.

642{
643 ASSERT(m_SlotId == 0);
644
645 /* QUIRK: Slot Type is always 0 */
646 PrepareCommand(static_cast<ULONG>(XhciTrbType::EnableSlot));
648}

Referenced by Enable(), and OnDisableSlotDone().

◆ SubmitSecondConfigure()

VOID XhciUsbDevice::SubmitSecondConfigure ( )
private

Definition at line 1294 of file slotdev.cpp.

1295{
1297 XhciRequestData* Data = XhciGetRequestData(m_PendingRequest);
1298 ULONG64 InputAddress;
1299 ULONG DropFlags;
1300 ULONG Index;
1301
1302 Data->EndpointsConfigure.FirstCommandFailed = TRUE;
1303 DisableEndpointList(Payload->EndpointsToEnableCount, Payload->EndpointsToEnable);
1304
1305 /* QUIRK: Context Entries stays 0 in this one */
1308
1309 DropFlags = 0;
1310 for (Index = 0; Index < Payload->EndpointsToDisableCount; Index++)
1311 DropFlags |= 1UL << XhciEndpoint::FromUcx(Payload->EndpointsToDisable[Index])->Dci();
1312
1313 InputControl()->AddFlags = 1;
1314 InputControl()->DropFlags = DropFlags;
1315
1316 InputAddress = InputContextAddress();
1317 PrepareCommand(static_cast<ULONG>(XhciTrbType::ConfigureEndpoint));
1318 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1319 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1321}

Referenced by OnConfigureEndpointDone().

◆ TakePending()

WDFREQUEST XhciUsbDevice::TakePending ( )
private

Definition at line 535 of file slotdev.cpp.

536{
538}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45

Referenced by CompletePending(), OnHostLost(), and Update().

◆ TtHub()

XhciUsbDevice * XhciUsbDevice::TtHub ( ) const
private

Definition at line 383 of file slotdev.cpp.

384{
385 if (m_Info.TtHub == NULL)
386 return NULL;
387
388 return FromUcx(m_Info.TtHub);
389}
static XhciUsbDevice * FromUcx(_In_ UCXUSBDEVICE UsbDevice)
Definition: slotdev.cpp:178
UCXUSBDEVICE TtHub
Definition: ucxusbdevice.h:177

Referenced by BuildAddressContext(), and BuildSlotContext().

◆ Update()

VOID XhciUsbDevice::Update ( _In_ WDFREQUEST  Request,
_Inout_ PUSBDEVICE_UPDATE  Payload 
)

Definition at line 1059 of file slotdev.cpp.

1062{
1064 ULONG64 InputAddress;
1065
1066 if (!Payload->Flags.UpdateMaxExitLatency)
1067 {
1068 if (WantsTunnelStateDsm(Payload))
1069 {
1070 /* Record the request first so the work item has one to complete */
1072 if (QueueTunnelStateDsm(Payload))
1073 return;
1074
1075 TakePending();
1076 }
1077
1078 ApplyUpdate(Payload);
1079 WdfRequestComplete(Request, STATUS_SUCCESS);
1080 return;
1081 }
1082
1083 /* Evaluate Context with only the slot flagged (xHCI 4.6.7) */
1085 InputControl()->AddFlags = 1;
1086 Slot = InputSlot();
1087 Slot->MaxExitLatency = Payload->MaxExitLatency & 0xFFFF;
1088 Slot->InterrupterTarget = 0;
1089
1090 /* QUIRK: a device without a slot sends this with Slot ID 0 */
1091 InputAddress = InputContextAddress();
1092 PrepareCommand(static_cast<ULONG>(XhciTrbType::EvaluateContext));
1093 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1094 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1095
1096 if (!m_Controller->IsAccessible())
1097 {
1098 DPRINT1("UPDATE for device %p with the controller gone\n", this);
1099 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
1100 return;
1101 }
1102
1105}

Referenced by XhciEvtUsbDeviceUpdate().

◆ VOID()

_In_ XhciUsbDevice::VOID ( NTAPI *  Done)

◆ WantsTunnelStateDsm()

BOOLEAN XhciUsbDevice::WantsTunnelStateDsm ( _In_ const USBDEVICE_UPDATE *  Payload) const
private

Definition at line 955 of file slotdev.cpp.

957{
958 return Payload->Flags.UpdateTunnelState && m_Controller->HasErrata(XhciErrata::Usb4TunnelFromAcpiDsm);
959}

Referenced by OnEvaluateContextDone(), and Update().

◆ ZeroInputContext()

VOID XhciUsbDevice::ZeroInputContext ( )

Member Data Documentation

◆ Context

_In_ _In_ NTSTATUS _In_ PVOID XhciUsbDevice::Context

Definition at line 78 of file slotdev.h.

◆ Info

_In_ UCXUSBDEVICE _In_ const UCXUSBDEVICE_INFO* XhciUsbDevice::Info

Definition at line 118 of file slotdev.h.

◆ m_AfterDisable

AfterDisable XhciUsbDevice::m_AfterDisable
private

Definition at line 306 of file slotdev.h.

Referenced by OnDisableSlotDone(), Reset(), and SubmitDisableSlot().

◆ m_Command

◆ m_ContextMask

ULONG XhciUsbDevice::m_ContextMask
private

Bit n set when DCI n is configured as far as this driver knows; bit 0 is the slot.

Definition at line 295 of file slotdev.h.

Referenced by BuildAddressContext(), ContextEntries(), EndpointsConfigure(), OnResetDeviceDone(), and Reset().

◆ m_ContextSize

◆ m_Controller

◆ m_DeviceDescriptor

USB_DEVICE_DESCRIPTOR XhciUsbDevice::m_DeviceDescriptor
private

Definition at line 284 of file slotdev.h.

Referenced by ApplyUpdate(), and DeviceDescriptor().

◆ m_EndpointCount

volatile LONG XhciUsbDevice::m_EndpointCount
private

Definition at line 298 of file slotdev.h.

◆ m_Endpoints

◆ m_Handle

UCXUSBDEVICE XhciUsbDevice::m_Handle
private

◆ m_Info

◆ m_Input

XhciDmaBuffer* XhciUsbDevice::m_Input
private

◆ m_IsHub

BOOLEAN XhciUsbDevice::m_IsHub
private

Definition at line 287 of file slotdev.h.

Referenced by ApplyUpdate(), and BuildSlotContext().

◆ m_LpmEnabled

BOOLEAN XhciUsbDevice::m_LpmEnabled
private

Definition at line 291 of file slotdev.h.

Referenced by ApplyUpdate(), and Disable().

◆ m_MustSucceed

BOOLEAN XhciUsbDevice::m_MustSucceed
private

◆ m_NumberOfPorts

ULONG XhciUsbDevice::m_NumberOfPorts
private

Definition at line 288 of file slotdev.h.

Referenced by BuildSlotContext(), and HubInfo().

◆ m_NumberOfTTs

ULONG XhciUsbDevice::m_NumberOfTTs
private

Definition at line 289 of file slotdev.h.

Referenced by BuildSlotContext(), and HubInfo().

◆ m_Output

XhciDmaBuffer* XhciUsbDevice::m_Output
private

Definition at line 281 of file slotdev.h.

Referenced by _IRQL_requires_(), Cleanup(), OnEnableSlotDone(), and OutputContext().

◆ m_PendingKind

PendingKind XhciUsbDevice::m_PendingKind
private

Definition at line 304 of file slotdev.h.

Referenced by OnAddressDeviceDone(), OnEnableSlotDone(), and SetPending().

◆ m_PendingPayload

PVOID XhciUsbDevice::m_PendingPayload
private

◆ m_PendingRequest

WDFREQUEST XhciUsbDevice::m_PendingRequest
private

Definition at line 302 of file slotdev.h.

Referenced by OnConfigureEndpointDone(), SetPending(), SubmitSecondConfigure(), and TakePending().

◆ m_ReconfigureBusy

BOOLEAN XhciUsbDevice::m_ReconfigureBusy
private

Definition at line 310 of file slotdev.h.

Referenced by FinishReconfigure().

◆ m_ReconfigureCommand

XhciCommand XhciUsbDevice::m_ReconfigureCommand
private

Definition at line 314 of file slotdev.h.

Referenced by StartReconfigure().

◆ m_ReconfigureCurrent

ReconfigureWaiter XhciUsbDevice::m_ReconfigureCurrent
private

Definition at line 313 of file slotdev.h.

Referenced by FinishReconfigure(), and StartReconfigure().

◆ m_ReconfigureInput

XhciDmaBuffer* XhciUsbDevice::m_ReconfigureInput
private

Definition at line 315 of file slotdev.h.

Referenced by Cleanup(), and StartReconfigure().

◆ m_ReconfigureLock

KSPIN_LOCK XhciUsbDevice::m_ReconfigureLock
private

Definition at line 309 of file slotdev.h.

Referenced by _IRQL_requires_(), and FinishReconfigure().

◆ m_ReconfigureQueued

ULONG XhciUsbDevice::m_ReconfigureQueued
private

Definition at line 311 of file slotdev.h.

Referenced by FinishReconfigure().

◆ m_ReconfigureWaiters

ReconfigureWaiter XhciUsbDevice::m_ReconfigureWaiters[XHCI_MAX_DCI+1]
private

Definition at line 312 of file slotdev.h.

Referenced by FinishReconfigure().

◆ m_ResumeTimeSet

BOOLEAN XhciUsbDevice::m_ResumeTimeSet
private

Definition at line 292 of file slotdev.h.

Referenced by ApplyUpdate(), and Disable().

◆ m_SlotEnabled

BOOLEAN XhciUsbDevice::m_SlotEnabled
private

◆ m_SlotId

◆ m_TTThinkTime

ULONG XhciUsbDevice::m_TTThinkTime
private

Definition at line 290 of file slotdev.h.

Referenced by BuildSlotContext(), and HubInfo().

◆ Status

◆ StreamId

_In_ ULONG XhciUsbDevice::StreamId

Definition at line 51 of file slotdev.h.

Referenced by _IRQL_requires_max_().

◆ TunnelDsmWorker

VOID NTAPI XhciUsbDevice::TunnelDsmWorker
staticprivate

Definition at line 239 of file slotdev.h.

Referenced by QueueTunnelStateDsm().

◆ UsbDevice

_In_ UCXUSBDEVICE XhciUsbDevice::UsbDevice

Definition at line 117 of file slotdev.h.

Referenced by _IRQL_requires_().


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