win-pvdrivers

view xenusb/xenusb_hub.c @ 670:b59c7dfdee9b

Updates to support latest pre-release version of pvusb. No longer compatible with current version.
author James Harper <james.harper@bendigoit.com.au>
date Wed Sep 23 17:06:30 2009 +1000 (2009-09-23)
parents 21e041d3e07d
children 63b0eb3f9d44
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 VOID
26 XenUsbHub_EvtIoDefault(
27 WDFQUEUE queue,
28 WDFREQUEST request)
29 {
30 NTSTATUS status;
31 WDF_REQUEST_PARAMETERS parameters;
33 FUNCTION_ENTER();
35 UNREFERENCED_PARAMETER(queue);
37 status = STATUS_UNSUCCESSFUL;
39 WDF_REQUEST_PARAMETERS_INIT(&parameters);
40 WdfRequestGetParameters(request, &parameters);
42 switch (parameters.Type)
43 {
44 case WdfRequestTypeCreate:
45 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
46 break;
47 case WdfRequestTypeClose:
48 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
49 break;
50 case WdfRequestTypeRead:
51 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
52 break;
53 case WdfRequestTypeWrite:
54 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
55 break;
56 case WdfRequestTypeDeviceControl:
57 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
59 break;
60 case WdfRequestTypeDeviceControlInternal:
61 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
62 break;
63 default:
64 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
65 break;
66 }
67 WdfRequestComplete(request, status);
69 FUNCTION_EXIT();
70 }
72 static NTSTATUS
73 XenUsbHub_BusIrpCompletionRoutine(
74 PDEVICE_OBJECT device_object,
75 PIRP irp,
76 PVOID context)
77 {
78 WDFREQUEST request = context;
80 UNREFERENCED_PARAMETER(device_object);
82 FUNCTION_ENTER();
84 WdfRequestCompleteWithInformation(request, irp->IoStatus.Status, irp->IoStatus.Information);
85 IoFreeIrp(irp);
87 FUNCTION_EXIT();
89 return STATUS_MORE_PROCESSING_REQUIRED;
90 }
92 static VOID
93 XenUsbHub_EvtIoDeviceControl(
94 WDFQUEUE queue,
95 WDFREQUEST request,
96 size_t output_buffer_length,
97 size_t input_buffer_length,
98 ULONG io_control_code)
99 {
100 NTSTATUS status;
101 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
102 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
103 //WDF_REQUEST_PARAMETERS wrp;
104 //PURB urb;
105 //xenusb_device_t *usb_device;
107 UNREFERENCED_PARAMETER(queue);
108 UNREFERENCED_PARAMETER(input_buffer_length);
109 UNREFERENCED_PARAMETER(output_buffer_length);
111 FUNCTION_ENTER();
113 status = STATUS_UNSUCCESSFUL;
115 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
116 //WdfRequestGetParameters(request, &wrp);
118 // these are in api\usbioctl.h
119 switch(io_control_code)
120 {
121 case IOCTL_USB_GET_NODE_INFORMATION:
122 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
123 break;
124 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
125 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
126 break;
127 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
128 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
129 break;
130 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
131 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
132 break;
133 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
134 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
135 break;
136 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
137 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
138 break;
139 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
140 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
141 break;
142 case IOCTL_USB_GET_HUB_CAPABILITIES:
143 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
144 break;
145 case IOCTL_USB_HUB_CYCLE_PORT:
146 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
147 break;
148 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
149 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
150 break;
151 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
152 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
153 break;
154 case IOCTL_GET_HCD_DRIVERKEY_NAME:
155 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME\n"));
156 break;
157 default:
158 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
159 break;
160 }
161 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
162 WdfRequestComplete(request, status);
164 FUNCTION_EXIT();
165 }
167 static VOID
168 XenUsbHub_EvtIoInternalDeviceControl(
169 WDFQUEUE queue,
170 WDFREQUEST request,
171 size_t output_buffer_length,
172 size_t input_buffer_length,
173 ULONG io_control_code)
174 {
175 NTSTATUS status;
176 WDFDEVICE device = WdfIoQueueGetDevice(queue);
177 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
178 WDF_REQUEST_PARAMETERS wrp;
179 PURB urb;
180 xenusb_device_t *usb_device;
182 UNREFERENCED_PARAMETER(input_buffer_length);
183 UNREFERENCED_PARAMETER(output_buffer_length);
185 //FUNCTION_ENTER();
187 status = STATUS_UNSUCCESSFUL;
189 WDF_REQUEST_PARAMETERS_INIT(&wrp);
190 WdfRequestGetParameters(request, &wrp);
192 // these are in api\usbioctl.h
193 switch(io_control_code)
194 {
195 case IOCTL_INTERNAL_USB_CYCLE_PORT:
196 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_CYCLE_PORT\n"));
197 break;
198 case IOCTL_INTERNAL_USB_ENABLE_PORT:
199 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_ENABLE_PORT\n"));
200 break;
201 case IOCTL_INTERNAL_USB_GET_BUS_INFO:
202 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_BUS_INFO\n"));
203 break;
204 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
205 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n"));
206 break;
207 case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
208 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_COUNT\n"));
209 KdPrint((__DRIVER_NAME " Count before increment = %p\n", *(PULONG)wrp.Parameters.Others.Arg1));
210 (*(PULONG)wrp.Parameters.Others.Arg1)++;
211 status = STATUS_SUCCESS;
212 break;
213 case IOCTL_INTERNAL_USB_GET_HUB_NAME:
214 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_HUB_NAME\n"));
215 break;
216 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
217 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_PORT_STATUS\n"));
218 *(PULONG)wrp.Parameters.Others.Arg1 = USBD_PORT_ENABLED | USBD_PORT_CONNECTED; /* enabled and connected */
219 status = STATUS_SUCCESS;
220 break;
221 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
222 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n"));
223 KdPrint((__DRIVER_NAME " WdfDeviceWdmGetPhysicalDevice(device) = %p\n", WdfDeviceWdmGetPhysicalDevice(device)));
224 //KdPrint((__DRIVER_NAME " IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device)) = %p\n", IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device))));
225 *(PVOID *)wrp.Parameters.Others.Arg1 = WdfDeviceWdmGetPhysicalDevice(device);
226 //*(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device));
227 *(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(xupdd->wdf_device_bus_fdo));
228 {
229 //PDEVICE_OBJECT hcdTopOfStack = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device));
230 PDEVICE_OBJECT hcdTopOfStack = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(xupdd->wdf_device_bus_fdo));
231 KdPrint((__DRIVER_NAME " hcdTopOfStack = %p\n", hcdTopOfStack));
232 KdPrint((__DRIVER_NAME " hcdTopOfStack->StackSize = %p\n", hcdTopOfStack->StackSize));
233 }
234 status = STATUS_SUCCESS;
235 break;
236 case IOCTL_INTERNAL_USB_RESET_PORT:
237 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_RESET_PORT\n"));
238 break;
239 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
240 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n"));
241 break;
242 case IOCTL_INTERNAL_USB_SUBMIT_URB:
243 urb = (PURB)wrp.Parameters.Others.Arg1;
244 ASSERT(urb);
245 usb_device = urb->UrbHeader.UsbdDeviceHandle;
246 if (!usb_device)
247 usb_device = xupdd->usb_device;
248 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
249 return;
250 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
251 KdPrint((__DRIVER_NAME " IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE (returning %p)\n", xupdd->usb_device));
252 *(PVOID *)wrp.Parameters.Others.Arg1 = xupdd->usb_device;
253 status = STATUS_SUCCESS;
254 break;
255 default:
256 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
257 break;
258 }
260 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
261 WdfRequestComplete(request, status);
263 //FUNCTION_EXIT();
264 }
266 NTSTATUS
267 XenUsbHub_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
268 {
269 NTSTATUS status = STATUS_SUCCESS;
271 UNREFERENCED_PARAMETER(device);
273 FUNCTION_ENTER();
275 switch (previous_state)
276 {
277 case WdfPowerDeviceD0:
278 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
279 break;
280 case WdfPowerDeviceD1:
281 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
282 break;
283 case WdfPowerDeviceD2:
284 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
285 break;
286 case WdfPowerDeviceD3:
287 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
288 break;
289 case WdfPowerDeviceD3Final:
290 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
291 break;
292 case WdfPowerDevicePrepareForHibernation:
293 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
294 break;
295 default:
296 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
297 break;
298 }
300 FUNCTION_EXIT();
302 return status;
303 }
305 NTSTATUS
306 XenUsbHub_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
307 {
308 NTSTATUS status = STATUS_SUCCESS;
309 //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
310 //PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
312 UNREFERENCED_PARAMETER(device);
314 FUNCTION_ENTER();
316 switch (target_state)
317 {
318 case WdfPowerDeviceD0:
319 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
320 break;
321 case WdfPowerDeviceD1:
322 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
323 break;
324 case WdfPowerDeviceD2:
325 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
326 break;
327 case WdfPowerDeviceD3:
328 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
329 break;
330 case WdfPowerDeviceD3Final:
331 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
332 break;
333 case WdfPowerDevicePrepareForHibernation:
334 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
335 break;
336 default:
337 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
338 break;
339 }
341 FUNCTION_EXIT();
343 return status;
344 }
346 NTSTATUS
347 XenUsbHub_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
348 {
349 NTSTATUS status = STATUS_SUCCESS;
351 UNREFERENCED_PARAMETER(device);
352 UNREFERENCED_PARAMETER(resources_raw);
353 UNREFERENCED_PARAMETER(resources_translated);
355 FUNCTION_ENTER();
356 FUNCTION_EXIT();
358 return status;
359 }
361 NTSTATUS
362 XenUsbHub_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
363 {
364 NTSTATUS status = STATUS_SUCCESS;
366 UNREFERENCED_PARAMETER(device);
367 UNREFERENCED_PARAMETER(resources_translated);
369 FUNCTION_ENTER();
370 FUNCTION_EXIT();
372 return status;
373 }
375 static VOID
376 XenUsbHub_EvtDeviceUsageNotification(WDFDEVICE device, WDF_SPECIAL_FILE_TYPE notification_type, BOOLEAN is_in_notification_path)
377 {
378 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
380 UNREFERENCED_PARAMETER(xupdd);
382 FUNCTION_ENTER();
384 switch (notification_type)
385 {
386 case WdfSpecialFilePaging:
387 KdPrint((__DRIVER_NAME " notification_type = Paging, flag = %d\n", is_in_notification_path));
388 break;
389 case WdfSpecialFileHibernation:
390 KdPrint((__DRIVER_NAME " notification_type = Hibernation, flag = %d\n", is_in_notification_path));
391 break;
392 case WdfSpecialFileDump:
393 KdPrint((__DRIVER_NAME " notification_type = Dump, flag = %d\n", is_in_notification_path));
394 break;
395 default:
396 KdPrint((__DRIVER_NAME " notification_type = %d, flag = %d\n", notification_type, is_in_notification_path));
397 break;
398 }
400 FUNCTION_EXIT();
401 }
403 static NTSTATUS
404 XenUsb_SubmitCompletionRoutine(
405 PDEVICE_OBJECT device_object,
406 PIRP irp,
407 PVOID context)
408 {
409 UNREFERENCED_PARAMETER(device_object);
411 FUNCTION_ENTER();
413 if (irp->PendingReturned)
414 {
415 KeSetEvent ((PKEVENT)context, IO_NO_INCREMENT, FALSE);
416 }
418 FUNCTION_EXIT();
420 return STATUS_MORE_PROCESSING_REQUIRED;
421 }
423 static NTSTATUS
424 XenUsbHub_UBIH_CreateUsbDevice(
425 PVOID BusContext,
426 PUSB_DEVICE_HANDLE *DeviceHandle,
427 PUSB_DEVICE_HANDLE *HubDeviceHandle,
428 USHORT PortStatus,
429 USHORT PortNumber)
430 {
431 NTSTATUS status = STATUS_SUCCESS;
432 WDFDEVICE device = BusContext;
433 FUNCTION_ENTER();
435 KdPrint((__DRIVER_NAME " device = %p\n", device));
436 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
437 KdPrint((__DRIVER_NAME " *DeviceHandle = %p\n", *DeviceHandle));
438 KdPrint((__DRIVER_NAME " HubDeviceHandle = %p\n", HubDeviceHandle));
439 KdPrint((__DRIVER_NAME " *HubDeviceHandle = %p\n", *HubDeviceHandle));
440 KdPrint((__DRIVER_NAME " PortStatus = %04X\n", PortStatus));
441 KdPrint((__DRIVER_NAME " PortNumber = %d\n", PortNumber));
442 *DeviceHandle = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
444 FUNCTION_EXIT();
445 return status;
446 }
448 static VOID
449 XenUsb_SetEventCallback(usbif_shadow_t *shadow)
450 {
451 FUNCTION_ENTER();
452 KeSetEvent(&shadow->event, IO_NO_INCREMENT, FALSE);
453 FUNCTION_EXIT();
454 }
456 static NTSTATUS
457 XenUsbHub_UBIH_InitializeUsbDevice(
458 PVOID BusContext,
459 PUSB_DEVICE_HANDLE DeviceHandle)
460 {
461 NTSTATUS status = STATUS_SUCCESS;
462 WDFDEVICE device = BusContext;
463 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
464 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
465 WDF_IO_QUEUE_CONFIG queue_config;
466 xenusb_device_t *usb_device = DeviceHandle;
467 PUCHAR ptr;
468 PVOID buf;
469 PMDL mdl;
470 usbif_shadow_t *shadow;
471 PUSB_DEVICE_DESCRIPTOR device_descriptor;
472 PUSB_CONFIGURATION_DESCRIPTOR config_descriptor;
473 PUSB_INTERFACE_DESCRIPTOR interface_descriptor;
474 PUSB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
475 int i, j, k;
476 PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
478 FUNCTION_ENTER();
480 KdPrint((__DRIVER_NAME " device = %p\n", device));
481 KdPrint((__DRIVER_NAME " usb_device = %p\n", usb_device));
482 usb_device->pdo_device = BusContext;
484 // get address from freelist and assign it to the device...
485 usb_device->address = 2;
486 // and get this stuff properly...
487 usb_device->port_number = 1;
488 xupdd->usb_device->device_speed = UsbHighSpeed;
489 xupdd->usb_device->device_type = Usb20Device;
491 buf = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
492 mdl = IoAllocateMdl(buf, PAGE_SIZE, FALSE, FALSE, NULL);
493 MmBuildMdlForNonPagedPool(mdl);
494 shadow = get_shadow_from_freelist(xudd);
496 /* set the address */
497 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
498 shadow->callback = XenUsb_SetEventCallback;
499 shadow->req.id = shadow->id;
500 shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | usb_device->port_number;
501 shadow->req.transfer_flags = 0;
502 shadow->req.buffer_length = 0;
503 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
504 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
505 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
506 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
507 setup_packet->bRequest = USB_REQUEST_SET_ADDRESS;
508 setup_packet->wValue.W = usb_device->address;
509 setup_packet->wIndex.W = 0;
510 setup_packet->wLength = shadow->req.buffer_length;
511 status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
512 //TODO: Handle failure here
513 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
514 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
515 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
516 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
517 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
518 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
520 /* get the device descriptor */
521 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
522 shadow->callback = XenUsb_SetEventCallback;
523 shadow->req.id = shadow->id;
524 shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
525 shadow->req.transfer_flags = 0;
526 shadow->req.buffer_length = PAGE_SIZE;
527 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
528 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
529 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
530 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
531 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
532 setup_packet->wValue.LowByte = 0;
533 setup_packet->wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; //device descriptor
534 setup_packet->wIndex.W = 0;
535 setup_packet->wLength = shadow->req.buffer_length;
536 status = XenUsb_ExecuteRequest(xudd, shadow, NULL, mdl, PAGE_SIZE);
537 //TODO: Handle failure here
538 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
539 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
540 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
541 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
542 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
543 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
544 ptr = buf;
545 device_descriptor = (PUSB_DEVICE_DESCRIPTOR)ptr;
546 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
547 KdPrint((__DRIVER_NAME " bNumConfigurations = %d\n", device_descriptor->bNumConfigurations));
548 memcpy(&usb_device->device_descriptor, device_descriptor, device_descriptor->bLength);
549 usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * device_descriptor->bNumConfigurations, XENUSB_POOL_TAG);
550 KdPrint((__DRIVER_NAME " bLength = %d\n", device_descriptor->bLength));
551 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", device_descriptor->bDescriptorType));
552 KdPrint((__DRIVER_NAME " bcdUSB = %04x\n", device_descriptor->bcdUSB));
553 KdPrint((__DRIVER_NAME " bDeviceClass = %02x\n", device_descriptor->bDeviceClass));
554 KdPrint((__DRIVER_NAME " bDeviceSubClass = %02x\n", device_descriptor->bDeviceSubClass));
555 KdPrint((__DRIVER_NAME " bDeviceProtocol = %02x\n", device_descriptor->bDeviceProtocol));
556 KdPrint((__DRIVER_NAME " idVendor = %04x\n", device_descriptor->idVendor));
557 KdPrint((__DRIVER_NAME " idProduct = %04x\n", device_descriptor->idProduct));
558 KdPrint((__DRIVER_NAME " bcdDevice = %04x\n", device_descriptor->bcdDevice));
559 KdPrint((__DRIVER_NAME " bNumConfigurations = %04x\n", device_descriptor->bNumConfigurations));
561 /* get the config descriptor */
562 for (i = 0; i < device_descriptor->bNumConfigurations; i++)
563 {
564 KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
565 shadow->callback = XenUsb_SetEventCallback;
566 shadow->req.id = shadow->id;
567 shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
568 shadow->req.transfer_flags = 0;
569 shadow->req.buffer_length = PAGE_SIZE;
570 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
571 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
572 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
573 setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
574 setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
575 setup_packet->wValue.LowByte = (UCHAR)(i + 1);
576 setup_packet->wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; //device descriptor
577 setup_packet->wIndex.W = 0;
578 setup_packet->wLength = shadow->req.buffer_length;
579 status = XenUsb_ExecuteRequest(xudd, shadow, buf, NULL, PAGE_SIZE);
580 //TODO: Handle failure here
581 KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
582 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
583 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
584 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
585 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
586 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
587 ptr = buf;
588 config_descriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ptr;
589 KdPrint((__DRIVER_NAME " Config %d\n", i));
590 KdPrint((__DRIVER_NAME " bLength = %d\n", config_descriptor->bLength));
591 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", config_descriptor->bDescriptorType));
592 KdPrint((__DRIVER_NAME " wTotalLength = %d\n", config_descriptor->wTotalLength));
593 KdPrint((__DRIVER_NAME " bNumInterfaces = %d\n", config_descriptor->bNumInterfaces));
594 KdPrint((__DRIVER_NAME " iConfiguration = %d\n", config_descriptor->iConfiguration));
595 KdPrint((__DRIVER_NAME " bConfigurationValue = %d\n", config_descriptor->bConfigurationValue));
596 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", config_descriptor->bmAttributes));
597 KdPrint((__DRIVER_NAME " MaxPower = %d\n", config_descriptor->MaxPower));
598 usb_device->configs[i] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * config_descriptor->bNumInterfaces, XENUSB_POOL_TAG);
599 usb_device->configs[i]->device = usb_device;
600 memcpy(&usb_device->configs[i]->config_descriptor, config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
601 ptr += config_descriptor->bLength;
602 for (j = 0; j < config_descriptor->bNumInterfaces; j++)
603 {
604 interface_descriptor = (PUSB_INTERFACE_DESCRIPTOR)ptr;
605 KdPrint((__DRIVER_NAME " Interface %d\n", j));
606 KdPrint((__DRIVER_NAME " bLength = %d\n", interface_descriptor->bLength));
607 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", interface_descriptor->bDescriptorType));
608 KdPrint((__DRIVER_NAME " bInterfaceNumber = %d\n", interface_descriptor->bInterfaceNumber));
609 KdPrint((__DRIVER_NAME " bAlternateSetting = %d\n", interface_descriptor->bAlternateSetting));
610 KdPrint((__DRIVER_NAME " bNumEndpoints = %d\n", interface_descriptor->bNumEndpoints));
611 KdPrint((__DRIVER_NAME " bInterfaceClass = %d\n", interface_descriptor->bInterfaceClass));
612 KdPrint((__DRIVER_NAME " bInterfaceSubClass = %d\n", interface_descriptor->bInterfaceSubClass));
613 KdPrint((__DRIVER_NAME " bInterfaceProtocol = %d\n", interface_descriptor->bInterfaceProtocol));
614 KdPrint((__DRIVER_NAME " iInterface = %d\n", interface_descriptor->iInterface));
615 ptr += interface_descriptor->bLength;
616 usb_device->configs[i]->interfaces[j] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * interface_descriptor->bNumEndpoints, XENUSB_POOL_TAG);
617 usb_device->configs[i]->interfaces[j]->config = usb_device->configs[i];
618 memcpy(&usb_device->configs[i]->interfaces[j]->interface_descriptor, interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
619 for (k = 0; k < interface_descriptor->bNumEndpoints; k++)
620 {
621 endpoint_descriptor = (PUSB_ENDPOINT_DESCRIPTOR)ptr;
622 KdPrint((__DRIVER_NAME " Endpoint %d\n", k));
623 KdPrint((__DRIVER_NAME " bLength = %d\n", endpoint_descriptor->bLength));
624 KdPrint((__DRIVER_NAME " bDescriptorType = %d\n", endpoint_descriptor->bDescriptorType));
625 KdPrint((__DRIVER_NAME " bEndpointAddress = %02x\n", endpoint_descriptor->bEndpointAddress));
626 KdPrint((__DRIVER_NAME " bmAttributes = %02x\n", endpoint_descriptor->bmAttributes));
627 KdPrint((__DRIVER_NAME " wMaxPacketSize = %d\n", endpoint_descriptor->wMaxPacketSize));
628 KdPrint((__DRIVER_NAME " bInterval = %d\n", endpoint_descriptor->bInterval));
629 ptr += endpoint_descriptor->bLength;
630 usb_device->configs[i]->interfaces[j]->endpoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
631 usb_device->configs[i]->interfaces[j]->endpoints[k]->interface = usb_device->configs[i]->interfaces[j];
632 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value = (usb_device->address << 8) | usb_device->port_number;
633 /* linux uses nonstandard endpoint type identifiers... */
634 switch(endpoint_descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
635 {
636 case USB_ENDPOINT_TYPE_CONTROL:
637 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_CTRL;
638 break;
639 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
640 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_ISOC;
641 break;
642 case USB_ENDPOINT_TYPE_BULK:
643 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_BULK;
644 break;
645 case USB_ENDPOINT_TYPE_INTERRUPT:
646 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_INTR;
647 break;
648 }
649 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x80);
650 usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x0F) << 15;
651 memcpy(&usb_device->configs[i]->interfaces[j]->endpoints[k]->endpoint_descriptor, endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
652 }
653 }
654 }
655 usb_device->active_config = usb_device->configs[0];
656 usb_device->active_interface = usb_device->configs[0]->interfaces[0];
658 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
659 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
660 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
661 status = WdfIoQueueCreate(xupdd->wdf_device_bus_fdo, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &usb_device->urb_queue);
662 if (!NT_SUCCESS(status)) {
663 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
664 return status;
665 }
667 put_shadow_on_freelist(xudd, shadow);
669 FUNCTION_EXIT();
670 return status;
671 }
673 static NTSTATUS
674 XenUsbHub_UBIH_GetUsbDescriptors(
675 PVOID BusContext,
676 PUSB_DEVICE_HANDLE DeviceHandle,
677 PUCHAR DeviceDescriptorBuffer,
678 PULONG DeviceDescriptorBufferLength,
679 PUCHAR ConfigDescriptorBuffer,
680 PULONG ConfigDescriptorBufferLength
681 )
682 {
683 NTSTATUS status = STATUS_SUCCESS;
684 WDFDEVICE device = BusContext;
685 xenusb_device_t *usb_device = DeviceHandle;
686 xenusb_config_t *usb_config;
687 PUCHAR ptr;
689 FUNCTION_ENTER();
691 KdPrint((__DRIVER_NAME " device = %p\n", device));
692 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
693 KdPrint((__DRIVER_NAME " DeviceDescriptorBuffer = %p\n", DeviceDescriptorBuffer));
694 KdPrint((__DRIVER_NAME " DeviceDescriptorBufferLength = %d\n", *DeviceDescriptorBufferLength));
695 KdPrint((__DRIVER_NAME " ConfigDescriptorBuffer = %p\n", ConfigDescriptorBuffer));
696 KdPrint((__DRIVER_NAME " ConfigDescriptorBufferLength = %d\n", *ConfigDescriptorBufferLength));
698 memcpy(DeviceDescriptorBuffer, &usb_device->device_descriptor, usb_device->device_descriptor.bLength);
699 *DeviceDescriptorBufferLength = usb_device->device_descriptor.bLength;
701 usb_config = usb_device->active_config;
702 ptr = ConfigDescriptorBuffer;
703 KdPrint((__DRIVER_NAME " memcpy(%p, %p, %d)\n", ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)));
704 memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
705 ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
706 #if 0
707 for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
708 {
709 memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
710 ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
711 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
712 for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
713 {
714 memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
715 ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
716 ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
717 }
718 }
719 #endif
720 *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); //((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
722 FUNCTION_EXIT();
723 return status;
724 }
726 static NTSTATUS
727 XenUsbHub_UBIH_RemoveUsbDevice (
728 PVOID BusContext,
729 PUSB_DEVICE_HANDLE DeviceHandle,
730 ULONG Flags)
731 {
732 NTSTATUS status = STATUS_SUCCESS;
734 UNREFERENCED_PARAMETER(BusContext);
735 UNREFERENCED_PARAMETER(DeviceHandle);
737 FUNCTION_ENTER();
739 if (Flags & USBD_KEEP_DEVICE_DATA)
740 KdPrint((__DRIVER_NAME " USBD_KEEP_DEVICE_DATA\n"));
742 if (Flags & USBD_MARK_DEVICE_BUSY)
743 KdPrint((__DRIVER_NAME " USBD_MARK_DEVICE_BUSY\n"));
745 FUNCTION_EXIT();
746 return status;
747 }
749 static NTSTATUS
750 XenUsbHub_UBIH_RestoreUsbDevice(
751 PVOID BusContext,
752 PUSB_DEVICE_HANDLE OldDeviceHandle,
753 PUSB_DEVICE_HANDLE NewDeviceHandle)
754 {
755 NTSTATUS status = STATUS_UNSUCCESSFUL;
757 UNREFERENCED_PARAMETER(BusContext);
758 UNREFERENCED_PARAMETER(OldDeviceHandle);
759 UNREFERENCED_PARAMETER(NewDeviceHandle);
761 FUNCTION_ENTER();
763 FUNCTION_EXIT();
764 return status;
765 }
767 static NTSTATUS
768 XenUsbHub_UBIH_GetPortHackFlags(
769 PVOID BusContext,
770 PULONG HackFlags)
771 {
772 NTSTATUS status = STATUS_UNSUCCESSFUL;
774 UNREFERENCED_PARAMETER(BusContext);
775 UNREFERENCED_PARAMETER(HackFlags);
777 FUNCTION_ENTER();
779 FUNCTION_EXIT();
780 return status;
781 }
783 static NTSTATUS
784 XenUsbHub_UBIH_QueryDeviceInformation(
785 PVOID BusContext,
786 PUSB_DEVICE_HANDLE DeviceHandle,
787 PVOID DeviceInformationBuffer,
788 ULONG DeviceInformationBufferLength,
789 PULONG LengthOfDataReturned)
790 {
791 PUSB_DEVICE_INFORMATION_0 udi = DeviceInformationBuffer;
792 xenusb_device_t *usb_device = DeviceHandle;
793 ULONG i;
794 ULONG required_size;
796 FUNCTION_ENTER();
798 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
799 KdPrint((__DRIVER_NAME " DeviceHandle = %p\n", DeviceHandle));
800 KdPrint((__DRIVER_NAME " DeviceInformationBuffer = %p\n", DeviceInformationBuffer));
801 KdPrint((__DRIVER_NAME " DeviceInformationBufferLength = %d\n", DeviceInformationBufferLength));
802 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", udi->InformationLevel));
803 required_size = (ULONG)FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[usb_device->active_interface->interface_descriptor.bNumEndpoints]);
804 KdPrint((__DRIVER_NAME " required_size = %d\n", required_size));
805 *LengthOfDataReturned = required_size;
806 if (DeviceInformationBufferLength < required_size)
807 {
808 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
809 FUNCTION_EXIT();
810 return STATUS_BUFFER_TOO_SMALL;
811 }
812 if (udi->InformationLevel != 0)
813 {
814 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
815 FUNCTION_EXIT();
816 return STATUS_NOT_SUPPORTED;
817 }
818 udi->ActualLength = required_size;
819 udi->PortNumber = 1;
820 memcpy(&udi->DeviceDescriptor, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
821 udi->CurrentConfigurationValue = usb_device->active_config->config_descriptor.bConfigurationValue;
822 udi->DeviceAddress = usb_device->address;
823 udi->HubAddress = 1; // ?
824 udi->DeviceSpeed = usb_device->device_speed;
825 udi->DeviceType = usb_device->device_type;
826 udi->NumberOfOpenPipes = usb_device->active_interface->interface_descriptor.bNumEndpoints;
827 for (i = 0; i < usb_device->active_interface->interface_descriptor.bNumEndpoints; i++)
828 {
829 memcpy(&udi->PipeList[i].EndpointDescriptor, &usb_device->active_interface->endpoints[i]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
830 udi->PipeList[0].ScheduleOffset = 0; // not necessarily right
831 }
832 FUNCTION_EXIT();
833 return STATUS_SUCCESS;
834 }
836 static NTSTATUS
837 XenUsbHub_UBIH_GetControllerInformation (
838 PVOID BusContext,
839 PVOID ControllerInformationBuffer,
840 ULONG ControllerInformationBufferLength,
841 PULONG LengthOfDataReturned)
842 {
843 NTSTATUS status = STATUS_UNSUCCESSFUL;
844 PUSB_CONTROLLER_INFORMATION_0 uci = ControllerInformationBuffer;
845 //WDFDEVICE device = BusContext;
846 //xenusb_device_t *usb_device = DeviceHandle;
848 FUNCTION_ENTER();
850 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
851 KdPrint((__DRIVER_NAME " ControllerInformationBuffer = %p\n", ControllerInformationBuffer));
852 KdPrint((__DRIVER_NAME " ControllerInformationBufferLength = %d\n", ControllerInformationBufferLength));
853 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", uci->InformationLevel));
854 if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
855 {
856 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
857 FUNCTION_EXIT();
858 return STATUS_BUFFER_TOO_SMALL;
859 }
860 if (uci->InformationLevel != 0)
861 {
862 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
863 FUNCTION_EXIT();
864 return STATUS_NOT_SUPPORTED;
865 }
867 uci->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
868 uci->SelectiveSuspendEnabled = FALSE;
869 uci->IsHighSpeedController = TRUE;
870 *LengthOfDataReturned = uci->ActualLength;
872 FUNCTION_EXIT();
873 return status;
874 }
876 static NTSTATUS
877 XenUsbHub_UBIH_ControllerSelectiveSuspend (
878 PVOID BusContext,
879 BOOLEAN Enable)
880 {
881 NTSTATUS status = STATUS_UNSUCCESSFUL;
883 UNREFERENCED_PARAMETER(BusContext);
884 UNREFERENCED_PARAMETER(Enable);
886 FUNCTION_ENTER();
888 FUNCTION_EXIT();
889 return status;
890 }
892 static NTSTATUS
893 XenUsbHub_UBIH_GetExtendedHubInformation (
894 PVOID BusContext,
895 PDEVICE_OBJECT HubPhysicalDeviceObject,
896 PVOID HubInformationBuffer,
897 ULONG HubInformationBufferLength,
898 PULONG LengthOfDataReturned)
899 {
900 PUSB_EXTHUB_INFORMATION_0 hib = HubInformationBuffer;
901 ULONG i;
903 FUNCTION_ENTER();
905 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
906 KdPrint((__DRIVER_NAME " HubPhysicalDeviceObject = %p\n", HubPhysicalDeviceObject));
907 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
908 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
909 KdPrint((__DRIVER_NAME " ->InformationLevel = %d\n", hib->InformationLevel));
910 if (HubInformationBufferLength < (ULONG)FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]))
911 {
912 KdPrint((__DRIVER_NAME " STATUS_BUFFER_TOO_SMALL\n"));
913 FUNCTION_EXIT();
914 return STATUS_BUFFER_TOO_SMALL;
915 }
916 if (hib->InformationLevel != 0)
917 {
918 KdPrint((__DRIVER_NAME " STATUS_NOT_SUPPORTED\n"));
919 FUNCTION_EXIT();
920 return STATUS_NOT_SUPPORTED;
921 }
922 //hib->InformationLevel = 0;
923 hib->NumberOfPorts = 8;
924 for (i = 0; i < hib->NumberOfPorts; i++)
925 {
926 hib->Port[i].PhysicalPortNumber = i + 1;
927 hib->Port[i].PortLabelNumber = i + 1;
928 hib->Port[i].VidOverride = 0;
929 hib->Port[i].PidOverride = 0;
930 hib->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2; // | USB_PORTATTR_NO_OVERCURRENT_UI;
931 }
932 *LengthOfDataReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
933 FUNCTION_EXIT();
934 return STATUS_SUCCESS;
935 }
937 static NTSTATUS
938 XenUsbHub_UBIH_GetRootHubSymbolicName(
939 PVOID BusContext,
940 PVOID HubInformationBuffer,
941 ULONG HubInformationBufferLength,
942 PULONG HubNameActualLength)
943 {
944 NTSTATUS status = STATUS_SUCCESS;
945 WDFDEVICE device = BusContext;
946 FUNCTION_ENTER();
948 KdPrint((__DRIVER_NAME " device = %p\n", device));
949 KdPrint((__DRIVER_NAME " HubInformationBuffer = %p\n", HubInformationBuffer));
950 KdPrint((__DRIVER_NAME " HubInformationBufferLength = %d\n", HubInformationBufferLength));
951 RtlStringCbCopyW(HubInformationBuffer, HubInformationBufferLength, L"ROOT_HUB");
952 *HubNameActualLength = 16;
954 FUNCTION_EXIT();
955 return status;
956 }
958 static PVOID
959 XenUsbHub_UBIH_GetDeviceBusContext(
960 PVOID BusContext,
961 PVOID DeviceHandle)
962 {
963 UNREFERENCED_PARAMETER(BusContext);
964 UNREFERENCED_PARAMETER(DeviceHandle);
966 FUNCTION_ENTER();
968 FUNCTION_EXIT();
969 return NULL;
970 }
972 static NTSTATUS
973 XenUsbHub_UBIH_Initialize20Hub (
974 PVOID BusContext,
975 PUSB_DEVICE_HANDLE HubDeviceHandle,
976 ULONG TtCount)
977 {
978 NTSTATUS status = STATUS_SUCCESS;
979 FUNCTION_ENTER();
980 KdPrint((__DRIVER_NAME " BusContext = %p\n", BusContext));
981 KdPrint((__DRIVER_NAME " HubDeviceHandle = %p\n", HubDeviceHandle));
982 KdPrint((__DRIVER_NAME " TtCount = %d\n", TtCount));
983 FUNCTION_EXIT();
984 return status;
985 }
987 static NTSTATUS
988 XenUsbHub_UBIH_RootHubInitNotification(
989 PVOID BusContext,
990 PVOID CallbackContext,
991 PRH_INIT_CALLBACK CallbackFunction)
992 {
993 NTSTATUS status = STATUS_SUCCESS;
994 WDFDEVICE device = BusContext;
995 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
997 FUNCTION_ENTER();
999 xupdd->BusCallbackFunction = CallbackFunction;
1000 xupdd->BusCallbackContext = CallbackContext;
1002 xupdd->BusCallbackFunction(xupdd->BusCallbackContext);
1004 FUNCTION_EXIT();
1005 return status;
1008 static NTSTATUS
1009 XenUsbHub_UBIH_FlushTransfers(
1010 PVOID BusContext,
1011 PUSB_DEVICE_HANDLE DeviceHandle)
1013 NTSTATUS status = STATUS_SUCCESS;
1015 UNREFERENCED_PARAMETER(BusContext);
1016 UNREFERENCED_PARAMETER(DeviceHandle);
1018 FUNCTION_ENTER();
1020 FUNCTION_EXIT();
1021 return status;
1024 static VOID
1025 XenUsbHub_UBIH_SetDeviceHandleData(
1026 PVOID BusContext,
1027 PUSB_DEVICE_HANDLE DeviceHandle,
1028 PDEVICE_OBJECT UsbDevicePdo)
1030 UNREFERENCED_PARAMETER(BusContext);
1031 UNREFERENCED_PARAMETER(DeviceHandle);
1032 UNREFERENCED_PARAMETER(UsbDevicePdo);
1034 FUNCTION_ENTER();
1035 FUNCTION_EXIT();
1038 static NTSTATUS
1039 XenUsbHub_UBIU_GetUSBDIVersion(
1040 PVOID BusContext,
1041 PUSBD_VERSION_INFORMATION VersionInformation,
1042 PULONG HcdCapabilities
1045 NTSTATUS status = STATUS_UNSUCCESSFUL;
1047 UNREFERENCED_PARAMETER(BusContext);
1048 UNREFERENCED_PARAMETER(VersionInformation);
1049 UNREFERENCED_PARAMETER(HcdCapabilities);
1051 FUNCTION_ENTER();
1053 FUNCTION_EXIT();
1054 return status;
1057 static NTSTATUS
1058 XenUsbHub_UBIU_QueryBusTime(
1059 PVOID BusContext,
1060 PULONG CurrentFrame
1063 NTSTATUS status = STATUS_UNSUCCESSFUL;
1065 UNREFERENCED_PARAMETER(BusContext);
1066 UNREFERENCED_PARAMETER(CurrentFrame);
1068 FUNCTION_ENTER();
1070 FUNCTION_EXIT();
1071 return status;
1074 static NTSTATUS
1075 XenUsbHub_UBIU_SubmitIsoOutUrb(
1076 PVOID BusContext,
1077 PURB Urb
1080 NTSTATUS status = STATUS_UNSUCCESSFUL;
1082 UNREFERENCED_PARAMETER(BusContext);
1083 UNREFERENCED_PARAMETER(Urb);
1085 FUNCTION_ENTER();
1087 FUNCTION_EXIT();
1088 return status;
1091 static NTSTATUS
1092 XenUsbHub_UBIU_QueryBusInformation(
1093 PVOID BusContext,
1094 ULONG Level,
1095 PVOID BusInformationBuffer,
1096 PULONG BusInformationBufferLength,
1097 PULONG BusInformationActualLength)
1099 NTSTATUS status = STATUS_UNSUCCESSFUL;
1101 UNREFERENCED_PARAMETER(BusContext);
1102 UNREFERENCED_PARAMETER(Level);
1103 UNREFERENCED_PARAMETER(BusInformationBuffer);
1104 UNREFERENCED_PARAMETER(BusInformationBufferLength);
1105 UNREFERENCED_PARAMETER(BusInformationActualLength);
1107 FUNCTION_ENTER();
1109 FUNCTION_EXIT();
1110 return status;
1113 static BOOLEAN
1114 XenUsbHub_UBIU_IsDeviceHighSpeed(PVOID BusContext)
1116 UNREFERENCED_PARAMETER(BusContext);
1118 FUNCTION_ENTER();
1120 FUNCTION_EXIT();
1121 return TRUE; //TODO: get port value
1124 static NTSTATUS
1125 XenUsbHub_UBIU_EnumLogEntry(
1126 PVOID BusContext,
1127 ULONG DriverTag,
1128 ULONG EnumTag,
1129 ULONG P1,
1130 ULONG P2
1133 NTSTATUS status = STATUS_SUCCESS;
1134 FUNCTION_ENTER();
1136 UNREFERENCED_PARAMETER(BusContext);
1138 KdPrint((__DRIVER_NAME " DriverTag = %08x\n", DriverTag));
1139 KdPrint((__DRIVER_NAME " EnumTag = %08x\n", EnumTag));
1140 KdPrint((__DRIVER_NAME " P1 = %08x\n", P1));
1141 KdPrint((__DRIVER_NAME " P2 = %08x\n", P2));
1143 FUNCTION_EXIT();
1144 return status;
1147 #if 0
1148 VOID
1149 XenUsb_EnumeratePorts(WDFDEVICE device)
1151 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
1152 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
1153 CHAR path[128];
1154 PCHAR err;
1155 PCHAR value;
1156 ULONG i;
1158 for (i = 0; i < xudd->num_ports; i++)
1160 ULONG port_value;
1161 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/port-%d", xudd->vectors.backend_path, i + 1);
1162 err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
1163 if (err)
1165 XenPci_FreeMem(err);
1166 KdPrint((__DRIVER_NAME " Failed to read port-%d\n", i + 1));
1167 continue;
1169 // 0=disconnected, 1=low_speed, 2=full_speed, 3= high_speed
1170 port_value = (ULONG)parse_numeric_string(value);
1171 XenPci_FreeMem(value);
1172 KdPrint((__DRIVER_NAME " port-%d : %d -> %d\n", i, xudd->ports[i].port_type, port_value));
1173 if (port_value != xudd->ports[i].port_type)
1175 xudd->ports[i].port_type = port_value;
1176 // need to do more than this - probably flush everything and ensure no more activity to the new port until it is set up...
1177 switch (port_value)
1179 case USB_PORT_TYPE_NOT_CONNECTED:
1180 xudd->ports[i].port_status = (1 << PORT_ENABLE);
1181 break;
1182 case USB_PORT_TYPE_LOW_SPEED:
1183 xudd->ports[i].port_status = (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1184 break;
1185 case USB_PORT_TYPE_FULL_SPEED:
1186 xudd->ports[i].port_status = (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1187 break;
1188 case USB_PORT_TYPE_HIGH_SPEED:
1189 xudd->ports[i].port_status = (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
1190 break;
1192 xudd->ports[i].port_change |= (1 << PORT_CONNECTION);
1196 #endif
1198 static VOID
1199 XenUsbHub_HubInterruptTimer(WDFTIMER timer)
1201 NTSTATUS status;
1202 xenusb_endpoint_t *endpoint = *GetEndpoint(timer);
1203 WDFDEVICE pdo_device = endpoint->interface->config->device->pdo_device;
1204 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(pdo_device);
1205 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
1206 WDF_REQUEST_PARAMETERS wrp;
1207 WDFREQUEST request;
1208 PURB urb;
1209 ULONG i;
1211 //FUNCTION_ENTER();
1212 WdfSpinLockAcquire(endpoint->interrupt_lock);
1213 status = WdfIoQueueRetrieveNextRequest(endpoint->interrupt_queue, &request);
1214 if (status == STATUS_NO_MORE_ENTRIES)
1216 WdfTimerStop(timer, FALSE);
1217 WdfSpinLockRelease(endpoint->interrupt_lock);
1218 KdPrint((__DRIVER_NAME " No More Entries\n", status));
1219 //FUNCTION_EXIT();
1220 return;
1222 if (!NT_SUCCESS(status))
1224 WdfTimerStop(timer, FALSE);
1225 WdfSpinLockRelease(endpoint->interrupt_lock);
1226 KdPrint((__DRIVER_NAME " Failed to get request from queue %08x\n", status));
1227 //FUNCTION_EXIT();
1228 return;
1231 WDF_REQUEST_PARAMETERS_INIT(&wrp);
1232 WdfRequestGetParameters(request, &wrp);
1234 urb = (PURB)wrp.Parameters.Others.Arg1;
1235 ASSERT(urb);
1236 ASSERT(urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
1237 RtlZeroMemory(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
1238 if (urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
1240 //urb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
1241 // check for hub change too
1242 //((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] |= 1;
1243 for (i = 0; i < xudd->num_ports; i++)
1245 if (xudd->ports[i].port_change)
1247 KdPrint((__DRIVER_NAME " Port change on port %d - status = %04x, change = %04x\n",
1248 xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change));
1249 ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
1252 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
1253 WdfSpinLockRelease(endpoint->interrupt_lock);
1254 WdfRequestComplete(request, STATUS_SUCCESS);
1256 else
1258 KdPrint((__DRIVER_NAME " Direction mismatch\n"));
1259 urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
1260 WdfSpinLockRelease(endpoint->interrupt_lock);
1261 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
1263 //FUNCTION_EXIT();
1264 return;
1267 NTSTATUS
1268 XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
1269 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
1270 PWDFDEVICE_INIT child_init)
1272 NTSTATUS status = STATUS_SUCCESS;
1273 WDFDEVICE bus_device = WdfChildListGetDevice(child_list);
1274 WDF_OBJECT_ATTRIBUTES child_attributes;
1275 WDFDEVICE child_device;
1276 PXENUSB_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENUSB_PDO_IDENTIFICATION_DESCRIPTION)identification_header;
1277 WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities;
1278 DECLARE_UNICODE_STRING_SIZE(buffer, 512);
1279 DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
1280 PXENUSB_PDO_DEVICE_DATA xupdd;
1281 PXENUSB_DEVICE_DATA xudd = GetXudd(bus_device);
1282 WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
1283 WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities;
1284 WDF_IO_QUEUE_CONFIG queue_config;
1285 WDF_QUERY_INTERFACE_CONFIG interface_config;
1286 USB_BUS_INTERFACE_HUB_V5 ubih;
1287 USB_BUS_INTERFACE_USBDI_V2 ubiu;
1288 WDF_TIMER_CONFIG timer_config;
1289 WDF_OBJECT_ATTRIBUTES timer_attributes;
1291 UNREFERENCED_PARAMETER(xudd);
1293 FUNCTION_ENTER();
1295 //KdPrint((__DRIVER_NAME " device = %d, port = %d, vendor_id = %04x, product_id = %04x\n",
1297 WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN);
1299 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks);
1300 child_pnp_power_callbacks.EvtDeviceD0Entry = XenUsbHub_EvtDeviceD0Entry;
1301 child_pnp_power_callbacks.EvtDeviceD0Exit = XenUsbHub_EvtDeviceD0Exit;
1302 child_pnp_power_callbacks.EvtDevicePrepareHardware = XenUsbHub_EvtDevicePrepareHardware;
1303 child_pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsbHub_EvtDeviceReleaseHardware;
1304 child_pnp_power_callbacks.EvtDeviceUsageNotification = XenUsbHub_EvtDeviceUsageNotification;
1305 WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks);
1307 RtlUnicodeStringPrintf(&buffer, L"USB\\ROOT_HUB");
1308 status = WdfPdoInitAssignDeviceID(child_init, &buffer);
1309 status = WdfPdoInitAddHardwareID(child_init, &buffer);
1311 RtlUnicodeStringPrintf(&buffer, L"VUSB_%d", identification->device_number);
1312 status = WdfPdoInitAssignInstanceID(child_init, &buffer);
1313 if (!NT_SUCCESS(status))
1315 return status;
1318 RtlUnicodeStringPrintf(&buffer, L"PVUSB device #%d", identification->device_number, identification);
1319 status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409);
1320 if (!NT_SUCCESS(status))
1322 return status;
1324 WdfPdoInitSetDefaultLocale(child_init, 0x0409);
1326 WdfDeviceInitSetPowerNotPageable(child_init);
1328 WdfDeviceInitSetIoType(child_init, WdfDeviceIoDirect);
1330 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENUSB_PDO_DEVICE_DATA);
1331 status = WdfDeviceCreate(&child_init, &child_attributes, &child_device);
1332 if (!NT_SUCCESS(status))
1334 return status;
1337 xupdd = GetXupdd(child_device);
1339 xudd->root_hub_device = child_device;
1341 xupdd->wdf_device = child_device;
1342 xupdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
1344 xupdd->usb_device = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
1345 // get address from freelist...
1346 xupdd->usb_device->pdo_device = child_device;
1347 xupdd->usb_device->address = 1;
1348 xupdd->usb_device->device_speed = UsbHighSpeed;
1349 xupdd->usb_device->device_type = Usb20Device;
1350 xupdd->usb_device->device_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
1351 xupdd->usb_device->device_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
1352 xupdd->usb_device->device_descriptor.bcdUSB = 0x0200;
1353 xupdd->usb_device->device_descriptor.bDeviceClass = 9;
1354 xupdd->usb_device->device_descriptor.bDeviceSubClass = 0;
1355 xupdd->usb_device->device_descriptor.bDeviceProtocol = 1;
1356 xupdd->usb_device->device_descriptor.bMaxPacketSize0 = 64;
1357 xupdd->usb_device->device_descriptor.idVendor = 0x0000;
1358 xupdd->usb_device->device_descriptor.idProduct = 0x0000;
1359 xupdd->usb_device->device_descriptor.bcdDevice = 0x0206;
1360 xupdd->usb_device->device_descriptor.iManufacturer = 3;
1361 xupdd->usb_device->device_descriptor.iProduct = 2;
1362 xupdd->usb_device->device_descriptor.iSerialNumber = 1;
1363 xupdd->usb_device->device_descriptor.bNumConfigurations = 1;
1364 xupdd->usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1365 xupdd->usb_device->configs[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1366 xupdd->usb_device->active_config = xupdd->usb_device->configs[0];
1367 xupdd->usb_device->configs[0]->device = xupdd->usb_device;
1368 xupdd->usb_device->configs[0]->config_descriptor.bLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1369 xupdd->usb_device->configs[0]->config_descriptor.bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE;
1370 xupdd->usb_device->configs[0]->config_descriptor.wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1371 xupdd->usb_device->configs[0]->config_descriptor.bNumInterfaces = 1;
1372 xupdd->usb_device->configs[0]->config_descriptor.bConfigurationValue = 1;
1373 xupdd->usb_device->configs[0]->config_descriptor.iConfiguration = 0;
1374 xupdd->usb_device->configs[0]->config_descriptor.bmAttributes = 0xe0;
1375 xupdd->usb_device->configs[0]->config_descriptor.MaxPower = 0;
1376 xupdd->usb_device->configs[0]->interfaces[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
1377 xupdd->usb_device->active_interface = xupdd->usb_device->configs[0]->interfaces[0];
1378 xupdd->usb_device->configs[0]->interfaces[0]->config = xupdd->usb_device->configs[0];
1379 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bLength = 9;
1380 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE;
1381 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceNumber = 0;
1382 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bAlternateSetting = 0;
1383 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bNumEndpoints = 1;
1384 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceClass = 9;
1385 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceSubClass = 0;
1386 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceProtocol = 0;
1387 xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.iInterface = 0;
1388 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
1389 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interface = xupdd->usb_device->configs[0]->interfaces[0];
1390 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->pipe_value = 0;
1391 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bLength = 7;
1392 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
1393 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bEndpointAddress = 0x81; // EP 1 IN
1394 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT;
1395 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.wMaxPacketSize = 2;
1396 xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bInterval = 12;
1397 WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_lock);
1398 WDF_TIMER_CONFIG_INIT(&timer_config, XenUsbHub_HubInterruptTimer);
1399 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timer_attributes, pxenusb_endpoint_t);
1400 timer_attributes.ParentObject = child_device;
1401 status = WdfTimerCreate(&timer_config, &timer_attributes, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer);
1402 if (!NT_SUCCESS(status)) {
1403 KdPrint((__DRIVER_NAME " Error creating timer 0x%x\n", status));
1404 return status;
1406 *GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
1408 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
1409 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
1410 queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
1411 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->urb_queue);
1412 if (!NT_SUCCESS(status)) {
1413 KdPrint((__DRIVER_NAME " Error creating urb_queue 0x%x\n", status));
1414 return status;
1416 WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
1417 queue_config.PowerManaged = TRUE;
1418 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
1419 &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_queue);
1420 if (!NT_SUCCESS(status)) {
1421 KdPrint((__DRIVER_NAME " Error creating timer io_queue 0x%x\n", status));
1422 return status;
1425 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
1426 queue_config.EvtIoInternalDeviceControl = XenUsbHub_EvtIoInternalDeviceControl;
1427 queue_config.EvtIoDeviceControl = XenUsbHub_EvtIoDeviceControl;
1428 queue_config.EvtIoDefault = XenUsbHub_EvtIoDefault;
1429 /* can't be power managed or deadlocks occur */
1430 queue_config.PowerManaged = FALSE;
1431 status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->io_queue);
1432 if (!NT_SUCCESS(status)) {
1433 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
1434 return status;
1437 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
1438 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
1439 WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
1441 WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities);
1442 child_pnp_capabilities.LockSupported = WdfFalse;
1443 child_pnp_capabilities.EjectSupported = WdfTrue;
1444 child_pnp_capabilities.Removable = WdfTrue;
1445 child_pnp_capabilities.DockDevice = WdfFalse;
1446 child_pnp_capabilities.UniqueID = WdfTrue;
1447 child_pnp_capabilities.SilentInstall = WdfTrue;
1448 child_pnp_capabilities.SurpriseRemovalOK = WdfTrue;
1449 child_pnp_capabilities.HardwareDisabled = WdfFalse;
1450 WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities);
1452 WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities);
1453 child_power_capabilities.DeviceD1 = WdfTrue;
1454 child_power_capabilities.WakeFromD1 = WdfTrue;
1455 child_power_capabilities.DeviceWake = PowerDeviceD1;
1456 child_power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD1;
1457 child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
1458 child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
1459 child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
1460 child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
1461 child_power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1462 WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);
1464 ubih.BusContext = child_device;
1465 ubih.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1466 ubih.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1467 ubih.CreateUsbDevice = XenUsbHub_UBIH_CreateUsbDevice;
1468 ubih.InitializeUsbDevice = XenUsbHub_UBIH_InitializeUsbDevice;
1469 ubih.GetUsbDescriptors = XenUsbHub_UBIH_GetUsbDescriptors;
1470 ubih.RemoveUsbDevice = XenUsbHub_UBIH_RemoveUsbDevice;
1471 ubih.RestoreUsbDevice = XenUsbHub_UBIH_RestoreUsbDevice;
1472 ubih.GetPortHackFlags = XenUsbHub_UBIH_GetPortHackFlags;
1473 ubih.QueryDeviceInformation = XenUsbHub_UBIH_QueryDeviceInformation;
1474 ubih.GetControllerInformation = XenUsbHub_UBIH_GetControllerInformation;
1475 ubih.ControllerSelectiveSuspend = XenUsbHub_UBIH_ControllerSelectiveSuspend;
1476 ubih.GetExtendedHubInformation = XenUsbHub_UBIH_GetExtendedHubInformation;
1477 ubih.GetRootHubSymbolicName = XenUsbHub_UBIH_GetRootHubSymbolicName;
1478 ubih.GetDeviceBusContext = XenUsbHub_UBIH_GetDeviceBusContext;
1479 ubih.Initialize20Hub = XenUsbHub_UBIH_Initialize20Hub;
1480 ubih.RootHubInitNotification = XenUsbHub_UBIH_RootHubInitNotification;
1481 ubih.FlushTransfers = XenUsbHub_UBIH_FlushTransfers;
1482 ubih.SetDeviceHandleData = XenUsbHub_UBIH_SetDeviceHandleData;
1483 ubih.Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
1484 ubih.Version = USB_BUSIF_HUB_VERSION_5;
1485 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubih, &USB_BUS_INTERFACE_HUB_GUID, NULL);
1486 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
1487 if (!NT_SUCCESS(status))
1488 return status;
1490 ubiu.BusContext = child_device;
1491 ubiu.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
1492 ubiu.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
1493 ubiu.GetUSBDIVersion = XenUsbHub_UBIU_GetUSBDIVersion;
1494 ubiu.QueryBusTime = XenUsbHub_UBIU_QueryBusTime;
1495 ubiu.SubmitIsoOutUrb = XenUsbHub_UBIU_SubmitIsoOutUrb;
1496 ubiu.QueryBusInformation = XenUsbHub_UBIU_QueryBusInformation;
1497 ubiu.IsDeviceHighSpeed = XenUsbHub_UBIU_IsDeviceHighSpeed;
1498 ubiu.EnumLogEntry = XenUsbHub_UBIU_EnumLogEntry;
1499 ubiu.Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
1500 ubiu.Version = USB_BUSIF_HUB_VERSION_2;
1501 WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubiu, &USB_BUS_INTERFACE_USBDI_GUID, NULL);
1502 status = WdfDeviceAddQueryInterface(child_device, &interface_config);
1503 if (!NT_SUCCESS(status))
1504 return status;
1506 status = WdfDeviceCreateDeviceInterface(child_device, &GUID_DEVINTERFACE_USB_HUB, NULL);
1507 if (!NT_SUCCESS(status))
1508 return status;
1510 FUNCTION_EXIT();
1512 return status;