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

Go to the source code of this file.

Macros

#define NDEBUG
 
#define UCX_COMPOSITE_VERSION   0x100
 
#define UCX_MAX_COMPOSITE_FUNCTIONS   255
 
#define UCX_MAX_FORWARD_PROGRESS_SIZE   (512 * 1024)
 

Functions

static ULONG64 NTAPI UcxSystemTimeNow (VOID)
 
static NTSTATUS NTAPI UcxBuildPortPath (_In_ UcxUsbDevice *Hub, _In_ ULONG PortNumber, _Inout_ PUCXUSBDEVICE_INFO Info)
 
static VOID NTAPI UcxDisconnectVisitor (_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
 
static BOOLEAN NTAPI UcxIsValidForwardProgressSize (_In_ ULONG Size)
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS UcxUsbDevice
 Sends a synchronous IOCTL to the specified device object.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file devobj.cpp.

◆ UCX_COMPOSITE_VERSION

#define UCX_COMPOSITE_VERSION   0x100

Definition at line 13 of file devobj.cpp.

◆ UCX_MAX_COMPOSITE_FUNCTIONS

#define UCX_MAX_COMPOSITE_FUNCTIONS   255

Definition at line 14 of file devobj.cpp.

◆ UCX_MAX_FORWARD_PROGRESS_SIZE

#define UCX_MAX_FORWARD_PROGRESS_SIZE   (512 * 1024)

Definition at line 15 of file devobj.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.

Definition at line 543 of file devobj.cpp.

547{
548 ULONG ControlSize = Info->ControlPipeMaxTransferSize;
549 UcxPipe* DefaultPipe = m_DefaultPipe;
550 PFN_UCX_HCD_ENDPOINT_ENABLE_FORWARD_PROGRESS Enable;
551 UcxPipe* Pipe;
552 ULONG Index;
554
555 PAGED_CODE();
556
557 if (ControlSize > UCX_MAX_FORWARD_PROGRESS_SIZE)
558 {
559 DPRINT1("UsbDevice %p control forward progress size %lu too large\n", m_Handle, ControlSize);
561 }
562
563 if (ControlSize != 0 && DefaultPipe->ReservedIoActive)
564 {
565 DPRINT1("UsbDevice %p control pipe forward progress already enabled\n", m_Handle);
567 }
568
569 for (Index = 0; Index < Info->NumberOfPipes; Index++)
570 {
571 Pipe = UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle);
572
573 if (!UcxIsValidForwardProgressSize(Info->Pipes[Index].ReservedTransferLimit) ||
574 Pipe->ReservedIoActive)
575 {
576 DPRINT1("UsbDevice %p pipe %lu bad forward progress size %lu or already enabled\n",
577 m_Handle, Index, Info->Pipes[Index].ReservedTransferLimit);
579 }
580 }
581
582 /* The control pipe keeps resources it already got if they are big enough */
583 if (ControlSize != 0 &&
584 !(DefaultPipe->ForwardProgressAllocatedByHcd &&
585 DefaultPipe->ReservedIoMaxBytes >= ControlSize))
586 {
587 Enable = m_DefaultEndpoint->m_Callbacks.EnableForwardProgress;
588 if (Enable == NULL)
589 {
590 DPRINT1("UsbDevice %p HCD has no forward progress callback for the control pipe\n", m_Handle);
592 }
593
594 Status = Enable(m_DefaultEndpoint->m_Handle, ControlSize);
595 if (!NT_SUCCESS(Status))
596 {
597 DPRINT1("UsbDevice %p control pipe forward progress failed 0x%lx\n", m_Handle, Status);
598 return Status;
599 }
600
601 DefaultPipe->ForwardProgressAllocatedByHcd = TRUE;
602 DefaultPipe->ReservedIoMaxBytes = ControlSize;
603 }
604
605 for (Index = 0; Index < Info->NumberOfPipes; Index++)
606 {
607 Pipe = UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle);
608
609 Enable = Pipe->Endpoint->m_Callbacks.EnableForwardProgress;
610 if (Enable == NULL)
611 {
612 DPRINT1("Endpoint %p HCD has no forward progress callback\n", Pipe->Endpoint->m_Handle);
614 }
615
616 Status = Enable(Pipe->Endpoint->m_Handle, Info->Pipes[Index].ReservedTransferLimit);
617 if (!NT_SUCCESS(Status))
618 {
619 DPRINT1("Endpoint %p forward progress failed 0x%lx\n", Pipe->Endpoint->m_Handle, Status);
620 return Status;
621 }
622
623 Pipe->ForwardProgressAllocatedByHcd = TRUE;
624 Pipe->ReservedIoMaxBytes = Info->Pipes[Index].ReservedTransferLimit;
625 }
626
627 /* Only marked once every pipe got its resources */
628 if (ControlSize != 0)
629 DefaultPipe->ReservedIoActive = TRUE;
630
631 for (Index = 0; Index < Info->NumberOfPipes; Index++)
632 UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle)->ReservedIoActive = TRUE;
633
634 return STATUS_SUCCESS;
635}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
static BOOLEAN NTAPI UcxIsValidForwardProgressSize(_In_ ULONG Size)
Definition: devobj.cpp:536
#define UCX_MAX_FORWARD_PROGRESS_SIZE
Definition: devobj.cpp:15
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: pipe.h:30
static UcxPipe * FromHandle(_In_ USBD_PIPE_HANDLE Handle)
Definition: pipe.h:53
ULONG ReservedIoMaxBytes
Definition: pipe.h:43
BOOLEAN ForwardProgressAllocatedByHcd
Definition: pipe.h:42
BOOLEAN ReservedIoActive
Definition: pipe.h:41
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741

◆ UcxBuildPortPath()

static NTSTATUS NTAPI UcxBuildPortPath ( _In_ UcxUsbDevice *  Hub,
_In_ ULONG  PortNumber,
_Inout_ PUCXUSBDEVICE_INFO  Info 
)
static

Low and full speed devices take the nearest high speed hub as their TT.

Definition at line 249 of file devobj.cpp.

253{
254 PUSB_DEVICE_PORT_PATH Path = &Info->PortPath;
255 ULONG ParentDepth;
256
257 if (Hub->IsRootHub())
258 {
259 Path->Size = sizeof(*Path);
260 Path->PortPathDepth = 1;
261 Path->PortPath[0] = PortNumber;
262 Path->TTHubDepth = 0;
263 Info->TtHub = NULL;
264 return STATUS_SUCCESS;
265 }
266
267 ParentDepth = Hub->m_Info.PortPath.PortPathDepth;
268 if (ParentDepth + 1 > MAX_USB_DEVICE_DEPTH)
269 {
270 DPRINT1("Hub %p port %lu is too deep for a device, depth %lu\n", Hub->m_Handle, PortNumber, ParentDepth + 1);
272 }
273
274 *Path = Hub->m_Info.PortPath;
275 Path->PortPathDepth = ParentDepth + 1;
276 Path->PortPath[ParentDepth] = PortNumber;
277
278 if (Info->DeviceSpeed == UsbLowSpeed || Info->DeviceSpeed == UsbFullSpeed)
279 {
280 if (Hub->Speed() == UsbHighSpeed)
281 {
282 Path->TTHubDepth = ParentDepth;
283 Info->TtHub = Hub->m_Handle;
284 }
285 else
286 {
287 Path->TTHubDepth = Hub->m_Info.PortPath.TTHubDepth;
288 Info->TtHub = Hub->m_Info.TtHub;
289 }
290 }
291
292 return STATUS_SUCCESS;
293}
HubFdo * Hub
Definition: bootdev.cpp:261
BOOLEAN IsRootHub() const
Definition: fdo.h:174
UNICODE_STRING Path
_In_ ULONG PortNumber
Definition: hubucx.h:272
#define MAX_USB_DEVICE_DEPTH
Definition: ucxusbdevice.h:163
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43

Referenced by UcxUsbDevice::CreateFromHub().

◆ UcxDisconnectVisitor()

static VOID NTAPI UcxDisconnectVisitor ( _In_ UcxUsbDevice *  Device,
_In_opt_ PVOID  Context 
)
static

Definition at line 420 of file devobj.cpp.

423{
424 PLIST_ENTRY Endpoints = (PLIST_ENTRY)Context;
427
428 Device->m_Disconnected = TRUE;
429
430 for (Entry = Device->m_EndpointList.Flink; Entry != &Device->m_EndpointList; Entry = Entry->Flink)
431 {
433
434 WdfObjectReference(Endpoint->m_Handle);
435 InsertHeadList(Endpoints, &Endpoint->m_DisconnectLink);
436 }
437}
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
#define InsertHeadList(ListHead, Entry)
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _LIST_ENTRY * PLIST_ENTRY
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803

Referenced by UcxUsbDevice::DisconnectPort().

◆ UcxIsValidForwardProgressSize()

static BOOLEAN NTAPI UcxIsValidForwardProgressSize ( _In_ ULONG  Size)
static

Validates one forward progress size: non zero and at most 512 KB.

Definition at line 536 of file devobj.cpp.

538{
539 return Size != 0 && Size <= UCX_MAX_FORWARD_PROGRESS_SIZE;
540}
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by _IRQL_requires_().

◆ UcxSystemTimeNow()

static ULONG64 NTAPI UcxSystemTimeNow ( VOID  )
static

Definition at line 27 of file devobj.cpp.

28{
30
32 return (ULONG64)Now.QuadPart;
33}
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
unsigned __int64 ULONG64
Definition: imports.h:198
struct tm * Now
Definition: output.c:19

Referenced by UcxUsbDevice::Create().