ReactOS 0.4.17-dev-1281-g065abb3
UcxUsbDevice Class Reference

#include <devobj.h>

Collaboration diagram for UcxUsbDevice:

Public Types

typedef VOID(UcxUsbDevice::* PFN_UCX_OPERATION_DONE) ()
 

Public Member Functions

VOID RemoteWakeNotification (_In_ ULONG Interface)
 
VOID DeleteFromHub ()
 
VOID DisconnectPort (_In_ ULONG PortNumber)
 
VOID SetPdo (_In_ PDEVICE_OBJECT Pdo)
 
ULONG64 Timestamp () const
 
BOOLEAN IsRootHub () const
 
BOOLEAN IsHub () const
 
USB_DEVICE_SPEED Speed () const
 
BOOLEAN AllowsEndpointStart () const
 
VOID InitializeAsRootHub (_In_ UCXROOTHUB Handle, _In_ UcxController *Controller)
 
VOID WalkSubtree (_In_ PFN_UCX_DEVICE_VISITOR Visitor, _In_opt_ PVOID Context, _In_ BOOLEAN IncludeDisconnected)
 
VOID DispatchManagement (_In_ WDFREQUEST Request, _In_ ULONG IoControlCode)
 
VOID FailManagement (_In_ WDFREQUEST Request, _In_ ULONG IoControlCode)
 
NTSTATUS OnHcdEnableDone (_In_ PIRP Irp, _In_ PUSBDEVICE_ENABLE Enable)
 
NTSTATUS OnHcdResetDone (_In_ PIRP Irp, _In_ PUSBDEVICE_RESET Reset)
 
NTSTATUS OnHcdEndpointsConfigureDone (_In_ PIRP Irp, _In_ PENDPOINTS_CONFIGURE Configure)
 
VOID CompleteHubOperation ()
 
VOID RegisterComposite (_In_ WDFREQUEST Request)
 
VOID UnregisterComposite (_In_ WDFREQUEST Request)
 
VOID SetFunctionData (_In_ WDFREQUEST Request)
 
VOID RequestRemoteWakeNotification (_In_ WDFREQUEST Request)
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS EnableForwardProgress(_In_ PUCXHUB_FORWARD_PROGRESS_INFO Info)
 
VOID TrackStaleHandles ()
 
VOID ReportNoPingResponseIfPending ()
 

Static Public Member Functions

static VOID InitSetEventCallbacks (_Inout_ PUCXUSBDEVICE_INIT Init, _In_ PUCX_USBDEVICE_EVENT_CALLBACKS Callbacks)
 
static _Must_inspect_result_ NTSTATUS Create (_In_ UCXCONTROLLER Controller, _Inout_ PUCXUSBDEVICE_INIT *Init, _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes, _Out_ UCXUSBDEVICE *UsbDevice)
 
static _Must_inspect_result_ NTSTATUS CreateFromHub (_In_ UCXUSBDEVICE Hub, _In_ PUCXHUB_DEVICE_CREATE_INFO Info, _Out_ UCXUSBDEVICE *UsbDevice)
 
static UcxUsbDevice * FromHandle (_In_ UCXUSBDEVICE Handle)
 

Public Attributes

UCXUSBDEVICE m_Handle
 
UcxController * m_Controller
 
UcxUsbDevice * m_ParentHub
 
UCXHUB_DEVICE_CONTEXT m_HubDeviceContext
 
ULONG m_Type
 
USHORT m_BcdUsb
 
UCXUSBDEVICE_INFO m_Info
 
UcxUsbDeviceCallbacks m_Callbacks
 
PDEVICE_OBJECT m_Pdo
 
ULONG64 m_Timestamp
 
LIST_ENTRY m_ChildList
 
LIST_ENTRY m_ChildLink
 
LIST_ENTRY m_EndpointList
 
LIST_ENTRY m_StaleEndpointList
 
BOOLEAN m_Disconnected
 
BOOLEAN m_ChildrenMayLeavePurge
 
BOOLEAN m_EndpointsMayLeavePurge
 
KSPIN_LOCK m_TrackingLock
 
LIST_ENTRY m_TrackingList
 
BOOLEAN m_StalePipeIoAllowed
 
UcxEndpoint * m_DefaultEndpoint
 
UcxPipe * m_DefaultPipe
 
BOOLEAN m_Enabled
 
BOOLEAN m_DeprogrammedByControllerReset
 
BOOLEAN m_PendingDelete
 
BOOLEAN m_ResetFailedByControllerReset
 
BOOLEAN m_EndpointResetFailedByControllerReset
 
BOOLEAN m_FailNextStreamClose
 
PVOID m_PendingOperation
 
PFN_UCX_OPERATION_DONE m_PendingOperationDone
 
LONG m_PendingOperationCount
 
LONG m_PendingNoPingResponse
 
ULONG m_TransferFailureCount
 
UCXHUB_HUB_CONTEXT m_HubContext
 
PFN_UCXHUB_CLEAR_TT_BUFFER m_HubClearTtBuffer
 
PFN_UCXHUB_NO_PING_RESPONSE m_HubNoPingResponse
 
BOOLEAN m_HubUsesGrownInterface
 
KSPIN_LOCK m_RemoteWakeLock
 
UcxRemoteWakeSlot m_RemoteWake
 
ULONG m_FunctionCount
 
UcxFunctionRecord * m_Functions
 
WDFMEMORY m_FunctionsMemory
 
KSPIN_LOCK m_UsbdHandleLock
 
LIST_ENTRY m_UsbdHandleList
 

Private Member Functions

VOID InitializeLists ()
 
VOID StartOperation (_In_ PVOID Pending, _In_ PFN_UCX_OPERATION_DONE Done, _In_ LONG Count)
 
PVOID TakeOperation ()
 
VOID FanOutToEndpoints (_In_ EpEvent Event)
 
VOID HandleHubPurgeIo (_In_ WDFREQUEST Request, _In_ BOOLEAN OnSuspend)
 
VOID HandleHubStartIo (_In_ WDFREQUEST Request)
 
VOID HandleHubAbortIo (_In_ WDFREQUEST Request)
 
VOID HandleHubTreePurge (_In_ WDFREQUEST Request)
 
VOID HandleHubReset (_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
 
VOID HandleHubDisable (_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
 
VOID HandleHubEndpointsConfigure (_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
 
VOID UpdateFromHub (_In_ WDFREQUEST Request)
 
VOID SendResetToController ()
 
VOID PendReset ()
 
VOID SendDisableToController ()
 
VOID PendDisable ()
 
VOID SendEndpointsConfigureToController ()
 
VOID PendEndpointsConfigure ()
 
VOID CompleteHubRequest ()
 
VOID CompleteEnableIrp ()
 
VOID CompleteEndpointsConfigureIrp ()
 
VOID FinishEndpointResetRequest ()
 

Static Private Attributes

static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
 
static EVT_WDF_REQUEST_CANCEL EvtRemoteWakeCancel
 

Detailed Description

Definition at line 49 of file devobj.h.

Member Typedef Documentation

◆ PFN_UCX_OPERATION_DONE

typedef VOID(UcxUsbDevice::* UcxUsbDevice::PFN_UCX_OPERATION_DONE) ()

Definition at line 53 of file devobj.h.

Member Function Documentation

◆ _IRQL_requires_()

UcxUsbDevice::_IRQL_requires_ ( PASSIVE_LEVEL  )

◆ AllowsEndpointStart()

BOOLEAN UcxUsbDevice::AllowsEndpointStart ( ) const
inline

Definition at line 130 of file devobj.h.

131 {
134 }
BOOLEAN m_Disconnected
Definition: devobj.h:231
BOOLEAN m_DeprogrammedByControllerReset
Definition: devobj.h:244
BOOLEAN m_Enabled
Definition: devobj.h:243
BOOLEAN m_EndpointsMayLeavePurge
Definition: devobj.h:233

Referenced by EndpointMachine::DeviceAllowsStart().

◆ CompleteEnableIrp()

VOID UcxUsbDevice::CompleteEnableIrp ( )
private

Definition at line 673 of file devicemgmt.cpp.

674{
676
678 DPRINT1("UsbDevice %p enable failed by controller reset\n", m_Handle);
679
681}
struct _IRP * PIRP
#define DPRINT1
Definition: precomp.h:8
UCXUSBDEVICE m_Handle
Definition: devobj.h:215
PVOID TakeOperation()
Definition: devobj.h:290
static VOID NTAPI UcxResumeIrpCompletion(_In_ PIRP Irp, _In_ NTSTATUS Status)
Definition: devicemgmt.cpp:662
_In_ PIRP Irp
Definition: kse.h:79
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136

Referenced by CompleteEnableIrp(), and OnHcdEnableDone().

◆ CompleteEndpointsConfigureIrp()

VOID UcxUsbDevice::CompleteEndpointsConfigureIrp ( )
private

◆ CompleteHubOperation()

VOID UcxUsbDevice::CompleteHubOperation ( )

An endpoint finished its part of the current hub operation.

Definition at line 358 of file devicemgmt.cpp.

359{
361
363 return;
364
367 (this->*Done)();
368}
#define InterlockedDecrement
Definition: armddk.h:52
PFN_UCX_OPERATION_DONE m_PendingOperationDone
Definition: devobj.h:254
VOID(UcxUsbDevice::* PFN_UCX_OPERATION_DONE)()
Definition: devobj.h:53
LONG m_PendingOperationCount
Definition: devobj.h:255
KEVENT Done
Definition: devreq.cpp:1162
#define NULL
Definition: types.h:112

Referenced by CompleteHubOperation(), and EndpointMachine::CompleteHubOperation().

◆ CompleteHubRequest()

VOID UcxUsbDevice::CompleteHubRequest ( )
private

Definition at line 654 of file devicemgmt.cpp.

655{
656 WdfRequestComplete((WDFREQUEST)TakeOperation(), STATUS_SUCCESS);
657}

Referenced by CompleteHubRequest(), HandleHubAbortIo(), HandleHubPurgeIo(), and HandleHubStartIo().

◆ Create()

_Must_inspect_result_ NTSTATUS UcxUsbDevice::Create ( _In_ UCXCONTROLLER  Controller,
_Inout_ PUCXUSBDEVICE_INIT *  Init,
_In_opt_ PWDF_OBJECT_ATTRIBUTES  Attributes,
_Out_ UCXUSBDEVICE *  UsbDevice 
)
static

Definition at line 81 of file devobj.cpp.

86{
88 UcxUsbDevice* Parent = FromHandle(Init->ParentHub);
90 WDF_OBJECT_ATTRIBUTES UcxAttributes;
94
95 PAGED_CODE();
96
97 *UsbDevice = NULL;
98
101
102 /* Devices hang off their parent hub so deleting a hub deletes what is below it */
103 if (Attributes != NULL)
104 Attributes->ParentObject = Init->ParentHub;
105 else
106 UcxAttributes.ParentObject = Init->ParentHub;
107
109 Attributes != NULL ? &UcxAttributes : NULL,
110 &Object);
111 if (!NT_SUCCESS(Status))
112 {
113 DPRINT1("UsbDevice object create failed under hub %p 0x%lx\n", Init->ParentHub, Status);
114 return Status;
115 }
116
117 Device = new (UcxGetUsbDeviceContext(Object)) UcxUsbDevice();
118 Device->m_Handle = (UCXUSBDEVICE)Object;
119 Device->m_Controller = ControllerContext;
120 Device->m_ParentHub = Parent;
121 Device->m_HubDeviceContext = Init->HubDeviceContext;
122 Device->m_Info = Init->Info;
123 Device->m_Callbacks = Init->Callbacks;
124 Device->m_Timestamp = UcxSystemTimeNow();
125 Device->InitializeLists();
126
127 /* Keeps the tree intact past WdfObjectDelete for stale endpoints of deleted devices */
128 WdfObjectReference(Parent->m_Handle);
129
130 {
131 SpinLockGuard Guard(&ControllerContext->m_TopologyLock);
132
133 if (Parent->m_Disconnected)
134 {
136 }
137 else
138 {
139 InsertTailList(&Parent->m_ChildList, &Device->m_ChildLink);
140 ControllerContext->m_ChildDeviceCount++;
141
142 /* A tree purge in progress above covers new devices too */
143 Device->m_ChildrenMayLeavePurge = Parent->m_ChildrenMayLeavePurge;
144 Device->m_EndpointsMayLeavePurge = Parent->m_ChildrenMayLeavePurge;
145 }
146 }
147
148 if (!NT_SUCCESS(Status))
149 {
150 DPRINT1("UsbDevice %p not created, parent hub %p is disconnected\n", Object, Parent->m_Handle);
152 return Status;
153 }
154
155 DPRINT("UsbDevice %p created under hub %p\n", Device->m_Handle, Parent->m_Handle);
156
157 *UsbDevice = Device->m_Handle;
158 Init->Created = Device->m_Handle;
159 *InitPointer = NULL;
160 return STATUS_SUCCESS;
161}
#define PAGED_CODE()
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
LONG NTSTATUS
Definition: precomp.h:26
static UcxController * FromHandle(_In_ UCXCONTROLLER Handle)
Definition: hostctl.cpp:14
KSPIN_LOCK m_TopologyLock
Definition: hostctl.h:310
ULONG m_ChildDeviceCount
Definition: hostctl.h:311
static UcxUsbDevice * FromHandle(_In_ UCXUSBDEVICE Handle)
Definition: devobj.cpp:18
static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
Definition: devobj.h:352
static ULONG64 NTAPI UcxSystemTimeNow(VOID)
Definition: devobj.cpp:27
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define InsertTailList(ListHead, Entry)
Status
Definition: gdiplustypes.h:24
_In_ UCXUSBDEVICE UsbDevice
Definition: hostctl.h:31
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define DPRINT
Definition: sndvol32.h:73
WDFOBJECT ParentObject
Definition: wdfobject.h:130
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback
Definition: wdfobject.h:115
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ NTSTATUS NTAPI UcxCreateObjectWithTwoContexts(_In_ PWDF_OBJECT_ATTRIBUTES Primary, _In_opt_ PWDF_OBJECT_ATTRIBUTES Secondary, _Out_ WDFOBJECT *Object)
Definition: ucxutil.cpp:19
WdfObjectDelete(String)
BOOL InitPointer(PPDEV ppdev)
Definition: pointer.c:143
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803

Referenced by Create().

◆ CreateFromHub()

_Must_inspect_result_ NTSTATUS UcxUsbDevice::CreateFromHub ( _In_ UCXUSBDEVICE  Hub,
_In_ PUCXHUB_DEVICE_CREATE_INFO  Info,
_Out_ UCXUSBDEVICE *  UsbDevice 
)
static

Definition at line 297 of file devobj.cpp.

301{
303 UcxController* Controller = HubDevice->m_Controller;
306
307 PAGED_CODE();
308 NT_ASSERT(HubDevice->IsHub());
309
310 RtlZeroMemory(&Init, sizeof(Init));
311 Init.ParentHub = Hub;
312 Init.HubDeviceContext = Info->HubDeviceContext;
313 Init.Info.Size = sizeof(Init.Info);
314 Init.Info.DeviceSpeed = Info->DeviceSpeed;
315
316 Status = UcxBuildPortPath(HubDevice, Info->PortNumber, &Init.Info);
317 if (!NT_SUCCESS(Status))
318 {
319 *UsbDevice = NULL;
320 return Status;
321 }
322
323 if (!Controller->BlockReset())
324 {
326 DPRINT1("Hub %p port %lu device add during controller reset 0x%lx\n", Hub, Info->PortNumber, Status);
327 }
328 else
329 {
330 Status = Controller->m_Config.EvtControllerUsbDeviceAdd(Controller->m_Handle, &Init.Info, &Init);
331 Controller->UnblockReset();
332
333 if (!NT_SUCCESS(Status))
334 DPRINT1("Hub %p port %lu HCD device add failed 0x%lx\n", Hub, Info->PortNumber, Status);
335 }
336
337 if (NT_SUCCESS(Status))
338 {
339 *UsbDevice = Init.Created;
340 return Status;
341 }
342
343 *UsbDevice = NULL;
344 if (Init.Created != NULL)
345 FromHandle(Init.Created)->DeleteFromHub();
346
347 return Status;
348}
HubFdo * Hub
Definition: bootdev.cpp:261
WDFDEVICE HubDevice
Definition: childpdo.cpp:989
VOID DeleteFromHub()
Definition: devobj.cpp:351
static NTSTATUS NTAPI UcxBuildPortPath(_In_ UcxUsbDevice *Hub, _In_ ULONG PortNumber, _Inout_ PUCXUSBDEVICE_INFO Info)
Definition: devobj.cpp:249
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by CreateFromHub().

◆ DeleteFromHub()

VOID UcxUsbDevice::DeleteFromHub ( )

Definition at line 351 of file devobj.cpp.

352{
353 LIST_ENTRY Stale;
356
357 PAGED_CODE();
358
359 DPRINT("UsbDevice %p deleted by the hub\n", m_Handle);
360
362
363 /* Endpoints still alive skip the stale stage from here on */
365
366 InitializeListHead(&Stale);
367 {
369
371 {
372 /* Move the whole stale list over in one step */
375 Stale.Flink->Blink = &Stale;
376 Stale.Blink->Flink = &Stale;
378 }
379 }
380
381 while (!IsListEmpty(&Stale))
382 {
383 Entry = RemoveHeadList(&Stale);
385
387 Endpoint->Post(EpEvent::StaleReplaced);
388 }
389
391}
UcxController * m_Controller
Definition: devobj.h:216
BOOLEAN m_PendingDelete
Definition: devobj.h:245
LIST_ENTRY m_StaleEndpointList
Definition: devobj.h:230
VOID NTAPI UcxDropLeakedUsbdHandles(_In_ UcxUsbDevice *Device)
Definition: clientif.cpp:615
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
#define TRUE
Definition: types.h:120
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
FORCEINLINE VOID NTAPI UcxClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: ucxutil.h:84

Referenced by CreateFromHub(), DeleteFromHub(), and UcxHubDeviceDelete().

◆ DisconnectPort()

VOID UcxUsbDevice::DisconnectPort ( _In_ ULONG  PortNumber)

Port 0 means this hub itself went away.

Definition at line 440 of file devobj.cpp.

442{
443 LIST_ENTRY Endpoints;
447
448 InitializeListHead(&Endpoints);
449
450 DPRINT("Hub %p disconnect on port %lu\n", m_Handle, PortNumber);
451
452 {
454
455 if (PortNumber == 0)
456 {
458 }
459 else
460 {
461 /* A new enumeration may already sit on the port beside the old device */
463 {
465 const USB_DEVICE_PORT_PATH* Path = &Child->m_Info.PortPath;
466
467 if (Path->PortPath[Path->PortPathDepth - 1] == PortNumber)
468 Child->WalkSubtree(UcxDisconnectVisitor, &Endpoints, FALSE);
469 }
470 }
471 }
472
473 while (!IsListEmpty(&Endpoints))
474 {
475 Entry = RemoveHeadList(&Endpoints);
477 Endpoint = CONTAINING_RECORD(Entry, UcxEndpoint, m_DisconnectLink);
478
479 /* Root hub endpoints have no machine */
480 if (Endpoint->HasMachine())
481 Endpoint->Post(EpEvent::HubDisconnect);
482
484 }
485}
VOID WalkSubtree(_In_ PFN_UCX_DEVICE_VISITOR Visitor, _In_opt_ PVOID Context, _In_ BOOLEAN IncludeDisconnected)
Definition: devobj.cpp:396
LIST_ENTRY m_ChildList
Definition: devobj.h:227
LIST_ENTRY m_ChildLink
Definition: devobj.h:228
static VOID NTAPI UcxDisconnectVisitor(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: devobj.cpp:420
#define FALSE
Definition: types.h:117
UNICODE_STRING Path
_In_ ULONG PortNumber
Definition: hubucx.h:272
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826

Referenced by DisconnectPort(), UcxController::SetFailed(), and UcxHubDeviceDisconnect().

◆ DispatchManagement()

VOID UcxUsbDevice::DispatchManagement ( _In_ WDFREQUEST  Request,
_In_ ULONG  IoControlCode 
)

Definition at line 80 of file devicemgmt.cpp.

83{
84 UCXCONTROLLER Controller = m_Controller->m_Handle;
87 PURB Urb;
88
90
91 DPRINT("UsbDevice %p IOCTL 0x%lx request %p\n", m_Handle, IoControlCode, Request);
92
93 switch (IoControlCode)
94 {
96 HandleHubPurgeIo(Request, ((PUSBDEVICE_PURGEIO)Arg1)->OnSuspend);
97 break;
98
101 break;
102
105 break;
106
109 break;
110
112 Urb = (PURB)Arg1;
113 if (Urb->UrbHeader.Function == URB_FUNCTION_OPEN_STATIC_STREAMS)
114 UcxEndpoint::FromPipe(Urb->UrbOpenStaticStreams.PipeHandle)->HandleClientStreamsEnable(Request);
115 else if (Urb->UrbHeader.Function == URB_FUNCTION_CLOSE_STATIC_STREAMS)
116 UcxEndpoint::FromPipe(Urb->UrbPipeRequest.PipeHandle)->HandleClientStreamsDisable(Request);
117 else
118 {
119 DPRINT1("UsbDevice %p unexpected URB function 0x%x\n", m_Handle, Urb->UrbHeader.Function);
120 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
121 }
122 break;
123
126 break;
127
130 break;
131
134 break;
135
138 break;
139
140 /* Goes to the device's default endpoint, not the one in the payload */
143 break;
144
147 break;
148
151 break;
152
155 break;
156
159 break;
160
161 default:
162 DPRINT1("UsbDevice %p unexpected IOCTL 0x%lx\n", m_Handle, IoControlCode);
163 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
164 break;
165 }
166}
UCXCONTROLLER m_Handle
Definition: hostctl.h:287
VOID HandleHubReset(_In_ WDFREQUEST Request)
Definition: pipeio.cpp:16
UcxEndpointCallbacks m_Callbacks
Definition: pipe.h:289
static UcxEndpoint * FromHandle(_In_ UCXENDPOINT Handle)
Definition: pipe.cpp:91
VOID HandleClientStreamsDisable(_In_ WDFREQUEST Request)
Definition: pipeio.cpp:298
VOID HandleClientStreamsEnable(_In_ WDFREQUEST Request)
Definition: pipeio.cpp:290
static UcxEndpoint * FromPipe(_In_ USBD_PIPE_HANDLE Handle)
Definition: pipe.h:241
VOID HandleHubStartIo(_In_ WDFREQUEST Request)
Definition: devicemgmt.cpp:422
VOID HandleHubTreePurge(_In_ WDFREQUEST Request)
Definition: devicemgmt.cpp:465
VOID HandleHubEndpointsConfigure(_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
Definition: devicemgmt.cpp:548
VOID HandleHubAbortIo(_In_ WDFREQUEST Request)
Definition: devicemgmt.cpp:433
UcxEndpoint * m_DefaultEndpoint
Definition: devobj.h:240
VOID HandleHubReset(_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
Definition: devicemgmt.cpp:501
VOID UpdateFromHub(_In_ WDFREQUEST Request)
Definition: devicemgmt.cpp:583
UcxUsbDeviceCallbacks m_Callbacks
Definition: devobj.h:222
ULONG64 m_Timestamp
Definition: devobj.h:224
VOID HandleHubDisable(_In_ WDFREQUEST Request, _In_ BOOLEAN AfterReset)
Definition: devicemgmt.cpp:532
VOID HandleHubPurgeIo(_In_ WDFREQUEST Request, _In_ BOOLEAN OnSuspend)
Definition: devicemgmt.cpp:409
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define IOCTL_UCXHUB_DEVICE_ENABLE
Definition: hubucx.h:53
#define IOCTL_UCXHUB_DEVICE_ADDRESS
Definition: hubucx.h:55
#define IOCTL_UCXHUB_DEVICE_TREE_PURGE_IO
Definition: hubucx.h:67
#define IOCTL_UCXHUB_DEVICE_START_IO
Definition: hubucx.h:60
#define IOCTL_UCXHUB_ENDPOINT_RESET
Definition: hubucx.h:63
#define IOCTL_UCXHUB_DEVICE_UPDATE
Definition: hubucx.h:56
#define IOCTL_UCXHUB_DEVICE_DISABLE
Definition: hubucx.h:58
#define IOCTL_UCXHUB_DEVICE_RESET
Definition: hubucx.h:54
#define IOCTL_UCXHUB_DEVICE_HUB_INFO
Definition: hubucx.h:57
#define IOCTL_UCXHUB_DEFAULT_ENDPOINT_UPDATE
Definition: hubucx.h:62
#define IOCTL_UCXHUB_ENDPOINTS_CONFIGURE
Definition: hubucx.h:61
#define IOCTL_UCXHUB_DEVICE_PURGE_IO
Definition: hubucx.h:59
#define IOCTL_UCXHUB_DEVICE_ABORT_IO
Definition: hubucx.h:68
PFN_UCX_DEFAULT_ENDPOINT_UPDATE DefaultEndpointUpdate
Definition: pipe.h:85
PVOID Arg1
Definition: ucxutil.h:103
UCX_USBDEVICE_EVENT_CALLBACKS Public
Definition: devobj.h:17
PFN_UCX_USBDEVICE_ADDRESS EvtUsbDeviceAddress
Definition: ucxusbdevice.h:350
PFN_UCX_USBDEVICE_ENABLE EvtUsbDeviceEnable
Definition: ucxusbdevice.h:347
PFN_UCX_USBDEVICE_HUB_INFO EvtUsbDeviceHubInfo
Definition: ucxusbdevice.h:352
Definition: usb.h:565
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _URB * PURB
#define URB_FUNCTION_OPEN_STATIC_STREAMS
Definition: usb.h:152
#define URB_FUNCTION_CLOSE_STATIC_STREAMS
Definition: usb.h:153
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32

Referenced by DispatchManagement().

◆ FailManagement()

VOID UcxUsbDevice::FailManagement ( _In_ WDFREQUEST  Request,
_In_ ULONG  IoControlCode 
)

Controller reset in progress or device deprogrammed.

Definition at line 170 of file devicemgmt.cpp.

173{
175 PURB Urb;
176
177 switch (IoControlCode)
178 {
179 /* The suspend hint is dropped on this path */
182 break;
183
186 break;
187
190 break;
191
193 Urb = (PURB)Arg1;
194 if (Urb->UrbHeader.Function == URB_FUNCTION_OPEN_STATIC_STREAMS)
195 {
196 UcxEndpoint* Endpoint = UcxEndpoint::FromPipe(Urb->UrbOpenStaticStreams.PipeHandle);
197
198 NT_ASSERT(!Endpoint->m_OpenFailedOnReset);
199 Endpoint->m_OpenFailedOnReset = TRUE;
200 DPRINT1("Endpoint %p static streams open failed by controller reset\n", Endpoint->m_Handle);
201 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
202 }
203 else if (Urb->UrbHeader.Function == URB_FUNCTION_CLOSE_STATIC_STREAMS)
204 {
205 UcxEndpoint::FromPipe(Urb->UrbPipeRequest.PipeHandle)->HandleClientStreamsDisable(Request);
206 }
207 else
208 {
209 DPRINT1("UsbDevice %p unexpected URB function 0x%x during reset\n", m_Handle, Urb->UrbHeader.Function);
210 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
211 }
212 break;
213
218 break;
219
222 break;
223
226 break;
227
231 DPRINT1("UsbDevice %p endpoint reset failed by controller reset\n", m_Handle);
232 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
233 break;
234
235 default:
236 DPRINT1("UsbDevice %p IOCTL 0x%lx failed by controller reset\n", m_Handle, IoControlCode);
237 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
238 break;
239 }
240}
BOOLEAN m_EndpointResetFailedByControllerReset
Definition: devobj.h:249
BOOLEAN m_ResetFailedByControllerReset
Definition: devobj.h:248

Referenced by FailManagement().

◆ FanOutToEndpoints()

VOID UcxUsbDevice::FanOutToEndpoints ( _In_ EpEvent  Event)
private

Definition at line 372 of file devicemgmt.cpp.

374{
375 LIST_ENTRY Endpoints;
378 LONG Count = 0;
379
380 InitializeListHead(&Endpoints);
381
382 {
384
386 {
388
389 WdfObjectReference(Endpoint->m_Handle);
390 InsertTailList(&Endpoints, &Endpoint->m_OperationLink);
391 Count++;
392 }
393 }
394
396
397 while (!IsListEmpty(&Endpoints))
398 {
399 Entry = RemoveHeadList(&Endpoints);
401 Endpoint = CONTAINING_RECORD(Entry, UcxEndpoint, m_OperationLink);
402
403 Endpoint->Post(Event);
405 }
406}
LIST_ENTRY m_EndpointList
Definition: devobj.h:229
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
long LONG
Definition: pedump.c:60
USHORT Count
Definition: userreq.cpp:200

Referenced by FanOutToEndpoints(), HandleHubAbortIo(), HandleHubPurgeIo(), and HandleHubStartIo().

◆ FinishEndpointResetRequest()

VOID UcxUsbDevice::FinishEndpointResetRequest ( )
private

Definition at line 691 of file devicemgmt.cpp.

Referenced by FinishEndpointResetRequest(), and OnHcdResetDone().

◆ FromHandle()

UcxUsbDevice * UcxUsbDevice::FromHandle ( _In_ UCXUSBDEVICE  Handle)
static

Definition at line 18 of file devobj.cpp.

20{
21 return UcxGetUsbDeviceContext(Handle);
22}
ULONG Handle
Definition: gdb_input.c:15

Referenced by Create(), CreateFromHub(), and FromHandle().

◆ HandleHubAbortIo()

VOID UcxUsbDevice::HandleHubAbortIo ( _In_ WDFREQUEST  Request)
private

Definition at line 433 of file devicemgmt.cpp.

435{
436 StartOperation(Request, &UcxUsbDevice::CompleteHubRequest, 0);
437 FanOutToEndpoints(EpEvent::HubAbort);
438}
VOID FanOutToEndpoints(_In_ EpEvent Event)
Definition: devicemgmt.cpp:372
VOID StartOperation(_In_ PVOID Pending, _In_ PFN_UCX_OPERATION_DONE Done, _In_ LONG Count)
Definition: devicemgmt.cpp:345

Referenced by DispatchManagement(), FailManagement(), and HandleHubAbortIo().

◆ HandleHubDisable()

VOID UcxUsbDevice::HandleHubDisable ( _In_ WDFREQUEST  Request,
_In_ BOOLEAN  AfterReset 
)
private

Definition at line 532 of file devicemgmt.cpp.

535{
537 UCXENDPOINT DefaultEndpoint = Disable->DefaultEndpoint;
538
541 AfterReset ? &UcxUsbDevice::PendDisable : &UcxUsbDevice::SendDisableToController,
542 1);
543
544 UcxEndpoint::FromHandle(DefaultEndpoint)->Post(EpEvent::HubDisable);
545}
BOOLEAN Post(_In_ EpEvent Event)
Definition: pipe.h:255
struct _USBDEVICE_DISABLE * PUSBDEVICE_DISABLE

Referenced by DispatchManagement(), FailManagement(), and HandleHubDisable().

◆ HandleHubEndpointsConfigure()

VOID UcxUsbDevice::HandleHubEndpointsConfigure ( _In_ WDFREQUEST  Request,
_In_ BOOLEAN  AfterReset 
)
private

Definition at line 548 of file devicemgmt.cpp.

551{
553 ULONG Count = Configure->EndpointsToDisableCount;
554 UCXENDPOINT* ToDisable = Configure->EndpointsToDisable;
555 ULONG Index;
556
557 if (Count == 0)
558 {
559 /* Unlike the parked path, nothing to disable after a reset is a failure here */
560 if (AfterReset)
561 {
562 DPRINT1("UsbDevice %p endpoints configure failed by controller reset\n", m_Handle);
563 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
564 }
565 else
566 {
568 }
569 return;
570 }
571
573 AfterReset ? &UcxUsbDevice::PendEndpointsConfigure
574 : &UcxUsbDevice::SendEndpointsConfigureToController,
575 Count);
576
577 for (Index = 0; Index < Count; Index++)
578 UcxEndpoint::FromHandle(ToDisable[Index])->Post(EpEvent::HubDisable);
579}
static LRESULT Configure(const CodecInfo *pi, HWND hWnd)
Definition: msrle32.c:1192
PFN_UCX_USBDEVICE_ENDPOINTS_CONFIGURE EvtUsbDeviceEndpointsConfigure
Definition: ucxusbdevice.h:346
uint32_t ULONG
Definition: typedefs.h:59
struct _ENDPOINTS_CONFIGURE * PENDPOINTS_CONFIGURE
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by DispatchManagement(), FailManagement(), and HandleHubEndpointsConfigure().

◆ HandleHubPurgeIo()

VOID UcxUsbDevice::HandleHubPurgeIo ( _In_ WDFREQUEST  Request,
_In_ BOOLEAN  OnSuspend 
)
private

Definition at line 409 of file devicemgmt.cpp.

412{
413 if (OnSuspend && m_Callbacks.Public.EvtUsbDeviceSuspend != NULL)
415
416 StartOperation(Request, &UcxUsbDevice::CompleteHubRequest, 0);
417 FanOutToEndpoints(EpEvent::HubPurge);
418}
PFN_UCX_USBDEVICE_SUSPEND EvtUsbDeviceSuspend
Definition: ucxusbdevice.h:355

Referenced by DispatchManagement(), FailManagement(), and HandleHubPurgeIo().

◆ HandleHubReset()

VOID UcxUsbDevice::HandleHubReset ( _In_ WDFREQUEST  Request,
_In_ BOOLEAN  AfterReset 
)
private

Definition at line 501 of file devicemgmt.cpp.

504{
506 ULONG Count = Reset->EndpointsToDisableCount;
507 UCXENDPOINT* ToDisable = Reset->EndpointsToDisable;
508 UCXENDPOINT DefaultEndpoint = Reset->DefaultEndpoint;
509 ULONG Index;
510
511 {
513
514 /* A tree purged device may leave tree purge once its parent has */
517 }
518
520 AfterReset ? &UcxUsbDevice::PendReset : &UcxUsbDevice::SendResetToController,
521 Count + 1);
522
523 /* The payload may be gone once the last post finishes the operation */
524 for (Index = 0; Index < Count; Index++)
525 UcxEndpoint::FromHandle(ToDisable[Index])->Post(EpEvent::HubDeviceReset);
526
527 UcxEndpoint::FromHandle(DefaultEndpoint)->Post(EpEvent::HubDeviceReset);
528}
static T & Reset(T &sei, UINT flags=SEE_MASK_FLAG_NO_UI)
UcxUsbDevice * m_ParentHub
Definition: devobj.h:217
struct _USBDEVICE_RESET * PUSBDEVICE_RESET

Referenced by DispatchManagement(), FailManagement(), and HandleHubReset().

◆ HandleHubStartIo()

VOID UcxUsbDevice::HandleHubStartIo ( _In_ WDFREQUEST  Request)
private

Definition at line 422 of file devicemgmt.cpp.

424{
427
428 StartOperation(Request, &UcxUsbDevice::CompleteHubRequest, 0);
429 FanOutToEndpoints(EpEvent::HubStartRequest);
430}
PFN_UCX_USBDEVICE_RESUME EvtUsbDeviceResume
Definition: ucxusbdevice.h:356

Referenced by DispatchManagement(), and HandleHubStartIo().

◆ HandleHubTreePurge()

VOID UcxUsbDevice::HandleHubTreePurge ( _In_ WDFREQUEST  Request)
private

Definition at line 465 of file devicemgmt.cpp.

467{
469 LIST_ENTRY Endpoints;
472 LONG Count = 0;
473
474 InitializeListHead(&Endpoints);
475
476 {
477 SpinLockGuard Guard(&Controller->m_TopologyLock);
478
480 }
481
482 for (Entry = Endpoints.Flink; Entry != &Endpoints; Entry = Entry->Flink)
483 Count++;
484
485 NT_ASSERT(Controller->m_PendingTreePurge == NULL && Controller->m_PendingTreePurgeEndpoints == 0);
486 Controller->m_PendingTreePurge = Request;
487 Controller->m_PendingTreePurgeEndpoints = Count;
488
489 while (!IsListEmpty(&Endpoints))
490 {
491 Entry = RemoveHeadList(&Endpoints);
493 Endpoint = CONTAINING_RECORD(Entry, UcxEndpoint, m_TreePurgeLink);
494
495 Endpoint->Post(EpEvent::HubTreePurge);
497 }
498}
static VOID NTAPI UcxTreePurgeVisitor(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: devicemgmt.cpp:444

Referenced by DispatchManagement(), FailManagement(), and HandleHubTreePurge().

◆ InitializeAsRootHub()

VOID UcxUsbDevice::InitializeAsRootHub ( _In_ UCXROOTHUB  Handle,
_In_ UcxController *  Controller 
)

Root hub setup; the device context lives on the UCXROOTHUB object.

Definition at line 50 of file devobj.cpp.

53{
54 m_Handle = (UCXUSBDEVICE)Handle;
57
58 /* Reported as SuperSpeed for filters that ask the controller about its speed */
59 m_Info.Size = sizeof(m_Info);
61
65}
UCXUSBDEVICE_INFO m_Info
Definition: devobj.h:221
VOID InitializeLists()
Definition: devobj.cpp:36
ULONG m_Type
Definition: devobj.h:219
#define UCX_DEVICE_TYPE_ROOT_HUB
Definition: devobj.h:12
#define UCX_DEVICE_TYPE_HUB
Definition: devobj.h:11
USB_DEVICE_SPEED DeviceSpeed
Definition: ucxusbdevice.h:176
@ UsbSuperSpeed
Definition: usb200.h:45

Referenced by UcxRootHub::Initialize(), and InitializeAsRootHub().

◆ InitializeLists()

VOID UcxUsbDevice::InitializeLists ( )
private

◆ InitSetEventCallbacks()

VOID UcxUsbDevice::InitSetEventCallbacks ( _Inout_ PUCXUSBDEVICE_INIT  Init,
_In_ PUCX_USBDEVICE_EVENT_CALLBACKS  Callbacks 
)
static

Definition at line 71 of file devobj.cpp.

74{
75 RtlZeroMemory(&Init->Callbacks, sizeof(Init->Callbacks));
76 RtlCopyMemory(&Init->Callbacks, Callbacks, min(Callbacks->Size, (ULONG)sizeof(Init->Callbacks)));
77}
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define min(a, b)
Definition: monoChain.cc:55
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by InitSetEventCallbacks().

◆ IsHub()

BOOLEAN UcxUsbDevice::IsHub ( ) const
inline

Definition at line 118 of file devobj.h.

119 {
120 return (m_Type & UCX_DEVICE_TYPE_HUB) != 0;
121 }

◆ IsRootHub()

BOOLEAN UcxUsbDevice::IsRootHub ( ) const
inline

Definition at line 112 of file devobj.h.

113 {
114 return (m_Type & UCX_DEVICE_TYPE_ROOT_HUB) != 0;
115 }

◆ OnHcdEnableDone()

NTSTATUS UcxUsbDevice::OnHcdEnableDone ( _In_ PIRP  Irp,
_In_ PUSBDEVICE_ENABLE  Enable 
)

Definition at line 709 of file devicemgmt.cpp.

712{
713 /* Completed again right here; the hub's routine runs nested */
714 if (!NT_SUCCESS(Irp->IoStatus.Status))
715 {
716 DPRINT1("UsbDevice %p HCD enable failed 0x%lx\n", m_Handle, Irp->IoStatus.Status);
719 }
720
721 StartOperation(Irp, &UcxUsbDevice::CompleteEnableIrp, 1);
722 m_Enabled = TRUE;
723 UcxEndpoint::FromHandle(Enable->DefaultEndpoint)->Post(EpEvent::ConfigureDone);
724
726}
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define IoCompleteRequest
Definition: irp.c:1272
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by OnHcdEnableDone().

◆ OnHcdEndpointsConfigureDone()

NTSTATUS UcxUsbDevice::OnHcdEndpointsConfigureDone ( _In_ PIRP  Irp,
_In_ PENDPOINTS_CONFIGURE  Configure 
)

Definition at line 743 of file devicemgmt.cpp.

746{
747 ULONG Count = Configure->EndpointsToEnableCount;
748 UCXENDPOINT* ToEnable = Configure->EndpointsToEnable;
749 ULONG Index;
750
751 if (!NT_SUCCESS(Irp->IoStatus.Status))
752 {
753 DPRINT1("UsbDevice %p HCD endpoints configure failed 0x%lx\n", m_Handle, Irp->IoStatus.Status);
756 }
757
758 if (Count == 0)
759 {
762 }
763
764 StartOperation(Irp, &UcxUsbDevice::CompleteEndpointsConfigureIrp, Count);
765
766 for (Index = 0; Index < Count; Index++)
767 UcxEndpoint::FromHandle(ToEnable[Index])->Post(EpEvent::ConfigureDone);
768
770}

Referenced by OnHcdEndpointsConfigureDone().

◆ OnHcdResetDone()

NTSTATUS UcxUsbDevice::OnHcdResetDone ( _In_ PIRP  Irp,
_In_ PUSBDEVICE_RESET  Reset 
)

Definition at line 730 of file devicemgmt.cpp.

733{
734 NT_ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
735
736 StartOperation(Irp, &UcxUsbDevice::FinishEndpointResetRequest, 1);
737 UcxEndpoint::FromHandle(Reset->DefaultEndpoint)->Post(EpEvent::DeviceResetDone);
738
740}

Referenced by OnHcdResetDone().

◆ PendDisable()

VOID UcxUsbDevice::PendDisable ( )
private

Definition at line 642 of file devicemgmt.cpp.

643{
644 UcxParkDuringReset(this, (WDFREQUEST)TakeOperation());
645}
static VOID NTAPI UcxParkDuringReset(_In_ UcxUsbDevice *Device, _In_ WDFREQUEST Request)
Definition: devicemgmt.cpp:624

Referenced by HandleHubDisable(), and PendDisable().

◆ PendEndpointsConfigure()

VOID UcxUsbDevice::PendEndpointsConfigure ( )
private

Definition at line 648 of file devicemgmt.cpp.

649{
650 UcxParkDuringReset(this, (WDFREQUEST)TakeOperation());
651}

Referenced by HandleHubEndpointsConfigure(), and PendEndpointsConfigure().

◆ PendReset()

VOID UcxUsbDevice::PendReset ( )
private

Definition at line 636 of file devicemgmt.cpp.

637{
638 UcxParkDuringReset(this, (WDFREQUEST)TakeOperation());
639}

Referenced by HandleHubReset(), and PendReset().

◆ RegisterComposite()

VOID UcxUsbDevice::RegisterComposite ( _In_ WDFREQUEST  Request)

Definition at line 640 of file devobj.cpp.

642{
644 PUSBD_FUNCTION_HANDLE Handles;
646 UcxFunctionRecord* Records;
647 WDFMEMORY Memory;
648 ULONG Index;
650
651 Handles = (PUSBD_FUNCTION_HANDLE)WdfRequestWdmGetIrp(Request)->AssociatedIrp.SystemBuffer;
652
653 if (Register == NULL || Handles == NULL ||
654 Register->Size != sizeof(*Register) ||
655 Register->Version != UCX_COMPOSITE_VERSION ||
656 Register->FunctionCount == 0 ||
657 Register->FunctionCount > UCX_MAX_COMPOSITE_FUNCTIONS)
658 {
659 DPRINT1("UsbDevice %p composite register rejected, request %p\n", m_Handle, Request);
660 WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
661 return;
662 }
663
665 Attributes.ParentObject = m_Handle;
666
667 Status = WdfMemoryCreate(&Attributes,
670 Register->FunctionCount * sizeof(UcxFunctionRecord),
671 &Memory,
672 (PVOID*)&Records);
673 if (!NT_SUCCESS(Status))
674 {
675 DPRINT1("UsbDevice %p function records allocation failed 0x%lx\n", m_Handle, Status);
676 WdfRequestComplete(Request, Status);
677 return;
678 }
679
680 RtlZeroMemory(Records, Register->FunctionCount * sizeof(UcxFunctionRecord));
681
682 {
684
685 if (m_FunctionsMemory != NULL)
686 {
688 }
689 else
690 {
691 m_FunctionCount = Register->FunctionCount;
692 m_Functions = Records;
694 }
695 }
696
697 if (!NT_SUCCESS(Status))
698 {
699 DPRINT1("UsbDevice %p is already registered as composite\n", m_Handle);
701 WdfRequestComplete(Request, Status);
702 return;
703 }
704
705 /* The output length is not checked */
706 for (Index = 0; Index < Register->FunctionCount; Index++)
707 {
708 Records[Index].Index = Index;
709 Records[Index].Device = this;
710 Handles[Index] = (USBD_FUNCTION_HANDLE)&Records[Index];
711 }
712
713 WdfRequestComplete(Request, STATUS_SUCCESS);
714}
ULONG m_FunctionCount
Definition: devobj.h:269
WDFMEMORY m_FunctionsMemory
Definition: devobj.h:271
UcxFunctionRecord * m_Functions
Definition: devobj.h:270
#define UCX_COMPOSITE_VERSION
Definition: devobj.cpp:13
#define UCX_MAX_COMPOSITE_FUNCTIONS
Definition: devobj.cpp:14
#define NonPagedPool
Definition: env_spec_w32.h:307
Config Register
Definition: hubwmi.cpp:126
UcxUsbDevice * Device
Definition: devobj.h:44
#define UCX_POOL_TAG
Definition: ucxutil.h:11
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
USBD_FUNCTION_HANDLE * PUSBD_FUNCTION_HANDLE
Definition: usbdlib.h:111
struct _REGISTER_COMPOSITE_DEVICE * PREGISTER_COMPOSITE_DEVICE
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147

Referenced by RegisterComposite().

◆ RemoteWakeNotification()

VOID UcxUsbDevice::RemoteWakeNotification ( _In_ ULONG  Interface)

Function wake from a device; completes the matching armed notification.

Definition at line 189 of file devobj.cpp.

191{
193 WDFREQUEST Request;
195 ULONG Index;
196
198
199 if (m_Functions == NULL)
200 {
203 }
204 else
205 {
206 for (Index = 0; Index < m_FunctionCount; Index++)
207 {
209
210 if (Candidate->Request != NULL && Candidate->Params->Interface == Interface)
211 {
212 Slot = Candidate;
213 break;
214 }
215 }
216 }
217
218 if (Slot == NULL)
219 {
221 DPRINT1("UsbDevice %p remote wake on interface %lu with no armed request\n", m_Handle, Interface);
222 return;
223 }
224
225 /* A failed unmark means the cancel routine owns the request */
226 if (!NT_SUCCESS(WdfRequestUnmarkCancelable(Slot->Request)))
227 {
229 DPRINT("UsbDevice %p remote wake request is being canceled\n", m_Handle);
230 return;
231 }
232
233 Request = Slot->Request;
234 Slot->Request = NULL;
235 Slot->Params = NULL;
236
238
239 DPRINT("UsbDevice %p remote wake on interface %lu\n", m_Handle, Interface);
240 WdfRequestComplete(Request, STATUS_SUCCESS);
241}
UcxRemoteWakeSlot m_RemoteWake
Definition: devobj.h:268
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
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
UcxRemoteWakeSlot Wake
Definition: devobj.h:46
WDFREQUEST Request
Definition: devobj.h:36
PREQUEST_REMOTE_WAKE_NOTIFICATION Params
Definition: devobj.h:37
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by RemoteWakeNotification(), and UcxApiUsbDeviceRemoteWakeNotification().

◆ ReportNoPingResponseIfPending()

VOID UcxUsbDevice::ReportNoPingResponseIfPending ( )

Called by failing transfer completions; tells the parent hub once per error.

Definition at line 521 of file devobj.cpp.

522{
524
526 return;
527
528 if (Parent != NULL && Parent->m_HubNoPingResponse != NULL)
529 Parent->m_HubNoPingResponse(Parent->m_HubContext, m_HubDeviceContext);
530}
#define InterlockedExchange
Definition: armddk.h:54
LONG m_PendingNoPingResponse
Definition: devobj.h:257
UCXHUB_DEVICE_CONTEXT m_HubDeviceContext
Definition: devobj.h:218

Referenced by ReportNoPingResponseIfPending().

◆ RequestRemoteWakeNotification()

VOID UcxUsbDevice::RequestRemoteWakeNotification ( _In_ WDFREQUEST  Request)

Definition at line 764 of file devobj.cpp.

766{
771
773 if (Params == NULL)
774 {
775 DPRINT1("UsbDevice %p remote wake request %p has no parameters\n", m_Handle, Request);
776 WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
777 return;
778 }
779
781
782 if ((m_Functions == NULL) != (Params->UsbdFunctionHandle == NULL))
783 {
785 }
786 else
787 {
789 : &((UcxFunctionRecord*)Params->UsbdFunctionHandle)->Wake;
790
791 if (Slot->Request != NULL)
792 {
794 }
795 else
796 {
797 Status = WdfRequestMarkCancelableEx(Request, UcxUsbDevice::EvtRemoteWakeCancel);
798 if (NT_SUCCESS(Status))
799 {
800 Slot->Request = Request;
801 Slot->Params = Params;
802 }
803 }
804 }
805
807
808 if (!NT_SUCCESS(Status))
809 {
810 DPRINT1("UsbDevice %p remote wake request %p failed 0x%lx\n", m_Handle, Request, Status);
811 WdfRequestComplete(Request, Status);
812 }
813}
static VOID Wake(_In_ UCHAR Csn)
Definition: hardware.c:154
struct _REQUEST_REMOTE_WAKE_NOTIFICATION * PREQUEST_REMOTE_WAKE_NOTIFICATION
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

Referenced by RequestRemoteWakeNotification().

◆ SendDisableToController()

VOID UcxUsbDevice::SendDisableToController ( )
private

Definition at line 609 of file devicemgmt.cpp.

610{
612}
PFN_UCX_USBDEVICE_DISABLE EvtUsbDeviceDisable
Definition: ucxusbdevice.h:348

Referenced by HandleHubDisable(), and SendDisableToController().

◆ SendEndpointsConfigureToController()

VOID UcxUsbDevice::SendEndpointsConfigureToController ( )
private

◆ SendResetToController()

VOID UcxUsbDevice::SendResetToController ( )
private

Definition at line 603 of file devicemgmt.cpp.

604{
606}
PFN_UCX_USBDEVICE_RESET EvtUsbDeviceReset
Definition: ucxusbdevice.h:349

Referenced by HandleHubReset(), and SendResetToController().

◆ SetFunctionData()

VOID UcxUsbDevice::SetFunctionData ( _In_ WDFREQUEST  Request)

Definition at line 747 of file devobj.cpp.

749{
751
752 Data = (PUCXHUB_FUNCTION_DATA)WdfRequestWdmGetIrp(Request)->AssociatedIrp.SystemBuffer;
753
754 {
756
757 ((UcxFunctionRecord*)Data->FunctionHandle)->ClientPdo = Data->PhysicalDeviceObject;
758 }
759
760 WdfRequestComplete(Request, STATUS_SUCCESS);
761}
struct _UCXHUB_FUNCTION_DATA * PUCXHUB_FUNCTION_DATA

Referenced by SetFunctionData().

◆ SetPdo()

VOID UcxUsbDevice::SetPdo ( _In_ PDEVICE_OBJECT  Pdo)

Definition at line 489 of file devobj.cpp.

491{
492 NT_ASSERT(m_Pdo == NULL);
493 m_Pdo = Pdo;
494}
PDEVICE_OBJECT m_Pdo
Definition: devobj.h:223
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280

Referenced by SetPdo(), and UcxHubDeviceSetPdo().

◆ Speed()

USB_DEVICE_SPEED UcxUsbDevice::Speed ( ) const
inline

Definition at line 124 of file devobj.h.

125 {
126 return m_Info.DeviceSpeed;
127 }

◆ StartOperation()

◆ TakeOperation()

◆ Timestamp()

ULONG64 UcxUsbDevice::Timestamp ( ) const
inline

Definition at line 99 of file devobj.h.

100 {
101 return m_Timestamp;
102 }

Referenced by UcxHubDeviceGetTimestamp().

◆ TrackStaleHandles()

VOID UcxUsbDevice::TrackStaleHandles ( )

Pipe handles are checked against the live endpoint list from now on.

Definition at line 500 of file devobj.cpp.

501{
504
506
509 {
511 {
513 InsertTailList(&m_TrackingList, &Endpoint->m_TrackingLink);
514 }
516 }
518}
BOOLEAN m_StalePipeIoAllowed
Definition: devobj.h:238
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135

Referenced by TrackStaleHandles(), and UpdateFromHub().

◆ UnregisterComposite()

VOID UcxUsbDevice::UnregisterComposite ( _In_ WDFREQUEST  Request)

Definition at line 718 of file devobj.cpp.

720{
721 WDFMEMORY Memory = NULL;
722
723 {
725
726 if (m_FunctionsMemory != NULL)
727 {
731 m_FunctionCount = 0;
732 }
733 }
734
735 if (Memory == NULL)
736 {
737 DPRINT1("UsbDevice %p composite unregister without a registration\n", m_Handle);
738 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE);
739 return;
740 }
741
743 WdfRequestComplete(Request, STATUS_SUCCESS);
744}

Referenced by UnregisterComposite().

◆ UpdateFromHub()

VOID UcxUsbDevice::UpdateFromHub ( _In_ WDFREQUEST  Request)
private

Definition at line 583 of file devicemgmt.cpp.

585{
587
588 if (Update->Flags.UpdateIsHub && Update->IsHub)
590
591 if (Update->Flags.UpdateAllowIoOnInvalidPipeHandles)
593
594 if (Update->Flags.UpdateDeviceDescriptor)
595 m_BcdUsb = Update->DeviceDescriptor->bcdUSB;
596
598}
@ Update
Definition: registry.c:565
VOID TrackStaleHandles()
Definition: devobj.cpp:500
USHORT m_BcdUsb
Definition: devobj.h:220
PFN_UCX_USBDEVICE_UPDATE EvtUsbDeviceUpdate
Definition: ucxusbdevice.h:351
struct _USBDEVICE_UPDATE * PUSBDEVICE_UPDATE

Referenced by DispatchManagement(), and UpdateFromHub().

◆ WalkSubtree()

VOID UcxUsbDevice::WalkSubtree ( _In_ PFN_UCX_DEVICE_VISITOR  Visitor,
_In_opt_ PVOID  Context,
_In_ BOOLEAN  IncludeDisconnected 
)

Definition at line 396 of file devobj.cpp.

400{
403
404 if (!IncludeDisconnected && m_Disconnected)
405 return;
406
407 Visitor(this, Context);
408
410 {
412 Child->WalkSubtree(Visitor, Context, IncludeDisconnected);
413 }
414}
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81

Referenced by DisconnectPort(), HandleHubTreePurge(), UcxController::WalkDevices(), and WalkSubtree().

Member Data Documentation

◆ EvtDestroy

VOID UcxUsbDevice::EvtDestroy
staticprivate

Definition at line 352 of file devobj.h.

Referenced by Create().

◆ EvtRemoteWakeCancel

VOID UcxUsbDevice::EvtRemoteWakeCancel
staticprivate

Definition at line 355 of file devobj.h.

Referenced by RequestRemoteWakeNotification().

◆ m_BcdUsb

USHORT UcxUsbDevice::m_BcdUsb

Definition at line 220 of file devobj.h.

Referenced by UpdateFromHub().

◆ m_Callbacks

◆ m_ChildLink

LIST_ENTRY UcxUsbDevice::m_ChildLink

Definition at line 228 of file devobj.h.

Referenced by DisconnectPort(), InitializeLists(), and WalkSubtree().

◆ m_ChildList

LIST_ENTRY UcxUsbDevice::m_ChildList

Definition at line 227 of file devobj.h.

Referenced by DisconnectPort(), InitializeLists(), and WalkSubtree().

◆ m_ChildrenMayLeavePurge

BOOLEAN UcxUsbDevice::m_ChildrenMayLeavePurge

Definition at line 232 of file devobj.h.

Referenced by FinishEndpointResetRequest(), HandleHubReset(), and InitializeAsRootHub().

◆ m_Controller

◆ m_DefaultEndpoint

UcxEndpoint* UcxUsbDevice::m_DefaultEndpoint

Definition at line 240 of file devobj.h.

Referenced by _IRQL_requires_(), and DispatchManagement().

◆ m_DefaultPipe

UcxPipe* UcxUsbDevice::m_DefaultPipe

Definition at line 241 of file devobj.h.

Referenced by _IRQL_requires_().

◆ m_DeprogrammedByControllerReset

BOOLEAN UcxUsbDevice::m_DeprogrammedByControllerReset

◆ m_Disconnected

BOOLEAN UcxUsbDevice::m_Disconnected

◆ m_Enabled

BOOLEAN UcxUsbDevice::m_Enabled

Definition at line 243 of file devobj.h.

Referenced by AllowsEndpointStart(), HandleHubDisable(), and OnHcdEnableDone().

◆ m_EndpointList

LIST_ENTRY UcxUsbDevice::m_EndpointList

Definition at line 229 of file devobj.h.

Referenced by FanOutToEndpoints(), InitializeLists(), and TrackStaleHandles().

◆ m_EndpointResetFailedByControllerReset

BOOLEAN UcxUsbDevice::m_EndpointResetFailedByControllerReset

Definition at line 249 of file devobj.h.

Referenced by FailManagement().

◆ m_EndpointsMayLeavePurge

BOOLEAN UcxUsbDevice::m_EndpointsMayLeavePurge

◆ m_FailNextStreamClose

BOOLEAN UcxUsbDevice::m_FailNextStreamClose

Definition at line 250 of file devobj.h.

◆ m_FunctionCount

ULONG UcxUsbDevice::m_FunctionCount

Definition at line 269 of file devobj.h.

Referenced by RegisterComposite(), RemoteWakeNotification(), and UnregisterComposite().

◆ m_Functions

UcxFunctionRecord* UcxUsbDevice::m_Functions

◆ m_FunctionsMemory

WDFMEMORY UcxUsbDevice::m_FunctionsMemory

Definition at line 271 of file devobj.h.

Referenced by RegisterComposite(), and UnregisterComposite().

◆ m_Handle

◆ m_HubClearTtBuffer

PFN_UCXHUB_CLEAR_TT_BUFFER UcxUsbDevice::m_HubClearTtBuffer

Definition at line 262 of file devobj.h.

◆ m_HubContext

UCXHUB_HUB_CONTEXT UcxUsbDevice::m_HubContext

Definition at line 261 of file devobj.h.

◆ m_HubDeviceContext

UCXHUB_DEVICE_CONTEXT UcxUsbDevice::m_HubDeviceContext

Definition at line 218 of file devobj.h.

Referenced by UcxEndpoint::NeedToCancelTransfers(), and ReportNoPingResponseIfPending().

◆ m_HubNoPingResponse

PFN_UCXHUB_NO_PING_RESPONSE UcxUsbDevice::m_HubNoPingResponse

Definition at line 263 of file devobj.h.

◆ m_HubUsesGrownInterface

BOOLEAN UcxUsbDevice::m_HubUsesGrownInterface

Definition at line 264 of file devobj.h.

◆ m_Info

UCXUSBDEVICE_INFO UcxUsbDevice::m_Info

Definition at line 221 of file devobj.h.

Referenced by InitializeAsRootHub(), UcxEndpoint::NeedToCancelTransfers(), and Speed().

◆ m_ParentHub

UcxUsbDevice* UcxUsbDevice::m_ParentHub

Definition at line 217 of file devobj.h.

Referenced by HandleHubReset(), and ReportNoPingResponseIfPending().

◆ m_Pdo

PDEVICE_OBJECT UcxUsbDevice::m_Pdo

Definition at line 223 of file devobj.h.

Referenced by SetPdo().

◆ m_PendingDelete

BOOLEAN UcxUsbDevice::m_PendingDelete

Definition at line 245 of file devobj.h.

Referenced by DeleteFromHub().

◆ m_PendingNoPingResponse

LONG UcxUsbDevice::m_PendingNoPingResponse

Definition at line 257 of file devobj.h.

Referenced by ReportNoPingResponseIfPending(), and UcxApiEndpointNoPingResponseError().

◆ m_PendingOperation

PVOID UcxUsbDevice::m_PendingOperation

Definition at line 253 of file devobj.h.

Referenced by StartOperation(), and TakeOperation().

◆ m_PendingOperationCount

LONG UcxUsbDevice::m_PendingOperationCount

Definition at line 255 of file devobj.h.

Referenced by CompleteHubOperation(), FanOutToEndpoints(), and StartOperation().

◆ m_PendingOperationDone

PFN_UCX_OPERATION_DONE UcxUsbDevice::m_PendingOperationDone

Definition at line 254 of file devobj.h.

Referenced by CompleteHubOperation(), and StartOperation().

◆ m_RemoteWake

UcxRemoteWakeSlot UcxUsbDevice::m_RemoteWake

Definition at line 268 of file devobj.h.

Referenced by RemoteWakeNotification(), and RequestRemoteWakeNotification().

◆ m_RemoteWakeLock

◆ m_ResetFailedByControllerReset

BOOLEAN UcxUsbDevice::m_ResetFailedByControllerReset

Definition at line 248 of file devobj.h.

Referenced by FailManagement().

◆ m_StaleEndpointList

LIST_ENTRY UcxUsbDevice::m_StaleEndpointList

Definition at line 230 of file devobj.h.

Referenced by DeleteFromHub(), and InitializeLists().

◆ m_StalePipeIoAllowed

BOOLEAN UcxUsbDevice::m_StalePipeIoAllowed

Definition at line 238 of file devobj.h.

Referenced by TrackStaleHandles().

◆ m_Timestamp

ULONG64 UcxUsbDevice::m_Timestamp

Definition at line 224 of file devobj.h.

Referenced by DispatchManagement(), and Timestamp().

◆ m_TrackingList

LIST_ENTRY UcxUsbDevice::m_TrackingList

Definition at line 237 of file devobj.h.

Referenced by InitializeLists(), and TrackStaleHandles().

◆ m_TrackingLock

KSPIN_LOCK UcxUsbDevice::m_TrackingLock

Definition at line 236 of file devobj.h.

Referenced by InitializeLists(), and TrackStaleHandles().

◆ m_TransferFailureCount

ULONG UcxUsbDevice::m_TransferFailureCount

Definition at line 258 of file devobj.h.

◆ m_Type

ULONG UcxUsbDevice::m_Type

Definition at line 219 of file devobj.h.

Referenced by InitializeAsRootHub(), IsHub(), IsRootHub(), and UpdateFromHub().

◆ m_UsbdHandleList

LIST_ENTRY UcxUsbDevice::m_UsbdHandleList

Definition at line 275 of file devobj.h.

Referenced by InitializeLists().

◆ m_UsbdHandleLock

KSPIN_LOCK UcxUsbDevice::m_UsbdHandleLock

Definition at line 274 of file devobj.h.

Referenced by InitializeLists(), and UcxUsbdHandle::Unregister().


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