ReactOS 0.4.17-dev-1281-g065abb3
urbroute.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define UCX_URB_FLAGS_KEEP_HUB_BITS   UCXHUB_URB_FLAGS_HUB_MASK
 
#define UCX_URB_FLAG_BUFFER_LOCKED   0x20000000
 
#define UCX_MAX_CONTROL_TRANSFER   0xFFFF
 

Functions

FORCEINLINE VOID NTAPI UcxStampProcessorNumber (_Inout_ PURB Urb)
 
FORCEINLINE VOID NTAPI UcxSetTransferDirection (_Inout_ PURB Urb, _In_ const UcxPipe *Pipe)
 
VOID NTAPI UcxLockTransferBuffer (_Inout_ PURB Urb)
 
VOID NTAPI UcxUnlockTransferBuffer (_Inout_ PURB Urb)
 
NTSTATUS NTAPI UcxUsbdStatusToNtStatus (_In_ USBD_STATUS UsbdStatus)
 
USBD_STATUS NTAPI UcxNtStatusToUsbdStatus (_In_ NTSTATUS Status)
 
NTSTATUS NTAPI UcxProcessLegacyUrb (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb)
 
BOOLEAN NTAPI UcxValidatePipeHandle (_In_ UcxUsbDevice *Device, _In_ USBD_PIPE_HANDLE Handle)
 
NTSTATUS NTAPI UcxForwardIrpToQueue (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue)
 
NTSTATUS NTAPI UcxForwardIrpWithRequest (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
 

Macro Definition Documentation

◆ UCX_MAX_CONTROL_TRANSFER

#define UCX_MAX_CONTROL_TRANSFER   0xFFFF

Definition at line 17 of file urbroute.h.

◆ UCX_URB_FLAG_BUFFER_LOCKED

#define UCX_URB_FLAG_BUFFER_LOCKED   0x20000000

Definition at line 14 of file urbroute.h.

◆ UCX_URB_FLAGS_KEEP_HUB_BITS

#define UCX_URB_FLAGS_KEEP_HUB_BITS   UCXHUB_URB_FLAGS_HUB_MASK

Definition at line 11 of file urbroute.h.

Function Documentation

◆ UcxForwardIrpToQueue()

NTSTATUS NTAPI UcxForwardIrpToQueue ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PIO_COMPLETION_ROUTINE  Completion,
_In_ PVOID  Context,
_In_ WDFQUEUE  Queue 
)

Definition at line 308 of file urbroute.cpp.

314{
315 UcxSetCompletionOnNext(RootHubPdo, Irp, Completion, Context);
316
317 WdfDeviceWdmDispatchIrpToIoQueue(RootHubPdo, Irp, Queue, WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP);
318 return STATUS_PENDING;
319}
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define STATUS_PENDING
Definition: telnetd.h:14
static VOID NTAPI UcxSetCompletionOnNext(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context)
Definition: urbroute.cpp:280
@ WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP
Definition: wdfdevice.h:437
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231

Referenced by UcxForwardDefaultPipeRequest(), UcxForwardStreamsUrb(), UcxHandleIsoch(), UcxProcessLegacyUrb(), and UcxXrbSubmitTransfer().

◆ UcxForwardIrpWithRequest()

NTSTATUS NTAPI UcxForwardIrpWithRequest ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PIO_COMPLETION_ROUTINE  Completion,
_In_ PVOID  Context,
_In_ WDFQUEUE  Queue,
_In_ WDFREQUEST  Request 
)

Definition at line 323 of file urbroute.cpp.

330{
333
334 UcxSetCompletionOnNext(RootHubPdo, Irp, Completion, Context);
336
338 Status = WdfRequestForwardToParentDeviceIoQueue(Request, Queue, &Options);
339 if (!NT_SUCCESS(Status))
340 {
341 /* A purging queue means a controller reset or a concurrent pipe reset */
342 if (Status == STATUS_WDF_BUSY)
344
345 DPRINT1("Forwarding request %p (IRP %p) to queue %p failed 0x%lx\n", Request, Irp, Queue, Status);
346 WdfRequestComplete(Request, Status);
347 }
348
349 return STATUS_PENDING;
350}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#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
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
FORCEINLINE VOID WDF_REQUEST_FORWARD_OPTIONS_INIT(_Out_ PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions)
Definition: wdfrequest.h:453
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2706

Referenced by UcxXrbSubmitTransfer().

◆ UcxLockTransferBuffer()

VOID NTAPI UcxLockTransferBuffer ( _Inout_ PURB  Urb)

Below DISPATCH_LEVEL, locks a buffer passed without an MDL so the HCD can map it.

Definition at line 82 of file urbroute.cpp.

84{
85 struct _URB_CONTROL_TRANSFER* Transfer = &Urb->UrbControlTransfer;
87 PMDL Mdl;
88
89 Urb->UrbHeader.UsbdFlags &= ~UCX_URB_FLAG_BUFFER_LOCKED;
90
91 /* At DISPATCH_LEVEL the buffer has to be resident already */
93 Transfer->TransferBufferMDL != NULL ||
94 Transfer->TransferBuffer == NULL ||
95 Transfer->TransferBufferLength == 0)
96 {
97 return;
98 }
99
101 if (Mdl == NULL)
102 {
103 DPRINT1("No MDL for the %lu byte buffer of URB %p\n", Transfer->TransferBufferLength, Urb);
104 return;
105 }
106
108
110 {
112 }
114 {
115 DPRINT1("Locking the buffer of URB %p failed 0x%lx\n", Urb, _SEH2_GetExceptionCode());
116 IoFreeMdl(Mdl);
117 Mdl = NULL;
118 }
119 _SEH2_END;
120
121 if (Mdl == NULL)
122 return;
123
124 Transfer->TransferBufferMDL = Mdl;
125 Urb->UrbHeader.UsbdFlags |= UCX_URB_FLAG_BUFFER_LOCKED;
126}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FP_OP Operation
Definition: fpcontrol.c:150
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:928
#define KernelMode
Definition: asm.h:38
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
PMDL TransferBufferMDL
Definition: usb.h:484
ULONG TransferFlags
Definition: usb.h:481
ULONG TransferBufferLength
Definition: usb.h:482
PVOID TransferBuffer
Definition: usb.h:483
#define UCX_URB_FLAG_BUFFER_LOCKED
Definition: urbroute.h:14
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:167
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
enum _LOCK_OPERATION LOCK_OPERATION
@ IoReadAccess
Definition: ketypes.h:931
@ IoWriteAccess
Definition: ketypes.h:932

Referenced by UcxForwardDefaultPipeRequest(), UcxHandleIsoch(), UcxProcessLegacyUrb(), and UcxXrbSubmitTransfer().

◆ UcxNtStatusToUsbdStatus()

USBD_STATUS NTAPI UcxNtStatusToUsbdStatus ( _In_ NTSTATUS  Status)

Definition at line 53 of file urbroute.cpp.

55{
56 switch (Status)
57 {
58 case STATUS_SUCCESS:
60
63
66
69
72
73 default:
75 }
76}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define USBD_STATUS_DEVICE_GONE
Definition: usb.h:222
#define USBD_STATUS_CANCELED
Definition: usb.h:225
#define USBD_STATUS_SUCCESS
Definition: usb.h:177
#define USBD_STATUS_NOT_SUPPORTED
Definition: usb.h:213
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:215
#define USBD_STATUS_INVALID_PARAMETER
Definition: usb.h:203

Referenced by UcxEndpoint::AbortPipe(), UcxEndpoint::GetIsochPathDelays(), UcxFailStreamsUrb(), UcxHandleGetCurrentFrame(), and UcxLegacyTransferCompletion().

◆ UcxProcessLegacyUrb()

NTSTATUS NTAPI UcxProcessLegacyUrb ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PURB  Urb 
)

Validates and routes a URB the way USBPORT did. Owns the IRP afterwards.

Definition at line 760 of file urbroute.cpp.

764{
767 UcxPipe* Pipe = NULL;
769 USHORT Code;
770
771 /* Short headers are not rejected */
772 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
773 Code = Urb->UrbHeader.Function;
774 Urb->UrbHeader.UsbdFlags &= UCX_URB_FLAGS_KEEP_HUB_BITS;
775
777 {
778 DPRINT1("URB %p has unknown function 0x%x\n", Urb, Code);
780 }
781
783
784 if (Function->Length != 0 && Function->Length != Urb->UrbHeader.Length)
785 {
786 DPRINT1("URB %p function 0x%x has length %u, expected %u\n", Urb, Code, Urb->UrbHeader.Length, Function->Length);
788 }
789
790 /* The hub fills in its UCXUSBDEVICE */
791 if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
792 {
793 DPRINT1("URB %p function 0x%x has no device handle\n", Urb, Code);
795 }
796
797 Device = UcxUsbDevice::FromHandle((UCXUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle);
798
799 if (Device->m_Disconnected)
800 {
801 DPRINT("URB %p function 0x%x for disconnected device %p\n", Urb, Code, Device);
803 }
804
805 if (Function->Flags & UCX_URB_TRANSFER)
806 {
809 {
810 DPRINT1("Transfer URB %p function 0x%x on device %p rejected, USBD status 0x%lx\n", Urb, Code, Device, Error);
812 }
813 }
814 else if (Function->Flags & UCX_URB_PIPE_REQUEST)
815 {
816 if (!UcxValidatePipeHandle(Device, Urb->UrbPipeRequest.PipeHandle))
817 {
818 DPRINT1("Pipe URB %p function 0x%x has invalid pipe %p\n", Urb, Code, Urb->UrbPipeRequest.PipeHandle);
820 }
821
822 Pipe = UcxPipe::FromHandle(Urb->UrbPipeRequest.PipeHandle);
823
824 /* Zero bandwidth pipes are not in the schedule; pipe requests on them just succeed */
827 }
828
829 /* Tells the completion routine whether the HCD ever saw it */
830 Urb->UrbHeader.Status = USBD_STATUS_PENDING;
831
832 switch (Function->Handler)
833 {
835 DPRINT1("URB %p function 0x%x is not supported\n", Urb, Code);
838
840 DPRINT1("URB %p has invalid function 0x%x\n", Urb, Code);
842
844 return Pipe->Endpoint->AbortPipe(Irp, Urb);
845
848
851 return UcxForwardIrpToQueue(RootHubPdo, Irp, UcxLegacyTransferCompletion, Urb, Pipe->Queue);
852
856 return UcxForwardIrpToQueue(RootHubPdo, Irp, UcxLegacyTransferCompletion, Urb, Pipe->Queue);
857
859 return UcxHandleIsoch(RootHubPdo, Irp, Urb, Pipe->Queue, Pipe);
860
861 default:
862 return UcxHandleStandardRequest(RootHubPdo, Irp, Urb, Pipe->Queue, Function);
863 }
864}
BOOL Error
Definition: chkdsk.c:66
#define ARRAYSIZE(a)
Definition: cat.c:25
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
static UcxUsbDevice * FromHandle(_In_ UCXUSBDEVICE Handle)
Definition: devobj.cpp:18
NTSTATUS NTAPI UcxCompleteUrb(_In_ PIRP Irp, _In_ PURB Urb, _In_ NTSTATUS Status, _In_ USBD_STATUS UsbdStatus)
Definition: clientxrb.cpp:23
#define Code
Definition: deflate.h:80
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT
Definition: sndvol32.h:73
Definition: pipe.h:30
static UcxPipe * FromHandle(_In_ USBD_PIPE_HANDLE Handle)
Definition: pipe.h:53
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI UcxUsbdStatusToNtStatus(_In_ USBD_STATUS UsbdStatus)
Definition: urbroute.cpp:18
#define UCX_URB_PIPE_REQUEST
Definition: urbroute.cpp:168
NTSTATUS NTAPI UcxForwardIrpToQueue(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue)
Definition: urbroute.cpp:308
static USBD_STATUS NTAPI UcxPrepareTransfer(_In_ PURB Urb, _In_ UcxUsbDevice *Device, _In_ const UcxUrbFunction *Function, _Outptr_ UcxPipe **TargetPipe)
Definition: urbroute.cpp:680
BOOLEAN NTAPI UcxValidatePipeHandle(_In_ UcxUsbDevice *Device, _In_ USBD_PIPE_HANDLE Handle)
Definition: urbroute.cpp:356
static NTSTATUS NTAPI UcxHandleStandardRequest(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ const UcxUrbFunction *Function)
Definition: urbroute.cpp:492
static NTSTATUS NTAPI UcxHandleGetCurrentFrame(_In_ PIRP Irp, _In_ PURB Urb, _In_ UcxUsbDevice *Device)
Definition: urbroute.cpp:619
static NTSTATUS NTAPI UcxHandleIsoch(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ UcxPipe *Pipe)
Definition: urbroute.cpp:574
static IO_COMPLETION_ROUTINE UcxLegacyTransferCompletion
Definition: urbroute.cpp:272
VOID NTAPI UcxLockTransferBuffer(_Inout_ PURB Urb)
Definition: urbroute.cpp:82
#define UCX_URB_TRANSFER
Definition: urbroute.cpp:165
static const UcxUrbFunction UcxUrbFunctions[]
Definition: urbroute.cpp:211
FORCEINLINE VOID NTAPI UcxSetTransferDirection(_Inout_ PURB Urb, _In_ const UcxPipe *Pipe)
Definition: urbroute.h:48
#define UCX_URB_FLAGS_KEEP_HUB_BITS
Definition: urbroute.h:11
#define USBD_STATUS_INVALID_PIPE_HANDLE
Definition: usb.h:205
LONG USBD_STATUS
Definition: usb.h:172
#define USBD_STATUS_PENDING
Definition: usb.h:179
#define USBD_STATUS_INVALID_URB_FUNCTION
Definition: usb.h:202
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by UcxProcessSubmitUrb().

◆ UcxSetTransferDirection()

FORCEINLINE VOID NTAPI UcxSetTransferDirection ( _Inout_ PURB  Urb,
_In_ const UcxPipe *  Pipe 
)

Pins TransferFlags' direction to the pipe; the client's own bit is ignored.

Definition at line 48 of file urbroute.h.

51{
52 if (Pipe->DirectionIn)
53 Urb->UrbControlTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
54 else
55 Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN;
56}

Referenced by UcxHandleIsoch(), UcxProcessLegacyUrb(), and UcxXrbSubmitTransfer().

◆ UcxStampProcessorNumber()

FORCEINLINE VOID NTAPI UcxStampProcessorNumber ( _Inout_ PURB  Urb)

Definition at line 32 of file urbroute.h.

34{
35 *(PULONG)&Urb->UrbControlTransfer.hca = KeGetCurrentProcessorNumber();
36}
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by UcxPrepareTransfer(), and UcxXrbSubmitTransfer().

◆ UcxUnlockTransferBuffer()

VOID NTAPI UcxUnlockTransferBuffer ( _Inout_ PURB  Urb)

Definition at line 130 of file urbroute.cpp.

132{
133 struct _URB_CONTROL_TRANSFER* Transfer = &Urb->UrbControlTransfer;
134
135 if (!(Urb->UrbHeader.UsbdFlags & UCX_URB_FLAG_BUFFER_LOCKED))
136 return;
137
139 IoFreeMdl(Transfer->TransferBufferMDL);
140 Transfer->TransferBufferMDL = NULL;
141 Urb->UrbHeader.UsbdFlags &= ~UCX_URB_FLAG_BUFFER_LOCKED;
142}
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1432

Referenced by UcxLegacyTransferCompletion(), and UcxXrbTransferCompletion().

◆ UcxUsbdStatusToNtStatus()

NTSTATUS NTAPI UcxUsbdStatusToNtStatus ( _In_ USBD_STATUS  UsbdStatus)

Definition at line 18 of file urbroute.cpp.

20{
21 switch (UsbdStatus)
22 {
25 return STATUS_SUCCESS;
26
29
35
38
41
43 return STATUS_CANCELLED;
44
45 default:
47 }
48}
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define USBD_STATUS_PORT_OPERATION_PENDING
Definition: usb.h:178
#define USBD_STATUS_BAD_START_FRAME
Definition: usb.h:209
_In_ NTSTATUS _In_ USBD_STATUS UsbdStatus
Definition: wdfusb.h:403

Referenced by UcxLegacyTransferCompletion(), UcxProcessLegacyUrb(), UcxXrbStreamsCompletion(), and UcxXrbTransferCompletion().

◆ UcxValidatePipeHandle()

BOOLEAN NTAPI UcxValidatePipeHandle ( _In_ UcxUsbDevice *  Device,
_In_ USBD_PIPE_HANDLE  Handle 
)

Definition at line 356 of file urbroute.cpp.

359{
363
364 if (Pipe != NULL && !Pipe->BelongsToStream)
365 {
366 if (Device->m_StalePipeIoAllowed)
367 {
368 SpinLockGuard Guard(&Device->m_TrackingLock);
369
370 for (Entry = Device->m_TrackingList.Flink; Entry != &Device->m_TrackingList; Entry = Entry->Flink)
371 {
372 if (&CONTAINING_RECORD(Entry, UcxEndpoint, m_TrackingLink)->m_Pipe == Pipe)
373 {
374 Valid = TRUE;
375 break;
376 }
377 }
378 }
379 else
380 {
381 Valid = Pipe->IsValid();
382 }
383 }
384
386 {
387 DPRINT1("Client used invalid pipe handle %p on device %p\n", Handle, Device);
390 }
391
392 return Valid;
393}
unsigned char BOOLEAN
Definition: actypes.h:127
BOOLEAN NTAPI UcxAnyUsbdHandleHasVerifier(_In_ UcxUsbDevice *Device)
Definition: clientif.cpp:646
BOOLEAN Valid
Definition: desccheck.cpp:2227
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
#define TRUE
Definition: types.h:120
ULONG Handle
Definition: gdb_input.c:15
BOOLEAN NTAPI KdRefreshDebuggerNotPresent(VOID)
Definition: kdapi.c:2679
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
NTSYSAPI void WINAPI DbgBreakPoint(void)

Referenced by UcxPrepareTransfer(), and UcxProcessLegacyUrb().