win-pvdrivers

view xenusb/xenusb_hub.c @ 991:e9903455ba9d

Fix low gref resource handling. again.
Tidy up.
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 21 23:25:36 2012 +1000 (2012-09-21)
parents ea3c61839ff5
children 329b9b9d47ec
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenusb.h"
21 #include <stdlib.h>
22 #include <usbioctl.h>
24 typedef struct _USB_START_FAILDATA {
25 ULONG LengthInBytes;
26 NTSTATUS NtStatus;
27 USBD_STATUS UsbdStatus;
28 ULONG ConnectStatus;
29 UCHAR DriverData[4];
30 } USB_START_FAILDATA, *PUSB_START_FAILDATA;
32 #pragma warning(disable: 4127) // conditional expression is constant
34 static EVT_WDF_DEVICE_D0_ENTRY XenUsbHub_EvtDeviceD0Entry;
35 static EVT_WDF_DEVICE_D0_EXIT XenUsbHub_EvtDeviceD0Exit;
36 static EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsbHub_EvtDevicePrepareHardware;
37 static EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsbHub_EvtDeviceReleaseHardware;
38 static EVT_WDF_DEVICE_USAGE_NOTIFICATION XenUsbHub_EvtDeviceUsageNotification;
39 static EVT_WDF_TIMER XenUsbHub_HubInterruptTimer;
40 static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsbHub_EvtIoInternalDeviceControl;
41 static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL XenUsbHub_EvtIoDeviceControl;
42 static EVT_WDF_IO_QUEUE_IO_DEFAULT XenUsbHub_EvtIoDefault;
43 static EVT_WDFDEVICE_WDM_IRP_PREPROCESS XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE;
45 static USB_BUSIFFN_CREATE_USB_DEVICE XenUsbHub_UBIH_CreateUsbDevice;
46 static USB_BUSIFFN_CREATE_USB_DEVICE_EX XenUsbHub_UBIH_CreateUsbDeviceEx;
47 static USB_BUSIFFN_CREATE_USB_DEVICE_V7 XenUsbHub_UBIH_CreateUsbDeviceV7;
48 static USB_BUSIFFN_INITIALIZE_USB_DEVICE XenUsbHub_UBIH_InitializeUsbDevice;
49 static USB_BUSIFFN_GET_USB_DESCRIPTORS XenUsbHub_UBIH_GetUsbDescriptors;
50 static USB_BUSIFFN_REMOVE_USB_DEVICE XenUsbHub_UBIH_RemoveUsbDevice;
51 static USB_BUSIFFN_RESTORE_DEVICE XenUsbHub_UBIH_RestoreUsbDevice;
52 static USB_BUSIFFN_GET_POTRTHACK_FLAGS XenUsbHub_UBIH_GetPortHackFlags;
53 static USB_BUSIFFN_GET_DEVICE_INFORMATION XenUsbHub_UBIH_QueryDeviceInformation;
54 static USB_BUSIFFN_GET_CONTROLLER_INFORMATION XenUsbHub_UBIH_GetControllerInformation;
55 static USB_BUSIFFN_CONTROLLER_SELECTIVE_SUSPEND XenUsbHub_UBIH_ControllerSelectiveSuspend;
56 static USB_BUSIFFN_GET_EXTENDED_HUB_INFO XenUsbHub_UBIH_GetExtendedHubInformation;
57 static USB_BUSIFFN_GET_ROOTHUB_SYM_NAME XenUsbHub_UBIH_GetRootHubSymbolicName;
58 static USB_BUSIFFN_GET_DEVICE_BUSCONTEXT XenUsbHub_UBIH_GetDeviceBusContext;
59 static USB_BUSIFFN_INITIALIZE_20HUB XenUsbHub_UBIH_Initialize20Hub;
60 static USB_BUSIFFN_ROOTHUB_INIT_NOTIFY XenUsbHub_UBIH_RootHubInitNotification;
61 static USB_BUSIFFN_FLUSH_TRANSFERS XenUsbHub_UBIH_FlushTransfers;
62 static USB_BUSIFFN_SET_DEVHANDLE_DATA XenUsbHub_UBIH_SetDeviceHandleData;
63 static USB_BUSIFFN_INITIALIZE_USB_DEVICE_EX XenUsbHub_UBIH_InitializeUsbDeviceEx;
64 static USB_BUSIFFN_IS_ROOT XenUsbHub_UBIH_HubIsRoot;
65 static USB_BUSIFFN_TEST_POINT XenUsbHub_UBIH_HubTestPoint;
66 static USB_BUSIFFN_GET_DEVICE_PERFORMANCE_INFO XenUsbHub_UBIH_GetDevicePerformanceInfo;
67 static USB_BUSIFFN_WAIT_ASYNC_POWERUP XenUsbHub_UBIH_WaitAsyncPowerUp;
68 static USB_BUSIFFN_GET_DEVICE_ADDRESS XenUsbHub_UBIH_GetDeviceAddress;
69 static USB_BUSIFFN_REF_DEVICE_HANDLE XenUsbHub_UBIH_RefDeviceHandle;
70 static USB_BUSIFFN_DEREF_DEVICE_HANDLE XenUsbHub_UBIH_DerefDeviceHandle;
71 static USB_BUSIFFN_SET_DEVICE_HANDLE_IDLE_READY_STATE XenUsbHub_UBIH_SetDeviceHandleIdleReadyState;
72 static USB_BUSIFFN_GET_CONTAINER_ID_FOR_PORT XenUsbHub_UBIH_GetContainerIdForPort;
73 static USB_BUSIFFN_SET_CONTAINER_ID_FOR_PORT XenUsbHub_UBIH_SetContainerIdForPort;
74 static USB_BUSIFFN_ABORT_ALL_DEVICE_PIPES XenUsbHub_UBIH_AbortAllDevicePipes;
75 static USB_BUSIFFN_SET_DEVICE_ERRATA_FLAG XenUsbHub_UBIH_SetDeviceErrataFlag;
76 static USB_BUSIFFN_ACQUIRE_SEMAPHORE XenUsbHub_UBIH_AcquireBusSemaphore;
77 static USB_BUSIFFN_RELEASE_SEMAPHORE XenUsbHub_UBIH_ReleaseBusSemaphore;
78 static USB_BUSIFFN_CALC_PIPE_BANDWIDTH XenUsbHub_UBIH_CaculatePipeBandwidth;
79 static USB_BUSIFFN_SET_BUS_WAKE_MODE XenUsbHub_UBIH_SetBusSystemWakeMode;
80 static USB_BUSIFFN_SET_DEVICE_FLAG XenUsbHub_UBIH_SetDeviceFlag;
86 static VOID
87 XenUsbHub_EvtIoDefault(
88 WDFQUEUE queue,
89 WDFREQUEST request)
90 {
91 NTSTATUS status;
92 WDF_REQUEST_PARAMETERS parameters;
94 FUNCTION_ENTER();
96 UNREFERENCED_PARAMETER(queue);
98 status = STATUS_UNSUCCESSFUL;
100 WDF_REQUEST_PARAMETERS_INIT(&parameters);
101 WdfRequestGetParameters(request, &parameters);
103 switch (parameters.Type)
104 {
105 case WdfRequestTypeCreate:
106 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
107 break;
108 case WdfRequestTypeClose:
109 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
110 break;
111 case WdfRequestTypeRead:
112 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
113 break;
114 case WdfRequestTypeWrite:
115 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
116 break;
117 case WdfRequestTypeDeviceControl:
118 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
120 break;
121 case WdfRequestTypeDeviceControlInternal:
122 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
123 break;
124 default:
125 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
126 break;
127 }
128 FUNCTION_MSG("Calling WdfRequestComplete with status = %08x\n");
129 WdfRequestComplete(request, status);
131 FUNCTION_EXIT();
132 }
134 static NTSTATUS
135 XenUsbHub_BusIrpCompletionRoutine(
136 PDEVICE_OBJECT device_object,
137 PIRP irp,
138 PVOID context)
139 {
140 WDFREQUEST request = context;
142 UNREFERENCED_PARAMETER(device_object);
144 FUNCTION_ENTER();
146 FUNCTION_MSG("Calling WdfRequestComplete with status = %08x\n");
147 WdfRequestCompleteWithInformation(request, irp->IoStatus.Status, irp->IoStatus.Information);
148 IoFreeIrp(irp);
150 FUNCTION_EXIT();
152 return STATUS_MORE_PROCESSING_REQUIRED;
153 }
155 static VOID
156 XenUsbHub_EvtIoDeviceControl(
157 WDFQUEUE queue,
158 WDFREQUEST request,
159 size_t output_buffer_length,
160 size_t input_buffer_length,
161 ULONG io_control_code)
162 {
163 NTSTATUS status;
164 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
165 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
166 //WDF_REQUEST_PARAMETERS wrp;
167 //PURB urb;
168 //xenusb_device_t *usb_device;
170 UNREFERENCED_PARAMETER(queue);
171 UNREFERENCED_PARAMETER(input_buffer_length);
172 UNREFERENCED_PARAMETER(output_buffer_length);
174 FUNCTION_ENTER();
176 status = STATUS_UNSUCCESSFUL;
178 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
179 //WdfRequestGetParameters(request, &wrp);
181 // these are in api\usbioctl.h
182 switch(io_control_code)
183 {
184 case IOCTL_USB_GET_NODE_INFORMATION:
185 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
186 break;
187 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
188 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
189 break;
190 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
191 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
192 break;
193 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
194 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
195 break;
196 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
197 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
198 break;
199 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
200 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
201 break;
202 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
203 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
204 break;
205 case IOCTL_USB_GET_HUB_CAPABILITIES:
206 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
207 break;
208 case IOCTL_USB_HUB_CYCLE_PORT:
209 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
210 break;
211 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
212 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
213 break;
214 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
215 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
216 break;
217 case IOCTL_GET_HCD_DRIVERKEY_NAME:
218 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME (***)\n"));
219 break;
220 default:
221 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
222 break;
223 }
224 FUNCTION_MSG("Calling WdfRequestComplete with status = %08x\n");
225 WdfRequestComplete(request, status);
227 FUNCTION_EXIT();
228 }
230 static VOID
231 XenUsbHub_EvtIoInternalDeviceControl(
232 WDFQUEUE queue,
233 WDFREQUEST request,
234 size_t output_buffer_length,
235 size_t input_buffer_length,
236 ULONG io_control_code)
237 {
238 NTSTATUS status;
239 WDFDEVICE device = WdfIoQueueGetDevice(queue);
240 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
241 WDF_REQUEST_PARAMETERS wrp;
242 PURB urb;
243 #if (NTDDI_VERSION >= NTDDI_VISTA)
244 PUSB_START_FAILDATA usfd;
245 PHUB_DEVICE_CONFIG_INFO hdci;
246 PUSB_TOPOLOGY_ADDRESS uta;
247 PUSB_HUB_NAME uhn;
248 size_t length;
249 #endif
250 xenusb_device_t *usb_device;
252 UNREFERENCED_PARAMETER(input_buffer_length);
253 UNREFERENCED_PARAMETER(output_buffer_length);
255 //FUNCTION_ENTER();
257 status = STATUS_UNSUCCESSFUL;
259 WDF_REQUEST_PARAMETERS_INIT(&wrp);
260 WdfRequestGetParameters(request, &wrp);
262 // these are in api\usbioctl.h
263 switch(io_control_code)
264 {
265 case IOCTL_INTERNAL_USB_CYCLE_PORT:
266 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_CYCLE_PORT\n"));
267 break;
268 case IOCTL_INTERNAL_USB_ENABLE_PORT:
269 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_ENABLE_PORT\n"));
270 break;
271 case IOCTL_INTERNAL_USB_GET_BUS_INFO:
272 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_BUS_INFO\n"));
273 break;
274 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
275 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n"));
276 break;
277 case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
278 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_COUNT\n"));
279 KdPrint((__DRIVER_NAME " Count before increment = %p\n", *(PULONG)wrp.Parameters.Others.Arg1));
280 (*(PULONG)wrp.Parameters.Others.Arg1)++;
281 status = STATUS_SUCCESS;
282 break;
283 #if (NTDDI_VERSION >= NTDDI_VISTA)
284 case IOCTL_INTERNAL_USB_GET_HUB_NAME:
285 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_NAME (hub)\n"));
286 status = WdfRequestRetrieveOutputBuffer(request, FIELD_OFFSET(USB_HUB_NAME, HubName) + 18, (PVOID *)&uhn, &length);
287 if (NT_SUCCESS(status))
288 {
289 /* not sure this is correct... it's not the full symbolic name */
290 uhn->ActualLength = sizeof(USB_HUB_NAME);
291 RtlStringCbCopyW(uhn->HubName, length - FIELD_OFFSET(USB_HUB_NAME, HubName), L"ROOT_HUB");
292 status = STATUS_SUCCESS;
293 }
294 break;
295 #endif
296 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
297 //FUNCTION_MSG("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
298 *(PULONG)wrp.Parameters.Others.Arg1 = USBD_PORT_ENABLED | USBD_PORT_CONNECTED; /* enabled and connected */
299 status = STATUS_SUCCESS;
300 break;
301 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
302 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n"));
303 KdPrint((__DRIVER_NAME " WdfDeviceWdmGetPhysicalDevice(device) = %p\n", WdfDeviceWdmGetPhysicalDevice(device)));
304 //KdPrint((__DRIVER_NAME " IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device)) = %p\n", IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device))));
305 *(PVOID *)wrp.Parameters.Others.Arg1 = WdfDeviceWdmGetPhysicalDevice(device);
306 //*(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device));
307 *(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(xupdd->wdf_device_bus_fdo));
308 status = STATUS_SUCCESS;
309 break;
310 case IOCTL_INTERNAL_USB_RESET_PORT:
311 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_RESET_PORT\n"));
312 break;
313 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
314 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n"));
315 break;
316 case IOCTL_INTERNAL_USB_SUBMIT_URB:
317 //KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_SUBMIT_URB\n"));
318 urb = (PURB)wrp.Parameters.Others.Arg1;
319 ASSERT(urb);
320 usb_device = urb->UrbHeader.UsbdDeviceHandle;
321 if (!usb_device)
322 usb_device = xupdd->usb_device;
323 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
324 return;
325 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
326 FUNCTION_MSG("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE (returning %p)\n", xupdd->usb_device);
327 *(PVOID *)wrp.Parameters.Others.Arg1 = xupdd->usb_device;
328 status = STATUS_SUCCESS;
329 break;
330 #if (NTDDI_VERSION >= NTDDI_VISTA)
331 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE_EX: /* incomplete probably */
332 FUNCTION_MSG("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE_EX (returning %p)\n", xupdd->usb_device);
333 *(PVOID *)wrp.Parameters.Others.Arg1 = xupdd->usb_device;
334 *(ULONG_PTR *)wrp.Parameters.Others.Arg2 = (ULONG_PTR)0x12345678;
335 status = STATUS_SUCCESS;
336 break;
337 case IOCTL_INTERNAL_USB_GET_TOPOLOGY_ADDRESS:
338 FUNCTION_MSG("IOCTL_INTERNAL_USB_GET_TOPOLOGY_ADDRESS\n");
339 uta = (PUSB_TOPOLOGY_ADDRESS)wrp.Parameters.Others.Arg1;
340 uta->PciBusNumber = 0;
341 uta->PciDeviceNumber = 0;
342 uta->PciFunctionNumber = 0;
343 uta->RootHubPortNumber = 0;
344 uta->HubPortNumber[1] = 0;
345 uta->HubPortNumber[2] = 0;
346 uta->HubPortNumber[3] = 0;
347 uta->HubPortNumber[4] = 0;
348 status = STATUS_SUCCESS;
349 break;
350 case IOCTL_INTERNAL_USB_GET_DEVICE_CONFIG_INFO:
351 FUNCTION_MSG("IOCTL_INTERNAL_USB_GET_DEVICE_CONFIG_INFO\n");
352 hdci = (PHUB_DEVICE_CONFIG_INFO)wrp.Parameters.Others.Arg1;
353 hdci->Version = 1;
354 hdci->Length = 192;
355 hdci->HubFlags.ul = 0;
356 hdci->HubFlags.HubIsHighSpeedCapable = 1;
357 hdci->HubFlags.HubIsHighSpeed = 1;
358 hdci->HubFlags.HubIsMultiTtCapable = 0;
359 hdci->HubFlags.HubIsMultiTt = 0;
360 hdci->HubFlags.HubIsRoot = 1;
361 hdci->HubFlags.HubIsArmedWakeOnConnect = 1;
362 hdci->HubFlags.HubIsBusPowered = 1;
363 //hdci->HardwareIds = ?;
364 //hdci->CompatibleIds = ?;
365 //hdci->DeviceDescription = ?;
366 status = STATUS_SUCCESS;
367 break;
368 case IOCTL_INTERNAL_USB_RECORD_FAILURE:
369 FUNCTION_MSG("IOCTL_INTERNAL_USB_RECORD_FAILURE\n");
370 usfd = (PUSB_START_FAILDATA)wrp.Parameters.Others.Arg1;
371 FUNCTION_MSG(" LengthInBytes = %d\n", usfd->LengthInBytes);
372 FUNCTION_MSG(" NtStatus = %08x\n", usfd->NtStatus);
373 FUNCTION_MSG(" UsbdStatus = %08x\n", usfd->UsbdStatus);
374 FUNCTION_MSG(" ConnectStatus = %08x\n", usfd->ConnectStatus);
375 status = STATUS_SUCCESS;
376 break;
377 #endif
378 default:
379 FUNCTION_MSG("Unknown IOCTL %08x\n", io_control_code);
380 break;
381 }
383 if (status != STATUS_SUCCESS)
384 FUNCTION_MSG("Calling WdfRequestComplete with status = %08x\n", status);
385 WdfRequestComplete(request, status);
387 //FUNCTION_EXIT();
388 }
390 static NTSTATUS
391 XenUsbHub_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
392 {
393 NTSTATUS status = STATUS_SUCCESS;
394 DECLARE_CONST_UNICODE_STRING(symbolicname_name, L"SymbolicName");
395 WDFSTRING symbolicname_value_wdfstring;
396 WDFKEY device_key;
397 UNICODE_STRING symbolicname_value;
399 UNREFERENCED_PARAMETER(device);
401 FUNCTION_ENTER();
403 switch (previous_state)
404 {
405 case WdfPowerDeviceD0:
406 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
407 break;
408 case WdfPowerDeviceD1:
409 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
410 break;
411 case WdfPowerDeviceD2:
412 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
413 break;
414 case WdfPowerDeviceD3:
415 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
416 break;
417 case WdfPowerDeviceD3Final:
418 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
419 break;
420 case WdfPowerDevicePrepareForHibernation:
421 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
422 break;
423 default:
424 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
425 break;
426 }
428 /* USB likes to have a registry key with the symbolic link name in it. Have to wait until D0Entry as this is the PDO */
429 status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolicname_value_wdfstring);
430 if (!NT_SUCCESS(status)) {
431 FUNCTION_MSG("WdfStringCreate = %08x\n", status);
432 return status;
433 }
434 status = WdfDeviceRetrieveDeviceInterfaceString(device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolicname_value_wdfstring);
435 if (!NT_SUCCESS(status)) {
436 FUNCTION_MSG("WdfDeviceREtrieveDeviceInterfaceString = %08x\n", status);
437 return status;
438 }
439 WdfStringGetUnicodeString(symbolicname_value_wdfstring, &symbolicname_value);
440 FUNCTION_MSG("ROOT_HUB SymbolicName = %S\n", symbolicname_value.Buffer);
441 status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &device_key);
442 if (!NT_SUCCESS(status)) {
443 FUNCTION_MSG("WdfDeviceOpenRegistryKey = %08x\n", status);
444 return status;
445 }
446 status = WdfRegistryAssignUnicodeString(device_key, &symbolicname_name, &symbolicname_value);
447 if (!NT_SUCCESS(status)) {
448 FUNCTION_MSG("WdfDeviceOpenRegistryKey = %08x\n", status);
449 return status;
450 }
451 WdfRegistryClose(device_key);
452 FUNCTION_EXIT();
454 return status;
455 }
457 static NTSTATUS
458 XenUsbHub_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
459 {
460 NTSTATUS status = STATUS_SUCCESS;
461 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
462 //PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
464 UNREFERENCED_PARAMETER(device);
466 FUNCTION_ENTER();
468 switch (target_state)
469 {
470 case WdfPowerDeviceD0:
471 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
472 break;
473 case WdfPowerDeviceD1:
474 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
475 break;
476 case WdfPowerDeviceD2:
477 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
478 break;
479 case WdfPowerDeviceD3:
480 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
481 break;
482 case WdfPowerDeviceD3Final:
483 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
484 break;
485 case WdfPowerDevicePrepareForHibernation:
486 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
487 break;
488 default:
489 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
490 break;
491 }
493 FUNCTION_EXIT();
495 return status;
496 }
498 static NTSTATUS
499 XenUsbHub_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
500 {
501 NTSTATUS status = STATUS_SUCCESS;
503 UNREFERENCED_PARAMETER(device);
504 UNREFERENCED_PARAMETER(resources_raw);
505 UNREFERENCED_PARAMETER(resources_translated);
507 FUNCTION_ENTER();
508 FUNCTION_EXIT();
510 return status;
511 }
513 static NTSTATUS
514 XenUsbHub_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
515 {
516 NTSTATUS status = STATUS_SUCCESS;
518 UNREFERENCED_PARAMETER(device);
519 UNREFERENCED_PARAMETER(resources_translated);
521 FUNCTION_ENTER();
522 FUNCTION_EXIT();
524 return status;
525 }
527 static VOID
528 XenUsbHub_EvtDeviceUsageNotification(WDFDEVICE device, WDF_SPECIAL_FILE_TYPE notification_type, BOOLEAN is_in_notification_path)
529 {
530 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
532 UNREFERENCED_PARAMETER(xupdd);
533 UNREFERENCED_PARAMETER(is_in_notification_path);
535 FUNCTION_ENTER();
537 switch (notification_type)
538 {
539 case WdfSpecialFilePaging:
540 KdPrint((__DRIVER_NAME " notification_type = Paging, flag = %d\n", is_in_notification_path));
541 break;
542 case WdfSpecialFileHibernation:
543 KdPrint((__DRIVER_NAME " notification_type = Hibernation, flag = %d\n", is_in_notification_path));
544 break;
545 case WdfSpecialFileDump:
546 KdPrint((__DRIVER_NAME " notification_type = Dump, flag = %d\n", is_in_notification_path));
547 break;
548 default:
549 KdPrint((__DRIVER_NAME " notification_type = %d, flag = %d\n", notification_type, is_in_notification_path));
550 break;
551 }
553 FUNCTION_EXIT();
554 }
556 static NTSTATUS
557 XenUsb_SubmitCompletionRoutine(
558 PDEVICE_OBJECT device_object,
559 PIRP irp,
560 PVOID context)
561 {
562 UNREFERENCED_PARAMETER(device_object);
564 FUNCTION_ENTER();
566 if (irp->PendingReturned)
567 {
568 KeSetEvent ((PKEVENT)context, IO_NO_INCREMENT, FALSE);
569 }
571 FUNCTION_EXIT();
573 return STATUS_MORE_PROCESSING_REQUIRED;
574 }
576 static NTSTATUS
577 XenUsbHub_UBIH_CreateUsbDevice(
578 PVOID BusContext,
579 PUSB_DEVICE_HANDLE *DeviceHandle,
580 PUSB_DEVICE_HANDLE HubDeviceHandle,
581 USHORT PortStatus,
582 USHORT PortNumber)
583 {
584 NTSTATUS status = STATUS_SUCCESS;
585 xenusb_device_t *usb_device;
587 UNREFERENCED_PARAMETER(BusContext);
588 UNREFERENCED_PARAMETER(HubDeviceHandle);
589 UNREFERENCED_PARAMETER(PortStatus);
591 FUNCTION_ENTER();
593 FUNCTION_MSG("BusContext = %p\n", BusContext);
594 FUNCTION_MSG("DeviceHandle = %p\n", DeviceHandle);
595 FUNCTION_MSG("*DeviceHandle = %p\n", *DeviceHandle);
596 FUNCTION_MSG("HubDeviceHandle = %p\n", HubDeviceHandle);
597 FUNCTION_MSG("PortStatus = %04X\n", PortStatus);
598 FUNCTION_MSG("PortNumber = %d\n", PortNumber);
599 usb_device = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
600 if (!usb_device) {
601 FUNCTION_EXIT();
602 return STATUS_INSUFFICIENT_RESOURCES;
603 }
604 usb_device->port_number = PortNumber;
605 *DeviceHandle = usb_device;
607 FUNCTION_EXIT();
608 return status;
609 }
611 static NTSTATUS
612 XenUsbHub_UBIH_InitializeUsbDevice(
613 PVOID BusContext,
614 PUSB_DEVICE_HANDLE DeviceHandle)
615 {
616 NTSTATUS status = STATUS_SUCCESS;
617 WDFDEVICE device = BusContext;
618 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
619 //PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
620 WDF_IO_QUEUE_CONFIG queue_config;
621 xenusb_device_t *usb_device = DeviceHandle;
622 PUCHAR ptr;
623 PVOID buf;
624 PMDL mdl;
625 pvurb_t pvurb; /* this can be local because it never leaves this routine */
626 PUSB_DEVICE_DESCRIPTOR device_descriptor;
627 PUSB_CONFIGURATION_DESCRIPTOR config_descriptor;
628 PUSB_INTERFACE_DESCRIPTOR interface_descriptor;
629 PUSB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
630 int i, j, k;
631 PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
632 WDF_MEMORY_DESCRIPTOR pvurb_descriptor;
633 WDF_REQUEST_SEND_OPTIONS send_options;
635 FUNCTION_ENTER();
637 KdPrint((__DRIVER_NAME " device = %p\n", device));
638 KdPrint((__DRIVER_NAME " usb_device = %p\n", usb_device));
639 usb_device->pdo_device = BusContext;
641 // TODO: get address from freelist and assign it to the device...
642 usb_device->address = (UCHAR)get_id_from_freelist(xupdd->dev_id_ss);
643 // TODO: get this stuff properly ...
644 xupdd->usb_device->device_speed = UsbHighSpeed;
645 xupdd->usb_device->device_type = Usb20Device;
647 buf = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
648 if (!buf) {
649 FUNCTION_MSG("ExAllocatePoolWithTag(buf) failed\n");
650 return STATUS_INSUFFICIENT_RESOURCES;
651 }
652 mdl = IoAllocateMdl(buf, PAGE_SIZE, FALSE, FALSE, NULL);
653 if (!mdl) {
654 FUNCTION_MSG("IoAllocateMdl(buf) failed\n", status);
655 return STATUS_INSUFFICIENT_RESOURCES;
656 }
657 MmBuildMdlForNonPagedPool(mdl);
659 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&pvurb_descriptor, &pvurb, sizeof(pvurb));
660 WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
661 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_SEC(10));
663 /* set the address */
664 pvurb.req.pipe = LINUX_PIPE_TYPE_CTRL | usb_device->port_number;
665 pvurb.req.transfer_flags = 0;
666 pvurb.req.buffer_length = 0;
667 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb.req.u.ctrl;
668 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
669 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
670 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
671 setup_packet->bRequest = USB_REQUEST_SET_ADDRESS;
672 setup_packet->wValue.W = usb_device->address;
673 setup_packet->wIndex.W = 0;
674 setup_packet->wLength = pvurb.req.buffer_length;
675 pvurb.mdl = NULL;
676 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, NULL, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
677 if (!NT_SUCCESS(status)) {
678 FUNCTION_MSG("WdfIoTargetSendInternalIoctlOthersSynchronously(USB_REQUEST_SET_ADDRESS) = %08x\n", status);
679 return status;
680 }
681 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
682 FUNCTION_MSG("rsp start_frame = %d\n", pvurb.rsp.start_frame);
683 FUNCTION_MSG("rsp status = %d\n", pvurb.rsp.status);
684 FUNCTION_MSG("rsp actual_length = %d\n", pvurb.rsp.actual_length);
685 FUNCTION_MSG("rsp error_count = %d\n", pvurb.rsp.error_count);
687 /* get the device descriptor */
688 pvurb.req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
689 pvurb.req.transfer_flags = 0;
690 pvurb.req.buffer_length = PAGE_SIZE;
691 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb.req.u.ctrl;
692 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
693 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
694 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
695 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
696 setup_packet->wValue.LowByte = 0;
697 setup_packet->wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; //device descriptor
698 setup_packet->wIndex.W = 0;
699 setup_packet->wLength = pvurb.req.buffer_length;
700 pvurb.mdl = mdl;
701 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, NULL, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
702 if (!NT_SUCCESS(status)) {
703 FUNCTION_MSG("WdfIoTargetSendInternalIoctlOthersSynchronously(USB_REQUEST_GET_DESCRIPTOR, USB_DEVICE_DESCRIPTOR_TYPE) = %08x\n", status);
704 return status;
705 }
706 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", pvurb.rsp.start_frame));
707 KdPrint((__DRIVER_NAME " rsp status = %d\n", pvurb.rsp.status));
708 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", pvurb.rsp.actual_length));
709 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", pvurb.rsp.error_count));
710 ptr = buf;
711 device_descriptor = (PUSB_DEVICE_DESCRIPTOR)ptr;
712 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
713 KdPrint((__DRIVER_NAME " bNumConfigurations = %d\n", device_descriptor->bNumConfigurations));
714 memcpy(&usb_device->device_descriptor, device_descriptor, device_descriptor->bLength);
715 usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * device_descriptor->bNumConfigurations, XENUSB_POOL_TAG);
716 if (!usb_device->configs) {
717 FUNCTION_MSG("ExAllocatePoolWithTag(usb_device->configs) failed\n");
718 return STATUS_INSUFFICIENT_RESOURCES;
719 }
720 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
721 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", device_descriptor->bDescriptorType));
722 KdPrint((__DRIVER_NAME " bcdUSB = %04x\n", device_descriptor->bcdUSB));
723 KdPrint((__DRIVER_NAME " bDeviceClass = %02x\n", device_descriptor->bDeviceClass));
724 KdPrint((__DRIVER_NAME " bDeviceSubClass = %02x\n", device_descriptor->bDeviceSubClass));
725 KdPrint((__DRIVER_NAME " bDeviceProtocol = %02x\n", device_descriptor->bDeviceProtocol));
726 KdPrint((__DRIVER_NAME " idVendor = %04x\n", device_descriptor->idVendor));
727 KdPrint((__DRIVER_NAME " idProduct = %04x\n", device_descriptor->idProduct));
728 KdPrint((__DRIVER_NAME " bcdDevice = %04x\n", device_descriptor->bcdDevice));
729 KdPrint((__DRIVER_NAME " bNumConfigurations = %04x\n", device_descriptor->bNumConfigurations));
731 /* get the config descriptor */
732 for (i = 0; i < device_descriptor->bNumConfigurations; i++)
733 {
734 pvurb.req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
735 pvurb.req.transfer_flags = 0;
736 pvurb.req.buffer_length = PAGE_SIZE;
737 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb.req.u.ctrl;
738 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
739 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
740 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
741 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
742 setup_packet->wValue.LowByte = (UCHAR)(i + 1);
743 setup_packet->wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; //device descriptor
744 setup_packet->wIndex.W = 0;
745 setup_packet->wLength = pvurb.req.buffer_length;
746 pvurb.mdl = mdl;
747 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, NULL, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
748 if (!NT_SUCCESS(status)) {
749 FUNCTION_MSG("WdfIoTargetSendInternalIoctlOthersSynchronously(USB_REQUEST_GET_DESCRIPTOR, USB_CONFIGURATION_DESCRIPTOR_TYPE) = %08x\n", status);
750 return status;
751 }
752 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", pvurb.rsp.start_frame));
753 KdPrint((__DRIVER_NAME " rsp status = %d\n", pvurb.rsp.status));
754 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", pvurb.rsp.actual_length));
755 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", pvurb.rsp.error_count));
756 ptr = buf;
757 config_descriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ptr;
758 KdPrint((__DRIVER_NAME " Config %d\n", i));
759 KdPrint((__DRIVER_NAME " bLength = %d\n", config_descriptor->bLength));
760 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", config_descriptor->bDescriptorType));
761 KdPrint((__DRIVER_NAME " wTotalLength = %d\n", config_descriptor->wTotalLength));
762 KdPrint((__DRIVER_NAME " bNumInterfaces = %d\n", config_descriptor->bNumInterfaces));
763 KdPrint((__DRIVER_NAME " iConfiguration = %d\n", config_descriptor->iConfiguration));
764 KdPrint((__DRIVER_NAME " bConfigurationValue = %d\n", config_descriptor->bConfigurationValue));
765 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", config_descriptor->bmAttributes));
766 KdPrint((__DRIVER_NAME " MaxPower = %d\n", config_descriptor->MaxPower));
767 usb_device->configs[i] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * config_descriptor->bNumInterfaces, XENUSB_POOL_TAG);
768 if (!usb_device->configs) {
769 FUNCTION_MSG("ExAllocatePoolWithTag(usb_device->configs[i]) failed\n");
770 return STATUS_INSUFFICIENT_RESOURCES;
771 }
772 usb_device->configs[i]->device = usb_device;
773 memcpy(&usb_device->configs[i]->config_descriptor, config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
774 usb_device->configs[i]->config_descriptor_all = ExAllocatePoolWithTag(NonPagedPool, config_descriptor->wTotalLength, XENUSB_POOL_TAG);
775 memcpy(usb_device->configs[i]->config_descriptor_all, config_descriptor, config_descriptor->wTotalLength);
776 ptr += config_descriptor->bLength;
777 j = 0;
778 while (j < config_descriptor->bNumInterfaces)
779 {
780 interface_descriptor = (PUSB_INTERFACE_DESCRIPTOR)ptr;
781 KdPrint((__DRIVER_NAME " Interface %d\n", j));
782 KdPrint((__DRIVER_NAME " bLength = %d\n", interface_descriptor->bLength));
783 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", interface_descriptor->bDescriptorType));
784 KdPrint((__DRIVER_NAME " bInterfaceNumber = %d\n", interface_descriptor->bInterfaceNumber));
785 KdPrint((__DRIVER_NAME " bAlternateSetting = %d\n", interface_descriptor->bAlternateSetting));
786 KdPrint((__DRIVER_NAME " bNumEndpoints = %d\n", interface_descriptor->bNumEndpoints));
787 KdPrint((__DRIVER_NAME " bInterfaceClass = %d\n", interface_descriptor->bInterfaceClass));
788 KdPrint((__DRIVER_NAME " bInterfaceSubClass = %d\n", interface_descriptor->bInterfaceSubClass));
789 KdPrint((__DRIVER_NAME " bInterfaceProtocol = %d\n", interface_descriptor->bInterfaceProtocol));
790 KdPrint((__DRIVER_NAME " iInterface = %d\n", interface_descriptor->iInterface));
791 ptr += interface_descriptor->bLength;
792 usb_device->configs[i]->interfaces[j] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * interface_descriptor->bNumEndpoints, XENUSB_POOL_TAG);
793 usb_device->configs[i]->interfaces[j]->config = usb_device->configs[i];
794 memcpy(&usb_device->configs[i]->interfaces[j]->interface_descriptor, interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
795 k = 0;
796 while (k < interface_descriptor->bNumEndpoints)
797 {
798 endpoint_descriptor = (PUSB_ENDPOINT_DESCRIPTOR)ptr;
799 if (endpoint_descriptor->bDescriptorType != 5)
800 {
801 KdPrint((__DRIVER_NAME " Unknown bDescriptorType %d found length = %d\n", endpoint_descriptor->bDescriptorType, endpoint_descriptor->bLength));
802 ptr += endpoint_descriptor->bLength;
803 continue;
804 }
806 KdPrint((__DRIVER_NAME " Endpoint %d\n", k));
807 KdPrint((__DRIVER_NAME " bLength = %d\n", endpoint_descriptor->bLength));
808 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", endpoint_descriptor->bDescriptorType));
809 KdPrint((__DRIVER_NAME " bEndpointAddress = %02x\n", endpoint_descriptor->bEndpointAddress));
810 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", endpoint_descriptor->bmAttributes));
811 KdPrint((__DRIVER_NAME " wMaxPacketSize = %d\n", endpoint_descriptor->wMaxPacketSize));
812 KdPrint((__DRIVER_NAME " bInterval = %d\n", endpoint_descriptor->bInterval));
813 ptr += endpoint_descriptor->bLength;
814 usb_device->configs[i]->interfaces[j]->endpoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
815 usb_device->configs[i]->interfaces[j]->endpoints[k]->interface = usb_device->configs[i]->interfaces[j];
816 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value = (usb_device->address << 8) | usb_device->port_number;
817 /* linux uses nonstandard endpoint type identifiers... */
818 switch(endpoint_descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
819 {
820 case USB_ENDPOINT_TYPE_CONTROL:
821 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_CTRL;
822 break;
823 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
824 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_ISOC;
825 break;
826 case USB_ENDPOINT_TYPE_BULK:
827 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_BULK;
828 break;
829 case USB_ENDPOINT_TYPE_INTERRUPT:
830 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_INTR;
831 break;
832 }
833 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x80);
834 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x0F) << 15;
835 memcpy(&usb_device->configs[i]->interfaces[j]->endpoints[k]->endpoint_descriptor, endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
836 k++;
837 }
838 j++;
839 }
840 }
841 ExFreePoolWithTag(buf, XENUSB_POOL_TAG);
843 usb_device->active_config = usb_device->configs[0];
844 usb_device->active_interface = usb_device->configs[0]->interfaces[0];
846 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel); // should this be serial?
847 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
848 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
849 status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &usb_device->urb_queue);
850 if (!NT_SUCCESS(status)) {
851 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
852 return status;
853 }
854 FUNCTION_EXIT();
855 return status;
856 }
858 static NTSTATUS
859 XenUsbHub_UBIH_GetUsbDescriptors(
860 PVOID BusContext,
861 PUSB_DEVICE_HANDLE DeviceHandle,
862 PUCHAR DeviceDescriptorBuffer,
863 PULONG DeviceDescriptorBufferLength,
864 PUCHAR ConfigDescriptorBuffer,
865 PULONG ConfigDescriptorBufferLength
866 )
867 {
868 NTSTATUS status = STATUS_SUCCESS;
869 xenusb_device_t *usb_device = DeviceHandle;
870 xenusb_config_t *usb_config;
871 PUCHAR ptr;
873 UNREFERENCED_PARAMETER(BusContext);
875 FUNCTION_ENTER();
877 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
878 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
879 KdPrint((__DRIVER_NAME " DeviceDescriptorBuffer = %p\n", DeviceDescriptorBuffer));
880 KdPrint((__DRIVER_NAME " DeviceDescriptorBufferLength = %d\n", *DeviceDescriptorBufferLength));
881 KdPrint((__DRIVER_NAME " ConfigDescriptorBuffer = %p\n", ConfigDescriptorBuffer));
882 KdPrint((__DRIVER_NAME " ConfigDescriptorBufferLength = %d\n", *ConfigDescriptorBufferLength));
884 memcpy(DeviceDescriptorBuffer, &usb_device->device_descriptor, usb_device->device_descriptor.bLength);
885 *DeviceDescriptorBufferLength = usb_device->device_descriptor.bLength;
887 usb_config = usb_device->active_config;
888 ptr = ConfigDescriptorBuffer;
889 memcpy(ptr, usb_config->config_descriptor_all, min(usb_config->config_descriptor.wTotalLength, *ConfigDescriptorBufferLength));
890 *ConfigDescriptorBufferLength = ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
892 #if 0
893 ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
894 // why was this here? ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += 1;
896 for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
897 {
898 memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
899 ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
900 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
901 for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
902 {
903 memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
904 ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
905 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
906 }
907 }
908 *ConfigDescriptorBufferLength = ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
909 #endif
911 FUNCTION_EXIT();
912 return status;
913 }
915 static NTSTATUS
916 XenUsbHub_UBIH_RemoveUsbDevice (
917 PVOID BusContext,
918 PUSB_DEVICE_HANDLE DeviceHandle,
919 ULONG Flags)
920 {
921 NTSTATUS status = STATUS_SUCCESS;
922 WDFDEVICE device = BusContext;
923 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
924 xenusb_device_t *usb_device = DeviceHandle;
925 int i, j, k;
927 FUNCTION_ENTER();
929 if (Flags & USBD_KEEP_DEVICE_DATA)
930 KdPrint((__DRIVER_NAME " USBD_KEEP_DEVICE_DATA\n"));
932 if (Flags & USBD_MARK_DEVICE_BUSY)
933 KdPrint((__DRIVER_NAME " USBD_MARK_DEVICE_BUSY\n"));
935 put_id_on_freelist(xupdd->dev_id_ss, (uint16_t)usb_device->address);
936 // check if there are no pending requests
937 for (i = 0; i < usb_device->device_descriptor.bNumConfigurations; i++) {
938 for (j = 0; j < usb_device->configs[i]->config_descriptor.bNumInterfaces; j++) {
939 for (k = 0; k < usb_device->configs[i]->interfaces[j]->interface_descriptor.bNumEndpoints; k++) {
940 ExFreePoolWithTag(usb_device->configs[i]->interfaces[j]->endpoints[k], XENUSB_POOL_TAG);
941 }
942 ExFreePoolWithTag(usb_device->configs[i]->interfaces[j], XENUSB_POOL_TAG);
943 }
944 ExFreePoolWithTag(usb_device->configs[i]->config_descriptor_all, XENUSB_POOL_TAG);
945 ExFreePoolWithTag(usb_device->configs[i], XENUSB_POOL_TAG);
946 }
947 ExFreePoolWithTag(usb_device->configs, XENUSB_POOL_TAG);
948 ExFreePoolWithTag(usb_device, XENUSB_POOL_TAG);
949 FUNCTION_EXIT();
950 return status;
951 }
953 static NTSTATUS
954 XenUsbHub_UBIH_RestoreUsbDevice(
955 PVOID BusContext,
956 PUSB_DEVICE_HANDLE OldDeviceHandle,
957 PUSB_DEVICE_HANDLE NewDeviceHandle)
958 {
959 NTSTATUS status = STATUS_UNSUCCESSFUL;
961 UNREFERENCED_PARAMETER(BusContext);
962 UNREFERENCED_PARAMETER(OldDeviceHandle);
963 UNREFERENCED_PARAMETER(NewDeviceHandle);
965 FUNCTION_ENTER();
967 FUNCTION_EXIT();
968 return status;
969 }
971 static NTSTATUS
972 XenUsbHub_UBIH_GetPortHackFlags(
973 PVOID BusContext,
974 PULONG HackFlags)
975 {
976 NTSTATUS status = STATUS_UNSUCCESSFUL;
978 UNREFERENCED_PARAMETER(BusContext);
979 UNREFERENCED_PARAMETER(HackFlags);
981 FUNCTION_ENTER();
983 FUNCTION_EXIT();
984 return status;
985 }
987 static NTSTATUS
988 XenUsbHub_UBIH_QueryDeviceInformation(
989 PVOID BusContext,
990 PUSB_DEVICE_HANDLE DeviceHandle,
991 PVOID DeviceInformationBuffer,
992 ULONG DeviceInformationBufferLength,
993 PULONG LengthOfDataReturned)
994 {
995 PUSB_DEVICE_INFORMATION_0 udi = DeviceInformationBuffer;
996 xenusb_device_t *usb_device = DeviceHandle;
997 ULONG i;
998 ULONG required_size;
1000 UNREFERENCED_PARAMETER(BusContext);
1002 FUNCTION_ENTER();
1004 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1005 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
1006 KdPrint((__DRIVER_NAME " DeviceInformationBuffer = %p\n", DeviceInformationBuffer));
1007 KdPrint((__DRIVER_NAME " DeviceInformationBufferLength = %d\n", DeviceInformationBufferLength));
1008 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", udi->InformationLevel));
1009 required_size = (ULONG)FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[usb_device->active_interface->interface_descriptor.bNumEndpoints]);
1010 KdPrint((__DRIVER_NAME " required_size = %d\n", required_size));
1011 *LengthOfDataReturned = required_size;
1012 udi->ActualLength = required_size;
1013 if (DeviceInformationBufferLength < required_size)
1015 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
1016 FUNCTION_EXIT();
1017 return STATUS_BUFFER_TOO_SMALL;
1019 if (udi->InformationLevel != 0)
1021 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
1022 FUNCTION_EXIT();
1023 return STATUS_NOT_SUPPORTED;
1025 udi->PortNumber = 1;
1026 memcpy(&udi->DeviceDescriptor, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
1027 udi->CurrentConfigurationValue = usb_device->active_config->config_descriptor.bConfigurationValue;
1028 udi->DeviceAddress = usb_device->address;
1029 udi->HubAddress = 1; // ?
1030 udi->DeviceSpeed = usb_device->device_speed;
1031 udi->DeviceType = usb_device->device_type;
1032 udi->NumberOfOpenPipes = usb_device->active_interface->interface_descriptor.bNumEndpoints;
1033 for (i = 0; i < usb_device->active_interface->interface_descriptor.bNumEndpoints; i++)
1035 memcpy(&udi->PipeList[i].EndpointDescriptor, &usb_device->active_interface->endpoints[i]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
1036 udi->PipeList[0].ScheduleOffset = 0; // not necessarily right
1038 FUNCTION_EXIT();
1039 return STATUS_SUCCESS;
1042 static NTSTATUS
1043 XenUsbHub_UBIH_GetControllerInformation (
1044 PVOID BusContext,
1045 PVOID ControllerInformationBuffer,
1046 ULONG ControllerInformationBufferLength,
1047 PULONG LengthOfDataReturned)
1049 NTSTATUS status = STATUS_UNSUCCESSFUL;
1050 PUSB_CONTROLLER_INFORMATION_0 uci = ControllerInformationBuffer;
1051 //WDFDEVICE device = BusContext;
1052 //xenusb_device_t *usb_device = DeviceHandle;
1054 UNREFERENCED_PARAMETER(BusContext);
1056 FUNCTION_ENTER();
1058 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1059 KdPrint((__DRIVER_NAME " ControllerInformationBuffer = %p\n", ControllerInformationBuffer));
1060 KdPrint((__DRIVER_NAME " ControllerInformationBufferLength = %d\n", ControllerInformationBufferLength));
1061 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", uci->InformationLevel));
1062 if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
1064 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
1065 FUNCTION_EXIT();
1066 return STATUS_BUFFER_TOO_SMALL;
1068 if (uci->InformationLevel != 0)
1070 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
1071 FUNCTION_EXIT();
1072 return STATUS_NOT_SUPPORTED;
1075 uci->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
1076 uci->SelectiveSuspendEnabled = FALSE;
1077 uci->IsHighSpeedController = TRUE;
1078 *LengthOfDataReturned = uci->ActualLength;
1080 FUNCTION_EXIT();
1081 return status;
1084 static NTSTATUS
1085 XenUsbHub_UBIH_ControllerSelectiveSuspend (
1086 PVOID BusContext,
1087 BOOLEAN Enable)
1089 NTSTATUS status = STATUS_UNSUCCESSFUL;
1091 UNREFERENCED_PARAMETER(BusContext);
1092 UNREFERENCED_PARAMETER(Enable);
1094 FUNCTION_ENTER();
1096 FUNCTION_EXIT();
1097 return status;
1100 static NTSTATUS
1101 XenUsbHub_UBIH_GetExtendedHubInformation (
1102 PVOID BusContext,
1103 PDEVICE_OBJECT HubPhysicalDeviceObject,
1104 PVOID HubInformationBuffer,
1105 ULONG HubInformationBufferLength,
1106 PULONG LengthOfDataReturned)
1108 PUSB_EXTHUB_INFORMATION_0 hib = HubInformationBuffer;
1109 ULONG i;
1111 UNREFERENCED_PARAMETER(BusContext);
1112 UNREFERENCED_PARAMETER(HubPhysicalDeviceObject);
1114 FUNCTION_ENTER();
1116 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1117 KdPrint((__DRIVER_NAME " HubPhysicalDeviceObject = %p\n", HubPhysicalDeviceObject));
1118 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
1119 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
1120 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", hib->InformationLevel));
1121 if (HubInformationBufferLength < (ULONG)FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]))
1123 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
1124 FUNCTION_EXIT();
1125 return STATUS_BUFFER_TOO_SMALL;
1127 #if 0
1128 if (hib->InformationLevel != 0)
1130 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
1131 FUNCTION_EXIT();
1132 return STATUS_NOT_SUPPORTED;
1134 #endif
1135 hib->InformationLevel = 0;
1136 hib->NumberOfPorts = 8;
1137 for (i = 0; i < hib->NumberOfPorts; i++)
1139 hib->Port[i].PhysicalPortNumber = i + 1;
1140 hib->Port[i].PortLabelNumber = i + 1;
1141 hib->Port[i].VidOverride = 0;
1142 hib->Port[i].PidOverride = 0;
1143 hib->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2; // | USB_PORTATTR_NO_OVERCURRENT_UI;
1145 *LengthOfDataReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
1146 FUNCTION_EXIT();
1147 return STATUS_SUCCESS;
1150 static NTSTATUS
1151 XenUsbHub_UBIH_GetRootHubSymbolicName(
1152 PVOID BusContext,
1153 PVOID HubInformationBuffer,
1154 ULONG HubInformationBufferLength,
1155 PULONG HubNameActualLength)
1157 NTSTATUS status = STATUS_SUCCESS;
1158 FUNCTION_ENTER();
1160 UNREFERENCED_PARAMETER(BusContext);
1162 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1163 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
1164 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
1165 RtlStringCbCopyW(HubInformationBuffer, HubInformationBufferLength, L"ROOT_HUB");
1166 *HubNameActualLength = 16;
1168 FUNCTION_EXIT();
1169 return status;
1172 static PVOID
1173 XenUsbHub_UBIH_GetDeviceBusContext(
1174 PVOID BusContext,
1175 PVOID DeviceHandle)
1177 UNREFERENCED_PARAMETER(BusContext);
1178 UNREFERENCED_PARAMETER(DeviceHandle);
1180 FUNCTION_ENTER();
1182 FUNCTION_EXIT();
1183 return NULL;
1186 static NTSTATUS
1187 XenUsbHub_UBIH_Initialize20Hub (
1188 PVOID BusContext,
1189 PUSB_DEVICE_HANDLE HubDeviceHandle,
1190 ULONG TtCount)
1192 NTSTATUS status = STATUS_SUCCESS;
1194 UNREFERENCED_PARAMETER(BusContext);
1195 UNREFERENCED_PARAMETER(HubDeviceHandle);
1196 UNREFERENCED_PARAMETER(TtCount);
1198 FUNCTION_ENTER();
1199 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1200 KdPrint((__DRIVER_NAME " HubDeviceHandle = %p\n", HubDeviceHandle));
1201 KdPrint((__DRIVER_NAME " TtCount = %d\n", TtCount));
1202 FUNCTION_EXIT();
1203 return status;
1206 static NTSTATUS
1207 XenUsbHub_UBIH_RootHubInitNotification(
1208 PVOID BusContext,
1209 PVOID CallbackContext,
1210 PRH_INIT_CALLBACK CallbackFunction)
1212 NTSTATUS status = STATUS_SUCCESS;
1213 WDFDEVICE device = BusContext;
1214 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
1216 FUNCTION_ENTER();
1218 xupdd->BusCallbackFunction = CallbackFunction;
1219 xupdd->BusCallbackContext = CallbackContext;
1221 xupdd->BusCallbackFunction(xupdd->BusCallbackContext);
1223 FUNCTION_EXIT();
1224 return status;
1227 /* This definition is incorrect in the docs */
1228 static VOID
1229 XenUsbHub_UBIH_FlushTransfers(
1230 PVOID BusContext,
1231 PVOID DeviceHandle)
1233 UNREFERENCED_PARAMETER(BusContext);
1234 UNREFERENCED_PARAMETER(DeviceHandle);
1236 FUNCTION_ENTER();
1238 FUNCTION_EXIT();
1241 static VOID
1242 XenUsbHub_UBIH_SetDeviceHandleData(
1243 PVOID BusContext,
1244 PUSB_DEVICE_HANDLE DeviceHandle,
1245 PDEVICE_OBJECT UsbDevicePdo)
1247 UNREFERENCED_PARAMETER(BusContext);
1248 UNREFERENCED_PARAMETER(DeviceHandle);
1249 UNREFERENCED_PARAMETER(UsbDevicePdo);
1251 FUNCTION_ENTER();
1252 FUNCTION_EXIT();
1255 static NTSTATUS
1256 XenUsbHub_UBIH_CreateUsbDeviceEx(
1257 PVOID BusContext,
1258 PUSB_DEVICE_HANDLE *DeviceHandle,
1259 PUSB_DEVICE_HANDLE HubDeviceHandle,
1260 USHORT PortStatus,
1261 USHORT PortNumber,
1262 PUSB_CD_ERROR_INFORMATION CdErrorInfo,
1263 USHORT TtPortNumber)
1265 NTSTATUS status = STATUS_SUCCESS;
1267 UNREFERENCED_PARAMETER(CdErrorInfo);
1268 UNREFERENCED_PARAMETER(TtPortNumber);
1270 FUNCTION_ENTER();
1272 status = XenUsbHub_UBIH_CreateUsbDevice(BusContext, DeviceHandle, HubDeviceHandle, PortStatus, PortNumber);
1274 KdPrint((__DRIVER_NAME " CdErrorInfo = %p\n", CdErrorInfo));
1275 KdPrint((__DRIVER_NAME " TtPortNumber = %d\n", TtPortNumber));
1277 FUNCTION_EXIT();
1278 return status;
1281 #if (NTDDI_VERSION >= NTDDI_VISTA)
1282 static NTSTATUS
1283 XenUsbHub_UBIH_CreateUsbDeviceV7(
1284 PVOID BusContext,
1285 PUSB_DEVICE_HANDLE *NewDeviceHandle,
1286 PUSB_DEVICE_HANDLE HsHubDeviceHandle,
1287 USHORT PortStatus,
1288 PUSB_PORT_PATH PortPath,
1289 PUSB_CD_ERROR_INFORMATION CdErrorInfo,
1290 USHORT TtPortNumber,
1291 PDEVICE_OBJECT PdoDeviceObject,
1292 PUNICODE_STRING PhysicalDeviceObjectName)
1294 NTSTATUS status;
1296 UNREFERENCED_PARAMETER(PdoDeviceObject);
1297 UNREFERENCED_PARAMETER(PhysicalDeviceObjectName);
1299 FUNCTION_ENTER();
1300 KdPrint((__DRIVER_NAME " PortPath->PortPathDepth = %d\n", PortPath->PortPathDepth));
1301 KdPrint((__DRIVER_NAME " PortPath->PortPath[%d] = %d\n", PortPath->PortPathDepth - 1));
1302 status = XenUsbHub_UBIH_CreateUsbDeviceEx(BusContext, NewDeviceHandle, &HsHubDeviceHandle, PortStatus, (USHORT)PortPath->PortPath[PortPath->PortPathDepth-1], CdErrorInfo, TtPortNumber);
1303 KdPrint((__DRIVER_NAME " PdoDeviceObject = %p\n", PdoDeviceObject));
1304 KdPrint((__DRIVER_NAME " PhysicalDeviceObjectName = %S\n", PhysicalDeviceObjectName->Buffer));
1305 FUNCTION_EXIT();
1306 return status;
1308 #endif
1310 static NTSTATUS
1311 XenUsbHub_UBIH_InitializeUsbDeviceEx(
1312 PVOID BusContext,
1313 PUSB_DEVICE_HANDLE DeviceHandle,
1314 PUSB_ID_ERROR_INFORMATION IdErrInfo)
1316 NTSTATUS status;
1318 UNREFERENCED_PARAMETER(BusContext);
1319 UNREFERENCED_PARAMETER(DeviceHandle);
1320 UNREFERENCED_PARAMETER(IdErrInfo);
1321 FUNCTION_ENTER();
1322 FUNCTION_MSG("IdErrInfo->Version = %d\n", IdErrInfo->Version);
1323 FUNCTION_MSG("IdErrInfo->PathError = %d\n", IdErrInfo->PathError);
1324 FUNCTION_MSG("IdErrInfo->Arg1 = %08x\n", IdErrInfo->Arg1);
1325 FUNCTION_MSG("IdErrInfo->UsbAddress = %d\n", IdErrInfo->UsbAddress);
1326 FUNCTION_MSG("IdErrInfo->NtStatus = %08x\n", IdErrInfo->NtStatus);
1327 FUNCTION_MSG("IdErrInfo->UsbdStatus = %08x\n", IdErrInfo->UsbdStatus);
1328 FUNCTION_MSG("IdErrInfo->XtraInfo = %s\n", IdErrInfo->XtraInfo);
1329 status = XenUsbHub_UBIH_InitializeUsbDevice(BusContext, DeviceHandle);
1330 FUNCTION_EXIT();
1331 return status;
1334 static BOOLEAN
1335 XenUsbHub_UBIH_HubIsRoot(
1336 PVOID BusContext,
1337 PVOID DeviceObject)
1339 UNREFERENCED_PARAMETER(BusContext);
1340 UNREFERENCED_PARAMETER(DeviceObject);
1342 FUNCTION_ENTER();
1343 FUNCTION_EXIT();
1344 return TRUE;
1347 static VOID
1348 XenUsbHub_UBIH_AcquireBusSemaphore(
1349 PVOID BusContext)
1351 UNREFERENCED_PARAMETER(BusContext);
1352 FUNCTION_ENTER();
1353 FUNCTION_EXIT();
1354 return;
1357 static VOID
1358 XenUsbHub_UBIH_ReleaseBusSemaphore(
1359 PVOID BusContext)
1361 UNREFERENCED_PARAMETER(BusContext);
1362 FUNCTION_ENTER();
1363 FUNCTION_EXIT();
1364 return;
1367 static ULONG
1368 XenUsbHub_UBIH_CaculatePipeBandwidth(
1369 PVOID BusContext,
1370 PUSBD_PIPE_INFORMATION PipeInfo,
1371 USB_DEVICE_SPEED DeviceSpeed)
1373 UNREFERENCED_PARAMETER(BusContext);
1374 UNREFERENCED_PARAMETER(PipeInfo);
1375 UNREFERENCED_PARAMETER(DeviceSpeed);
1376 FUNCTION_ENTER();
1377 FUNCTION_EXIT();
1378 return (ULONG)-1;
1381 static VOID
1382 XenUsbHub_UBIH_SetBusSystemWakeMode(
1383 PVOID BusContext,
1384 ULONG Mode)
1386 UNREFERENCED_PARAMETER(BusContext);
1387 UNREFERENCED_PARAMETER(Mode);
1388 FUNCTION_ENTER();
1389 FUNCTION_EXIT();
1390 return;
1393 static VOID
1394 XenUsbHub_UBIH_SetDeviceFlag(
1395 PVOID BusContext,
1396 GUID *DeviceFlagGuid,
1397 PVOID ValueData,
1398 ULONG ValueLength)
1400 UNREFERENCED_PARAMETER(BusContext);
1401 UNREFERENCED_PARAMETER(DeviceFlagGuid);
1402 UNREFERENCED_PARAMETER(ValueData);
1403 UNREFERENCED_PARAMETER(ValueLength);
1404 FUNCTION_ENTER();
1405 FUNCTION_EXIT();
1406 return;
1409 static NTSTATUS
1410 XenUsbHub_UBIH_HubTestPoint(
1411 PVOID bus_context,
1412 PVOID device_handle,
1413 ULONG op_code,
1414 PVOID test_data)
1416 UNREFERENCED_PARAMETER(bus_context);
1417 UNREFERENCED_PARAMETER(device_handle);
1418 UNREFERENCED_PARAMETER(op_code);
1419 UNREFERENCED_PARAMETER(test_data);
1420 FUNCTION_ENTER();
1421 FUNCTION_MSG("device_handle = %p\n", device_handle);
1422 FUNCTION_MSG("op_code = %p\n", op_code);
1423 FUNCTION_MSG("test_data = %p\n", test_data);
1424 FUNCTION_EXIT();
1425 return STATUS_SUCCESS;
1428 static NTSTATUS
1429 XenUsbHub_UBIH_GetDevicePerformanceInfo(
1430 PVOID BusContext,
1431 PUSB_DEVICE_HANDLE DeviceHandle,
1432 PVOID DeviceInformationBuffer,
1433 ULONG DeviceInformationBufferLength,
1434 PULONG LengthOfDataCopied)
1436 UNREFERENCED_PARAMETER(BusContext);
1437 UNREFERENCED_PARAMETER(DeviceHandle);
1438 UNREFERENCED_PARAMETER(DeviceInformationBuffer);
1439 UNREFERENCED_PARAMETER(DeviceInformationBufferLength);
1440 UNREFERENCED_PARAMETER(LengthOfDataCopied);
1441 FUNCTION_ENTER();
1442 FUNCTION_EXIT();
1443 return STATUS_UNSUCCESSFUL;
1446 static NTSTATUS
1447 XenUsbHub_UBIH_WaitAsyncPowerUp(
1448 PVOID BusContext)
1450 UNREFERENCED_PARAMETER(BusContext);
1451 FUNCTION_ENTER();
1452 FUNCTION_EXIT();
1453 return STATUS_UNSUCCESSFUL;
1456 static NTSTATUS
1457 XenUsbHub_UBIH_GetDeviceAddress(
1458 PVOID BusContext,
1459 PUSB_DEVICE_HANDLE DeviceHandle,
1460 PUSHORT DeviceAddress)
1462 UNREFERENCED_PARAMETER(BusContext);
1463 UNREFERENCED_PARAMETER(DeviceHandle);
1464 UNREFERENCED_PARAMETER(DeviceAddress);
1465 FUNCTION_ENTER();
1466 FUNCTION_EXIT();
1467 return STATUS_UNSUCCESSFUL;
1470 static NTSTATUS
1471 XenUsbHub_UBIH_RefDeviceHandle(
1472 PVOID BusContext,
1473 PUSB_DEVICE_HANDLE DeviceHandle,
1474 PVOID Object,
1475 ULONG Tag)
1477 UNREFERENCED_PARAMETER(BusContext);
1478 UNREFERENCED_PARAMETER(DeviceHandle);
1479 UNREFERENCED_PARAMETER(Object);
1480 UNREFERENCED_PARAMETER(Tag);
1481 FUNCTION_ENTER();
1482 FUNCTION_MSG("This should do something\n");
1483 FUNCTION_EXIT();
1484 return STATUS_SUCCESS;
1487 static VOID
1488 XenUsbHub_UBIH_DerefDeviceHandle(
1489 PVOID BusContext,
1490 PUSB_DEVICE_HANDLE DeviceHandle,
1491 PVOID Object,
1492 ULONG Tag)
1494 UNREFERENCED_PARAMETER(BusContext);
1495 UNREFERENCED_PARAMETER(DeviceHandle);
1496 UNREFERENCED_PARAMETER(Object);
1497 UNREFERENCED_PARAMETER(Tag);
1498 FUNCTION_ENTER();
1499 FUNCTION_MSG("This should do something\n");
1500 FUNCTION_EXIT();
1503 static ULONG
1504 XenUsbHub_UBIH_SetDeviceHandleIdleReadyState(
1505 PVOID BusContext,
1506 PUSB_DEVICE_HANDLE DeviceHandle,
1507 ULONG NewIdleReadyState)
1509 UNREFERENCED_PARAMETER(BusContext);
1510 UNREFERENCED_PARAMETER(DeviceHandle);
1511 UNREFERENCED_PARAMETER(NewIdleReadyState);
1512 FUNCTION_ENTER();
1513 FUNCTION_EXIT();
1514 return (ULONG)-1;
1517 static NTSTATUS
1518 XenUsbHub_UBIH_GetContainerIdForPort(
1519 PVOID BusContext,
1520 USHORT PortNumber,
1521 LPGUID ContainerId)
1523 UNREFERENCED_PARAMETER(BusContext);
1524 UNREFERENCED_PARAMETER(PortNumber);
1525 UNREFERENCED_PARAMETER(ContainerId);
1526 FUNCTION_ENTER();
1527 FUNCTION_EXIT();
1528 return STATUS_UNSUCCESSFUL;
1531 static VOID
1532 XenUsbHub_UBIH_SetContainerIdForPort(
1533 PVOID BusContext,
1534 USHORT PortNumber,
1535 LPGUID ContainerId)
1537 UNREFERENCED_PARAMETER(BusContext);
1538 UNREFERENCED_PARAMETER(PortNumber);
1539 UNREFERENCED_PARAMETER(ContainerId);
1540 FUNCTION_ENTER();
1541 FUNCTION_EXIT();
1544 static NTSTATUS
1545 XenUsbHub_UBIH_AbortAllDevicePipes(
1546 PVOID BusContext,
1547 PUSB_DEVICE_HANDLE DeviceHandle)
1549 UNREFERENCED_PARAMETER(BusContext);
1550 UNREFERENCED_PARAMETER(DeviceHandle);
1551 FUNCTION_ENTER();
1552 FUNCTION_EXIT();
1553 return STATUS_SUCCESS;
1556 static VOID
1557 XenUsbHub_UBIH_SetDeviceErrataFlag(
1558 PVOID BusContext,
1559 PUSB_DEVICE_HANDLE DeviceHandle,
1560 ULONG DeviceErrataFlag)
1562 UNREFERENCED_PARAMETER(BusContext);
1563 UNREFERENCED_PARAMETER(DeviceHandle);
1564 UNREFERENCED_PARAMETER(DeviceErrataFlag);
1565 FUNCTION_ENTER();
1566 FUNCTION_EXIT();
1567 return;
1570 static NTSTATUS
1571 XenUsbHub_UBIU_GetUSBDIVersion(
1572 PVOID BusContext,
1573 PUSBD_VERSION_INFORMATION VersionInformation,
1574 PULONG HcdCapabilities
1577 NTSTATUS status = STATUS_UNSUCCESSFUL;
1579 UNREFERENCED_PARAMETER(BusContext);
1580 UNREFERENCED_PARAMETER(VersionInformation);
1581 UNREFERENCED_PARAMETER(HcdCapabilities);
1583 FUNCTION_ENTER();
1585 FUNCTION_EXIT();
1586 return status;
1589 static NTSTATUS
1590 XenUsbHub_UBIU_QueryBusTime(
1591 PVOID BusContext,
1592 PULONG CurrentFrame
1595 NTSTATUS status = STATUS_SUCCESS;
1596 static ULONG frame_no = 0;
1598 UNREFERENCED_PARAMETER(BusContext);
1599 UNREFERENCED_PARAMETER(CurrentFrame);
1601 //FUNCTION_ENTER();
1602 *CurrentFrame = frame_no++;
1603 //FUNCTION_EXIT();
1604 return status;
1607 static NTSTATUS
1608 XenUsbHub_UBIU_SubmitIsoOutUrb(
1609 PVOID BusContext,
1610 PURB Urb
1613 NTSTATUS status = STATUS_UNSUCCESSFUL;
1615 UNREFERENCED_PARAMETER(BusContext);
1616 UNREFERENCED_PARAMETER(Urb);
1618 FUNCTION_ENTER();
1620 FUNCTION_EXIT();
1621 return status;
1624 static NTSTATUS
1625 XenUsbHub_UBIU_QueryBusInformation(
1626 PVOID BusContext,
1627 ULONG Level,
1628 PVOID BusInformationBuffer,
1629 PULONG BusInformationBufferLength,
1630 PULONG BusInformationActualLength)
1632 NTSTATUS status = STATUS_UNSUCCESSFUL;
1634 UNREFERENCED_PARAMETER(BusContext);
1635 UNREFERENCED_PARAMETER(Level);
1636 UNREFERENCED_PARAMETER(BusInformationBuffer);
1637 UNREFERENCED_PARAMETER(BusInformationBufferLength);
1638 UNREFERENCED_PARAMETER(BusInformationActualLength);
1640 FUNCTION_ENTER();
1642 FUNCTION_EXIT();
1643 return status;
1646 static BOOLEAN
1647 XenUsbHub_UBIU_IsDeviceHighSpeed(PVOID BusContext)
1649 UNREFERENCED_PARAMETER(BusContext);
1651 FUNCTION_ENTER();
1653 FUNCTION_EXIT();
1654 return TRUE; //TODO: get port value
1657 static NTSTATUS
1658 XenUsbHub_UBIU_EnumLogEntry(
1659 PVOID BusContext,
1660 ULONG DriverTag,
1661 ULONG EnumTag,
1662 ULONG P1,
1663 ULONG P2
1666 NTSTATUS status = STATUS_SUCCESS;
1667 FUNCTION_ENTER();
1669 UNREFERENCED_PARAMETER(BusContext);
1670 UNREFERENCED_PARAMETER(DriverTag);
1671 UNREFERENCED_PARAMETER(EnumTag);
1672 UNREFERENCED_PARAMETER(P1);
1673 UNREFERENCED_PARAMETER(P2);
1675 KdPrint((__DRIVER_NAME " DriverTag = %08x\n", DriverTag));
1676 KdPrint((__DRIVER_NAME " EnumTag = %08x\n", EnumTag));
1677 KdPrint((__DRIVER_NAME " P1 = %08x\n", P1));
1678 KdPrint((__DRIVER_NAME " P2 = %08x\n", P2));
1680 FUNCTION_EXIT();
1681 return status;
1684 static NTSTATUS
1685 XenUsbHub_UBIU_QueryBusTimeEx(
1686 PVOID BusContext,
1687 PULONG HighSpeedFrameCounter)
1689 UNREFERENCED_PARAMETER(BusContext);
1690 UNREFERENCED_PARAMETER(HighSpeedFrameCounter);
1691 FUNCTION_ENTER();
1692 FUNCTION_EXIT();
1693 return STATUS_UNSUCCESSFUL;
1696 static NTSTATUS
1697 XenUsbHub_UBIU_QueryControllerType(
1698 PVOID BusContext,
1699 PULONG HcdiOptionFlags,
1700 PUSHORT PciVendorId,
1701 PUSHORT PciDeviceId,
1702 PUCHAR PciClass,
1703 PUCHAR PciSubClass,
1704 PUCHAR PciRevisionId,
1705 PUCHAR PciProgIf)
1707 UNREFERENCED_PARAMETER(BusContext);
1708 UNREFERENCED_PARAMETER(HcdiOptionFlags);
1709 UNREFERENCED_PARAMETER(PciVendorId);
1710 UNREFERENCED_PARAMETER(PciDeviceId);
1711 UNREFERENCED_PARAMETER(PciClass);
1712 UNREFERENCED_PARAMETER(PciSubClass);
1713 UNREFERENCED_PARAMETER(PciRevisionId);
1714 UNREFERENCED_PARAMETER(PciProgIf);
1715 FUNCTION_ENTER();
1716 FUNCTION_EXIT();
1717 return STATUS_UNSUCCESSFUL;
1720 static NTSTATUS
1721 XenUsbHub_UBIHSS_SuspendHub(
1722 PVOID BusContext)
1724 UNREFERENCED_PARAMETER(BusContext);
1725 FUNCTION_ENTER();
1726 FUNCTION_EXIT();
1727 return STATUS_SUCCESS;
1730 static NTSTATUS
1731 XenUsbHub_UBIHSS_ResumeHub(
1732 PVOID BusContext)
1734 UNREFERENCED_PARAMETER(BusContext);
1735 FUNCTION_ENTER();
1736 FUNCTION_EXIT();
1737 return STATUS_SUCCESS;
1740 VOID
1741 XenUsbHub_ProcessHubInterruptEvent(xenusb_endpoint_t *endpoint)
1743 NTSTATUS status;
1744 WDFDEVICE pdo_device = endpoint->interface->config->device->pdo_device;
1745 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(pdo_device);
1746 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
1747 WDF_REQUEST_PARAMETERS wrp;
1748 WDFREQUEST request;
1749 PURB urb;
1750 ULONG i;
1751 BOOLEAN port_change_flag = FALSE;
1753 FUNCTION_ENTER();
1754 WdfSpinLockAcquire(endpoint->lock);
1755 status = WdfIoQueueRetrieveNextRequest(endpoint->queue, &request);
1756 if (status == STATUS_NO_MORE_ENTRIES)
1758 WdfSpinLockRelease(endpoint->lock);
1759 KdPrint((__DRIVER_NAME " No More Entries\n", status));
1760 FUNCTION_EXIT();
1761 return;
1763 if (!NT_SUCCESS(status))
1765 WdfSpinLockRelease(endpoint->lock);
1766 KdPrint((__DRIVER_NAME " Failed to get request from queue %08x\n", status));
1767 FUNCTION_EXIT();
1768 return;
1771 WDF_REQUEST_PARAMETERS_INIT(&wrp);
1772 WdfRequestGetParameters(request, &wrp);
1774 urb = (PURB)wrp.Parameters.Others.Arg1;
1775 ASSERT(urb);
1776 ASSERT(urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
1777 RtlZeroMemory(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
1779 for (i = 0; i < xudd->num_ports; i++)
1781 FUNCTION_MSG("port %d - status = %04x, change = %04x\n", xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
1782 if (xudd->ports[i].port_change) {
1783 FUNCTION_MSG("Port change on port %d - status = %04x, change = %04x\n",
1784 xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
1785 ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
1786 port_change_flag = TRUE;
1788 FUNCTION_MSG("port %d - status = %04x, change = %04x\n", xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
1790 WdfSpinLockRelease(endpoint->lock);
1791 if (port_change_flag)
1793 FUNCTION_MSG("Completing request %p\n", request);
1794 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
1795 WdfRequestComplete(request, STATUS_SUCCESS);
1797 else
1799 FUNCTION_MSG("Requeuing request %p\n", request);
1800 WdfRequestRequeue(request);
1802 FUNCTION_EXIT();
1803 return;
1806 static NTSTATUS
1807 XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
1809 PIO_STACK_LOCATION stack;
1810 union {
1811 USB_BUS_INTERFACE_HUB_V5 ubih5;
1812 #if (NTDDI_VERSION >= NTDDI_VISTA)
1813 USB_BUS_INTERFACE_HUB_V7 ubih6;
1814 USB_BUS_INTERFACE_HUB_V7 ubih7;
1815 #endif
1816 } *ubih;
1817 union {
1818 USB_BUS_INTERFACE_USBDI_V1 ubiu0;
1819 USB_BUS_INTERFACE_USBDI_V1 ubiu1;
1820 USB_BUS_INTERFACE_USBDI_V2 ubiu2;
1821 #if (NTDDI_VERSION >= NTDDI_VISTA)
1822 USB_BUS_INTERFACE_USBDI_V3 ubiu3;
1823 #endif
1824 } *ubiu;
1826 FUNCTION_ENTER();
1828 stack = IoGetCurrentIrpStackLocation(irp);
1830 if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
1832 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_HUB_GUID\n"));
1833 if ((stack->Parameters.QueryInterface.Version == USB_BUSIF_HUB_VERSION_5 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V5))
1834 #if (NTDDI_VERSION >= NTDDI_VISTA)
1835 || (stack->Parameters.QueryInterface.Version == USB_BUSIF_HUB_VERSION_6 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V6))
1836 || (stack->Parameters.QueryInterface.Version == USB_BUSIF_HUB_VERSION_7 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V7))
1837 #endif
1840 ubih = (PVOID)stack->Parameters.QueryInterface.Interface;
1841 ubih->ubih5.Size = stack->Parameters.QueryInterface.Size;
1842 ubih->ubih5.Version = stack->Parameters.QueryInterface.Version;
1843 ubih->ubih5.BusContext = device;
1844 ubih->ubih5.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1845 ubih->ubih5.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1846 /* these two were changed to the Ex functions in v6 so we set them here so they don't get overwritten */
1847 ubih->ubih5.CreateUsbDevice = XenUsbHub_UBIH_CreateUsbDevice;
1848 ubih->ubih5.InitializeUsbDevice = XenUsbHub_UBIH_InitializeUsbDevice;
1849 switch (stack->Parameters.QueryInterface.Version)
1851 #if (NTDDI_VERSION >= NTDDI_VISTA)
1852 case USB_BUSIF_HUB_VERSION_7:
1853 ubih->ubih7.HubTestPoint = XenUsbHub_UBIH_HubTestPoint;
1854 ubih->ubih7.GetDevicePerformanceInfo = XenUsbHub_UBIH_GetDevicePerformanceInfo;
1855 ubih->ubih7.WaitAsyncPowerUp = XenUsbHub_UBIH_WaitAsyncPowerUp;
1856 ubih->ubih7.GetDeviceAddress = XenUsbHub_UBIH_GetDeviceAddress;
1857 ubih->ubih7.RefDeviceHandle = XenUsbHub_UBIH_RefDeviceHandle;
1858 ubih->ubih7.DerefDeviceHandle = XenUsbHub_UBIH_DerefDeviceHandle;
1859 ubih->ubih7.SetDeviceHandleIdleReadyState = XenUsbHub_UBIH_SetDeviceHandleIdleReadyState;
1860 ubih->ubih7.CreateUsbDeviceV7 = XenUsbHub_UBIH_CreateUsbDeviceV7;
1861 ubih->ubih7.GetContainerIdForPort = XenUsbHub_UBIH_GetContainerIdForPort;
1862 ubih->ubih7.SetContainerIdForPort = XenUsbHub_UBIH_SetContainerIdForPort;
1863 ubih->ubih7.AbortAllDevicePipes = XenUsbHub_UBIH_AbortAllDevicePipes;
1864 ubih->ubih7.SetDeviceErrataFlag = XenUsbHub_UBIH_SetDeviceErrataFlag;
1865 /* fall through */
1866 case USB_BUSIF_HUB_VERSION_6:
1867 ubih->ubih6.CreateUsbDevice = XenUsbHub_UBIH_CreateUsbDeviceEx;
1868 ubih->ubih6.InitializeUsbDevice = XenUsbHub_UBIH_InitializeUsbDeviceEx;
1869 ubih->ubih6.HubIsRoot = XenUsbHub_UBIH_HubIsRoot;
1870 ubih->ubih6.AcquireBusSemaphore = XenUsbHub_UBIH_AcquireBusSemaphore;
1871 ubih->ubih6.ReleaseBusSemaphore = XenUsbHub_UBIH_ReleaseBusSemaphore;
1872 ubih->ubih6.CaculatePipeBandwidth = XenUsbHub_UBIH_CaculatePipeBandwidth;
1873 ubih->ubih6.SetBusSystemWakeMode = XenUsbHub_UBIH_SetBusSystemWakeMode;
1874 ubih->ubih6.SetDeviceFlag = XenUsbHub_UBIH_SetDeviceFlag;
1875 /* fall through */
1876 #endif
1877 case USB_BUSIF_HUB_VERSION_5:
1878 ubih->ubih5.GetUsbDescriptors = XenUsbHub_UBIH_GetUsbDescriptors;
1879 ubih->ubih5.RemoveUsbDevice = XenUsbHub_UBIH_RemoveUsbDevice;
1880 ubih->ubih5.RestoreUsbDevice = XenUsbHub_UBIH_RestoreUsbDevice;
1881 ubih->ubih5.GetPortHackFlags = XenUsbHub_UBIH_GetPortHackFlags;
1882 ubih->ubih5.QueryDeviceInformation = XenUsbHub_UBIH_QueryDeviceInformation;
1883 ubih->ubih5.GetControllerInformation = XenUsbHub_UBIH_GetControllerInformation;
1884 ubih->ubih5.ControllerSelectiveSuspend = XenUsbHub_UBIH_ControllerSelectiveSuspend;
1885 ubih->ubih5.GetExtendedHubInformation = XenUsbHub_UBIH_GetExtendedHubInformation;
1886 ubih->ubih5.GetRootHubSymbolicName = XenUsbHub_UBIH_GetRootHubSymbolicName;
1887 ubih->ubih5.GetDeviceBusContext = XenUsbHub_UBIH_GetDeviceBusContext;
1888 ubih->ubih5.Initialize20Hub = XenUsbHub_UBIH_Initialize20Hub;
1889 ubih->ubih5.RootHubInitNotification = XenUsbHub_UBIH_RootHubInitNotification;
1890 ubih->ubih5.FlushTransfers = XenUsbHub_UBIH_FlushTransfers;
1891 ubih->ubih5.SetDeviceHandleData = XenUsbHub_UBIH_SetDeviceHandleData;
1893 irp->IoStatus.Information = 0;
1894 irp->IoStatus.Status = STATUS_SUCCESS;
1896 else
1898 KdPrint((__DRIVER_NAME " size/version mismatch\n"));
1901 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
1903 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_USBDI_GUID\n"));
1904 if ((stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_0 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V0))
1905 || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_1 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V1))
1906 || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_2 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2))
1907 #if (NTDDI_VERSION >= NTDDI_VISTA)
1908 || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_3 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V3))
1909 #endif
1912 ubiu = (PVOID)stack->Parameters.QueryInterface.Interface;
1913 ubiu->ubiu0.Size = stack->Parameters.QueryInterface.Size;
1914 ubiu->ubiu0.Version = stack->Parameters.QueryInterface.Version;
1915 ubiu->ubiu0.BusContext = device;
1916 ubiu->ubiu0.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1917 ubiu->ubiu0.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1918 switch (stack->Parameters.QueryInterface.Version)
1920 #if (NTDDI_VERSION >= NTDDI_VISTA)
1921 case USB_BUSIF_USBDI_VERSION_3:
1922 ubiu->ubiu3.QueryBusTimeEx = XenUsbHub_UBIU_QueryBusTimeEx;
1923 ubiu->ubiu3.QueryControllerType = XenUsbHub_UBIU_QueryControllerType;
1924 /* fall through */
1925 #endif
1926 case USB_BUSIF_USBDI_VERSION_2:
1927 ubiu->ubiu2.EnumLogEntry = XenUsbHub_UBIU_EnumLogEntry;
1928 /* fall through */
1929 case USB_BUSIF_USBDI_VERSION_1:
1930 ubiu->ubiu1.IsDeviceHighSpeed = XenUsbHub_UBIU_IsDeviceHighSpeed;
1931 /* fall through */
1932 case USB_BUSIF_USBDI_VERSION_0:
1933 ubiu->ubiu0.GetUSBDIVersion = XenUsbHub_UBIU_GetUSBDIVersion;
1934 ubiu->ubiu0.QueryBusTime = XenUsbHub_UBIU_QueryBusTime;
1935 ubiu->ubiu0.SubmitIsoOutUrb = XenUsbHub_UBIU_SubmitIsoOutUrb;
1936 ubiu->ubiu0.QueryBusInformation = XenUsbHub_UBIU_QueryBusInformation;
1938 irp->IoStatus.Information = 0;
1939 irp->IoStatus.Status = STATUS_SUCCESS;
1941 else
1943 KdPrint((__DRIVER_NAME " size/version mismatch\n"));
1946 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_TRANSLATOR_INTERFACE_STANDARD, sizeof(GUID)) == 0)
1947 KdPrint((__DRIVER_NAME " GUID_TRANSLATOR_INTERFACE_STANDARD\n"));
1948 #if (NTDDI_VERSION >= NTDDI_VISTA)
1949 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_PNP_LOCATION_INTERFACE, sizeof(GUID)) == 0)
1950 KdPrint((__DRIVER_NAME " GUID_PNP_LOCATION_INTERFACE\n"));
1951 #endif
1952 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_MINIDUMP_GUID, sizeof(GUID)) == 0)
1953 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_HUB_MINIDUMP_GUID\n"));
1954 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_SS_GUID, sizeof(GUID)) == 0)
1955 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_HUB_SS_GUID\n"));
1956 else
1957 KdPrint((__DRIVER_NAME " GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
1958 stack->Parameters.QueryInterface.InterfaceType->Data1,
1959 stack->Parameters.QueryInterface.InterfaceType->Data2,
1960 stack->Parameters.QueryInterface.InterfaceType->Data3,
1961 (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
1962 stack->Parameters.QueryInterface.InterfaceType->Data4[1],
1963 stack->Parameters.QueryInterface.InterfaceType->Data4[2],
1964 stack->Parameters.QueryInterface.InterfaceType->Data4[3],
1965 stack->Parameters.QueryInterface.InterfaceType->Data4[4],
1966 stack->Parameters.QueryInterface.InterfaceType->Data4[5],
1967 stack->Parameters.QueryInterface.InterfaceType->Data4[6],
1968 stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
1970 KdPrint((__DRIVER_NAME " Size = %d\n", stack->Parameters.QueryInterface.Size));
1971 KdPrint((__DRIVER_NAME " Version = %d\n", stack->Parameters.QueryInterface.Version));
1972 KdPrint((__DRIVER_NAME " Interface = %p\n", stack->Parameters.QueryInterface.Interface));
1974 IoSkipCurrentIrpStackLocation(irp);
1976 FUNCTION_EXIT();
1978 return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
1981 NTSTATUS
1982 XenUsbHub_PLI_GetLocationString(PVOID context, PWCHAR *location_strings) {
1983 UNREFERENCED_PARAMETER(context);
1985 FUNCTION_ENTER();
1986 *location_strings = L"james\0";
1987 FUNCTION_EXIT();
1988 return STATUS_SUCCESS;
1991 NTSTATUS
1992 XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
1993 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
1994 PWDFDEVICE_INIT child_init)
1996 NTSTATUS status = STATUS_SUCCESS;
1997 WDFDEVICE bus_device = WdfChildListGetDevice(child_list);
1998 WDF_OBJECT_ATTRIBUTES child_attributes;
1999 WDFDEVICE child_device;
2000 PXENUSB_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENUSB_PDO_IDENTIFICATION_DESCRIPTION)identification_header;
2001 WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities;
2002 DECLARE_UNICODE_STRING_SIZE(buffer, 512);
2003 DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
2004 PXENUSB_PDO_DEVICE_DATA xupdd;
2005 PXENUSB_DEVICE_DATA xudd = GetXudd(bus_device);
2006 WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
2007 WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities;
2008 WDF_IO_QUEUE_CONFIG queue_config;
2009 WDF_IO_TARGET_OPEN_PARAMS target_params;
2010 #if (NTDDI_VERSION >= NTDDI_VISTA)
2011 WDF_QUERY_INTERFACE_CONFIG interface_config;
2012 #if 0
2013 USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND ubihss;
2014 #endif
2015 PNP_LOCATION_INTERFACE pli;
2016 #endif
2017 UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
2018 int i;
2020 FUNCTION_ENTER();
2022 //KdPrint((__DRIVER_NAME " device = %d, port = %d, vendor_id = %04x, product_id = %04x\n",
2024 WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN);
2026 status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE,
2027 IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
2028 if (!NT_SUCCESS(status))
2030 return status;
2033 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks);
2034 child_pnp_power_callbacks.EvtDeviceD0Entry = XenUsbHub_EvtDeviceD0Entry;
2035 child_pnp_power_callbacks.EvtDeviceD0Exit = XenUsbHub_EvtDeviceD0Exit;
2036 child_pnp_power_callbacks.EvtDevicePrepareHardware = XenUsbHub_EvtDevicePrepareHardware;
2037 child_pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsbHub_EvtDeviceReleaseHardware;
2038 child_pnp_power_callbacks.EvtDeviceUsageNotification = XenUsbHub_EvtDeviceUsageNotification;
2039 WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks);
2041 RtlUnicodeStringPrintf(&buffer, L"USB\\ROOT_HUB");
2042 status = WdfPdoInitAssignDeviceID(child_init, &buffer);
2043 status = WdfPdoInitAddHardwareID(child_init, &buffer);
2045 RtlUnicodeStringPrintf(&buffer, L"VUSB_%d", identification->device_number);
2046 status = WdfPdoInitAssignInstanceID(child_init, &buffer);
2047 if (!NT_SUCCESS(status))
2049 return status;
2052 RtlUnicodeStringPrintf(&buffer, L"PVUSB device #%d", identification->device_number, identification);
2053 status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409);
2054 if (!NT_SUCCESS(status))
2056 return status;
2058 WdfPdoInitSetDefaultLocale(child_init, 0x0409);
2060 WdfDeviceInitSetPowerNotPageable(child_init);
2062 WdfDeviceInitSetIoType(child_init, WdfDeviceIoDirect);
2064 WdfPdoInitAllowForwardingRequestToParent(child_init);
2066 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENUSB_PDO_DEVICE_DATA);
2067 status = WdfDeviceCreate(&child_init, &child_attributes, &child_device);
2068 if (!NT_SUCCESS(status))
2070 return status;
2073 xupdd = GetXupdd(child_device);
2075 xudd->root_hub_device = child_device;
2077 stack_new(&xupdd->dev_id_ss, DEV_ID_COUNT);
2078 /* 0 is invalid and 1 is the root hub */
2079 for (i = 2; i < DEV_ID_COUNT; i++) {
2080 put_id_on_freelist(xupdd->dev_id_ss, (uint16_t)i);
2083 xupdd->wdf_device = child_device;
2084 xupdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
2086 status = WdfIoTargetCreate(bus_device, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->bus_fdo_target);
2087 ASSERT(NT_SUCCESS(status));
2088 WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&target_params, WdfDeviceWdmGetDeviceObject(bus_device));
2089 status = WdfIoTargetOpen(xupdd->bus_fdo_target, &target_params);
2090 ASSERT(NT_SUCCESS(status));
2092 xupdd->usb_device = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
2093 // get address from freelist...
2094 xupdd->usb_device->pdo_device = child_device;
2095 xupdd->usb_device->address = 1;
2096 xupdd->usb_device->device_speed = UsbHighSpeed;
2097 xupdd->usb_device->device_type = Usb20Device;
2098 xupdd->usb_device->device_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
2099 xupdd->usb_device->device_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
2100 xupdd->usb_device->device_descriptor.bcdUSB = 0x0200;
2101 xupdd->usb_device->device_descriptor.bDeviceClass = 9;
2102 xupdd->usb_device->device_descriptor.bDeviceSubClass = 0;
2103 xupdd->usb_device->device_descriptor.bDeviceProtocol = 1;
2104 xupdd->usb_device->device_descriptor.bMaxPacketSize0 = 64;
2105 xupdd->usb_device->device_descriptor.idVendor = 0x0000;
2106 xupdd->usb_device->device_descriptor.idProduct = 0x0000;
2107 xupdd->usb_device->device_descriptor.bcdDevice = 0x0206;
2108 xupdd->usb_device->device_descriptor.iManufacturer = 3;
2109 xupdd->usb_device->device_descriptor.iProduct = 2;
2110 xupdd->usb_device->device_descriptor.iSerialNumber = 1;
2111 xupdd->usb_device->device_descriptor.bNumConfigurations = 1;
2112 xupdd->usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * 1, XENUSB_POOL_TAG);
2113 xupdd->usb_device->configs[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
2114 xupdd->usb_device->active_config = xupdd->usb_device->configs[0];
2115 xupdd->usb_device->configs[0]->device = xupdd->usb_device;
2116 xupdd->usb_device->configs[0]->config_descriptor.bLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
2117 xupdd->usb_device->configs[0]->config_descriptor.bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE;
2118 xupdd->usb_device->configs[0]->config_descriptor.wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
2119 xupdd->usb_device->configs[0]->config_descriptor.bNumInterfaces = 1;
2120 xupdd->usb_device->configs[0]->config_descriptor.bConfigurationValue = 1;
2121 xupdd->usb_device->configs[0]->config_descriptor.iConfiguration = 0;
2122 xupdd->usb_device->configs[0]->config_descriptor.bmAttributes = 0xe0;
2123 xupdd->usb_device->configs[0]->config_descriptor.MaxPower = 0;
2124 xupdd->usb_device->configs[0]->interfaces[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
2125 xupdd->usb_device->active_interface = xupdd->usb_device->configs[0]->interfaces[0];
2126 xupdd->usb_device->configs[0]->interfaces[0]->config = xupdd->usb_device->configs[0];
2127 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bLength = 9;
2128 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE;
2129 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceNumber = 0;
2130 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bAlternateSetting = 0;
2131 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bNumEndpoints = 1;
2132 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceClass = 9;
2133 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceSubClass = 0;
2134 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceProtocol = 0;
2135 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.iInterface = 0;
2136 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
2137 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interface = xupdd->usb_device->configs[0]->interfaces[0];
2138 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->pipe_value = 0;
2139 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bLength = 7;
2140 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
2141 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bEndpointAddress = 0x81; // EP 1 IN
2142 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT;
2143 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.wMaxPacketSize = 2;
2144 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bInterval = 12;
2145 WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->lock);
2147 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
2148 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
2149 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
2150 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->urb_queue);
2151 if (!NT_SUCCESS(status)) {
2152 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
2153 return status;
2156 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
2157 //WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queue_attributes, pxenusb_endpoint_t);
2158 queue_config.PowerManaged = TRUE;
2159 //queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_Interrupt_SUBMIT_URB;
2160 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
2161 &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->queue);
2162 if (!NT_SUCCESS(status)) {
2163 KdPrint((__DRIVER_NAME " Error creating timer io_queue 0x%x\n", status));
2164 return status;
2166 //*GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->queue) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
2168 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
2169 queue_config.EvtIoInternalDeviceControl = XenUsbHub_EvtIoInternalDeviceControl;
2170 queue_config.EvtIoDeviceControl = XenUsbHub_EvtIoDeviceControl;
2171 queue_config.EvtIoDefault = XenUsbHub_EvtIoDefault;
2172 /* can't be power managed or deadlocks occur */
2173 queue_config.PowerManaged = FALSE;
2174 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->io_queue);
2175 if (!NT_SUCCESS(status)) {
2176 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
2177 return status;
2180 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
2181 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
2182 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
2184 WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities);
2185 child_pnp_capabilities.LockSupported = WdfFalse;
2186 child_pnp_capabilities.EjectSupported = WdfTrue;
2187 child_pnp_capabilities.Removable = WdfTrue;
2188 child_pnp_capabilities.DockDevice = WdfFalse;
2189 child_pnp_capabilities.UniqueID = WdfTrue;
2190 child_pnp_capabilities.SilentInstall = WdfTrue;
2191 child_pnp_capabilities.SurpriseRemovalOK = WdfTrue;
2192 child_pnp_capabilities.HardwareDisabled = WdfFalse;
2193 WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities);
2195 WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities);
2196 child_power_capabilities.DeviceD1 = WdfTrue;
2197 child_power_capabilities.WakeFromD1 = WdfTrue;
2198 child_power_capabilities.DeviceWake = PowerDeviceD1;
2199 child_power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD0;
2200 child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
2201 child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
2202 child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
2203 child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
2204 child_power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
2205 WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);
2207 #if (NTDDI_VERSION >= NTDDI_VISTA)
2208 #if 0
2209 ubihss.BusContext = child_device;
2210 ubihss.Size = sizeof(USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND);
2211 ubihss.Version = USB_BUSIF_HUB_SS_VERSION_0;
2212 ubihss.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
2213 ubihss.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
2214 ubihss.SuspendHub = XenUsbHub_UBIHSS_SuspendHub;
2215 ubihss.ResumeHub = XenUsbHub_UBIHSS_ResumeHub;
2216 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubihss, &USB_BUS_INTERFACE_HUB_SS_GUID, NULL);
2217 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
2218 if (!NT_SUCCESS(status))
2219 return status;
2220 #endif
2221 pli.Size = sizeof(USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND);
2222 pli.Version = 1;
2223 pli.Context = child_device;
2224 pli.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
2225 pli.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
2226 pli.GetLocationString = XenUsbHub_PLI_GetLocationString;
2227 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&pli, &GUID_PNP_LOCATION_INTERFACE, NULL);
2228 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
2229 if (!NT_SUCCESS(status))
2230 return status;
2231 #endif
2233 status = WdfDeviceCreateDeviceInterface(child_device, &GUID_DEVINTERFACE_USB_HUB, NULL);
2234 if (!NT_SUCCESS(status))
2235 return status;
2237 FUNCTION_EXIT();
2239 return status;