ReactOS 0.4.17-dev-1281-g065abb3
xferring.cpp File Reference
#include "xhcidrv.h"
#include <debug.h>
Include dependency graph for xferring.cpp:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME (XhciTransferRing, XhciRingContext)
 
static ULONG NTAPI XhciRingCountList (_In_ const LIST_ENTRY *Head)
 
static VOID NTAPI XhciRingAppendList (_Inout_ PLIST_ENTRY To, _Inout_ PLIST_ENTRY From)
 
static VOID NTAPI XhciRingPrependList (_Inout_ PLIST_ENTRY To, _Inout_ PLIST_ENTRY From)
 
static VOID NTAPI XhciRingQueueCleanup (_In_ WDFOBJECT Object)
 
static VOID NTAPI XhciRingGrowthWorkItem (_In_ WDFWORKITEM WorkItem)
 
static WDF_IO_FORWARD_PROGRESS_ACTION NTAPI XhciRingExamineForwardProgress (_In_ WDFQUEUE Queue, _In_ PIRP Irp)
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS XhciTransferRing
 Sends a synchronous IOCTL to the specified device object.
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) NTSTATUS XhciTransferRing
 

Variables

static const ULONG XhciRingSegmentBytes = 0x200
 
static const ULONG XhciRingWideSegmentBytes = 0x1000
 
static const ULONG XhciRingDoubleBufferBytes = 0x200
 
static const ULONG XhciRingSingleSegmentStage = (XhciRingSegmentBytes / sizeof(XHCI_TRB) - 4) * PAGE_SIZE
 
static const ULONG XhciRingIdleWaitMs = 5000
 
static const ULONG XhciRingIdleWaitUs = 100000
 
static const USBD_STATUS XhciRingUsbdNotSet = (USBD_STATUS)0xFFFFFFFF
 
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciRingQueueCleanup
 
static EVT_WDF_WORKITEM XhciRingGrowthWorkItem
 
static EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS XhciRingExamineForwardProgress
 
static KSPIN_LOCK XhciLiveRingLock
 
static LIST_ENTRY XhciLiveRings = { &XhciLiveRings, &XhciLiveRings }
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file xferring.cpp.

Function Documentation

◆ _IRQL_requires_()

_IRQL_requires_ ( PASSIVE_LEVEL  )

Sends a synchronous IOCTL to the specified device object.

Parameters
[in]IoControlCodeThe IOCTL to send to the device.
[in]DeviceObjectPointer to the device object that will handle the IOCTL.
[in]InputBufferOptional pointer to a buffer containing input data for the IOCTL. When specified, the buffer should be at least of InputBufferLength size.
[in]InputBufferLengthSize in bytes, of the buffer pointed by InputBuffer.
[out]OutputBufferOptional pointer to a buffer that will receive output data from the IOCTL. When specified, the buffer should be at least of OutputBufferLength size.
[in]OutputBufferLengthSize in bytes, of the buffer pointed by OutputBuffer.
[in]FileObjectOptional pointer to a file object that may be necessary for the IOCTL.
Returns
An NTSTATUS code indicating success or failure of this function.
Note
Must be called at PASSIVE_LEVEL with all APCs enabled.

Nothing is found unless the PCI bus driver publishes the properties.

The root hub name without its prefix; NULL when the PDO has no name.

Grows a private buffer to what the helper asks for.

Lets KMDF handle the IRP, then hands it back here still uncompleted.

Waits for the device machine to answer a PnP or power event; returns the PnP status.

Deletes the UCX endpoints of the disabled pipes, then the interface record.

One 4 byte value; the registry type is not checked.

Reread whenever user experience settings change; the open status is returned.

Sends a synchronous IOCTL to the specified device object.

STATUS_SUCCESS when the caller's token is an administrator's.

Sends a synchronous IOCTL to the specified device object.

Reads one value of a walk. A missing value only clears Present; FALSE means stop.

Reads up to Size bytes of a value into a zeroed buffer; the type is not checked.

Writes a REG_BINARY value into the device's usbflags subkey.

Sets or clears ExtPropertiesInstalled from ExtPropDescSemaphore in the hardware key.

Fails only when a port cannot be bound to the USB4 host router its ACPI node names.

Assigns device, hardware, compatible, container and instance ids to a new child PDO.

Answers IRP_MN_QUERY_DEVICE_TEXT on a child PDO; always completes the IRP.

Takes the connector map lock, needed around HubConnectorFindCompanion.

Device hardware key values read at PDO prepare hardware.

Saves the MS OS 2.0 set info in usbflags when the set asks for alternate enumeration.

MsOs20Flags and EnumerationRetryCount, written at PDO start.

Rereads the UXD record; UpdateRequired says whether the device id changes.

Replacement PnP id of a UXD reserved device, or an empty String. Always succeeds.

Telemetry values under the device's Ceip subkey.

BootPathSurpriseRemovalCount + 1.

This machine's dual role features for a dual role partner.

Tells UCX the WDM PDO of the device; call right after the child PDO was created.

IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME: Argument1 and its length Argument2.

IOCTL_INTERNAL_USB_GET_BUS_INFO for the device: the 16 byte USB_BUS_NOTIFICATION at Argument1.

Registers the GUID_USB_WMI_NODE_INFO instance of a child PDO (not for hubs or composites).

Registers the boot device surprise removal event on an external, non hub boot PDO.

Fires the boot device surprise removal event, if one is registered.

Sends a synchronous IOCTL to the specified device object.

Publishes "<port>#<host>" for every bound port on the hub's PDO. QUIRK: with no bound port an older value is left in place.

Binds USB 3 ports to the host routers named by the USB4 DVSEC; an earlier ACPI mapping wins.

Waits on a PnP handshake event with no timeout, printing a watchdog line every minute so a stuck machine is visible in the debugger.

Copies up to Size bytes of a device property; a failed query leaves the field zero.

Only the controller name length is real; both bandwidth fields read 0.

The answer overlays a USB_HUB_NAME on TotalSize, so TotalSize comes back as the name length + 4.

Evaluates a method without arguments into Output.

Drops every MSI descriptor and keeps only lists that still offer a line interrupt.

Picks the list with the best MSI offer: MSI-X first, then the most messages.

Keeps message descriptors covering Wanted messages and removes the others.

Evaluates _DSM on the controller ACPI object with a buffer as Arg3; returns up to 8 result bytes, 0 on failure.

Definition at line 122 of file xferring.cpp.

129{
130 XhciController* Controller = Endpoint->Controller();
131 WDF_IO_QUEUE_CONFIG QueueConfig;
133 WDF_DPC_CONFIG DpcConfig;
134 PFN_WDF_DPC CompletionDpc;
135 XhciTransferRing* NewRing;
136 WDFQUEUE Queue;
137 ULONG TransferType;
139 ULONG MaxStageSize;
140 BOOLEAN NoLinkInTd;
142
143 *Ring = NULL;
144
145 TransferType = Endpoint->TransferType();
146 MaxStageSize = Controller->m_Buffers.MaxDmaSize() - PAGE_SIZE;
147 NoLinkInTd = Controller->HasErrata(XhciErrata::RingKeepTdInOneSegment);
148
149 if (TransferType == USB_ENDPOINT_TYPE_CONTROL)
150 {
154 CompletionDpc = XhciControlRing::EvtCompletionDpc;
155
156 /* A whole control transfer must fit one segment when no Link TRB may split it */
158 }
159 else if (TransferType == USB_ENDPOINT_TYPE_BULK || TransferType == USB_ENDPOINT_TYPE_INTERRUPT)
160 {
163 CompletionDpc = XhciBulkRing::EvtCompletionDpc;
165
166 if (NoLinkInTd)
167 MaxStageSize = XhciRingSingleSegmentStage;
168 }
169 else if (TransferType == USB_ENDPOINT_TYPE_ISOCHRONOUS)
170 {
173 CompletionDpc = XhciIsochRing::EvtCompletionDpc;
175 }
176 else
177 {
178 DPRINT1("Endpoint DCI %lu has transfer type %lu, no transfer ring for it\n",
179 Endpoint->Dci(), TransferType);
180 return STATUS_UNSUCCESSFUL;
181 }
182
184 Attributes.ParentObject = Parent;
185 Attributes.EvtCleanupCallback = XhciRingQueueCleanup;
186
187 Status = WdfIoQueueCreate(Controller->m_Device, &QueueConfig, &Attributes, &Queue);
188 if (!NT_SUCCESS(Status))
189 {
190 DPRINT1("Queue for DCI %lu stream %lu not created, 0x%08lx\n",
191 Endpoint->Dci(), StreamId, Status);
192 return Status;
193 }
194
195 /* The context is zeroed by WDF, so cleanup copes with any step below failing */
196 NewRing = new (XhciRingContext(Queue)) XhciTransferRing;
197 KeInitializeSpinLock(&NewRing->m_Lock);
201 NewRing->m_Device = Endpoint->Device();
202 NewRing->m_Endpoint = Endpoint;
203 NewRing->m_StreamId = StreamId;
204 NewRing->m_TransferType = TransferType;
205 NewRing->m_Queue = Queue;
206 NewRing->m_MapState = static_cast<LONG>(XhciMapState::Halted);
207 NewRing->m_SegmentSize = SegmentSize;
209 NewRing->m_MaxStageSize = MaxStageSize;
210 NewRing->m_MapRegisterCount = Controller->m_Buffers.MapRegisterCount();
211 NewRing->m_LastIndex = SegmentSize / sizeof(XHCI_TRB) - 1;
212 NewRing->m_Cycle = 1;
213 NewRing->m_Controller = Controller;
214
215 if (!NewRing->IsControl())
216 {
217 WDF_WORKITEM_CONFIG WorkConfig;
218
219 Status = WdfIoQueueReadyNotify(Queue,
222 NewRing);
223 if (!NT_SUCCESS(Status))
224 {
225 DPRINT1("Ready notification for DCI %lu stream %lu not registered, 0x%08lx\n",
226 Endpoint->Dci(), StreamId, Status);
227 return Status;
228 }
229
231 WorkConfig.AutomaticSerialization = FALSE;
233 Attributes.ParentObject = Queue;
234
235 Status = WdfWorkItemCreate(&WorkConfig, &Attributes, &NewRing->m_GrowthItem);
236 if (!NT_SUCCESS(Status))
237 {
238 DPRINT1("Segment growth work item for DCI %lu stream %lu not created, 0x%08lx\n",
239 Endpoint->Dci(), StreamId, Status);
240 return Status;
241 }
242 }
243
244 WDF_DPC_CONFIG_INIT(&DpcConfig, CompletionDpc);
245 DpcConfig.AutomaticSerialization = TRUE;
247 Attributes.ParentObject = Queue;
248
249 Status = WdfDpcCreate(&DpcConfig, &Attributes, &NewRing->m_CompletionDpc);
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("Completion DPC for DCI %lu stream %lu not created, 0x%08lx\n",
253 Endpoint->Dci(), StreamId, Status);
254 return Status;
255 }
256
257 /* Take the first segment now so a later enable at DISPATCH_LEVEL never allocates */
258 Status = NewRing->EnsureFreeSegments(1, FALSE);
259 if (NT_SUCCESS(Status))
260 {
261 XhciSpinLockGuard Guard(&NewRing->m_Lock);
262
263 if (IsListEmpty(&NewRing->m_FreeSegments))
264 {
266 }
267 else
268 {
272 NewRing->m_Trbs = (PXHCI_TRB)NewRing->m_Segment->VirtualAddress;
273 }
274 }
275
276 if (!NT_SUCCESS(Status))
277 {
278 DPRINT1("No initial segment for DCI %lu stream %lu, 0x%08lx\n",
279 Endpoint->Dci(), StreamId, Status);
280 return Status;
281 }
282
283 if (NewRing->IsControl())
285 else if (NewRing->IsIsoch())
287 else
289
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT1("Type setup for DCI %lu stream %lu failed, 0x%08lx\n",
293 Endpoint->Dci(), StreamId, Status);
294 return Status;
295 }
296
297 NewRing->m_TypeReady = TRUE;
298 NewRing->MakeLive();
299
300 DPRINT("Ring %p for DCI %lu stream %lu type %lu, segment 0x%lx, stage max 0x%lx\n",
301 NewRing, Endpoint->Dci(), StreamId, TransferType, SegmentSize, MaxStageSize);
302
303 *Ring = NewRing;
304 return STATUS_SUCCESS;
305}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:357
static EVT_WDF_DPC EvtCompletionDpc
Definition: bulkio.h:115
static EVT_WDF_IO_QUEUE_STATE ReadyNotification
Definition: bulkio.h:113
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: bulkio.h:114
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: ctrlxfer.h:36
static EVT_WDF_IO_QUEUE_IO_DEFAULT EvtIoDefault
Definition: ctrlxfer.h:35
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:178
static EVT_WDF_DPC EvtCompletionDpc
Definition: ctrlxfer.h:37
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: isoxfer.h:102
static EVT_WDF_DPC EvtCompletionDpc
Definition: isoxfer.h:103
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:422
static EVT_WDF_IO_QUEUE_STATE ReadyNotification
Definition: isoxfer.h:101
BOOLEAN IsControl() const
Definition: xferring.cpp:321
WDFDPC m_CompletionDpc
Definition: xferring.h:176
KSPIN_LOCK m_Lock
Definition: xferring.h:177
WDFQUEUE m_Queue
Definition: xferring.h:175
XhciController * m_Controller
Definition: xferring.h:170
ULONG m_DoubleBufferSize
Definition: xferring.h:184
BOOLEAN IsIsoch() const
Definition: xferring.cpp:334
LIST_ENTRY m_LiveLink
Definition: xferring.h:226
ULONG m_LastIndex
Definition: xferring.h:191
ULONG m_MapRegisterCount
Definition: xferring.h:186
WDFWORKITEM m_GrowthItem
Definition: xferring.h:233
ULONG m_StreamId
Definition: xferring.h:173
XhciUsbDevice * m_Device
Definition: xferring.h:171
ULONG m_SegmentSize
Definition: xferring.h:183
NTSTATUS EnsureFreeSegments(_In_ ULONG Count, _In_ BOOLEAN Async)
Definition: xferring.cpp:853
LIST_ENTRY m_FreeSegments
Definition: xferring.h:193
LIST_ENTRY m_DoubleBuffers
Definition: xferring.h:194
PXHCI_TRB m_Trbs
Definition: xferring.h:189
XhciDmaBuffer * m_Segment
Definition: xferring.h:188
volatile LONG m_MapState
Definition: xferring.h:178
XhciEndpoint * m_Endpoint
Definition: xferring.h:172
ULONG m_MaxStageSize
Definition: xferring.h:185
BOOLEAN m_TypeReady
Definition: xferring.h:229
ULONG m_TransferType
Definition: xferring.h:174
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:24
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
long LONG
Definition: pedump.c:60
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
LIST_ENTRY Link
Definition: dmapool.h:15
PVOID VirtualAddress
Definition: dmapool.h:16
BOOLEAN AutomaticSerialization
Definition: wdfdpc.h:77
PFN_WDF_IO_QUEUE_IO_DEFAULT EvtIoDefault
Definition: wdfio.h:399
PFN_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: wdfio.h:413
BOOLEAN AutomaticSerialization
Definition: wdfworkitem.h:79
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231
FORCEINLINE VOID WDF_DPC_CONFIG_INIT(_Out_ PWDF_DPC_CONFIG Config, _In_ PFN_WDF_DPC EvtDpcFunc)
Definition: wdfdpc.h:83
EVT_WDF_DPC * PFN_WDF_DPC
Definition: wdfdpc.h:64
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:426
@ WdfIoQueueDispatchSequential
Definition: wdfio.h:78
@ WdfIoQueueDispatchManual
Definition: wdfio.h:80
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
_Inout_ PVOID _In_ ULONG SegmentSize
Definition: exfuncs.h:1102
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciRingQueueCleanup
Definition: xferring.cpp:30
static const ULONG XhciRingSegmentBytes
Definition: xferring.cpp:14
static EVT_WDF_WORKITEM XhciRingGrowthWorkItem
Definition: xferring.cpp:31
static const ULONG XhciRingSingleSegmentStage
Definition: xferring.cpp:19
static const ULONG XhciRingDoubleBufferBytes
Definition: xferring.cpp:16
static const ULONG XhciRingWideSegmentBytes
Definition: xferring.cpp:15
@ RingKeepTdInOneSegment
struct _XHCI_TRB * PXHCI_TRB
struct _XHCI_TRB XHCI_TRB
FORCEINLINE VOID NTAPI XhciClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: xhciutil.h:117

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION; the idle machine owns the IRP afterwards.

Records hub over current in the hub hardware key, once per devnode.

First selective suspend of the device; the registry write runs in a work item.

"USB device not recognized" popup for a port.

A hub was attached beyond the allowed tier depth.

The selected configuration draws more power than the port can give.

The controller ran out of bandwidth for the device; fired by the out of bandwidth timer.

Definition at line 458 of file xferring.cpp.

461{
462 ASSERT(m_MapState == static_cast<LONG>(XhciMapState::Halted));
463
464 if (m_Segment == NULL)
465 {
466 DPRINT1("Ring for DCI %lu stream %lu has no segment to enable\n",
467 m_Endpoint->Dci(), m_StreamId);
469 }
470
471 InitializeRing();
472
473 if (IsControl())
475 else if (IsIsoch())
477 else
479
480 DPRINT("Ring for DCI %lu stream %lu enabled\n", m_Endpoint->Dci(), m_StreamId);
481 return STATUS_SUCCESS;
482}
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:401
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:230
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:468
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178

◆ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME()

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME ( XhciTransferRing  ,
XhciRingContext   
)

◆ XhciRingAppendList()

static VOID NTAPI XhciRingAppendList ( _Inout_ PLIST_ENTRY  To,
_Inout_ PLIST_ENTRY  From 
)
static

Moves every entry of From to the tail of To, keeping their order.

Definition at line 60 of file xferring.cpp.

63{
64 while (!IsListEmpty(From))
66}
#define InsertTailList(ListHead, Entry)

Referenced by XhciTransferRing::Cleanup(), XhciTransferRing::EnsureFreeSegments(), and XhciTransferRing::ReturnSegments().

◆ XhciRingCountList()

static ULONG NTAPI XhciRingCountList ( _In_ const LIST_ENTRY *  Head)
static

Definition at line 44 of file xferring.cpp.

46{
47 const LIST_ENTRY* Entry;
48 ULONG Count = 0;
49
50 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
51 Count++;
52
53 return Count;
54}
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT Count
Definition: userreq.cpp:200

Referenced by XhciTransferRing::Cleanup(), XhciTransferRing::EnsureFreeSegments(), and XhciTransferRing::TakeSegments().

◆ XhciRingExamineForwardProgress()

static WDF_IO_FORWARD_PROGRESS_ACTION NTAPI XhciRingExamineForwardProgress ( _In_ WDFQUEUE  Queue,
_In_ PIRP  Irp 
)
static

Definition at line 103 of file xferring.cpp.

106{
107 PURB Urb;
108
110
111 /* Control and bulk URBs keep TransferFlags at the same offset */
113 if (Urb != NULL &&
114 (Urb->UrbBulkOrInterruptTransfer.TransferFlags & USB3_URB_RESERVED_RESOURCES))
115 {
117 }
118
120}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define USB3_URB_RESERVED_RESOURCES
Definition: hubreq.cpp:15
_In_ PIRP Irp
Definition: kse.h:79
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
struct _IO_STACK_LOCATION::@5100::@5139 Others
union _IO_STACK_LOCATION::@1823 Parameters
Definition: usb.h:565
struct _URB * PURB
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
@ WdfIoForwardProgressActionUseReservedRequest
Definition: wdfio.h:462
@ WdfIoForwardProgressActionFailRequest
Definition: wdfio.h:461

◆ XhciRingGrowthWorkItem()

static VOID NTAPI XhciRingGrowthWorkItem ( _In_ WDFWORKITEM  WorkItem)
static

Definition at line 92 of file xferring.cpp.

94{
95 WDFQUEUE Queue = (WDFQUEUE)WdfWorkItemGetParentObject(WorkItem);
96
97 XhciTransferRing::FromQueue(Queue)->GrowSegments();
98}
static XhciTransferRing * FromQueue(_In_ WDFQUEUE Queue)
Definition: xferring.cpp:308
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227

◆ XhciRingPrependList()

static VOID NTAPI XhciRingPrependList ( _Inout_ PLIST_ENTRY  To,
_Inout_ PLIST_ENTRY  From 
)
static

Moves every entry of From to the head of To, keeping their order.

Definition at line 72 of file xferring.cpp.

75{
76 while (!IsListEmpty(From))
78}
#define InsertHeadList(ListHead, Entry)
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975

Referenced by XhciTransferRing::ReturnSegments(), and XhciTransferRing::TakeSegments().

◆ XhciRingQueueCleanup()

static VOID NTAPI XhciRingQueueCleanup ( _In_ WDFOBJECT  Object)
static

Definition at line 83 of file xferring.cpp.

85{
86 XhciRingContext(Object)->Cleanup();
87}
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Variable Documentation

◆ XhciLiveRingLock

KSPIN_LOCK XhciLiveRingLock
static

◆ XhciLiveRings

LIST_ENTRY XhciLiveRings = { &XhciLiveRings, &XhciLiveRings }
static

Definition at line 39 of file xferring.cpp.

Referenced by XhciTransferRing::MakeLive(), and XhciTransferRing::ReferenceLiveRing().

◆ XhciRingDoubleBufferBytes

const ULONG XhciRingDoubleBufferBytes = 0x200
static

Definition at line 16 of file xferring.cpp.

Referenced by _IRQL_requires_().

◆ XhciRingExamineForwardProgress

EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS XhciRingExamineForwardProgress
static

Definition at line 32 of file xferring.cpp.

◆ XhciRingGrowthWorkItem

EVT_WDF_WORKITEM XhciRingGrowthWorkItem
static

Definition at line 31 of file xferring.cpp.

Referenced by _IRQL_requires_().

◆ XhciRingIdleWaitMs

const ULONG XhciRingIdleWaitMs = 5000
static

Definition at line 22 of file xferring.cpp.

◆ XhciRingIdleWaitUs

const ULONG XhciRingIdleWaitUs = 100000
static

Definition at line 23 of file xferring.cpp.

◆ XhciRingQueueCleanup

EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciRingQueueCleanup
static

Definition at line 30 of file xferring.cpp.

Referenced by _IRQL_requires_().

◆ XhciRingSegmentBytes

const ULONG XhciRingSegmentBytes = 0x200
static

Definition at line 14 of file xferring.cpp.

Referenced by _IRQL_requires_().

◆ XhciRingSingleSegmentStage

const ULONG XhciRingSingleSegmentStage = (XhciRingSegmentBytes / sizeof(XHCI_TRB) - 4) * PAGE_SIZE
static

Largest bulk stage when a TD may not cross a Link TRB: one segment less a few TRBs, one page each.

Definition at line 19 of file xferring.cpp.

Referenced by _IRQL_requires_().

◆ XhciRingUsbdNotSet

const USBD_STATUS XhciRingUsbdNotSet = (USBD_STATUS)0xFFFFFFFF
static

USBD status meaning "no hardware result", for the caller to replace with its default.

Definition at line 26 of file xferring.cpp.

Referenced by XhciTransferRing::UsbdStatusFromCompletionCode().

◆ XhciRingWideSegmentBytes

const ULONG XhciRingWideSegmentBytes = 0x1000
static

Definition at line 15 of file xferring.cpp.

Referenced by _IRQL_requires_().