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
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
17 USBHUB_ParentFDOStartDevice(
18 IN PDEVICE_OBJECT DeviceObject
,
21 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
22 PURB Urb
, ConfigurationUrb
;
23 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
24 PUSBD_INTERFACE_LIST_ENTRY InterfaceList
;
28 // get hub device extension
29 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
31 // Send the StartDevice to lower device object
32 Status
= ForwardIrpAndWait(HubDeviceExtension
->LowerDeviceObject
, Irp
);
34 if (!NT_SUCCESS(Status
))
36 // failed to start pdo
37 DPRINT1("Failed to start the RootHub PDO\n");
41 // FIXME get capabilities
43 Urb
= ExAllocatePool(NonPagedPool
, sizeof(URB
));
47 DPRINT1("No memory\n");
48 return STATUS_INSUFFICIENT_RESOURCES
;
52 // lets get device descriptor
53 UsbBuildGetDescriptorRequest(Urb
,
54 sizeof(Urb
->UrbControlDescriptorRequest
),
55 USB_DEVICE_DESCRIPTOR_TYPE
,
58 &HubDeviceExtension
->HubDeviceDescriptor
,
60 sizeof(USB_DEVICE_DESCRIPTOR
),
64 // get hub device descriptor
65 Status
= SubmitRequestToRootHub(HubDeviceExtension
->LowerDeviceObject
,
66 IOCTL_INTERNAL_USB_SUBMIT_URB
,
70 if (!NT_SUCCESS(Status
))
72 // failed to get device descriptor of hub
73 DPRINT1("Failed to get hub device descriptor with Status %x!\n", Status
);
78 // now get configuration descriptor
79 UsbBuildGetDescriptorRequest(Urb
,
80 sizeof(Urb
->UrbControlDescriptorRequest
),
81 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
84 &HubDeviceExtension
->HubConfigDescriptor
,
86 sizeof(USB_CONFIGURATION_DESCRIPTOR
) + sizeof(USB_INTERFACE_DESCRIPTOR
) + sizeof(USB_ENDPOINT_DESCRIPTOR
),
89 // request configuration descriptor
90 Status
= SubmitRequestToRootHub(HubDeviceExtension
->LowerDeviceObject
,
91 IOCTL_INTERNAL_USB_SUBMIT_URB
,
95 if (!NT_SUCCESS(Status
))
97 // failed to get configuration descriptor
98 DPRINT1("Failed to get hub configuration descriptor with status %x\n", Status
);
104 ASSERT(HubDeviceExtension
->HubConfigDescriptor
.wTotalLength
== sizeof(USB_CONFIGURATION_DESCRIPTOR
) + sizeof(USB_INTERFACE_DESCRIPTOR
) + sizeof(USB_ENDPOINT_DESCRIPTOR
));
105 ASSERT(HubDeviceExtension
->HubConfigDescriptor
.bDescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
);
106 ASSERT(HubDeviceExtension
->HubConfigDescriptor
.bLength
== sizeof(USB_CONFIGURATION_DESCRIPTOR
));
107 ASSERT(HubDeviceExtension
->HubConfigDescriptor
.bNumInterfaces
== 1);
108 ASSERT(HubDeviceExtension
->HubInterfaceDescriptor
.bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
109 ASSERT(HubDeviceExtension
->HubInterfaceDescriptor
.bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
110 ASSERT(HubDeviceExtension
->HubInterfaceDescriptor
.bNumEndpoints
== 1);
111 ASSERT(HubDeviceExtension
->HubEndPointDescriptor
.bDescriptorType
== USB_ENDPOINT_DESCRIPTOR_TYPE
);
112 ASSERT(HubDeviceExtension
->HubEndPointDescriptor
.bLength
== sizeof(USB_ENDPOINT_DESCRIPTOR
));
113 ASSERT(HubDeviceExtension
->HubEndPointDescriptor
.bmAttributes
== USB_ENDPOINT_TYPE_INTERRUPT
);
114 ASSERT(HubDeviceExtension
->HubEndPointDescriptor
.bEndpointAddress
== 0x81); // interrupt in
116 // Build hub descriptor request
117 UsbBuildVendorRequest(Urb
,
118 URB_FUNCTION_CLASS_DEVICE
,
119 sizeof(Urb
->UrbControlVendorClassRequest
),
120 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
122 USB_REQUEST_GET_DESCRIPTOR
,
123 USB_DEVICE_CLASS_RESERVED
,
125 &HubDeviceExtension
->HubDescriptor
,
127 sizeof(USB_HUB_DESCRIPTOR
),
131 Status
= SubmitRequestToRootHub(HubDeviceExtension
->LowerDeviceObject
,
132 IOCTL_INTERNAL_USB_SUBMIT_URB
,
136 if (!NT_SUCCESS(Status
))
138 DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status
);
140 return STATUS_UNSUCCESSFUL
;
144 ASSERT(HubDeviceExtension
->HubDescriptor
.bDescriptorLength
== sizeof(USB_HUB_DESCRIPTOR
));
145 ASSERT(HubDeviceExtension
->HubDescriptor
.bNumberOfPorts
);
146 ASSERT(HubDeviceExtension
->HubDescriptor
.bDescriptorType
== 0x29);
148 // store number of ports
149 DPRINT1("NumberOfPorts %lu\n", HubDeviceExtension
->HubDescriptor
.bNumberOfPorts
);
150 HubDeviceExtension
->UsbExtHubInfo
.NumberOfPorts
= HubDeviceExtension
->HubDescriptor
.bNumberOfPorts
;
152 // allocate interface list
153 InterfaceList
= ExAllocatePool(NonPagedPool
, sizeof(USBD_INTERFACE_LIST_ENTRY
) * (HubDeviceExtension
->HubConfigDescriptor
.bNumInterfaces
+ 1));
157 DPRINT1("No memory\n");
158 return STATUS_INSUFFICIENT_RESOURCES
;
162 RtlZeroMemory(InterfaceList
, sizeof(USBD_INTERFACE_LIST_ENTRY
) * (HubDeviceExtension
->HubConfigDescriptor
.bNumInterfaces
+ 1));
164 // grab all interface descriptors
165 for(Index
= 0; Index
< HubDeviceExtension
->HubConfigDescriptor
.bNumInterfaces
; Index
++)
167 // Get the first Configuration Descriptor
168 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension
->HubConfigDescriptor
,
169 &HubDeviceExtension
->HubConfigDescriptor
,
170 Index
, 0, -1, -1, -1);
173 InterfaceList
[Index
].InterfaceDescriptor
= InterfaceDescriptor
;
176 // now create configuration request
177 ConfigurationUrb
= USBD_CreateConfigurationRequestEx(&HubDeviceExtension
->HubConfigDescriptor
,
178 (PUSBD_INTERFACE_LIST_ENTRY
)&InterfaceList
);
179 if (ConfigurationUrb
== NULL
)
181 // failed to build urb
182 DPRINT1("Failed to build configuration urb\n");
184 return STATUS_INSUFFICIENT_RESOURCES
;
188 Status
= SubmitRequestToRootHub(HubDeviceExtension
->LowerDeviceObject
,
189 IOCTL_INTERNAL_USB_SUBMIT_URB
,
193 if (!NT_SUCCESS(Status
))
195 DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status
);
197 ExFreePool(ConfigurationUrb
);
198 return STATUS_UNSUCCESSFUL
;
201 // store configuration & pipe handle
202 HubDeviceExtension
->ConfigurationHandle
= ConfigurationUrb
->UrbSelectConfiguration
.ConfigurationHandle
;
203 HubDeviceExtension
->PipeHandle
= ConfigurationUrb
->UrbSelectConfiguration
.Interface
.Pipes
[0].PipeHandle
;
204 DPRINT("Hub Configuration Handle %x\n", HubDeviceExtension
->ConfigurationHandle
);
207 ExFreePool(ConfigurationUrb
);
210 // FIXME build SCE interrupt request