Skip to content

Commit 82d9d77

Browse files
committed
[USBHUB]
- Check if FDO is root hub fdo - Partly implement fdo hub initialization - Implement IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO svn path=/trunk/; revision=55927
1 parent 9e6f877 commit 82d9d77

File tree

6 files changed

+357
-67
lines changed

6 files changed

+357
-67
lines changed

reactos/drivers/usb/usbhub/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ add_definitions(-DDEBUG_MODE)
33

44
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
55

6-
add_library(usbhub SHARED fdo.c misc.c pdo.c usbhub.c usbhub.rc)
6+
add_library(usbhub SHARED fdo.c misc.c pdo.c hub_fdo.c usbhub.c usbhub.rc)
77

88
target_link_libraries(usbhub ${PSEH_LIB})
99

reactos/drivers/usb/usbhub/fdo.c

Lines changed: 34 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -27,71 +27,6 @@ DestroyUsbChildDeviceObject(
2727
IN PDEVICE_OBJECT UsbHubDeviceObject,
2828
IN LONG PortId);
2929

30-
NTSTATUS
31-
SubmitRequestToRootHub(
32-
IN PDEVICE_OBJECT RootHubDeviceObject,
33-
IN ULONG IoControlCode,
34-
OUT PVOID OutParameter1,
35-
OUT PVOID OutParameter2)
36-
{
37-
KEVENT Event;
38-
PIRP Irp;
39-
IO_STATUS_BLOCK IoStatus;
40-
NTSTATUS Status;
41-
PIO_STACK_LOCATION Stack = NULL;
42-
43-
KeInitializeEvent(&Event, NotificationEvent, FALSE);
44-
45-
//
46-
// Build Control Request
47-
//
48-
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
49-
RootHubDeviceObject,
50-
NULL, 0,
51-
NULL, 0,
52-
TRUE,
53-
&Event,
54-
&IoStatus);
55-
56-
if (Irp == NULL)
57-
{
58-
DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
59-
return STATUS_INSUFFICIENT_RESOURCES;
60-
}
61-
62-
//
63-
// Initialize the status block before sending the IRP
64-
//
65-
IoStatus.Status = STATUS_NOT_SUPPORTED;
66-
IoStatus.Information = 0;
67-
68-
//
69-
// Get Next Stack Location and Initialize it
70-
//
71-
Stack = IoGetNextIrpStackLocation(Irp);
72-
Stack->Parameters.Others.Argument1 = OutParameter1;
73-
Stack->Parameters.Others.Argument2 = OutParameter2;
74-
75-
//
76-
// Call RootHub
77-
//
78-
Status = IoCallDriver(RootHubDeviceObject, Irp);
79-
80-
//
81-
// Its ok to block here as this function is called in an nonarbitrary thread
82-
//
83-
if (Status == STATUS_PENDING)
84-
{
85-
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
86-
Status = IoStatus.Status;
87-
}
88-
89-
//
90-
// The IO Manager will free the IRP
91-
//
92-
93-
return Status;
94-
}
9530

9631
NTSTATUS
9732
GetPortStatusAndChange(
@@ -1507,6 +1442,31 @@ RootHubInitCallbackFunction(
15071442
}
15081443
}
15091444

1445+
BOOLEAN
1446+
USBHUB_IsRootHubFDO(
1447+
IN PDEVICE_OBJECT DeviceObject)
1448+
{
1449+
NTSTATUS Status;
1450+
PDEVICE_OBJECT RootHubPhysicalDeviceObject = NULL;
1451+
PHUB_DEVICE_EXTENSION HubDeviceExtension;
1452+
1453+
// get hub device extension
1454+
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
1455+
1456+
// Get the Root Hub Pdo
1457+
Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
1458+
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
1459+
&RootHubPhysicalDeviceObject,
1460+
NULL);
1461+
1462+
// FIXME handle error
1463+
ASSERT(NT_SUCCESS(Status));
1464+
1465+
// physical device object is only obtained for root hubs
1466+
return (RootHubPhysicalDeviceObject != NULL);
1467+
}
1468+
1469+
15101470
NTSTATUS
15111471
USBHUB_FdoStartDevice(
15121472
IN PDEVICE_OBJECT DeviceObject,
@@ -1969,7 +1929,15 @@ USBHUB_FdoHandlePnp(
19691929
{
19701930
case IRP_MN_START_DEVICE:
19711931
{
1972-
Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
1932+
if (USBHUB_IsRootHubFDO(DeviceObject))
1933+
{
1934+
// start root hub fdo
1935+
Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
1936+
}
1937+
else
1938+
{
1939+
Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
1940+
}
19731941
break;
19741942
}
19751943

reactos/drivers/usb/usbhub/hub_fdo.c

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* PROJECT: ReactOS Universal Serial Bus Hub Driver
3+
* LICENSE: GPL - See COPYING in the top level directory
4+
* FILE: drivers/usb/usbhub/hub_fdo.c
5+
* PURPOSE: Hub FDO
6+
* PROGRAMMERS:
7+
* Michael Martin ([email protected])
8+
* Johannes Anderwald ([email protected])
9+
*/
10+
#include "usbhub.h"
11+
12+
NTSTATUS
13+
USBHUB_ParentFDOStartDevice(
14+
IN PDEVICE_OBJECT DeviceObject,
15+
IN PIRP Irp)
16+
{
17+
PHUB_DEVICE_EXTENSION HubDeviceExtension;
18+
PURB Urb, ConfigurationUrb;
19+
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
20+
PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
21+
ULONG Index;
22+
NTSTATUS Status;
23+
24+
// get hub device extension
25+
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
26+
27+
// Send the StartDevice to lower device object
28+
Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
29+
30+
if (!NT_SUCCESS(Status))
31+
{
32+
// failed to start pdo
33+
DPRINT1("Failed to start the RootHub PDO\n");
34+
return Status;
35+
}
36+
37+
// FIXME get capabilities
38+
39+
Urb = ExAllocatePool(NonPagedPool, sizeof(URB));
40+
if (!Urb)
41+
{
42+
// no memory
43+
DPRINT1("No memory\n");
44+
return STATUS_INSUFFICIENT_RESOURCES;
45+
}
46+
47+
48+
// lets get device descriptor
49+
UsbBuildGetDescriptorRequest(Urb,
50+
sizeof(Urb->UrbControlDescriptorRequest),
51+
USB_DEVICE_DESCRIPTOR_TYPE,
52+
0,
53+
0,
54+
&HubDeviceExtension->HubDeviceDescriptor,
55+
NULL,
56+
sizeof(USB_DEVICE_DESCRIPTOR),
57+
NULL);
58+
59+
60+
// get hub device descriptor
61+
Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
62+
IOCTL_INTERNAL_USB_SUBMIT_URB,
63+
Urb,
64+
NULL);
65+
66+
if (!NT_SUCCESS(Status))
67+
{
68+
// failed to get device descriptor of hub
69+
DPRINT1("Failed to get hub device descriptor with Status %x!\n", Status);
70+
ExFreePool(Urb);
71+
return Status;
72+
}
73+
74+
// now get configuration descriptor
75+
UsbBuildGetDescriptorRequest(Urb,
76+
sizeof(Urb->UrbControlDescriptorRequest),
77+
USB_CONFIGURATION_DESCRIPTOR_TYPE,
78+
0,
79+
0,
80+
&HubDeviceExtension->HubConfigDescriptor,
81+
NULL,
82+
sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
83+
NULL);
84+
85+
// request configuration descriptor
86+
Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
87+
IOCTL_INTERNAL_USB_SUBMIT_URB,
88+
Urb,
89+
NULL);
90+
91+
if (!NT_SUCCESS(Status))
92+
{
93+
// failed to get configuration descriptor
94+
DPRINT1("Failed to get hub configuration descriptor with status %x\n", Status);
95+
ExFreePool(Urb);
96+
return Status;
97+
}
98+
99+
// sanity checks
100+
ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength == sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR));
101+
ASSERT(HubDeviceExtension->HubConfigDescriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
102+
ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
103+
ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1);
104+
ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
105+
ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
106+
ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1);
107+
ASSERT(HubDeviceExtension->HubEndPointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
108+
ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
109+
ASSERT(HubDeviceExtension->HubEndPointDescriptor.bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT);
110+
ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 0x81); // interrupt in
111+
112+
// Build hub descriptor request
113+
UsbBuildVendorRequest(Urb,
114+
URB_FUNCTION_CLASS_DEVICE,
115+
sizeof(Urb->UrbControlVendorClassRequest),
116+
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
117+
0,
118+
USB_REQUEST_GET_DESCRIPTOR,
119+
USB_DEVICE_CLASS_RESERVED,
120+
0,
121+
&HubDeviceExtension->HubDescriptor,
122+
NULL,
123+
sizeof(USB_HUB_DESCRIPTOR),
124+
NULL);
125+
126+
// send request
127+
Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
128+
IOCTL_INTERNAL_USB_SUBMIT_URB,
129+
Urb,
130+
NULL);
131+
132+
if (!NT_SUCCESS(Status))
133+
{
134+
DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
135+
ExFreePool(Urb);
136+
return STATUS_UNSUCCESSFUL;
137+
}
138+
139+
// sanity checks
140+
ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == sizeof(USB_HUB_DESCRIPTOR));
141+
ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts);
142+
ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);
143+
144+
// store number of ports
145+
DPRINT1("NumberOfPorts %lu\n", HubDeviceExtension->HubDescriptor.bNumberOfPorts);
146+
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts = HubDeviceExtension->HubDescriptor.bNumberOfPorts;
147+
148+
// allocate interface list
149+
InterfaceList = ExAllocatePool(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));
150+
if (!InterfaceList)
151+
{
152+
// no memory
153+
DPRINT1("No memory\n");
154+
return STATUS_INSUFFICIENT_RESOURCES;
155+
}
156+
157+
// zero list
158+
RtlZeroMemory(InterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));
159+
160+
// grab all interface descriptors
161+
for(Index = 0; Index < HubDeviceExtension->HubConfigDescriptor.bNumInterfaces; Index++)
162+
{
163+
// Get the first Configuration Descriptor
164+
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
165+
&HubDeviceExtension->HubConfigDescriptor,
166+
Index, 0, -1, -1, -1);
167+
168+
// store in list
169+
InterfaceList[Index].InterfaceDescriptor = InterfaceDescriptor;
170+
}
171+
172+
// now create configuration request
173+
ConfigurationUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
174+
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
175+
if (ConfigurationUrb == NULL)
176+
{
177+
// failed to build urb
178+
DPRINT1("Failed to build configuration urb\n");
179+
ExFreePool(Urb);
180+
return STATUS_INSUFFICIENT_RESOURCES;
181+
}
182+
183+
// send request
184+
Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
185+
IOCTL_INTERNAL_USB_SUBMIT_URB,
186+
ConfigurationUrb,
187+
NULL);
188+
189+
if (!NT_SUCCESS(Status))
190+
{
191+
DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
192+
ExFreePool(Urb);
193+
ExFreePool(ConfigurationUrb);
194+
return STATUS_UNSUCCESSFUL;
195+
}
196+
197+
// store configuration & pipe handle
198+
HubDeviceExtension->ConfigurationHandle = ConfigurationUrb->UrbSelectConfiguration.ConfigurationHandle;
199+
HubDeviceExtension->PipeHandle = ConfigurationUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
200+
DPRINT("Hub Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
201+
202+
// free urb
203+
ExFreePool(ConfigurationUrb);
204+
ExFreePool(Urb);
205+
206+
// FIXME build SCE interrupt request
207+
208+
// FIXME create pdos
209+
210+
return Status;
211+
}
212+

0 commit comments

Comments
 (0)