ReactOS 0.4.17-dev-1281-g065abb3
XhciCommandRing Class Reference

#include <cmdring.h>

Collaboration diagram for XhciCommandRing:

Public Member Functions

NTSTATUS Create (_In_ XhciController *Controller)
 
NTSTATUS Prepare ()
 
VOID Release ()
 
NTSTATUS D0Entry ()
 
VOID PostInterruptsEntry ()
 
VOID PreReset ()
 
VOID PostReset ()
 
VOID PostResetSuccess ()
 
VOID FailAll ()
 
VOID OnHostLost ()
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) VOID Submit(_Inout_ XhciCommand *Command)
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS SubmitAndWait(_Inout_ XhciCommand *Command)
 
VOID OnCompletionEvent (_In_ const XHCI_TRB *Event)
 

Static Public Attributes

static EVT_WDF_TIMER EvtTimer
 

Private Types

enum class  RingState : ULONG { Uninitialized , Prepared , Released }
 
enum class  ResetPhase : ULONG {
  Idle , Requested , Resetting , AfterReset ,
  Failed
}
 

Private Member Functions

VOID InitializeRing ()
 
VOID OnTimer ()
 
VOID PlaceLocked (_Inout_ XhciCommand *Command, _In_ BOOLEAN FrontOfLine, _Inout_ PLIST_ENTRY Finished)
 
VOID PutOnRingLocked (_Inout_ XhciCommand *Command)
 
VOID RestartStoppedRingLocked (_Inout_ PLIST_ENTRY Finished)
 
VOID HandleRingStopped (_In_ const XHCI_TRB *Event)
 
VOID DrainAllLocked (_Inout_ PLIST_ENTRY Finished)
 
VOID FailEverything ()
 
ULONG64 TrbAddress (_In_ ULONG Index) const
 

Private Attributes

XhciController * m_Controller
 
WDFTIMER m_Timer
 
KSPIN_LOCK m_Lock
 
RingState m_State
 
ResetPhase m_Reset
 
XhciDmaBuffer * m_Segment
 
PXHCI_TRB m_Trbs
 
ULONG64 m_RingAddress
 
ULONG64 m_LinkAddress
 
ULONG m_Enqueue
 
ULONG m_Dequeue
 
ULONG m_Cycle
 
LIST_ENTRY m_Pending
 
LIST_ENTRY m_Waiting
 
BOOLEAN m_OutOfOrderSeen
 
BOOLEAN m_Aborting
 
LONG m_AbortTicks
 
BOOLEAN m_DrainFromTimer
 

Detailed Description

The command ring.

Definition at line 42 of file cmdring.h.

Member Enumeration Documentation

◆ ResetPhase

Enumerator
Idle 
Requested 
Resetting 
AfterReset 
Failed 

Definition at line 86 of file cmdring.h.

◆ RingState

Enumerator
Uninitialized 
Prepared 
Released 

Definition at line 79 of file cmdring.h.

Member Function Documentation

◆ _IRQL_requires_()

XhciCommandRing::_IRQL_requires_ ( PASSIVE_LEVEL  )

PASSIVE_LEVEL helper: submits and waits for Done.

◆ _IRQL_requires_max_()

XhciCommandRing::_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Queues Command; Done always runs exactly once, possibly before this returns.

◆ Create()

NTSTATUS XhciCommandRing::Create ( _In_ XhciController *  Controller)

Definition at line 95 of file cmdring.cpp.

97{
101
102 PAGED_CODE();
103
105 m_Timer = NULL;
109 m_Segment = NULL;
110 m_Trbs = NULL;
111 m_RingAddress = 0;
112 m_LinkAddress = 0;
113 m_Enqueue = 0;
114 m_Dequeue = 0;
120 m_AbortTicks = 0;
122
124 Config.TolerableDelay = XhciCmdTickSlackMs;
125 Config.AutomaticSerialization = FALSE;
126
128 Attributes.ParentObject = Controller->m_Device;
129 Attributes.ExecutionLevel = WdfExecutionLevelDispatch;
130
131 Status = WdfTimerCreate(&Config, &Attributes, &m_Timer);
132 if (!NT_SUCCESS(Status))
133 {
134 DPRINT1("Command timer creation failed 0x%lx\n", Status);
135 m_Timer = NULL;
136 return Status;
137 }
138
139 XhciGetCommandTimerContext(m_Timer)->Ring = this;
140 return STATUS_SUCCESS;
141}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY m_Waiting
Definition: cmdring.h:143
static EVT_WDF_TIMER EvtTimer
Definition: cmdring.h:76
BOOLEAN m_OutOfOrderSeen
Definition: cmdring.h:144
LONG m_AbortTicks
Definition: cmdring.h:146
ResetPhase m_Reset
Definition: cmdring.h:134
XhciDmaBuffer * m_Segment
Definition: cmdring.h:135
ULONG64 m_RingAddress
Definition: cmdring.h:137
WDFTIMER m_Timer
Definition: cmdring.h:131
RingState m_State
Definition: cmdring.h:133
ULONG64 m_LinkAddress
Definition: cmdring.h:138
XhciController * m_Controller
Definition: cmdring.h:130
BOOLEAN m_Aborting
Definition: cmdring.h:145
LIST_ENTRY m_Pending
Definition: cmdring.h:142
KSPIN_LOCK m_Lock
Definition: cmdring.h:132
BOOLEAN m_DrainFromTimer
Definition: cmdring.h:147
ULONG m_Dequeue
Definition: cmdring.h:140
ULONG m_Enqueue
Definition: cmdring.h:139
PXHCI_TRB m_Trbs
Definition: cmdring.h:136
ULONG m_Cycle
Definition: cmdring.h:141
static const ULONG XhciCmdTickSlackMs
Definition: cmdring.cpp:22
static const ULONG XhciCmdTickMs
Definition: cmdring.cpp:21
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:24
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
#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
#define XHCI_TRB_CYCLE
Definition: xhcihw.h:22

Referenced by XhciController::Initialize().

◆ D0Entry()

NTSTATUS XhciCommandRing::D0Entry ( )

Definition at line 247 of file cmdring.cpp.

248{
250 return STATUS_SUCCESS;
251}
VOID InitializeRing()
Definition: cmdring.cpp:214

Referenced by XhciController::RunD0Pass().

◆ DrainAllLocked()

VOID XhciCommandRing::DrainAllLocked ( _Inout_ PLIST_ENTRY  Finished)
private

Definition at line 350 of file cmdring.cpp.

352{
354
355 /* QUIRK: Code keeps whatever it last held, so handlers must check Status first */
356 while (!IsListEmpty(&m_Pending))
357 {
360 InsertTailList(Finished, &Command->Link);
361 }
362
363 while (!IsListEmpty(&m_Waiting))
364 {
367 InsertTailList(Finished, &Command->Link);
368 }
369}
static XhciCommand *NTAPI XhciCmdFromLink(_In_ PLIST_ENTRY Entry)
Definition: cmdring.cpp:57
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
Definition: shell.h:41
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136

Referenced by FailEverything(), OnTimer(), PostReset(), and Release().

◆ FailAll()

VOID XhciCommandRing::FailAll ( )

Definition at line 807 of file cmdring.cpp.

808{
810}
VOID FailEverything()
Definition: cmdring.cpp:787

Referenced by XhciController::InternalReset().

◆ FailEverything()

VOID XhciCommandRing::FailEverything ( )
private

Definition at line 787 of file cmdring.cpp.

788{
789 LIST_ENTRY Finished;
791
792 InitializeListHead(&Finished);
793
798 DrainAllLocked(&Finished);
799 if (m_Timer)
800 WdfTimerStop(m_Timer, FALSE);
802
803 XhciCmdCompleteList(&Finished);
804}
VOID DrainAllLocked(_Inout_ PLIST_ENTRY Finished)
Definition: cmdring.cpp:350
static VOID NTAPI XhciCmdCompleteList(_Inout_ PLIST_ENTRY Finished)
Definition: cmdring.cpp:67
#define TRUE
Definition: types.h:120
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
Definition: typedefs.h:120
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by FailAll(), and OnHostLost().

◆ HandleRingStopped()

VOID XhciCommandRing::HandleRingStopped ( _In_ const XHCI_TRB *  Event)
private

Definition at line 571 of file cmdring.cpp.

573{
574 LIST_ENTRY Finished;
575 ULONG64 Reported;
578
579 InitializeListHead(&Finished);
580 Reported = XhciTrbPointer(Event) & ~0xFULL;
581
583
586
587 if (Reported != Expected && !(Reported == m_LinkAddress && m_Dequeue == 0))
588 {
589 DPRINT1("Command ring stopped at 0x%I64x, expected 0x%I64x; asking for a reset\n",
590 Reported, Expected);
593
594 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciCmdReasonDequeueMismatch);
595 return;
596 }
597
598 RestartStoppedRingLocked(&Finished);
599
601
602 XhciCmdCompleteList(&Finished);
603}
BOOLEAN Expected
ULONG64 TrbAddress(_In_ ULONG Index) const
Definition: cmdring.h:124
VOID RestartStoppedRingLocked(_Inout_ PLIST_ENTRY Finished)
Definition: cmdring.cpp:515
static const ULONG XhciCmdReasonDequeueMismatch
Definition: cmdring.cpp:27
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
unsigned __int64 ULONG64
Definition: imports.h:198
FORCEINLINE ULONG64 NTAPI XhciTrbPointer(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:60

Referenced by OnCompletionEvent().

◆ InitializeRing()

VOID XhciCommandRing::InitializeRing ( )
private

Definition at line 214 of file cmdring.cpp.

215{
218
220 return;
221
223
226
227 m_Enqueue = 0;
228 m_Dequeue = 0;
231
232 /* The Link TRB starts with cycle 0, so the xHC does not follow it until we wrap */
234 Link->Dword[0] = static_cast<ULONG>(m_RingAddress);
235 Link->Dword[1] = static_cast<ULONG>(m_RingAddress >> 32);
236 Link->Dword[2] = 0;
237 Link->Dword[3] = (static_cast<ULONG>(XhciTrbType::Link) << XHCI_TRB_TYPE_SHIFT) |
239
242
244}
BOOLEAN IsAccessible() const
Definition: hc.cpp:193
XhciRegisters m_Registers
Definition: hc.h:91
VOID WriteOperational64(_In_ ULONG Offset, _In_ ULONG64 Value)
Definition: mmio.cpp:460
static const ULONG XhciCmdUsable
Definition: cmdring.cpp:15
static const ULONG XhciCmdTrbCount
Definition: cmdring.cpp:14
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE VOID KeMemoryBarrier(VOID)
Definition: ke.h:58
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define XHCI_TRB_TYPE_SHIFT
Definition: xhcihw.h:23
#define XHCI_LINK_TOGGLE_CYCLE
Definition: xhcihw.h:184
#define XHCI_OP_CRCR
Definition: xhcihw.h:385

Referenced by D0Entry(), and PostReset().

◆ OnCompletionEvent()

VOID XhciCommandRing::OnCompletionEvent ( _In_ const XHCI_TRB *  Event)

Definition at line 438 of file cmdring.cpp.

440{
441 LIST_ENTRY Finished;
445 ULONG64 Pointer;
446 BOOLEAN Retired;
447 BOOLEAN OutOfOrder;
449
451 if (Code == XhciCompletionCode::CommandRingStopped)
452 {
454 return;
455 }
456
457 InitializeListHead(&Finished);
458 Pointer = XhciTrbPointer(Event) & ~0xFULL;
459 Retired = FALSE;
460 OutOfOrder = FALSE;
461
463
465 {
467 if (!Command->Matched && TrbAddress(Command->RingIndex) == Pointer)
468 {
469 Command->Matched = TRUE;
470 Command->Code = Code;
471 Command->Completion = *Event;
472 break;
473 }
474 }
475
476 /* Retire in ring order so the dequeue index stays in step with the xHC */
477 while (!IsListEmpty(&m_Pending))
478 {
480 if (!Command->Matched)
481 break;
482
484 ASSERT(Command->RingIndex == m_Dequeue);
486 Command->Status = XhciCmdStatusFromCode(Command->Code);
487 InsertTailList(&Finished, &Command->Link);
488 Retired = TRUE;
489
490 if (!IsListEmpty(&m_Waiting))
492 }
493
494 /* QUIRK: an event that matches nothing counts as out of order too */
495 if (!Retired && !m_OutOfOrderSeen)
496 {
497 DPRINT1("Command completion out of order: TRB 0x%I64x code %lu\n",
498 Pointer, static_cast<ULONG>(Code));
500 OutOfOrder = TRUE;
501 }
502
504 WdfTimerStop(m_Timer, FALSE);
505
507
508 if (OutOfOrder)
509 m_Controller->RaiseControllerFault(XhciRecovery::Ignore, XhciCmdReasonOutOfOrder);
510
511 XhciCmdCompleteList(&Finished);
512}
unsigned char BOOLEAN
Definition: actypes.h:127
VOID PlaceLocked(_Inout_ XhciCommand *Command, _In_ BOOLEAN FrontOfLine, _Inout_ PLIST_ENTRY Finished)
Definition: cmdring.cpp:303
VOID HandleRingStopped(_In_ const XHCI_TRB *Event)
Definition: cmdring.cpp:571
static const ULONG XhciCmdReasonOutOfOrder
Definition: cmdring.cpp:26
static NTSTATUS NTAPI XhciCmdStatusFromCode(_In_ XhciCompletionCode Code)
Definition: cmdring.cpp:42
#define Code
Definition: deflate.h:80
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707
XhciCompletionCode
Definition: xhcihw.h:110
FORCEINLINE ULONG NTAPI XhciTrbCompletionCode(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:42

◆ OnHostLost()

VOID XhciCommandRing::OnHostLost ( )

Definition at line 813 of file cmdring.cpp.

814{
816}

Referenced by XhciController::RunRecovery().

◆ OnTimer()

VOID XhciCommandRing::OnTimer ( )
private

Definition at line 614 of file cmdring.cpp.

615{
616 LIST_ENTRY Finished;
617 XhciCommand* Head;
618 ULONG64 Crcr;
620 BOOLEAN NewlyGone;
621 BOOLEAN WantReset;
622 BOOLEAN WantInternal = FALSE;
624
625 InitializeListHead(&Finished);
627 NewlyGone = FALSE;
628 WantReset = FALSE;
629
631
633 {
635
636 if (!Head && !m_Aborting)
637 {
638 WdfTimerStop(m_Timer, FALSE);
639 }
640 else
641 {
643
644 if (Crcr == ~0ULL)
645 {
646 DPRINT1("Command ring control reads all ones, controller is gone\n");
648 NewlyGone = TRUE;
649 }
650 else if (m_Aborting)
651 {
652 m_AbortTicks--;
653 if (m_AbortTicks <= 0)
654 {
656
657 if (Crcr & XHCI_CRCR_RUNNING)
658 {
659 DPRINT1("Command abort timed out with the ring running; asking for a reset\n");
660 WdfTimerStop(m_Timer, FALSE);
662 WantReset = TRUE;
663 WantInternal = (Head != NULL && Head->Internal);
664 }
665 else
666 {
667 DPRINT1("Command abort timed out with the ring stopped; restarting it\n");
668 RestartStoppedRingLocked(&Finished);
669 }
670 }
671 }
672 else
673 {
674 if (Head->Countdown > 0)
675 Head->Countdown--;
676
677 if (Head->Countdown == XhciCmdTicksFirstAbort || Head->Countdown == 0)
678 {
679 if (Crcr & XHCI_CRCR_RUNNING)
680 {
681 DPRINT1("Command type %lu timed out, aborting\n", XhciTrbType(&Head->Trb));
682
683 /* Address Device with BSR clear waits on the bus, so it is not a controller fault */
684 if (XhciTrbType(&Head->Trb) != static_cast<ULONG>(XhciTrbType::AddressDevice) ||
685 (Head->Trb.Dword[3] & XhciCmdBlockSetAddress))
686 {
687 DPRINT1("Controller did not finish a command within %ld s\n",
689 }
690
694 Crcr | XHCI_CRCR_ABORT);
695 }
696 else
697 {
698 DPRINT1("Command ring not running with a command pending; asking for a reset\n");
699 WdfTimerStop(m_Timer, FALSE);
701 WantReset = TRUE;
702 WantInternal = Head->Internal;
703 }
704 }
705 }
706 }
707 }
708
709 if (!Accessible)
710 {
712 DrainAllLocked(&Finished);
713
714 WdfTimerStop(m_Timer, FALSE);
715 }
716
718
719 if (NewlyGone)
721
722 XhciCmdCompleteList(&Finished);
723
724 if (WantReset)
725 {
726 m_Controller->RaiseControllerFault(WantInternal ? XhciRecovery::InternalReset : XhciRecovery::ResetHost,
728 }
729}
VOID MarkGone()
Definition: hc.cpp:1924
ULONG64 ReadOperational64(_In_ ULONG Offset) const
Definition: mmio.cpp:450
static const ULONG XhciCmdReasonAbortFailed
Definition: cmdring.cpp:25
static const LONG XhciCmdTicksAbortWait
Definition: cmdring.cpp:20
static const LONG XhciCmdTicksFirstAbort
Definition: cmdring.cpp:19
static const LONG XhciCmdTicksInitial
Definition: cmdring.cpp:18
static const ULONG XhciCmdBlockSetAddress
Definition: cmdring.cpp:30
#define ULL(a, b)
Definition: format_msg.c:27
LONG Countdown
Definition: cmdring.h:35
XHCI_TRB Trb
Definition: cmdring.h:21
BOOLEAN Internal
Definition: cmdring.h:27
ULONG Dword[4]
Definition: xhcihw.h:17
#define XHCI_CRCR_RUNNING
Definition: xhcihw.h:180
XhciTrbType
Definition: xhcihw.h:68
#define XHCI_CRCR_ABORT
Definition: xhcihw.h:179

◆ PlaceLocked()

VOID XhciCommandRing::PlaceLocked ( _Inout_ XhciCommand *  Command,
_In_ BOOLEAN  FrontOfLine,
_Inout_ PLIST_ENTRY  Finished 
)
private

Definition at line 303 of file cmdring.cpp.

307{
308 BOOLEAN Park;
309
311 {
312 /* Fail at once; Done runs after the ring lock is dropped */
314 InsertTailList(Finished, &Command->Link);
315 return;
316 }
317
318 Park = FALSE;
320 {
321 Park = TRUE;
322 }
323 else if (m_Aborting)
324 {
325 Park = TRUE;
326 }
327 else if (!IsListEmpty(&m_Pending) && m_Controller->HasErrata(XhciErrata::CmdOneInFlight))
328 {
329 Park = TRUE;
330 }
331 else if ((m_Enqueue + 1) % XhciCmdUsable == m_Dequeue)
332 {
333 Command->Countdown = XhciCmdTicksInitial;
334 Park = TRUE;
335 }
336
337 if (!Park)
338 {
340 return;
341 }
342
343 if (FrontOfLine)
345 else
347}
VOID PutOnRingLocked(_Inout_ XhciCommand *Command)
Definition: cmdring.cpp:260
BOOLEAN HasErrata(_In_ XhciErrata Bit) const
Definition: hc.h:58
#define InsertHeadList(ListHead, Entry)

Referenced by OnCompletionEvent(), PostResetSuccess(), and RestartStoppedRingLocked().

◆ PostInterruptsEntry()

VOID XhciCommandRing::PostInterruptsEntry ( )

Definition at line 254 of file cmdring.cpp.

255{
256 /* The controller module issues the vendor firmware queries through SubmitAndWait */
257}

Referenced by XhciController::D0EntryPostInterruptsEnabled().

◆ PostReset()

VOID XhciCommandRing::PostReset ( )

Definition at line 743 of file cmdring.cpp.

744{
745 LIST_ENTRY Finished;
747
748 InitializeListHead(&Finished);
749
751 DrainAllLocked(&Finished);
752 WdfTimerStop(m_Timer, FALSE);
755
756 XhciCmdCompleteList(&Finished);
757
759}

Referenced by XhciController::InternalReset().

◆ PostResetSuccess()

VOID XhciCommandRing::PostResetSuccess ( )

Definition at line 762 of file cmdring.cpp.

763{
764 LIST_ENTRY Finished;
767
768 InitializeListHead(&Finished);
770
772
774
775 while (!IsListEmpty(&m_Waiting))
777
778 while (!IsListEmpty(&Requeue))
780
782
783 XhciCmdCompleteList(&Finished);
784}
_In_ WDFREQUEST _In_ BOOLEAN Requeue
Definition: wdfrequest.h:1654

Referenced by XhciController::InternalReset().

◆ Prepare()

NTSTATUS XhciCommandRing::Prepare ( )

Definition at line 144 of file cmdring.cpp.

145{
146 PAGED_CODE();
147
149 if (!m_Segment)
150 {
151 DPRINT1("No common buffer for the command ring, 0x%lx\n", STATUS_INSUFFICIENT_RESOURCES);
153 }
154
155 m_Trbs = static_cast<PXHCI_TRB>(m_Segment->VirtualAddress);
158 m_Enqueue = 0;
159 m_Dequeue = 0;
163
164 /* A restart after a failed controller must accept commands again */
168
170 return STATUS_SUCCESS;
171}
XhciCommonBuffer m_Buffers
Definition: hc.h:92
PHYSICAL_ADDRESS LogicalAddress
Definition: dmapool.h:17
PVOID VirtualAddress
Definition: dmapool.h:16
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by XhciController::PrepareHardware().

◆ PreReset()

VOID XhciCommandRing::PreReset ( )

Definition at line 732 of file cmdring.cpp.

Referenced by XhciController::InternalReset().

◆ PutOnRingLocked()

VOID XhciCommandRing::PutOnRingLocked ( _Inout_ XhciCommand *  Command)
private

Definition at line 260 of file cmdring.cpp.

262{
263 volatile ULONG* Control;
265 BOOLEAN WasIdle;
266
268
269 Command->Countdown = XhciCmdTicksInitial;
270 Command->Matched = FALSE;
271 Command->RingIndex = m_Enqueue;
272
273 /* Dword 3 holds the cycle bit, so the xHC may only see it after the rest */
274 Slot->Dword[0] = Command->Trb.Dword[0];
275 Slot->Dword[1] = Command->Trb.Dword[1];
276 Slot->Dword[2] = Command->Trb.Dword[2];
278 Control = &Slot->Dword[3];
279 *Control = (Command->Trb.Dword[3] & ~XHCI_TRB_CYCLE) | m_Cycle;
280
281 WasIdle = IsListEmpty(&m_Pending);
283
284 m_Enqueue++;
286 {
287 /* Hand the Link TRB over with the cycle of the pass that just ended */
292 m_Enqueue = 0;
293 }
294
297
298 if (WasIdle)
300}
VOID RingDoorbell(_In_ ULONG Index, _In_ ULONG Value)
Definition: mmio.cpp:507
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_MS(_In_ ULONGLONG Time)
Definition: wdfcore.h:80
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by PlaceLocked().

◆ Release()

VOID XhciCommandRing::Release ( )

Definition at line 174 of file cmdring.cpp.

175{
176 LIST_ENTRY Finished;
178
179 PAGED_CODE();
180
181 InitializeListHead(&Finished);
182
184 {
185 if (m_Timer)
186 WdfTimerStop(m_Timer, TRUE);
187
190
193 {
194 DPRINT1("Command ring released with commands outstanding\n");
195 DrainAllLocked(&Finished);
196 }
199
200 /* Complete these commands so no caller waits forever */
201 XhciCmdCompleteList(&Finished);
202
204 }
205
206 m_Segment = NULL;
207 m_Trbs = NULL;
208 m_RingAddress = 0;
209 m_LinkAddress = 0;
211}

Referenced by XhciController::ReleaseHardware().

◆ RestartStoppedRingLocked()

VOID XhciCommandRing::RestartStoppedRingLocked ( _Inout_ PLIST_ENTRY  Finished)
private

Definition at line 515 of file cmdring.cpp.

517{
519 XhciCommand* Head;
520 ULONG RingCycle;
521
522 if (!IsListEmpty(&m_Pending))
523 {
525
526 if (Head->Countdown <= 0)
527 {
528 DPRINT1("Command type %lu aborted twice, failing it\n", XhciTrbType(&Head->Trb));
529
532
533 /* TRBs behind a wrapped enqueue index still carry the previous cycle */
534 RingCycle = m_Cycle;
535 if (m_Dequeue > m_Enqueue)
536 RingCycle ^= XHCI_TRB_CYCLE;
537
539 TrbAddress(m_Dequeue) | RingCycle);
540
541 Head->Code = XhciCompletionCode::CommandAborted;
543 InsertTailList(Finished, &Head->Link);
544 }
545 else if (Head->Countdown == XhciCmdTicksFirstAbort)
546 {
547 DPRINT1("Command type %lu still not done after the first abort, retrying\n",
548 XhciTrbType(&Head->Trb));
549 }
550 else if (Head->Countdown != XhciCmdTicksInitial)
551 {
552 DPRINT1("Unexpected command countdown %ld after the ring stopped\n", Head->Countdown);
553 }
554 }
555
556 if (!IsListEmpty(&m_Pending))
557 {
560 }
561
563 while (!IsListEmpty(&m_Waiting))
565
566 while (!IsListEmpty(&Requeue))
568}
LIST_ENTRY Link
Definition: cmdring.h:28
XhciCompletionCode Code
Definition: cmdring.h:24
NTSTATUS Status
Definition: cmdring.h:26
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163

Referenced by HandleRingStopped(), and OnTimer().

◆ TrbAddress()

ULONG64 XhciCommandRing::TrbAddress ( _In_ ULONG  Index) const
inlineprivate

Definition at line 124 of file cmdring.h.

126 {
127 return m_RingAddress + Index * sizeof(XHCI_TRB);
128 }
_In_ WDFCOLLECTION _In_ ULONG Index
struct _XHCI_TRB XHCI_TRB

Referenced by HandleRingStopped(), OnCompletionEvent(), Prepare(), and RestartStoppedRingLocked().

Member Data Documentation

◆ EvtTimer

VOID NTAPI XhciCommandRing::EvtTimer
static

Definition at line 76 of file cmdring.h.

Referenced by Create().

◆ m_Aborting

BOOLEAN XhciCommandRing::m_Aborting
private

◆ m_AbortTicks

LONG XhciCommandRing::m_AbortTicks
private

Definition at line 146 of file cmdring.h.

Referenced by Create(), and OnTimer().

◆ m_Controller

◆ m_Cycle

ULONG XhciCommandRing::m_Cycle
private

Definition at line 141 of file cmdring.h.

Referenced by Create(), InitializeRing(), Prepare(), PutOnRingLocked(), and RestartStoppedRingLocked().

◆ m_Dequeue

ULONG XhciCommandRing::m_Dequeue
private

◆ m_DrainFromTimer

BOOLEAN XhciCommandRing::m_DrainFromTimer
private

Definition at line 147 of file cmdring.h.

Referenced by Create(), FailEverything(), OnTimer(), and Prepare().

◆ m_Enqueue

ULONG XhciCommandRing::m_Enqueue
private

◆ m_LinkAddress

ULONG64 XhciCommandRing::m_LinkAddress
private

Definition at line 138 of file cmdring.h.

Referenced by Create(), HandleRingStopped(), Prepare(), and Release().

◆ m_Lock

◆ m_OutOfOrderSeen

BOOLEAN XhciCommandRing::m_OutOfOrderSeen
private

Definition at line 144 of file cmdring.h.

Referenced by Create(), and OnCompletionEvent().

◆ m_Pending

◆ m_Reset

ResetPhase XhciCommandRing::m_Reset
private

◆ m_RingAddress

ULONG64 XhciCommandRing::m_RingAddress
private

Definition at line 137 of file cmdring.h.

Referenced by Create(), InitializeRing(), Prepare(), Release(), and TrbAddress().

◆ m_Segment

XhciDmaBuffer* XhciCommandRing::m_Segment
private

Definition at line 135 of file cmdring.h.

Referenced by Create(), Prepare(), and Release().

◆ m_State

RingState XhciCommandRing::m_State
private

Definition at line 133 of file cmdring.h.

Referenced by Create(), InitializeRing(), OnTimer(), Prepare(), and Release().

◆ m_Timer

WDFTIMER XhciCommandRing::m_Timer
private

◆ m_Trbs

PXHCI_TRB XhciCommandRing::m_Trbs
private

Definition at line 136 of file cmdring.h.

Referenced by Create(), InitializeRing(), Prepare(), PutOnRingLocked(), and Release().

◆ m_Waiting


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