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

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static ULONG NTAPI HubClampTierDepth (_In_ ULONG Depth)
 
static BOOLEAN NTAPI HubAddPort (_In_ HubFdo *Hub, _In_ const HubPortInfo *Info)
 
static VOID NTAPI HubTrackPortRange (_In_ USHORT PortNumber, _Inout_ PUSHORT First, _Inout_ PUSHORT Last)
 
static BOOLEAN NTAPI HubDescriptorSaysFixed (_In_ const UCHAR *Bitmap, _In_ ULONG PortNumber)
 
 _IRQL_requires_ (PASSIVE_LEVEL) BOOLEAN HubFdo
 Sends a synchronous IOCTL to the specified device object.
 

Variables

static const char HubTagRegistration [] = "hub child registration"
 
static const char HubTagPnpPower [] = "hub child pnp power"
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file fanout.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.

Definition at line 108 of file fanout.cpp.

111{
113 ULONG Count20 = IsRootHub() ? m_RootHubInfo.Info.NumberOf20Ports : 0;
114 ULONG Count30 = IsRootHub() ? m_RootHubInfo.Info.NumberOf30Ports : 0;
115 ULONG BitmapBytes;
116 ULONG Index;
121
122 PAGED_CODE();
123
124 if (!IsRootHub())
125 {
126 if (m_Parent.HubSpeed == UsbSuperSpeed)
127 Count30 = m_HubDescriptor.Usb30.bNumberOfPorts;
128 else
129 Count20 = m_HubDescriptor.Usb20.bNumberOfPorts;
130 }
131
132 m_First20Port = 0xFFFF;
133 m_Last20Port = 0;
134
135 for (Index = 0; Index < Count20; Index++)
136 {
137 RtlZeroMemory(&Info, sizeof(Info));
138 Info.Properties = (ULONG)PortProperty::Removable;
139 Info.Protocol = 0x200;
140
141 if (IsRootHub())
142 {
143 const ROOTHUB_20PORT_INFO* Root = m_Root20Ports[Index];
144
145 Info.PortNumber = Root->PortNumber;
146 if (Root->Removable == TriStateFalse)
147 Info.Properties &= ~(ULONG)PortProperty::Removable;
148 if (Root->IntegratedHubImplemented == TriStateTrue)
150 if (Root->ControllerUsb20HardwareLpmFlags.Flags.L1CapabilitySupported)
152 if (Root->ControllerUsb20HardwareLpmFlags.Flags.BeslLpmCapabilitySupported)
153 Info.Properties |= (ULONG)PortProperty::BeslCapable;
154 Info.TotalHubDepth = HubClampTierDepth(Root->HubDepth);
155 }
156 else
157 {
158 Info.PortNumber = (USHORT)(Index + 1);
159 if (HubDescriptorSaysFixed(&m_HubDescriptor.Usb20.bRemoveAndPowerMask[0], Info.PortNumber))
160 Info.Properties &= ~(ULONG)PortProperty::Removable;
161 Info.TotalHubDepth = m_ParentInfo.TotalHubDepth;
162 }
163
164 HubTrackPortRange(Info.PortNumber, &m_First20Port, &m_Last20Port);
165 if (!HubAddPort(this, &Info))
166 goto Failed;
167 }
168
169 m_First30Port = 0xFFFF;
170 m_Last30Port = 0;
171
172 for (Index = 0; Index < Count30; Index++)
173 {
174 RtlZeroMemory(&Info, sizeof(Info));
175 Info.Properties = (ULONG)PortProperty::Removable;
176 Info.Protocol = 0x300;
177
178 if (IsRootHub())
179 {
180 const ROOTHUB_30PORT_INFO_EX* Root = m_Root30Ports[Index];
181
182 Info.PortNumber = Root->Info.PortNumber;
183 if (Root->Info.Removable == TriStateFalse)
184 Info.Properties &= ~(ULONG)PortProperty::Removable;
185 if (Root->Info.DebugCapable == TriStateTrue)
188 if (Root->Info.MinorRevision != 0)
189 Info.SspIsochBurstCount = m_SspIsochBurstCount;
190 Info.SublinkSpeedAttr = Root->Speeds;
191 Info.SublinkSpeedAttrCount = Root->SpeedsCount;
192 Info.TotalHubDepth = HubClampTierDepth(Root->Info.HubDepth);
193 }
194 else
195 {
196 Info.PortNumber = (USHORT)(Index + 1);
197 if (HubDescriptorSaysFixed((const UCHAR*)&m_HubDescriptor.Usb30.DeviceRemovable, Info.PortNumber))
198 Info.Properties &= ~(ULONG)PortProperty::Removable;
199 if (m_Parent.IsEnhancedSuperSpeed)
200 {
202 Info.SspIsochBurstCount = m_SspIsochBurstCount;
203 }
204 Info.SublinkSpeedAttr = m_ParentInfo.SublinkSpeedAttr;
205 Info.SublinkSpeedAttrCount = m_ParentInfo.SublinkSpeedAttrCount;
206 Info.TotalHubDepth = m_ParentInfo.TotalHubDepth;
207 }
208
209 HubTrackPortRange(Info.PortNumber, &m_First30Port, &m_Last30Port);
210 if (!HubAddPort(this, &Info))
211 goto Failed;
212 }
213
214 m_PortCount = max(m_Last20Port, m_Last30Port);
215 if (m_PortCount == 0)
216 DPRINT1("Hub %p reports no ports\n", m_Device);
217 NT_ASSERT(m_PortCount != 0);
218
219 /* External hubs read the whole interrupt packet into the bitmap; only the allocation is ULONG aligned */
220 BitmapBytes = max(2, m_PortCount / 8 + 1);
221 BitmapBytes = max(BitmapBytes, m_InterruptMaxPacket);
222
224 Attributes.ParentObject = m_Device;
225
226 Status = WdfMemoryCreate(&Attributes,
229 ALIGN_UP_BY(BitmapBytes, sizeof(ULONG)),
230 &m_Interrupt.BitmapMemory,
231 &Buffer);
232 if (!NT_SUCCESS(Status))
233 {
234 DPRINT1("Hub %p change bitmap allocation failed 0x%lx\n", m_Device, Status);
235 goto Failed;
236 }
237
238 m_Interrupt.BitmapBuffer = (PUCHAR)Buffer;
239 m_Interrupt.BitmapMaxBytes = BitmapBytes;
240
241 DPRINT("Hub %p has %lu ports, bitmap %lu bytes\n", m_Device, m_PortCount, BitmapBytes);
242
244 return TRUE;
245
246Failed:
247 while (!IsListEmpty(&m_Mux.Ports))
248 {
249 Entry = RemoveHeadList(&m_Mux.Ports);
250 m_Mux.PortCount--;
251 WdfObjectDelete(CONTAINING_RECORD(Entry, HubPort, m_HubLink)->m_Object);
252 }
253
254 return FALSE;
255}
#define PAGED_CODE()
#define ALIGN_UP_BY(size, align)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Pdo m_Device
Definition: childpdo.cpp:3337
Definition: bufpool.h:45
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#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 RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
static ULONG NTAPI HubClampTierDepth(_In_ ULONG Depth)
Definition: fanout.cpp:26
static BOOLEAN NTAPI HubDescriptorSaysFixed(_In_ const UCHAR *Bitmap, _In_ ULONG PortNumber)
Definition: fanout.cpp:101
static VOID NTAPI HubTrackPortRange(_In_ USHORT PortNumber, _Inout_ PUSHORT First, _Inout_ PUSHORT Last)
Definition: fanout.cpp:86
static BOOLEAN NTAPI HubAddPort(_In_ HubFdo *Hub, _In_ const HubPortInfo *Info)
Definition: fanout.cpp:63
Status
Definition: gdiplustypes.h:24
WDFKEY Root
#define HUB_TAG_HUB
Definition: hubutil.h:12
unsigned short USHORT
Definition: pedump.c:61
@ Failed
Definition: arc.h:88
#define DPRINT
Definition: sndvol32.h:73
Definition: typedefs.h:120
#define max(a, b)
Definition: svc.c:63
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
@ TriStateFalse
Definition: ucxroothub.h:23
@ TriStateTrue
Definition: ucxroothub.h:24
@ UsbSuperSpeed
Definition: usb200.h:45
WdfObjectDelete(String)
_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
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define NT_ASSERT
Definition: rtlfuncs.h:3334

◆ HubAddPort()

static BOOLEAN NTAPI HubAddPort ( _In_ HubFdo *  Hub,
_In_ const HubPortInfo *  Info 
)
static

Adds one port to the end of the list; 2.0 ports are created before 3.0 ports.

Definition at line 63 of file fanout.cpp.

66{
67 HubPort* Port = HubPort::Create(Hub, Info);
68
69 if (Port == NULL)
70 {
71 DPRINT1("Hub %p port %u create failed\n", Hub->m_Device, Info->PortNumber);
72 return FALSE;
73 }
74
75 DPRINT("Hub %p created port %u (%p), protocol 0x%x\n",
76 Hub->m_Device, Info->PortNumber, Port, Info->Protocol);
77
78 InsertTailList(&Hub->m_Mux.Ports, &Port->m_HubLink);
80 return TRUE;
81}
HubFdo * Hub
Definition: bootdev.cpp:261
WDFDEVICE m_Device
Definition: fdo.h:349
HubMux m_Mux
Definition: fdo.h:407
#define NULL
Definition: types.h:112
#define InsertTailList(ListHead, Entry)
CPPORT Port[4]
Definition: headless.c:38
LIST_ENTRY Ports
Definition: fdo.h:69
ULONG PortCount
Definition: fdo.h:70

Referenced by _IRQL_requires_().

◆ HubClampTierDepth()

static ULONG NTAPI HubClampTierDepth ( _In_ ULONG  Depth)
static

Definition at line 26 of file fanout.cpp.

28{
29 return (Depth == 0 || Depth > 5) ? 5 : Depth;
30}
UINT Depth
Definition: d3d12.idl:4644

Referenced by _IRQL_requires_().

◆ HubDescriptorSaysFixed()

static BOOLEAN NTAPI HubDescriptorSaysFixed ( _In_ const UCHAR *  Bitmap,
_In_ ULONG  PortNumber 
)
static

Definition at line 101 of file fanout.cpp.

104{
105 return (Bitmap[PortNumber / 8] & (1 << (PortNumber % 8))) != 0;
106}
_In_ ULONG PortNumber
Definition: hubucx.h:272

Referenced by _IRQL_requires_().

◆ HubTrackPortRange()

static VOID NTAPI HubTrackPortRange ( _In_ USHORT  PortNumber,
_Inout_ PUSHORT  First,
_Inout_ PUSHORT  Last 
)
static

Definition at line 86 of file fanout.cpp.

90{
91 if (PortNumber < *First)
93 if (PortNumber > *Last)
94 *Last = PortNumber;
95}
WCHAR First[]
Definition: FormatMessage.c:11

Referenced by _IRQL_requires_().

Variable Documentation

◆ HubTagPnpPower

const char HubTagPnpPower[] = "hub child pnp power"
static

Definition at line 20 of file fanout.cpp.

Referenced by HubFdo::QueuePowerDownToDevices(), and HubFdo::QueuePowerUpToDevices().

◆ HubTagRegistration

const char HubTagRegistration[] = "hub child registration"
static

Definition at line 19 of file fanout.cpp.

Referenced by HubFdo::RegisterDevice(), and HubFdo::UnregisterDevice().