win-pvdrivers

view xenusb/xenusb_hub.c @ 840:c750a369bce5

Added tag 0.11.0.252 for changeset e48c6f765e5f
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 03 14:26:04 2011 +1100 (2011-02-03)
parents 5bdb7251370c
children 3aa213de2a31
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>
23 #pragma warning(disable: 4127) // conditional expression is constant
25 static EVT_WDF_DEVICE_D0_ENTRY XenUsbHub_EvtDeviceD0Entry;
26 static EVT_WDF_DEVICE_D0_EXIT XenUsbHub_EvtDeviceD0Exit;
27 static EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsbHub_EvtDevicePrepareHardware;
28 static EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsbHub_EvtDeviceReleaseHardware;
29 static EVT_WDF_DEVICE_USAGE_NOTIFICATION XenUsbHub_EvtDeviceUsageNotification;
30 static EVT_WDF_TIMER XenUsbHub_HubInterruptTimer;
31 static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsbHub_EvtIoInternalDeviceControl;
32 static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL XenUsbHub_EvtIoDeviceControl;
33 static EVT_WDF_IO_QUEUE_IO_DEFAULT XenUsbHub_EvtIoDefault;
34 static USB_BUSIFFN_CREATE_USB_DEVICE XenUsbHub_UBIH_CreateUsbDevice;
35 static USB_BUSIFFN_INITIALIZE_USB_DEVICE XenUsbHub_UBIH_InitializeUsbDevice;
36 static USB_BUSIFFN_GET_USB_DESCRIPTORS XenUsbHub_UBIH_GetUsbDescriptors;
37 static USB_BUSIFFN_REMOVE_USB_DEVICE XenUsbHub_UBIH_RemoveUsbDevice;
38 static USB_BUSIFFN_RESTORE_DEVICE XenUsbHub_UBIH_RestoreUsbDevice;
39 static USB_BUSIFFN_GET_POTRTHACK_FLAGS XenUsbHub_UBIH_GetPortHackFlags;
40 static USB_BUSIFFN_GET_DEVICE_INFORMATION XenUsbHub_UBIH_QueryDeviceInformation;
41 static USB_BUSIFFN_GET_CONTROLLER_INFORMATION XenUsbHub_UBIH_GetControllerInformation;
42 static USB_BUSIFFN_CONTROLLER_SELECTIVE_SUSPEND XenUsbHub_UBIH_ControllerSelectiveSuspend;
43 static USB_BUSIFFN_GET_EXTENDED_HUB_INFO XenUsbHub_UBIH_GetExtendedHubInformation;
44 static USB_BUSIFFN_GET_ROOTHUB_SYM_NAME XenUsbHub_UBIH_GetRootHubSymbolicName;
45 static USB_BUSIFFN_GET_DEVICE_BUSCONTEXT XenUsbHub_UBIH_GetDeviceBusContext;
46 static USB_BUSIFFN_INITIALIZE_20HUB XenUsbHub_UBIH_Initialize20Hub;
47 static USB_BUSIFFN_ROOTHUB_INIT_NOTIFY XenUsbHub_UBIH_RootHubInitNotification;
48 static USB_BUSIFFN_FLUSH_TRANSFERS XenUsbHub_UBIH_FlushTransfers;
49 static USB_BUSIFFN_SET_DEVHANDLE_DATA XenUsbHub_UBIH_SetDeviceHandleData;
51 static VOID
52 XenUsbHub_EvtIoDefault(
53 WDFQUEUE queue,
54 WDFREQUEST request)
55 {
56 NTSTATUS status;
57 WDF_REQUEST_PARAMETERS parameters;
59 FUNCTION_ENTER();
61 UNREFERENCED_PARAMETER(queue);
63 status = STATUS_UNSUCCESSFUL;
65 WDF_REQUEST_PARAMETERS_INIT(&parameters);
66 WdfRequestGetParameters(request, &parameters);
68 switch (parameters.Type)
69 {
70 case WdfRequestTypeCreate:
71 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
72 break;
73 case WdfRequestTypeClose:
74 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
75 break;
76 case WdfRequestTypeRead:
77 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
78 break;
79 case WdfRequestTypeWrite:
80 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
81 break;
82 case WdfRequestTypeDeviceControl:
83 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
85 break;
86 case WdfRequestTypeDeviceControlInternal:
87 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
88 break;
89 default:
90 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
91 break;
92 }
93 WdfRequestComplete(request, status);
95 FUNCTION_EXIT();
96 }
98 static NTSTATUS
99 XenUsbHub_BusIrpCompletionRoutine(
100 PDEVICE_OBJECT device_object,
101 PIRP irp,
102 PVOID context)
103 {
104 WDFREQUEST request = context;
106 UNREFERENCED_PARAMETER(device_object);
108 FUNCTION_ENTER();
110 WdfRequestCompleteWithInformation(request, irp->IoStatus.Status, irp->IoStatus.Information);
111 IoFreeIrp(irp);
113 FUNCTION_EXIT();
115 return STATUS_MORE_PROCESSING_REQUIRED;
116 }
118 static VOID
119 XenUsbHub_EvtIoDeviceControl(
120 WDFQUEUE queue,
121 WDFREQUEST request,
122 size_t output_buffer_length,
123 size_t input_buffer_length,
124 ULONG io_control_code)
125 {
126 NTSTATUS status;
127 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
128 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
129 //WDF_REQUEST_PARAMETERS wrp;
130 //PURB urb;
131 //xenusb_device_t *usb_device;
133 UNREFERENCED_PARAMETER(queue);
134 UNREFERENCED_PARAMETER(input_buffer_length);
135 UNREFERENCED_PARAMETER(output_buffer_length);
137 FUNCTION_ENTER();
139 status = STATUS_UNSUCCESSFUL;
141 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
142 //WdfRequestGetParameters(request, &wrp);
144 // these are in api\usbioctl.h
145 switch(io_control_code)
146 {
147 case IOCTL_USB_GET_NODE_INFORMATION:
148 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
149 break;
150 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
151 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
152 break;
153 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
154 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
155 break;
156 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
157 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
158 break;
159 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
160 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
161 break;
162 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
163 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
164 break;
165 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
166 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
167 break;
168 case IOCTL_USB_GET_HUB_CAPABILITIES:
169 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
170 break;
171 case IOCTL_USB_HUB_CYCLE_PORT:
172 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
173 break;
174 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
175 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
176 break;
177 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
178 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
179 break;
180 case IOCTL_GET_HCD_DRIVERKEY_NAME:
181 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME\n"));
182 break;
183 default:
184 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
185 break;
186 }
187 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
188 WdfRequestComplete(request, status);
190 FUNCTION_EXIT();
191 }
193 static VOID
194 XenUsbHub_EvtIoInternalDeviceControl(
195 WDFQUEUE queue,
196 WDFREQUEST request,
197 size_t output_buffer_length,
198 size_t input_buffer_length,
199 ULONG io_control_code)
200 {
201 NTSTATUS status;
202 WDFDEVICE device = WdfIoQueueGetDevice(queue);
203 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
204 WDF_REQUEST_PARAMETERS wrp;
205 PURB urb;
206 xenusb_device_t *usb_device;
208 UNREFERENCED_PARAMETER(input_buffer_length);
209 UNREFERENCED_PARAMETER(output_buffer_length);
211 //FUNCTION_ENTER();
213 status = STATUS_UNSUCCESSFUL;
215 WDF_REQUEST_PARAMETERS_INIT(&wrp);
216 WdfRequestGetParameters(request, &wrp);
218 // these are in api\usbioctl.h
219 switch(io_control_code)
220 {
221 case IOCTL_INTERNAL_USB_CYCLE_PORT:
222 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_CYCLE_PORT\n"));
223 break;
224 case IOCTL_INTERNAL_USB_ENABLE_PORT:
225 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_ENABLE_PORT\n"));
226 break;
227 case IOCTL_INTERNAL_USB_GET_BUS_INFO:
228 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_BUS_INFO\n"));
229 break;
230 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
231 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n"));
232 break;
233 case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
234 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_COUNT\n"));
235 KdPrint((__DRIVER_NAME " Count before increment = %p\n", *(PULONG)wrp.Parameters.Others.Arg1));
236 (*(PULONG)wrp.Parameters.Others.Arg1)++;
237 status = STATUS_SUCCESS;
238 break;
239 case IOCTL_INTERNAL_USB_GET_HUB_NAME:
240 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_NAME\n"));
241 break;
242 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
243 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_PORT_STATUS\n"));
244 *(PULONG)wrp.Parameters.Others.Arg1 = USBD_PORT_ENABLED | USBD_PORT_CONNECTED; /* enabled and connected */
245 status = STATUS_SUCCESS;
246 break;
247 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
248 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n"));
249 KdPrint((__DRIVER_NAME " WdfDeviceWdmGetPhysicalDevice(device) = %p\n", WdfDeviceWdmGetPhysicalDevice(device)));
250 //KdPrint((__DRIVER_NAME " IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device)) = %p\n", IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device))));
251 *(PVOID *)wrp.Parameters.Others.Arg1 = WdfDeviceWdmGetPhysicalDevice(device);
252 //*(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device));
253 *(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(xupdd->wdf_device_bus_fdo));
254 status = STATUS_SUCCESS;
255 break;
256 case IOCTL_INTERNAL_USB_RESET_PORT:
257 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_RESET_PORT\n"));
258 break;
259 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
260 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n"));
261 break;
262 case IOCTL_INTERNAL_USB_SUBMIT_URB:
263 urb = (PURB)wrp.Parameters.Others.Arg1;
264 ASSERT(urb);
265 usb_device = urb->UrbHeader.UsbdDeviceHandle;
266 if (!usb_device)
267 usb_device = xupdd->usb_device;
268 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
269 return;
270 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
271 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE (returning %p)\n", xupdd->usb_device));
272 *(PVOID *)wrp.Parameters.Others.Arg1 = xupdd->usb_device;
273 status = STATUS_SUCCESS;
274 break;
275 default:
276 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
277 break;
278 }
280 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
281 WdfRequestComplete(request, status);
283 //FUNCTION_EXIT();
284 }
286 static NTSTATUS
287 XenUsbHub_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
288 {
289 NTSTATUS status = STATUS_SUCCESS;
291 UNREFERENCED_PARAMETER(device);
293 FUNCTION_ENTER();
295 switch (previous_state)
296 {
297 case WdfPowerDeviceD0:
298 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
299 break;
300 case WdfPowerDeviceD1:
301 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
302 break;
303 case WdfPowerDeviceD2:
304 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
305 break;
306 case WdfPowerDeviceD3:
307 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
308 break;
309 case WdfPowerDeviceD3Final:
310 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
311 break;
312 case WdfPowerDevicePrepareForHibernation:
313 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
314 break;
315 default:
316 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
317 break;
318 }
320 FUNCTION_EXIT();
322 return status;
323 }
325 static NTSTATUS
326 XenUsbHub_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
327 {
328 NTSTATUS status = STATUS_SUCCESS;
329 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
330 //PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
332 UNREFERENCED_PARAMETER(device);
334 FUNCTION_ENTER();
336 switch (target_state)
337 {
338 case WdfPowerDeviceD0:
339 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
340 break;
341 case WdfPowerDeviceD1:
342 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
343 break;
344 case WdfPowerDeviceD2:
345 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
346 break;
347 case WdfPowerDeviceD3:
348 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
349 break;
350 case WdfPowerDeviceD3Final:
351 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
352 break;
353 case WdfPowerDevicePrepareForHibernation:
354 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
355 break;
356 default:
357 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
358 break;
359 }
361 FUNCTION_EXIT();
363 return status;
364 }
366 static NTSTATUS
367 XenUsbHub_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
368 {
369 NTSTATUS status = STATUS_SUCCESS;
371 UNREFERENCED_PARAMETER(device);
372 UNREFERENCED_PARAMETER(resources_raw);
373 UNREFERENCED_PARAMETER(resources_translated);
375 FUNCTION_ENTER();
376 FUNCTION_EXIT();
378 return status;
379 }
381 static NTSTATUS
382 XenUsbHub_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
383 {
384 NTSTATUS status = STATUS_SUCCESS;
386 UNREFERENCED_PARAMETER(device);
387 UNREFERENCED_PARAMETER(resources_translated);
389 FUNCTION_ENTER();
390 FUNCTION_EXIT();
392 return status;
393 }
395 static VOID
396 XenUsbHub_EvtDeviceUsageNotification(WDFDEVICE device, WDF_SPECIAL_FILE_TYPE notification_type, BOOLEAN is_in_notification_path)
397 {
398 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
400 UNREFERENCED_PARAMETER(xupdd);
401 UNREFERENCED_PARAMETER(is_in_notification_path);
403 FUNCTION_ENTER();
405 switch (notification_type)
406 {
407 case WdfSpecialFilePaging:
408 KdPrint((__DRIVER_NAME " notification_type = Paging, flag = %d\n", is_in_notification_path));
409 break;
410 case WdfSpecialFileHibernation:
411 KdPrint((__DRIVER_NAME " notification_type = Hibernation, flag = %d\n", is_in_notification_path));
412 break;
413 case WdfSpecialFileDump:
414 KdPrint((__DRIVER_NAME " notification_type = Dump, flag = %d\n", is_in_notification_path));
415 break;
416 default:
417 KdPrint((__DRIVER_NAME " notification_type = %d, flag = %d\n", notification_type, is_in_notification_path));
418 break;
419 }
421 FUNCTION_EXIT();
422 }
424 static NTSTATUS
425 XenUsb_SubmitCompletionRoutine(
426 PDEVICE_OBJECT device_object,
427 PIRP irp,
428 PVOID context)
429 {
430 UNREFERENCED_PARAMETER(device_object);
432 FUNCTION_ENTER();
434 if (irp->PendingReturned)
435 {
436 KeSetEvent ((PKEVENT)context, IO_NO_INCREMENT, FALSE);
437 }
439 FUNCTION_EXIT();
441 return STATUS_MORE_PROCESSING_REQUIRED;
442 }
444 static NTSTATUS
445 XenUsbHub_UBIH_CreateUsbDevice(
446 PVOID BusContext,
447 PUSB_DEVICE_HANDLE *DeviceHandle,
448 PUSB_DEVICE_HANDLE *HubDeviceHandle,
449 USHORT PortStatus,
450 USHORT PortNumber)
451 {
452 NTSTATUS status = STATUS_SUCCESS;
454 UNREFERENCED_PARAMETER(BusContext);
455 UNREFERENCED_PARAMETER(HubDeviceHandle);
456 UNREFERENCED_PARAMETER(PortStatus);
457 UNREFERENCED_PARAMETER(PortNumber);
459 FUNCTION_ENTER();
461 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
462 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
463 KdPrint((__DRIVER_NAME " *DeviceHandle = %p\n", *DeviceHandle));
464 KdPrint((__DRIVER_NAME " HubDeviceHandle = %p\n", HubDeviceHandle));
465 KdPrint((__DRIVER_NAME " *HubDeviceHandle = %p\n", *HubDeviceHandle));
466 KdPrint((__DRIVER_NAME " PortStatus = %04X\n", PortStatus));
467 KdPrint((__DRIVER_NAME " PortNumber = %d\n", PortNumber));
468 *DeviceHandle = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
470 FUNCTION_EXIT();
471 return status;
472 }
474 static VOID
475 XenUsb_SetEventCallback(usbif_shadow_t *shadow)
476 {
477 FUNCTION_ENTER();
478 KeSetEvent(&shadow->event, IO_NO_INCREMENT, FALSE);
479 FUNCTION_EXIT();
480 }
482 static NTSTATUS
483 XenUsbHub_UBIH_InitializeUsbDevice(
484 PVOID BusContext,
485 PUSB_DEVICE_HANDLE DeviceHandle)
486 {
487 NTSTATUS status = STATUS_SUCCESS;
488 WDFDEVICE device = BusContext;
489 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
490 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
491 WDF_IO_QUEUE_CONFIG queue_config;
492 xenusb_device_t *usb_device = DeviceHandle;
493 PUCHAR ptr;
494 PVOID buf;
495 PMDL mdl;
496 usbif_shadow_t *shadow;
497 PUSB_DEVICE_DESCRIPTOR device_descriptor;
498 PUSB_CONFIGURATION_DESCRIPTOR config_descriptor;
499 PUSB_INTERFACE_DESCRIPTOR interface_descriptor;
500 PUSB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
501 int i, j, k;
502 PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
504 FUNCTION_ENTER();
506 KdPrint((__DRIVER_NAME " device = %p\n", device));
507 KdPrint((__DRIVER_NAME " usb_device = %p\n", usb_device));
508 usb_device->pdo_device = BusContext;
510 // get address from freelist and assign it to the device...
511 usb_device->address = 2;
512 // and get this stuff properly...
513 usb_device->port_number = 1;
514 xupdd->usb_device->device_speed = UsbHighSpeed;
515 xupdd->usb_device->device_type = Usb20Device;
517 buf = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
518 mdl = IoAllocateMdl(buf, PAGE_SIZE, FALSE, FALSE, NULL);
519 MmBuildMdlForNonPagedPool(mdl);
520 shadow = get_shadow_from_freelist(xudd);
522 /* set the address */
523 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
524 shadow->callback = XenUsb_SetEventCallback;
525 shadow->req.id = shadow->id;
526 shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | usb_device->port_number;
527 shadow->req.transfer_flags = 0;
528 shadow->req.buffer_length = 0;
529 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
530 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
531 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
532 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
533 setup_packet->bRequest = USB_REQUEST_SET_ADDRESS;
534 setup_packet->wValue.W = usb_device->address;
535 setup_packet->wIndex.W = 0;
536 setup_packet->wLength = shadow->req.buffer_length;
537 status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
538 //TODO: Handle failure here
539 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
540 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
541 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
542 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
543 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
544 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
546 /* get the device descriptor */
547 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
548 shadow->callback = XenUsb_SetEventCallback;
549 shadow->req.id = shadow->id;
550 shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
551 shadow->req.transfer_flags = 0;
552 shadow->req.buffer_length = PAGE_SIZE;
553 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
554 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
555 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
556 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
557 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
558 setup_packet->wValue.LowByte = 0;
559 setup_packet->wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; //device descriptor
560 setup_packet->wIndex.W = 0;
561 setup_packet->wLength = shadow->req.buffer_length;
562 status = XenUsb_ExecuteRequest(xudd, shadow, NULL, mdl, PAGE_SIZE);
563 //TODO: Handle failure here
564 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
565 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
566 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
567 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
568 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
569 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
570 ptr = buf;
571 device_descriptor = (PUSB_DEVICE_DESCRIPTOR)ptr;
572 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
573 KdPrint((__DRIVER_NAME " bNumConfigurations = %d\n", device_descriptor->bNumConfigurations));
574 memcpy(&usb_device->device_descriptor, device_descriptor, device_descriptor->bLength);
575 usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * device_descriptor->bNumConfigurations, XENUSB_POOL_TAG);
576 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
577 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", device_descriptor->bDescriptorType));
578 KdPrint((__DRIVER_NAME " bcdUSB = %04x\n", device_descriptor->bcdUSB));
579 KdPrint((__DRIVER_NAME " bDeviceClass = %02x\n", device_descriptor->bDeviceClass));
580 KdPrint((__DRIVER_NAME " bDeviceSubClass = %02x\n", device_descriptor->bDeviceSubClass));
581 KdPrint((__DRIVER_NAME " bDeviceProtocol = %02x\n", device_descriptor->bDeviceProtocol));
582 KdPrint((__DRIVER_NAME " idVendor = %04x\n", device_descriptor->idVendor));
583 KdPrint((__DRIVER_NAME " idProduct = %04x\n", device_descriptor->idProduct));
584 KdPrint((__DRIVER_NAME " bcdDevice = %04x\n", device_descriptor->bcdDevice));
585 KdPrint((__DRIVER_NAME " bNumConfigurations = %04x\n", device_descriptor->bNumConfigurations));
587 /* get the config descriptor */
588 for (i = 0; i < device_descriptor->bNumConfigurations; i++)
589 {
590 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
591 shadow->callback = XenUsb_SetEventCallback;
592 shadow->req.id = shadow->id;
593 shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
594 shadow->req.transfer_flags = 0;
595 shadow->req.buffer_length = PAGE_SIZE;
596 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
597 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
598 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
599 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
600 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
601 setup_packet->wValue.LowByte = (UCHAR)(i + 1);
602 setup_packet->wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; //device descriptor
603 setup_packet->wIndex.W = 0;
604 setup_packet->wLength = shadow->req.buffer_length;
605 status = XenUsb_ExecuteRequest(xudd, shadow, buf, NULL, PAGE_SIZE);
606 //TODO: Handle failure here
607 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
608 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
609 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
610 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
611 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
612 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
613 ptr = buf;
614 config_descriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ptr;
615 KdPrint((__DRIVER_NAME " Config %d\n", i));
616 KdPrint((__DRIVER_NAME " bLength = %d\n", config_descriptor->bLength));
617 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", config_descriptor->bDescriptorType));
618 KdPrint((__DRIVER_NAME " wTotalLength = %d\n", config_descriptor->wTotalLength));
619 KdPrint((__DRIVER_NAME " bNumInterfaces = %d\n", config_descriptor->bNumInterfaces));
620 KdPrint((__DRIVER_NAME " iConfiguration = %d\n", config_descriptor->iConfiguration));
621 KdPrint((__DRIVER_NAME " bConfigurationValue = %d\n", config_descriptor->bConfigurationValue));
622 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", config_descriptor->bmAttributes));
623 KdPrint((__DRIVER_NAME " MaxPower = %d\n", config_descriptor->MaxPower));
624 usb_device->configs[i] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * config_descriptor->bNumInterfaces, XENUSB_POOL_TAG);
625 usb_device->configs[i]->device = usb_device;
626 memcpy(&usb_device->configs[i]->config_descriptor, config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
627 ptr += config_descriptor->bLength;
628 for (j = 0; j < config_descriptor->bNumInterfaces; j++)
629 {
630 interface_descriptor = (PUSB_INTERFACE_DESCRIPTOR)ptr;
631 KdPrint((__DRIVER_NAME " Interface %d\n", j));
632 KdPrint((__DRIVER_NAME " bLength = %d\n", interface_descriptor->bLength));
633 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", interface_descriptor->bDescriptorType));
634 KdPrint((__DRIVER_NAME " bInterfaceNumber = %d\n", interface_descriptor->bInterfaceNumber));
635 KdPrint((__DRIVER_NAME " bAlternateSetting = %d\n", interface_descriptor->bAlternateSetting));
636 KdPrint((__DRIVER_NAME " bNumEndpoints = %d\n", interface_descriptor->bNumEndpoints));
637 KdPrint((__DRIVER_NAME " bInterfaceClass = %d\n", interface_descriptor->bInterfaceClass));
638 KdPrint((__DRIVER_NAME " bInterfaceSubClass = %d\n", interface_descriptor->bInterfaceSubClass));
639 KdPrint((__DRIVER_NAME " bInterfaceProtocol = %d\n", interface_descriptor->bInterfaceProtocol));
640 KdPrint((__DRIVER_NAME " iInterface = %d\n", interface_descriptor->iInterface));
641 ptr += interface_descriptor->bLength;
642 usb_device->configs[i]->interfaces[j] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * interface_descriptor->bNumEndpoints, XENUSB_POOL_TAG);
643 usb_device->configs[i]->interfaces[j]->config = usb_device->configs[i];
644 memcpy(&usb_device->configs[i]->interfaces[j]->interface_descriptor, interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
645 for (k = 0; k < interface_descriptor->bNumEndpoints; k++)
646 {
647 endpoint_descriptor = (PUSB_ENDPOINT_DESCRIPTOR)ptr;
648 KdPrint((__DRIVER_NAME " Endpoint %d\n", k));
649 KdPrint((__DRIVER_NAME " bLength = %d\n", endpoint_descriptor->bLength));
650 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", endpoint_descriptor->bDescriptorType));
651 KdPrint((__DRIVER_NAME " bEndpointAddress = %02x\n", endpoint_descriptor->bEndpointAddress));
652 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", endpoint_descriptor->bmAttributes));
653 KdPrint((__DRIVER_NAME " wMaxPacketSize = %d\n", endpoint_descriptor->wMaxPacketSize));
654 KdPrint((__DRIVER_NAME " bInterval = %d\n", endpoint_descriptor->bInterval));
655 ptr += endpoint_descriptor->bLength;
656 usb_device->configs[i]->interfaces[j]->endpoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
657 usb_device->configs[i]->interfaces[j]->endpoints[k]->interface = usb_device->configs[i]->interfaces[j];
658 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value = (usb_device->address << 8) | usb_device->port_number;
659 /* linux uses nonstandard endpoint type identifiers... */
660 switch(endpoint_descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
661 {
662 case USB_ENDPOINT_TYPE_CONTROL:
663 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_CTRL;
664 break;
665 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
666 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_ISOC;
667 break;
668 case USB_ENDPOINT_TYPE_BULK:
669 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_BULK;
670 break;
671 case USB_ENDPOINT_TYPE_INTERRUPT:
672 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_INTR;
673 break;
674 }
675 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x80);
676 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x0F) << 15;
677 memcpy(&usb_device->configs[i]->interfaces[j]->endpoints[k]->endpoint_descriptor, endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
678 }
679 }
680 }
681 usb_device->active_config = usb_device->configs[0];
682 usb_device->active_interface = usb_device->configs[0]->interfaces[0];
684 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
685 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
686 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
687 status = WdfIoQueueCreate(xupdd->wdf_device_bus_fdo, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &usb_device->urb_queue);
688 if (!NT_SUCCESS(status)) {
689 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
690 return status;
691 }
693 put_shadow_on_freelist(xudd, shadow);
695 FUNCTION_EXIT();
696 return status;
697 }
699 static NTSTATUS
700 XenUsbHub_UBIH_GetUsbDescriptors(
701 PVOID BusContext,
702 PUSB_DEVICE_HANDLE DeviceHandle,
703 PUCHAR DeviceDescriptorBuffer,
704 PULONG DeviceDescriptorBufferLength,
705 PUCHAR ConfigDescriptorBuffer,
706 PULONG ConfigDescriptorBufferLength
707 )
708 {
709 NTSTATUS status = STATUS_SUCCESS;
710 xenusb_device_t *usb_device = DeviceHandle;
711 xenusb_config_t *usb_config;
712 PUCHAR ptr;
714 UNREFERENCED_PARAMETER(BusContext);
716 FUNCTION_ENTER();
718 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
719 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
720 KdPrint((__DRIVER_NAME " DeviceDescriptorBuffer = %p\n", DeviceDescriptorBuffer));
721 KdPrint((__DRIVER_NAME " DeviceDescriptorBufferLength = %d\n", *DeviceDescriptorBufferLength));
722 KdPrint((__DRIVER_NAME " ConfigDescriptorBuffer = %p\n", ConfigDescriptorBuffer));
723 KdPrint((__DRIVER_NAME " ConfigDescriptorBufferLength = %d\n", *ConfigDescriptorBufferLength));
725 memcpy(DeviceDescriptorBuffer, &usb_device->device_descriptor, usb_device->device_descriptor.bLength);
726 *DeviceDescriptorBufferLength = usb_device->device_descriptor.bLength;
728 usb_config = usb_device->active_config;
729 ptr = ConfigDescriptorBuffer;
730 KdPrint((__DRIVER_NAME " memcpy(%p, %p, %d)\n", ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)));
731 memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
732 ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
733 #if 0
734 for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
735 {
736 memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
737 ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
738 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
739 for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
740 {
741 memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
742 ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
743 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
744 }
745 }
746 #endif
747 *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); //((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
749 FUNCTION_EXIT();
750 return status;
751 }
753 static NTSTATUS
754 XenUsbHub_UBIH_RemoveUsbDevice (
755 PVOID BusContext,
756 PUSB_DEVICE_HANDLE DeviceHandle,
757 ULONG Flags)
758 {
759 NTSTATUS status = STATUS_SUCCESS;
761 UNREFERENCED_PARAMETER(BusContext);
762 UNREFERENCED_PARAMETER(DeviceHandle);
764 FUNCTION_ENTER();
766 if (Flags & USBD_KEEP_DEVICE_DATA)
767 KdPrint((__DRIVER_NAME " USBD_KEEP_DEVICE_DATA\n"));
769 if (Flags & USBD_MARK_DEVICE_BUSY)
770 KdPrint((__DRIVER_NAME " USBD_MARK_DEVICE_BUSY\n"));
772 FUNCTION_EXIT();
773 return status;
774 }
776 static NTSTATUS
777 XenUsbHub_UBIH_RestoreUsbDevice(
778 PVOID BusContext,
779 PUSB_DEVICE_HANDLE OldDeviceHandle,
780 PUSB_DEVICE_HANDLE NewDeviceHandle)
781 {
782 NTSTATUS status = STATUS_UNSUCCESSFUL;
784 UNREFERENCED_PARAMETER(BusContext);
785 UNREFERENCED_PARAMETER(OldDeviceHandle);
786 UNREFERENCED_PARAMETER(NewDeviceHandle);
788 FUNCTION_ENTER();
790 FUNCTION_EXIT();
791 return status;
792 }
794 static NTSTATUS
795 XenUsbHub_UBIH_GetPortHackFlags(
796 PVOID BusContext,
797 PULONG HackFlags)
798 {
799 NTSTATUS status = STATUS_UNSUCCESSFUL;
801 UNREFERENCED_PARAMETER(BusContext);
802 UNREFERENCED_PARAMETER(HackFlags);
804 FUNCTION_ENTER();
806 FUNCTION_EXIT();
807 return status;
808 }
810 static NTSTATUS
811 XenUsbHub_UBIH_QueryDeviceInformation(
812 PVOID BusContext,
813 PUSB_DEVICE_HANDLE DeviceHandle,
814 PVOID DeviceInformationBuffer,
815 ULONG DeviceInformationBufferLength,
816 PULONG LengthOfDataReturned)
817 {
818 PUSB_DEVICE_INFORMATION_0 udi = DeviceInformationBuffer;
819 xenusb_device_t *usb_device = DeviceHandle;
820 ULONG i;
821 ULONG required_size;
823 UNREFERENCED_PARAMETER(BusContext);
825 FUNCTION_ENTER();
827 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
828 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
829 KdPrint((__DRIVER_NAME " DeviceInformationBuffer = %p\n", DeviceInformationBuffer));
830 KdPrint((__DRIVER_NAME " DeviceInformationBufferLength = %d\n", DeviceInformationBufferLength));
831 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", udi->InformationLevel));
832 required_size = (ULONG)FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[usb_device->active_interface->interface_descriptor.bNumEndpoints]);
833 KdPrint((__DRIVER_NAME " required_size = %d\n", required_size));
834 *LengthOfDataReturned = required_size;
835 udi->ActualLength = required_size;
836 if (DeviceInformationBufferLength < required_size)
837 {
838 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
839 FUNCTION_EXIT();
840 return STATUS_BUFFER_TOO_SMALL;
841 }
842 if (udi->InformationLevel != 0)
843 {
844 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
845 FUNCTION_EXIT();
846 return STATUS_NOT_SUPPORTED;
847 }
848 udi->PortNumber = 1;
849 memcpy(&udi->DeviceDescriptor, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
850 udi->CurrentConfigurationValue = usb_device->active_config->config_descriptor.bConfigurationValue;
851 udi->DeviceAddress = usb_device->address;
852 udi->HubAddress = 1; // ?
853 udi->DeviceSpeed = usb_device->device_speed;
854 udi->DeviceType = usb_device->device_type;
855 udi->NumberOfOpenPipes = usb_device->active_interface->interface_descriptor.bNumEndpoints;
856 for (i = 0; i < usb_device->active_interface->interface_descriptor.bNumEndpoints; i++)
857 {
858 memcpy(&udi->PipeList[i].EndpointDescriptor, &usb_device->active_interface->endpoints[i]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
859 udi->PipeList[0].ScheduleOffset = 0; // not necessarily right
860 }
861 FUNCTION_EXIT();
862 return STATUS_SUCCESS;
863 }
865 static NTSTATUS
866 XenUsbHub_UBIH_GetControllerInformation (
867 PVOID BusContext,
868 PVOID ControllerInformationBuffer,
869 ULONG ControllerInformationBufferLength,
870 PULONG LengthOfDataReturned)
871 {
872 NTSTATUS status = STATUS_UNSUCCESSFUL;
873 PUSB_CONTROLLER_INFORMATION_0 uci = ControllerInformationBuffer;
874 //WDFDEVICE device = BusContext;
875 //xenusb_device_t *usb_device = DeviceHandle;
877 UNREFERENCED_PARAMETER(BusContext);
879 FUNCTION_ENTER();
881 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
882 KdPrint((__DRIVER_NAME " ControllerInformationBuffer = %p\n", ControllerInformationBuffer));
883 KdPrint((__DRIVER_NAME " ControllerInformationBufferLength = %d\n", ControllerInformationBufferLength));
884 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", uci->InformationLevel));
885 if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
886 {
887 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
888 FUNCTION_EXIT();
889 return STATUS_BUFFER_TOO_SMALL;
890 }
891 if (uci->InformationLevel != 0)
892 {
893 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
894 FUNCTION_EXIT();
895 return STATUS_NOT_SUPPORTED;
896 }
898 uci->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
899 uci->SelectiveSuspendEnabled = FALSE;
900 uci->IsHighSpeedController = TRUE;
901 *LengthOfDataReturned = uci->ActualLength;
903 FUNCTION_EXIT();
904 return status;
905 }
907 static NTSTATUS
908 XenUsbHub_UBIH_ControllerSelectiveSuspend (
909 PVOID BusContext,
910 BOOLEAN Enable)
911 {
912 NTSTATUS status = STATUS_UNSUCCESSFUL;
914 UNREFERENCED_PARAMETER(BusContext);
915 UNREFERENCED_PARAMETER(Enable);
917 FUNCTION_ENTER();
919 FUNCTION_EXIT();
920 return status;
921 }
923 static NTSTATUS
924 XenUsbHub_UBIH_GetExtendedHubInformation (
925 PVOID BusContext,
926 PDEVICE_OBJECT HubPhysicalDeviceObject,
927 PVOID HubInformationBuffer,
928 ULONG HubInformationBufferLength,
929 PULONG LengthOfDataReturned)
930 {
931 PUSB_EXTHUB_INFORMATION_0 hib = HubInformationBuffer;
932 ULONG i;
934 UNREFERENCED_PARAMETER(BusContext);
935 UNREFERENCED_PARAMETER(HubPhysicalDeviceObject);
937 FUNCTION_ENTER();
939 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
940 KdPrint((__DRIVER_NAME " HubPhysicalDeviceObject = %p\n", HubPhysicalDeviceObject));
941 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
942 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
943 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", hib->InformationLevel));
944 if (HubInformationBufferLength < (ULONG)FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]))
945 {
946 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
947 FUNCTION_EXIT();
948 return STATUS_BUFFER_TOO_SMALL;
949 }
950 if (hib->InformationLevel != 0)
951 {
952 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
953 FUNCTION_EXIT();
954 return STATUS_NOT_SUPPORTED;
955 }
956 //hib->InformationLevel = 0;
957 hib->NumberOfPorts = 8;
958 for (i = 0; i < hib->NumberOfPorts; i++)
959 {
960 hib->Port[i].PhysicalPortNumber = i + 1;
961 hib->Port[i].PortLabelNumber = i + 1;
962 hib->Port[i].VidOverride = 0;
963 hib->Port[i].PidOverride = 0;
964 hib->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2; // | USB_PORTATTR_NO_OVERCURRENT_UI;
965 }
966 *LengthOfDataReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
967 FUNCTION_EXIT();
968 return STATUS_SUCCESS;
969 }
971 static NTSTATUS
972 XenUsbHub_UBIH_GetRootHubSymbolicName(
973 PVOID BusContext,
974 PVOID HubInformationBuffer,
975 ULONG HubInformationBufferLength,
976 PULONG HubNameActualLength)
977 {
978 NTSTATUS status = STATUS_SUCCESS;
979 FUNCTION_ENTER();
981 UNREFERENCED_PARAMETER(BusContext);
983 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
984 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
985 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
986 RtlStringCbCopyW(HubInformationBuffer, HubInformationBufferLength, L"ROOT_HUB");
987 *HubNameActualLength = 16;
989 FUNCTION_EXIT();
990 return status;
991 }
993 static PVOID
994 XenUsbHub_UBIH_GetDeviceBusContext(
995 PVOID BusContext,
996 PVOID DeviceHandle)
997 {
998 UNREFERENCED_PARAMETER(BusContext);
999 UNREFERENCED_PARAMETER(DeviceHandle);
1001 FUNCTION_ENTER();
1003 FUNCTION_EXIT();
1004 return NULL;
1007 static NTSTATUS
1008 XenUsbHub_UBIH_Initialize20Hub (
1009 PVOID BusContext,
1010 PUSB_DEVICE_HANDLE HubDeviceHandle,
1011 ULONG TtCount)
1013 NTSTATUS status = STATUS_SUCCESS;
1015 UNREFERENCED_PARAMETER(BusContext);
1016 UNREFERENCED_PARAMETER(HubDeviceHandle);
1017 UNREFERENCED_PARAMETER(TtCount);
1019 FUNCTION_ENTER();
1020 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
1021 KdPrint((__DRIVER_NAME " HubDeviceHandle = %p\n", HubDeviceHandle));
1022 KdPrint((__DRIVER_NAME " TtCount = %d\n", TtCount));
1023 FUNCTION_EXIT();
1024 return status;
1027 static NTSTATUS
1028 XenUsbHub_UBIH_RootHubInitNotification(
1029 PVOID BusContext,
1030 PVOID CallbackContext,
1031 PRH_INIT_CALLBACK CallbackFunction)
1033 NTSTATUS status = STATUS_SUCCESS;
1034 WDFDEVICE device = BusContext;
1035 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
1037 FUNCTION_ENTER();
1039 xupdd->BusCallbackFunction = CallbackFunction;
1040 xupdd->BusCallbackContext = CallbackContext;
1042 xupdd->BusCallbackFunction(xupdd->BusCallbackContext);
1044 FUNCTION_EXIT();
1045 return status;
1048 /* This definition is incorrect in the docs */
1049 static VOID
1050 XenUsbHub_UBIH_FlushTransfers(
1051 PVOID BusContext,
1052 PVOID DeviceHandle)
1054 UNREFERENCED_PARAMETER(BusContext);
1055 UNREFERENCED_PARAMETER(DeviceHandle);
1057 FUNCTION_ENTER();
1059 FUNCTION_EXIT();
1062 static VOID
1063 XenUsbHub_UBIH_SetDeviceHandleData(
1064 PVOID BusContext,
1065 PUSB_DEVICE_HANDLE DeviceHandle,
1066 PDEVICE_OBJECT UsbDevicePdo)
1068 UNREFERENCED_PARAMETER(BusContext);
1069 UNREFERENCED_PARAMETER(DeviceHandle);
1070 UNREFERENCED_PARAMETER(UsbDevicePdo);
1072 FUNCTION_ENTER();
1073 FUNCTION_EXIT();
1076 static NTSTATUS
1077 XenUsbHub_UBIU_GetUSBDIVersion(
1078 PVOID BusContext,
1079 PUSBD_VERSION_INFORMATION VersionInformation,
1080 PULONG HcdCapabilities
1083 NTSTATUS status = STATUS_UNSUCCESSFUL;
1085 UNREFERENCED_PARAMETER(BusContext);
1086 UNREFERENCED_PARAMETER(VersionInformation);
1087 UNREFERENCED_PARAMETER(HcdCapabilities);
1089 FUNCTION_ENTER();
1091 FUNCTION_EXIT();
1092 return status;
1095 static NTSTATUS
1096 XenUsbHub_UBIU_QueryBusTime(
1097 PVOID BusContext,
1098 PULONG CurrentFrame
1101 NTSTATUS status = STATUS_UNSUCCESSFUL;
1103 UNREFERENCED_PARAMETER(BusContext);
1104 UNREFERENCED_PARAMETER(CurrentFrame);
1106 FUNCTION_ENTER();
1108 FUNCTION_EXIT();
1109 return status;
1112 static NTSTATUS
1113 XenUsbHub_UBIU_SubmitIsoOutUrb(
1114 PVOID BusContext,
1115 PURB Urb
1118 NTSTATUS status = STATUS_UNSUCCESSFUL;
1120 UNREFERENCED_PARAMETER(BusContext);
1121 UNREFERENCED_PARAMETER(Urb);
1123 FUNCTION_ENTER();
1125 FUNCTION_EXIT();
1126 return status;
1129 static NTSTATUS
1130 XenUsbHub_UBIU_QueryBusInformation(
1131 PVOID BusContext,
1132 ULONG Level,
1133 PVOID BusInformationBuffer,
1134 PULONG BusInformationBufferLength,
1135 PULONG BusInformationActualLength)
1137 NTSTATUS status = STATUS_UNSUCCESSFUL;
1139 UNREFERENCED_PARAMETER(BusContext);
1140 UNREFERENCED_PARAMETER(Level);
1141 UNREFERENCED_PARAMETER(BusInformationBuffer);
1142 UNREFERENCED_PARAMETER(BusInformationBufferLength);
1143 UNREFERENCED_PARAMETER(BusInformationActualLength);
1145 FUNCTION_ENTER();
1147 FUNCTION_EXIT();
1148 return status;
1151 static BOOLEAN
1152 XenUsbHub_UBIU_IsDeviceHighSpeed(PVOID BusContext)
1154 UNREFERENCED_PARAMETER(BusContext);
1156 FUNCTION_ENTER();
1158 FUNCTION_EXIT();
1159 return TRUE; //TODO: get port value
1162 static NTSTATUS
1163 XenUsbHub_UBIU_EnumLogEntry(
1164 PVOID BusContext,
1165 ULONG DriverTag,
1166 ULONG EnumTag,
1167 ULONG P1,
1168 ULONG P2
1171 NTSTATUS status = STATUS_SUCCESS;
1172 FUNCTION_ENTER();
1174 UNREFERENCED_PARAMETER(BusContext);
1175 UNREFERENCED_PARAMETER(DriverTag);
1176 UNREFERENCED_PARAMETER(EnumTag);
1177 UNREFERENCED_PARAMETER(P1);
1178 UNREFERENCED_PARAMETER(P2);
1180 KdPrint((__DRIVER_NAME " DriverTag = %08x\n", DriverTag));
1181 KdPrint((__DRIVER_NAME " EnumTag = %08x\n", EnumTag));
1182 KdPrint((__DRIVER_NAME " P1 = %08x\n", P1));
1183 KdPrint((__DRIVER_NAME " P2 = %08x\n", P2));
1185 FUNCTION_EXIT();
1186 return status;
1189 #if 0
1190 VOID
1191 XenUsb_EnumeratePorts(WDFDEVICE device)
1193 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
1194 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
1195 CHAR path[128];
1196 PCHAR err;
1197 PCHAR value;
1198 ULONG i;
1200 for (i = 0; i < xudd->num_ports; i++)
1202 ULONG port_value;
1203 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/port-%d", xudd->vectors.backend_path, i + 1);
1204 err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
1205 if (err)
1207 XenPci_FreeMem(err);
1208 KdPrint((__DRIVER_NAME " Failed to read port-%d\n", i + 1));
1209 continue;
1211 // 0=disconnected, 1=low_speed, 2=full_speed, 3= high_speed
1212 port_value = (ULONG)parse_numeric_string(value);
1213 XenPci_FreeMem(value);
1214 KdPrint((__DRIVER_NAME " port-%d : %d -> %d\n", i, xudd->ports[i].port_type, port_value));
1215 if (port_value != xudd->ports[i].port_type)
1217 xudd->ports[i].port_type = port_value;
1218 // need to do more than this - probably flush everything and ensure no more activity to the new port until it is set up...
1219 switch (port_value)
1221 case USB_PORT_TYPE_NOT_CONNECTED:
1222 xudd->ports[i].port_status = (1 << PORT_ENABLE);
1223 break;
1224 case USB_PORT_TYPE_LOW_SPEED:
1225 xudd->ports[i].port_status = (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1226 break;
1227 case USB_PORT_TYPE_FULL_SPEED:
1228 xudd->ports[i].port_status = (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1229 break;
1230 case USB_PORT_TYPE_HIGH_SPEED:
1231 xudd->ports[i].port_status = (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1232 break;
1234 xudd->ports[i].port_change |= (1 << PORT_CONNECTION);
1238 #endif
1240 static VOID
1241 XenUsbHub_HubInterruptTimer(WDFTIMER timer)
1243 NTSTATUS status;
1244 xenusb_endpoint_t *endpoint = *GetEndpoint(timer);
1245 WDFDEVICE pdo_device = endpoint->interface->config->device->pdo_device;
1246 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(pdo_device);
1247 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
1248 WDF_REQUEST_PARAMETERS wrp;
1249 WDFREQUEST request;
1250 PURB urb;
1251 ULONG i;
1253 //FUNCTION_ENTER();
1254 WdfSpinLockAcquire(endpoint->interrupt_lock);
1255 status = WdfIoQueueRetrieveNextRequest(endpoint->interrupt_queue, &request);
1256 if (status == STATUS_NO_MORE_ENTRIES)
1258 WdfTimerStop(timer, FALSE);
1259 WdfSpinLockRelease(endpoint->interrupt_lock);
1260 KdPrint((__DRIVER_NAME " No More Entries\n", status));
1261 //FUNCTION_EXIT();
1262 return;
1264 if (!NT_SUCCESS(status))
1266 WdfTimerStop(timer, FALSE);
1267 WdfSpinLockRelease(endpoint->interrupt_lock);
1268 KdPrint((__DRIVER_NAME " Failed to get request from queue %08x\n", status));
1269 //FUNCTION_EXIT();
1270 return;
1273 WDF_REQUEST_PARAMETERS_INIT(&wrp);
1274 WdfRequestGetParameters(request, &wrp);
1276 urb = (PURB)wrp.Parameters.Others.Arg1;
1277 ASSERT(urb);
1278 ASSERT(urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
1279 RtlZeroMemory(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
1280 if (urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
1282 //urb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
1283 // check for hub change too
1284 //((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] |= 1;
1285 for (i = 0; i < xudd->num_ports; i++)
1287 if (xudd->ports[i].port_change)
1289 KdPrint((__DRIVER_NAME " Port change on port %d - status = %04x, change = %04x\n",
1290 xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change));
1291 ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
1294 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
1295 WdfSpinLockRelease(endpoint->interrupt_lock);
1296 WdfRequestComplete(request, STATUS_SUCCESS);
1298 else
1300 KdPrint((__DRIVER_NAME " Direction mismatch\n"));
1301 urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
1302 WdfSpinLockRelease(endpoint->interrupt_lock);
1303 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
1305 //FUNCTION_EXIT();
1306 return;
1309 NTSTATUS
1310 XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
1311 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
1312 PWDFDEVICE_INIT child_init)
1314 NTSTATUS status = STATUS_SUCCESS;
1315 WDFDEVICE bus_device = WdfChildListGetDevice(child_list);
1316 WDF_OBJECT_ATTRIBUTES child_attributes;
1317 WDFDEVICE child_device;
1318 PXENUSB_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENUSB_PDO_IDENTIFICATION_DESCRIPTION)identification_header;
1319 WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities;
1320 DECLARE_UNICODE_STRING_SIZE(buffer, 512);
1321 DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
1322 PXENUSB_PDO_DEVICE_DATA xupdd;
1323 PXENUSB_DEVICE_DATA xudd = GetXudd(bus_device);
1324 WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
1325 WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities;
1326 WDF_IO_QUEUE_CONFIG queue_config;
1327 WDF_QUERY_INTERFACE_CONFIG interface_config;
1328 USB_BUS_INTERFACE_HUB_V5 ubih;
1329 USB_BUS_INTERFACE_USBDI_V2 ubiu;
1330 WDF_TIMER_CONFIG timer_config;
1331 WDF_OBJECT_ATTRIBUTES timer_attributes;
1333 UNREFERENCED_PARAMETER(xudd);
1335 FUNCTION_ENTER();
1337 //KdPrint((__DRIVER_NAME " device = %d, port = %d, vendor_id = %04x, product_id = %04x\n",
1339 WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN);
1341 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks);
1342 child_pnp_power_callbacks.EvtDeviceD0Entry = XenUsbHub_EvtDeviceD0Entry;
1343 child_pnp_power_callbacks.EvtDeviceD0Exit = XenUsbHub_EvtDeviceD0Exit;
1344 child_pnp_power_callbacks.EvtDevicePrepareHardware = XenUsbHub_EvtDevicePrepareHardware;
1345 child_pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsbHub_EvtDeviceReleaseHardware;
1346 child_pnp_power_callbacks.EvtDeviceUsageNotification = XenUsbHub_EvtDeviceUsageNotification;
1347 WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks);
1349 RtlUnicodeStringPrintf(&buffer, L"USB\\ROOT_HUB");
1350 status = WdfPdoInitAssignDeviceID(child_init, &buffer);
1351 status = WdfPdoInitAddHardwareID(child_init, &buffer);
1353 RtlUnicodeStringPrintf(&buffer, L"VUSB_%d", identification->device_number);
1354 status = WdfPdoInitAssignInstanceID(child_init, &buffer);
1355 if (!NT_SUCCESS(status))
1357 return status;
1360 RtlUnicodeStringPrintf(&buffer, L"PVUSB device #%d", identification->device_number, identification);
1361 status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409);
1362 if (!NT_SUCCESS(status))
1364 return status;
1366 WdfPdoInitSetDefaultLocale(child_init, 0x0409);
1368 WdfDeviceInitSetPowerNotPageable(child_init);
1370 WdfDeviceInitSetIoType(child_init, WdfDeviceIoDirect);
1372 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENUSB_PDO_DEVICE_DATA);
1373 status = WdfDeviceCreate(&child_init, &child_attributes, &child_device);
1374 if (!NT_SUCCESS(status))
1376 return status;
1379 xupdd = GetXupdd(child_device);
1381 xudd->root_hub_device = child_device;
1383 xupdd->wdf_device = child_device;
1384 xupdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
1386 xupdd->usb_device = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
1387 // get address from freelist...
1388 xupdd->usb_device->pdo_device = child_device;
1389 xupdd->usb_device->address = 1;
1390 xupdd->usb_device->device_speed = UsbHighSpeed;
1391 xupdd->usb_device->device_type = Usb20Device;
1392 xupdd->usb_device->device_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
1393 xupdd->usb_device->device_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
1394 xupdd->usb_device->device_descriptor.bcdUSB = 0x0200;
1395 xupdd->usb_device->device_descriptor.bDeviceClass = 9;
1396 xupdd->usb_device->device_descriptor.bDeviceSubClass = 0;
1397 xupdd->usb_device->device_descriptor.bDeviceProtocol = 1;
1398 xupdd->usb_device->device_descriptor.bMaxPacketSize0 = 64;
1399 xupdd->usb_device->device_descriptor.idVendor = 0x0000;
1400 xupdd->usb_device->device_descriptor.idProduct = 0x0000;
1401 xupdd->usb_device->device_descriptor.bcdDevice = 0x0206;
1402 xupdd->usb_device->device_descriptor.iManufacturer = 3;
1403 xupdd->usb_device->device_descriptor.iProduct = 2;
1404 xupdd->usb_device->device_descriptor.iSerialNumber = 1;
1405 xupdd->usb_device->device_descriptor.bNumConfigurations = 1;
1406 xupdd->usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1407 xupdd->usb_device->configs[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1408 xupdd->usb_device->active_config = xupdd->usb_device->configs[0];
1409 xupdd->usb_device->configs[0]->device = xupdd->usb_device;
1410 xupdd->usb_device->configs[0]->config_descriptor.bLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1411 xupdd->usb_device->configs[0]->config_descriptor.bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE;
1412 xupdd->usb_device->configs[0]->config_descriptor.wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1413 xupdd->usb_device->configs[0]->config_descriptor.bNumInterfaces = 1;
1414 xupdd->usb_device->configs[0]->config_descriptor.bConfigurationValue = 1;
1415 xupdd->usb_device->configs[0]->config_descriptor.iConfiguration = 0;
1416 xupdd->usb_device->configs[0]->config_descriptor.bmAttributes = 0xe0;
1417 xupdd->usb_device->configs[0]->config_descriptor.MaxPower = 0;
1418 xupdd->usb_device->configs[0]->interfaces[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1419 xupdd->usb_device->active_interface = xupdd->usb_device->configs[0]->interfaces[0];
1420 xupdd->usb_device->configs[0]->interfaces[0]->config = xupdd->usb_device->configs[0];
1421 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bLength = 9;
1422 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE;
1423 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceNumber = 0;
1424 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bAlternateSetting = 0;
1425 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bNumEndpoints = 1;
1426 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceClass = 9;
1427 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceSubClass = 0;
1428 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceProtocol = 0;
1429 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.iInterface = 0;
1430 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
1431 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interface = xupdd->usb_device->configs[0]->interfaces[0];
1432 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->pipe_value = 0;
1433 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bLength = 7;
1434 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
1435 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bEndpointAddress = 0x81; // EP 1 IN
1436 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT;
1437 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.wMaxPacketSize = 2;
1438 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bInterval = 12;
1439 WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_lock);
1440 WDF_TIMER_CONFIG_INIT(&timer_config, XenUsbHub_HubInterruptTimer);
1441 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timer_attributes, pxenusb_endpoint_t);
1442 timer_attributes.ParentObject = child_device;
1443 status = WdfTimerCreate(&timer_config, &timer_attributes, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer);
1444 if (!NT_SUCCESS(status)) {
1445 KdPrint((__DRIVER_NAME " Error creating timer 0x%x\n", status));
1446 return status;
1448 *GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
1450 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
1451 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
1452 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
1453 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->urb_queue);
1454 if (!NT_SUCCESS(status)) {
1455 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
1456 return status;
1458 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
1459 queue_config.PowerManaged = TRUE;
1460 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
1461 &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_queue);
1462 if (!NT_SUCCESS(status)) {
1463 KdPrint((__DRIVER_NAME " Error creating timer io_queue 0x%x\n", status));
1464 return status;
1467 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
1468 queue_config.EvtIoInternalDeviceControl = XenUsbHub_EvtIoInternalDeviceControl;
1469 queue_config.EvtIoDeviceControl = XenUsbHub_EvtIoDeviceControl;
1470 queue_config.EvtIoDefault = XenUsbHub_EvtIoDefault;
1471 /* can't be power managed or deadlocks occur */
1472 queue_config.PowerManaged = FALSE;
1473 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->io_queue);
1474 if (!NT_SUCCESS(status)) {
1475 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
1476 return status;
1479 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
1480 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
1481 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
1483 WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities);
1484 child_pnp_capabilities.LockSupported = WdfFalse;
1485 child_pnp_capabilities.EjectSupported = WdfTrue;
1486 child_pnp_capabilities.Removable = WdfTrue;
1487 child_pnp_capabilities.DockDevice = WdfFalse;
1488 child_pnp_capabilities.UniqueID = WdfTrue;
1489 child_pnp_capabilities.SilentInstall = WdfTrue;
1490 child_pnp_capabilities.SurpriseRemovalOK = WdfTrue;
1491 child_pnp_capabilities.HardwareDisabled = WdfFalse;
1492 WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities);
1494 WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities);
1495 child_power_capabilities.DeviceD1 = WdfTrue;
1496 child_power_capabilities.WakeFromD1 = WdfTrue;
1497 child_power_capabilities.DeviceWake = PowerDeviceD1;
1498 child_power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD1;
1499 child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
1500 child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
1501 child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
1502 child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
1503 child_power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1504 WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);
1506 ubih.BusContext = child_device;
1507 ubih.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1508 ubih.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1509 ubih.CreateUsbDevice = XenUsbHub_UBIH_CreateUsbDevice;
1510 ubih.InitializeUsbDevice = XenUsbHub_UBIH_InitializeUsbDevice;
1511 ubih.GetUsbDescriptors = XenUsbHub_UBIH_GetUsbDescriptors;
1512 ubih.RemoveUsbDevice = XenUsbHub_UBIH_RemoveUsbDevice;
1513 ubih.RestoreUsbDevice = XenUsbHub_UBIH_RestoreUsbDevice;
1514 ubih.GetPortHackFlags = XenUsbHub_UBIH_GetPortHackFlags;
1515 ubih.QueryDeviceInformation = XenUsbHub_UBIH_QueryDeviceInformation;
1516 ubih.GetControllerInformation = XenUsbHub_UBIH_GetControllerInformation;
1517 ubih.ControllerSelectiveSuspend = XenUsbHub_UBIH_ControllerSelectiveSuspend;
1518 ubih.GetExtendedHubInformation = XenUsbHub_UBIH_GetExtendedHubInformation;
1519 ubih.GetRootHubSymbolicName = XenUsbHub_UBIH_GetRootHubSymbolicName;
1520 ubih.GetDeviceBusContext = XenUsbHub_UBIH_GetDeviceBusContext;
1521 ubih.Initialize20Hub = XenUsbHub_UBIH_Initialize20Hub;
1522 ubih.RootHubInitNotification = XenUsbHub_UBIH_RootHubInitNotification;
1523 ubih.FlushTransfers = XenUsbHub_UBIH_FlushTransfers;
1524 ubih.SetDeviceHandleData = XenUsbHub_UBIH_SetDeviceHandleData;
1525 ubih.Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
1526 ubih.Version = USB_BUSIF_HUB_VERSION_5;
1527 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubih, &USB_BUS_INTERFACE_HUB_GUID, NULL);
1528 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
1529 if (!NT_SUCCESS(status))
1530 return status;
1532 ubiu.BusContext = child_device;
1533 ubiu.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1534 ubiu.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1535 ubiu.GetUSBDIVersion = XenUsbHub_UBIU_GetUSBDIVersion;
1536 ubiu.QueryBusTime = XenUsbHub_UBIU_QueryBusTime;
1537 ubiu.SubmitIsoOutUrb = XenUsbHub_UBIU_SubmitIsoOutUrb;
1538 ubiu.QueryBusInformation = XenUsbHub_UBIU_QueryBusInformation;
1539 ubiu.IsDeviceHighSpeed = XenUsbHub_UBIU_IsDeviceHighSpeed;
1540 ubiu.EnumLogEntry = XenUsbHub_UBIU_EnumLogEntry;
1541 ubiu.Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
1542 ubiu.Version = USB_BUSIF_HUB_VERSION_2;
1543 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubiu, &USB_BUS_INTERFACE_USBDI_GUID, NULL);
1544 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
1545 if (!NT_SUCCESS(status))
1546 return status;
1548 status = WdfDeviceCreateDeviceInterface(child_device, &GUID_DEVINTERFACE_USB_HUB, NULL);
1549 if (!NT_SUCCESS(status))
1550 return status;
1552 FUNCTION_EXIT();
1554 return status;