win-pvdrivers

view xenusb/xenusb_fdo.c @ 752:2ecb5104c33a

usb changes to support device hiding changes
author James Harper <james.harper@bendigoit.com.au>
date Sun Jan 10 10:14:07 2010 +1100 (2010-01-10)
parents 5bdb7251370c
children bbc6c94b9621
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"
22 /* Not really necessary but keeps PREfast happy */
23 static EVT_WDF_DEVICE_D0_ENTRY XenUsb_EvtDeviceD0Entry;
24 static EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
25 static EVT_WDF_DEVICE_D0_EXIT XenUsb_EvtDeviceD0Exit;
26 static EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
27 static EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsb_EvtDevicePrepareHardware;
28 static EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsb_EvtDeviceReleaseHardware;
29 static EVT_WDF_DEVICE_QUERY_REMOVE XenUsb_EvtDeviceQueryRemove;
30 static EVT_WDFDEVICE_WDM_IRP_PREPROCESS XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE;
31 static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL XenUsb_EvtIoDeviceControl;
32 static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl;
33 static EVT_WDF_IO_QUEUE_IO_DEFAULT XenUsb_EvtIoDefault;
34 static EVT_WDF_PROGRAM_DMA XenUsb_ExecuteRequestCallback;
36 static BOOLEAN
37 XenUsb_ExecuteRequestCallback(
38 WDFDMATRANSACTION dma_transaction,
39 WDFDEVICE device,
40 PVOID context,
41 WDF_DMA_DIRECTION direction,
42 PSCATTER_GATHER_LIST sg_list)
43 {
44 usbif_shadow_t *shadow = context;
45 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
46 ULONG i;
47 int notify;
48 KIRQL old_irql;
50 UNREFERENCED_PARAMETER(direction);
51 UNREFERENCED_PARAMETER(dma_transaction);
53 //FUNCTION_ENTER();
55 shadow->req.buffer_length = 0;
56 for (i = 0; i < sg_list->NumberOfElements; i++)
57 {
58 shadow->req.seg[i].gref = (grant_ref_t)(sg_list->Elements->Address.QuadPart >> PAGE_SHIFT);
59 shadow->req.seg[i].offset = (USHORT)sg_list->Elements->Address.LowPart & (PAGE_SIZE - 1);
60 shadow->req.seg[i].length = (USHORT)sg_list->Elements->Length;
61 shadow->req.buffer_length = shadow->req.buffer_length + (USHORT)sg_list->Elements->Length;
62 }
63 shadow->req.nr_buffer_segs = (USHORT)sg_list->NumberOfElements;
64 //KdPrint((__DRIVER_NAME " buffer_length = %d\n", shadow->req.buffer_length));
65 //KdPrint((__DRIVER_NAME " nr_buffer_segs = %d\n", shadow->req.nr_buffer_segs));
67 KeAcquireSpinLock(&xudd->urb_ring_lock, &old_irql);
68 *RING_GET_REQUEST(&xudd->urb_ring, xudd->urb_ring.req_prod_pvt) = shadow->req;
69 xudd->urb_ring.req_prod_pvt++;
70 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
71 if (notify)
72 {
73 //KdPrint((__DRIVER_NAME " Notifying\n"));
74 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
75 }
76 KeReleaseSpinLock(&xudd->urb_ring_lock, old_irql);
78 //FUNCTION_EXIT();
80 return TRUE;
81 }
83 NTSTATUS
84 XenUsb_ExecuteRequest(
85 PXENUSB_DEVICE_DATA xudd,
86 usbif_shadow_t *shadow,
87 PVOID transfer_buffer,
88 PMDL transfer_buffer_mdl,
89 ULONG transfer_buffer_length)
90 {
91 NTSTATUS status;
92 KIRQL old_irql;
93 PMDL mdl;
94 int notify;
96 //FUNCTION_ENTER();
98 //KdPrint((__DRIVER_NAME " transfer_buffer_length = %d\n", transfer_buffer_length));
99 shadow->total_length = 0;
100 if (!transfer_buffer_length)
101 {
102 shadow->mdl = NULL;
103 shadow->dma_transaction = NULL;
104 shadow->req.nr_buffer_segs = 0;
105 shadow->req.buffer_length = 0;
107 KeAcquireSpinLock(&xudd->urb_ring_lock, &old_irql);
108 *RING_GET_REQUEST(&xudd->urb_ring, xudd->urb_ring.req_prod_pvt) = shadow->req;
109 xudd->urb_ring.req_prod_pvt++;
110 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
111 if (notify)
112 {
113 //KdPrint((__DRIVER_NAME " Notifying\n"));
114 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
115 }
116 KeReleaseSpinLock(&xudd->urb_ring_lock, old_irql);
117 //FUNCTION_EXIT();
118 return STATUS_SUCCESS;
119 }
120 ASSERT(transfer_buffer || transfer_buffer_mdl);
121 if (transfer_buffer)
122 {
123 mdl = IoAllocateMdl(transfer_buffer, transfer_buffer_length, FALSE, FALSE, NULL);
124 ASSERT(mdl);
125 MmBuildMdlForNonPagedPool(mdl);
126 shadow->mdl = mdl;
127 }
128 else
129 {
130 if (!MmGetMdlVirtualAddress(transfer_buffer_mdl))
131 {
132 /* WdfDmaTransactionInitialize has a bug where it crashes on VirtualAddress == 0 */
133 PVOID addr = MmGetSystemAddressForMdlSafe(transfer_buffer_mdl, LowPagePriority);
134 //KdPrint((__DRIVER_NAME " Mapping MDL with NULL VA to work around bug in WdfDmaTransactionInitialize\n"));
135 if (!addr)
136 {
137 KdPrint((__DRIVER_NAME " Could not map MDL\n"));
138 return STATUS_INSUFFICIENT_RESOURCES;
139 }
140 mdl = IoAllocateMdl(addr, transfer_buffer_length, FALSE, FALSE, NULL);
141 ASSERT(mdl);
142 MmBuildMdlForNonPagedPool(mdl);
143 shadow->mdl = mdl;
144 }
145 else
146 {
147 mdl = transfer_buffer_mdl;
148 shadow->mdl = NULL;
149 }
150 }
151 status = WdfDmaTransactionCreate(xudd->dma_enabler, WDF_NO_OBJECT_ATTRIBUTES, &shadow->dma_transaction);
152 if (!NT_SUCCESS(status))
153 {
154 KdPrint((__DRIVER_NAME " WdfDmaTransactionCreate status = %08x\n", status));
155 if (shadow->mdl)
156 {
157 IoFreeMdl(shadow->mdl);
158 }
159 FUNCTION_EXIT();
160 return status;
161 }
163 ASSERT(shadow->dma_transaction);
164 ASSERT(mdl);
165 ASSERT(transfer_buffer_length);
167 status = WdfDmaTransactionInitialize(
168 shadow->dma_transaction,
169 XenUsb_ExecuteRequestCallback,
170 (shadow->req.pipe & LINUX_PIPE_DIRECTION_IN)?WdfDmaDirectionReadFromDevice:WdfDmaDirectionWriteToDevice,
171 mdl,
172 MmGetMdlVirtualAddress(mdl),
173 transfer_buffer_length);
174 if (!NT_SUCCESS(status))
175 {
176 KdPrint((__DRIVER_NAME " WdfDmaTransactionInitialize status = %08x\n", status));
177 WdfObjectDelete(shadow->dma_transaction);
178 if (shadow->mdl)
179 {
180 IoFreeMdl(shadow->mdl);
181 }
182 //FUNCTION_EXIT();
183 return status;
184 }
185 WdfDmaTransactionSetMaximumLength(shadow->dma_transaction, (USBIF_MAX_SEGMENTS_PER_REQUEST - 1) * PAGE_SIZE);
186 status = WdfDmaTransactionExecute(shadow->dma_transaction, shadow);
187 if (!NT_SUCCESS(status))
188 {
189 KdPrint((__DRIVER_NAME " WdfDmaTransactionExecute status = %08x\n", status));
190 WdfObjectDelete(shadow->dma_transaction);
191 if (shadow->mdl)
192 {
193 IoFreeMdl(shadow->mdl);
194 }
195 //FUNCTION_EXIT();
196 return status;
197 }
198 //FUNCTION_EXIT();
199 return status;
200 }
202 NTSTATUS
203 XenUsb_EvtDeviceQueryRemove(WDFDEVICE device)
204 {
205 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
206 NTSTATUS status = STATUS_SUCCESS;
208 UNREFERENCED_PARAMETER(device);
210 FUNCTION_ENTER();
211 FUNCTION_EXIT();
212 return status;
213 }
215 static NTSTATUS
216 XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
217 {
218 PIO_STACK_LOCATION stack;
220 FUNCTION_ENTER();
222 stack = IoGetCurrentIrpStackLocation(irp);
224 if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
225 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_HUB_GUID\n"));
226 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
227 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_USBDI_GUID\n"));
228 else
229 KdPrint((__DRIVER_NAME " GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
230 stack->Parameters.QueryInterface.InterfaceType->Data1,
231 stack->Parameters.QueryInterface.InterfaceType->Data2,
232 stack->Parameters.QueryInterface.InterfaceType->Data3,
233 (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
234 stack->Parameters.QueryInterface.InterfaceType->Data4[1],
235 stack->Parameters.QueryInterface.InterfaceType->Data4[2],
236 stack->Parameters.QueryInterface.InterfaceType->Data4[3],
237 stack->Parameters.QueryInterface.InterfaceType->Data4[4],
238 stack->Parameters.QueryInterface.InterfaceType->Data4[5],
239 stack->Parameters.QueryInterface.InterfaceType->Data4[6],
240 stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
242 KdPrint((__DRIVER_NAME " Size = %d\n", stack->Parameters.QueryInterface.Size));
243 KdPrint((__DRIVER_NAME " Version = %d\n", stack->Parameters.QueryInterface.Version));
244 KdPrint((__DRIVER_NAME " Interface = %p\n", stack->Parameters.QueryInterface.Interface));
247 IoSkipCurrentIrpStackLocation(irp);
249 FUNCTION_EXIT();
251 return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
252 }
254 /* called at DISPATCH_LEVEL */
255 static BOOLEAN
256 XenUsb_HandleEvent(PVOID context)
257 {
258 PXENUSB_DEVICE_DATA xudd = context;
259 RING_IDX prod, cons;
260 usbif_urb_response_t *urb_rsp;
261 usbif_conn_response_t *conn_rsp;
262 usbif_conn_request_t *conn_req;
263 int more_to_do;
264 usbif_shadow_t *complete_head = NULL, *complete_tail = NULL;
265 usbif_shadow_t *shadow;
267 //FUNCTION_ENTER();
269 more_to_do = TRUE;
270 KeAcquireSpinLockAtDpcLevel(&xudd->urb_ring_lock);
271 while (more_to_do)
272 {
273 prod = xudd->urb_ring.sring->rsp_prod;
274 KeMemoryBarrier();
275 for (cons = xudd->urb_ring.rsp_cons; cons != prod; cons++)
276 {
277 urb_rsp = RING_GET_RESPONSE(&xudd->urb_ring, cons);
278 shadow = &xudd->shadows[urb_rsp->id];
279 ASSERT(shadow->callback);
280 shadow->rsp = *urb_rsp;
281 shadow->next = NULL;
282 shadow->total_length += urb_rsp->actual_length;
283 #if 0
284 KdPrint((__DRIVER_NAME " rsp id = %d\n", shadow->rsp.id));
285 KdPrint((__DRIVER_NAME " rsp start_frame = %d\n", shadow->rsp.start_frame));
286 KdPrint((__DRIVER_NAME " rsp status = %d\n", shadow->rsp.status));
287 KdPrint((__DRIVER_NAME " rsp actual_length = %d\n", shadow->rsp.actual_length));
288 KdPrint((__DRIVER_NAME " rsp error_count = %d\n", shadow->rsp.error_count));
289 KdPrint((__DRIVER_NAME " total_length = %d\n", shadow->total_length));
290 #endif
291 if (complete_tail)
292 {
293 complete_tail->next = shadow;
294 }
295 else
296 {
297 complete_head = shadow;
298 }
299 complete_tail = shadow;
300 }
302 xudd->urb_ring.rsp_cons = cons;
303 if (cons != xudd->urb_ring.req_prod_pvt)
304 {
305 RING_FINAL_CHECK_FOR_RESPONSES(&xudd->urb_ring, more_to_do);
306 }
307 else
308 {
309 xudd->urb_ring.sring->rsp_event = cons + 1;
310 more_to_do = FALSE;
311 }
312 }
313 KeReleaseSpinLockFromDpcLevel(&xudd->urb_ring_lock);
315 more_to_do = TRUE;
316 KeAcquireSpinLockAtDpcLevel(&xudd->conn_ring_lock);
317 while (more_to_do)
318 {
319 prod = xudd->conn_ring.sring->rsp_prod;
320 KeMemoryBarrier();
321 for (cons = xudd->conn_ring.rsp_cons; cons != prod; cons++)
322 {
323 conn_rsp = RING_GET_RESPONSE(&xudd->conn_ring, cons);
324 KdPrint((__DRIVER_NAME " conn_rsp->portnum = %d\n", conn_rsp->portnum));
325 KdPrint((__DRIVER_NAME " conn_rsp->speed = %d\n", conn_rsp->speed));
327 xudd->ports[conn_rsp->portnum].port_type = conn_rsp->speed;
328 switch (conn_rsp->speed)
329 {
330 case USB_PORT_TYPE_NOT_CONNECTED:
331 xudd->ports[conn_rsp->portnum].port_status = (1 << PORT_ENABLE);
332 break;
333 case USB_PORT_TYPE_LOW_SPEED:
334 xudd->ports[conn_rsp->portnum].port_status = (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
335 break;
336 case USB_PORT_TYPE_FULL_SPEED:
337 xudd->ports[conn_rsp->portnum].port_status = (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
338 break;
339 case USB_PORT_TYPE_HIGH_SPEED:
340 xudd->ports[conn_rsp->portnum].port_status = (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
341 break;
342 }
343 xudd->ports[conn_rsp->portnum].port_change |= (1 << PORT_CONNECTION);
345 // notify pending interrupt urb?
347 conn_req = RING_GET_REQUEST(&xudd->conn_ring, xudd->conn_ring.req_prod_pvt);
348 conn_req->id = conn_rsp->id;
349 xudd->conn_ring.req_prod_pvt++;
350 }
352 xudd->conn_ring.rsp_cons = cons;
353 if (cons != xudd->conn_ring.req_prod_pvt)
354 {
355 RING_FINAL_CHECK_FOR_RESPONSES(&xudd->conn_ring, more_to_do);
356 }
357 else
358 {
359 xudd->conn_ring.sring->rsp_event = cons + 1;
360 more_to_do = FALSE;
361 }
362 }
363 KeReleaseSpinLockFromDpcLevel(&xudd->conn_ring_lock);
365 shadow = complete_head;
366 while (shadow != NULL)
367 {
368 if (shadow->dma_transaction)
369 {
370 NTSTATUS status;
371 BOOLEAN dma_complete;
372 if (shadow->rsp.status != 0 || shadow->rsp.actual_length != shadow->req.buffer_length)
373 {
374 WdfDmaTransactionDmaCompletedFinal(shadow->dma_transaction, shadow->total_length, &status);
375 WdfObjectDelete(shadow->dma_transaction);
376 if (shadow->mdl)
377 {
378 IoFreeMdl(shadow->mdl);
379 }
380 shadow->callback(shadow);
381 }
382 else
383 {
384 dma_complete = WdfDmaTransactionDmaCompleted(shadow->dma_transaction, &status);
385 if (dma_complete)
386 {
387 WdfObjectDelete(shadow->dma_transaction);
388 if (shadow->mdl)
389 {
390 IoFreeMdl(shadow->mdl);
391 }
392 shadow->callback(shadow);
393 }
394 }
395 }
396 else
397 {
398 shadow->callback(shadow);
399 }
400 shadow = shadow->next;
401 }
402 //FUNCTION_EXIT();
404 return TRUE;
405 }
407 static NTSTATUS
408 XenUsb_StartXenbusInit(PXENUSB_DEVICE_DATA xudd)
409 {
410 PUCHAR ptr;
411 USHORT type;
412 PCHAR setting, value, value2;
414 xudd->urb_sring = NULL;
415 xudd->event_channel = 0;
417 ptr = xudd->config_page;
418 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
419 {
420 switch(type)
421 {
422 case XEN_INIT_TYPE_READ_STRING_BACK:
423 case XEN_INIT_TYPE_READ_STRING_FRONT:
424 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
425 break;
426 case XEN_INIT_TYPE_VECTORS:
427 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
428 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
429 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
430 {
431 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
432 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
433 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
434 return STATUS_UNSUCCESSFUL;
435 }
436 else
437 memcpy(&xudd->vectors, value, sizeof(XENPCI_VECTORS));
438 break;
439 case XEN_INIT_TYPE_STATE_PTR:
440 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
441 xudd->device_state = (PXENPCI_DEVICE_STATE)value;
442 break;
443 #if 0
444 case XEN_INIT_TYPE_GRANT_ENTRIES:
445 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
446 memcpy(xudd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
447 break;
448 #endif
449 default:
450 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
451 break;
452 }
453 }
455 return STATUS_SUCCESS;
456 }
458 static NTSTATUS
459 XenUsb_CompleteXenbusInit(PXENUSB_DEVICE_DATA xudd)
460 {
461 PUCHAR ptr;
462 USHORT type;
463 PCHAR setting, value, value2;
464 ULONG i;
466 ptr = xudd->config_page;
467 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
468 {
469 switch(type)
470 {
471 case XEN_INIT_TYPE_RING: /* frontend ring */
472 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
473 if (strcmp(setting, "urb-ring-ref") == 0)
474 {
475 xudd->urb_sring = (usbif_urb_sring_t *)value;
476 FRONT_RING_INIT(&xudd->urb_ring, xudd->urb_sring, PAGE_SIZE);
477 }
478 if (strcmp(setting, "conn-ring-ref") == 0)
479 {
480 xudd->conn_sring = (usbif_conn_sring_t *)value;
481 FRONT_RING_INIT(&xudd->conn_ring, xudd->conn_sring, PAGE_SIZE);
482 }
483 break;
484 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
485 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL_DPC - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
486 if (strcmp(setting, "event-channel") == 0)
487 {
488 xudd->event_channel = PtrToUlong(value);
489 }
490 break;
491 case XEN_INIT_TYPE_READ_STRING_BACK:
492 case XEN_INIT_TYPE_READ_STRING_FRONT:
493 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
494 break;
495 default:
496 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
497 break;
498 }
499 }
500 if (xudd->urb_sring == NULL || xudd->conn_sring == NULL || xudd->event_channel == 0)
501 {
502 KdPrint((__DRIVER_NAME " Missing settings\n"));
503 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
504 return STATUS_UNSUCCESSFUL;
505 }
507 xudd->shadow_free = 0;
508 memset(xudd->shadows, 0, sizeof(usbif_shadow_t) * SHADOW_ENTRIES);
509 for (i = 0; i < SHADOW_ENTRIES; i++)
510 {
511 xudd->shadows[i].id = (uint16_t)i;
512 put_shadow_on_freelist(xudd, &xudd->shadows[i]);
513 }
515 return STATUS_SUCCESS;
516 }
518 NTSTATUS
519 XenUsb_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
520 {
521 NTSTATUS status = STATUS_SUCCESS;
522 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
523 PCM_PARTIAL_RESOURCE_DESCRIPTOR raw_descriptor, translated_descriptor;
524 ULONG i;
525 PUCHAR ptr;
527 FUNCTION_ENTER();
529 ASSERT(WdfCmResourceListGetCount(resources_raw) == WdfCmResourceListGetCount(resources_translated));
531 for (i = 0; i < WdfCmResourceListGetCount(resources_raw); i++)
532 {
533 raw_descriptor = WdfCmResourceListGetDescriptor(resources_raw, i);
534 translated_descriptor = WdfCmResourceListGetDescriptor(resources_translated, i);
535 switch (raw_descriptor->Type) {
536 case CmResourceTypePort:
537 KdPrint((__DRIVER_NAME " IoPort Address(%x) Length: %d\n", translated_descriptor->u.Port.Start.LowPart, translated_descriptor->u.Port.Length));
538 break;
539 case CmResourceTypeMemory:
540 KdPrint((__DRIVER_NAME " Memory (%x:%x) Length:(%d)\n", translated_descriptor->u.Memory.Start.LowPart, translated_descriptor->u.Memory.Start.HighPart, translated_descriptor->u.Memory.Length));
541 KdPrint((__DRIVER_NAME " Memory flags = %04X\n", translated_descriptor->Flags));
542 xudd->config_page = MmMapIoSpace(translated_descriptor->u.Memory.Start, translated_descriptor->u.Memory.Length, MmNonCached);
543 KdPrint((__DRIVER_NAME " Memory mapped to %p\n", xudd->config_page));
544 break;
545 case CmResourceTypeInterrupt:
546 KdPrint((__DRIVER_NAME " irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector));
547 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", translated_descriptor->u.Interrupt.Vector));
548 KdPrint((__DRIVER_NAME " irq_level = %03x\n", translated_descriptor->u.Interrupt.Level));
549 break;
550 case CmResourceTypeDevicePrivate:
551 KdPrint((__DRIVER_NAME " Private Data: 0x%02x 0x%02x 0x%02x\n", translated_descriptor->u.DevicePrivate.Data[0], translated_descriptor->u.DevicePrivate.Data[1], translated_descriptor->u.DevicePrivate.Data[2]));
552 break;
553 default:
554 KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", translated_descriptor->Type));
555 break;
556 }
557 }
559 #if 0
560 *** No owner thread found for resource 808a5920
561 *** No owner thread found for resource 808a5920
562 *** No owner thread found for resource 808a5920
563 *** No owner thread found for resource 808a5920
564 Probably caused by : USBSTOR.SYS ( USBSTOR!USBSTOR_SyncSendUsbRequest+77 )
566 f78e27a4 8081df53 809c560e f78e27c4 809c560e nt!IovCallDriver+0x82
567 f78e27b0 809c560e 80a5ff00 82b431a8 00000000 nt!IofCallDriver+0x13
568 f78e27c4 809b550c 82b431a8 8454ef00 8454ef00 nt!ViFilterDispatchGeneric+0x2a
569 f78e27f4 8081df53 bac7818a f78e2808 bac7818a nt!IovCallDriver+0x112
570 f78e2800 bac7818a f78e282c bac79d3c 8454ef00 nt!IofCallDriver+0x13
571 f78e2808 bac79d3c 8454ef00 82b431a8 80a5ff00 usbhub!USBH_PassIrp+0x18
572 f78e282c bac79f08 822ea7c0 8454ef00 f78e286c usbhub!USBH_FdoDispatch+0x4c
573 f78e283c 809b550c 822ea708 8454ef00 8454efb0 usbhub!USBH_HubDispatch+0x5e
574 f78e286c 8081df53 809c560e f78e288c 809c560e nt!IovCallDriver+0x112
575 f78e2878 809c560e 80a5ff00 8233dad0 00000000 nt!IofCallDriver+0x13
576 f78e288c 809b550c 8233dad0 8454ef00 8454efd4 nt!ViFilterDispatchGeneric+0x2a
577 f78e28bc 8081df53 bac7c15e f78e28e0 bac7c15e nt!IovCallDriver+0x112
578 f78e28c8 bac7c15e 822ea7c0 81f98df8 8454ef00 nt!IofCallDriver+0x13
579 f78e28e0 bac7ca33 822ea7c0 8454ef00 80a5ff00 usbhub!USBH_PdoUrbFilter+0x14c
580 f78e2900 bac79ef2 8380cfb0 8454ef00 f78e2940 usbhub!USBH_PdoDispatch+0x211
581 f78e2910 809b550c 81f98d40 8454ef00 82334c80 usbhub!USBH_HubDispatch+0x48
582 f78e2940 8081df53 ba2ed27d f78e2978 ba2ed27d nt!IovCallDriver+0x112
583 f78e294c ba2ed27d 82334bc8 8380cfb0 82334c80 nt!IofCallDriver+0x13
584 f78e2978 ba2ed570 82334bc8 8380cfb0 00000000 USBSTOR!USBSTOR_SyncSendUsbRequest+0x77
585 f78e29ac ba2ee0a4 82334bc8 82334bc8 82334c80 USBSTOR!USBSTOR_SelectConfiguration+0x7e
586 f78e29ec ba2ee1e8 82334bc8 83caced8 80a5ff00 USBSTOR!USBSTOR_FdoStartDevice+0x68
587 f78e2a04 809b550c 82334bc8 83caced8 83cacffc USBSTOR!USBSTOR_Pnp+0x5a
588 f78e2a34 8081df53 8090d728 f78e2a6c 8090d728 nt!IovCallDriver+0x112
589 f78e2a40 8090d728 f78e2aac 81f98d40 00000000 nt!IofCallDriver+0x13
590 f78e2a6c 8090d7bb 82334bc8 f78e2a88 00000000 nt!IopSynchronousCall+0xb8
591 f78e2ab0 8090a684 81f98d40 823c71a8 00000001 nt!IopStartDevice+0x4d
592 f78e2acc 8090cd9d 81f98d40 00000001 823c71a8 nt!PipProcessStartPhase1+0x4e
593 f78e2d24 8090d21c 82403628 00000001 00000000 nt!PipProcessDevNodeTree+0x1db
594 f78e2d58 80823345 00000003 82d06020 808ae5fc nt!PiProcessReenumeration+0x60
595 f78e2d80 80880469 00000000 00000000 82d06020 nt!PipDeviceActionWorker+0x16b
596 f78e2dac 80949b7c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
597 f78e2ddc 8088e092 8088037e 00000001 00000000 nt!PspSystemThreadStartup+0x2e
598 #endif
600 status = XenUsb_StartXenbusInit(xudd);
602 ptr = xudd->config_page;
603 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
604 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
605 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "urb-ring-ref", NULL, NULL);
606 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "conn-ring-ref", NULL, NULL);
607 #pragma warning(suppress:4054)
608 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenUsb_HandleEvent, xudd);
609 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
610 status = xudd->vectors.XenPci_XenConfigDevice(xudd->vectors.context);
612 status = XenUsb_CompleteXenbusInit(xudd);
614 FUNCTION_EXIT();
616 return status;
617 }
619 NTSTATUS
620 XenUsb_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
621 {
622 NTSTATUS status = STATUS_SUCCESS;
623 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
624 ULONG i;
625 int notify;
626 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
628 UNREFERENCED_PARAMETER(device);
630 FUNCTION_ENTER();
632 switch (previous_state)
633 {
634 case WdfPowerDeviceD0:
635 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
636 break;
637 case WdfPowerDeviceD1:
638 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
639 break;
640 case WdfPowerDeviceD2:
641 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
642 break;
643 case WdfPowerDeviceD3:
644 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
645 break;
646 case WdfPowerDeviceD3Final:
647 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
648 break;
649 case WdfPowerDevicePrepareForHibernation:
650 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
651 break;
652 default:
653 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
654 break;
655 }
657 /* fill conn ring with requests */
658 for (i = 0; i < USB_CONN_RING_SIZE; i++)
659 {
660 usbif_conn_request_t *req = RING_GET_REQUEST(&xudd->conn_ring, i);
661 req->id = (uint16_t)i;
662 }
663 xudd->conn_ring.req_prod_pvt = i;
665 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
666 if (notify)
667 {
668 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
669 }
671 FUNCTION_EXIT();
673 return status;
674 }
676 NTSTATUS
677 XenUsb_EvtDeviceD0EntryPostInterruptsEnabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
678 {
679 NTSTATUS status = STATUS_SUCCESS;
680 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
682 UNREFERENCED_PARAMETER(device);
683 UNREFERENCED_PARAMETER(previous_state);
685 FUNCTION_ENTER();
687 FUNCTION_EXIT();
689 return status;
690 }
692 NTSTATUS
693 XenUsb_EvtDeviceD0ExitPreInterruptsDisabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
694 {
695 NTSTATUS status = STATUS_SUCCESS;
697 UNREFERENCED_PARAMETER(device);
699 FUNCTION_ENTER();
701 switch (target_state)
702 {
703 case WdfPowerDeviceD0:
704 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
705 break;
706 case WdfPowerDeviceD1:
707 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
708 break;
709 case WdfPowerDeviceD2:
710 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
711 break;
712 case WdfPowerDeviceD3:
713 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
714 break;
715 case WdfPowerDeviceD3Final:
716 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
717 break;
718 case WdfPowerDevicePrepareForHibernation:
719 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
720 break;
721 default:
722 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
723 break;
724 }
726 FUNCTION_EXIT();
728 return status;
729 }
731 NTSTATUS
732 XenUsb_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
733 {
734 NTSTATUS status = STATUS_SUCCESS;
735 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
737 FUNCTION_ENTER();
739 UNREFERENCED_PARAMETER(device);
741 switch (target_state)
742 {
743 case WdfPowerDeviceD0:
744 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
745 break;
746 case WdfPowerDeviceD1:
747 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
748 break;
749 case WdfPowerDeviceD2:
750 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
751 break;
752 case WdfPowerDeviceD3:
753 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
754 break;
755 case WdfPowerDeviceD3Final:
756 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
757 break;
758 case WdfPowerDevicePrepareForHibernation:
759 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
760 break;
761 default:
762 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
763 break;
764 }
766 FUNCTION_EXIT();
768 return status;
769 }
771 NTSTATUS
772 XenUsb_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
773 {
774 NTSTATUS status = STATUS_SUCCESS;
776 UNREFERENCED_PARAMETER(device);
777 UNREFERENCED_PARAMETER(resources_translated);
779 FUNCTION_ENTER();
780 FUNCTION_EXIT();
782 return status;
783 }
785 VOID
786 XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list)
787 {
788 NTSTATUS status;
789 PXENUSB_DEVICE_DATA xudd = GetXudd(WdfChildListGetDevice(child_list));
790 XENUSB_PDO_IDENTIFICATION_DESCRIPTION child_description;
791 CHAR path[128];
792 PCHAR err;
793 PCHAR value;
794 ULONG i;
796 FUNCTION_ENTER();
798 WdfChildListBeginScan(child_list);
800 // hold the queue on each device and set each device to a pending state
801 // read backend/num_ports
802 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/num-ports", xudd->vectors.backend_path);
803 err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
804 if (err)
805 {
806 XenPci_FreeMem(err);
807 WdfChildListEndScan(child_list);
808 KdPrint((__DRIVER_NAME " Failed to read num-ports\n"));
809 return;
810 }
811 xudd->num_ports = (ULONG)parse_numeric_string(value);
812 XenPci_FreeMem(value);
813 KdPrint((__DRIVER_NAME " num-ports = %d\n", xudd->num_ports));
815 for (i = 0; i < 8; i++)
816 {
817 xudd->ports[i].port_number = i + 1;
818 xudd->ports[i].port_type = USB_PORT_TYPE_NOT_CONNECTED;
819 xudd->ports[i].port_status = 1 << PORT_ENABLE;
820 xudd->ports[i].port_change = 0x0000;
821 }
823 /* only a single root hub is enumerated */
824 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description));
826 child_description.device_number = 0; //TODO: get the proper index from parent
828 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL);
829 if (!NT_SUCCESS(status))
830 {
831 KdPrint((__DRIVER_NAME " WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status));
832 }
834 WdfChildListEndScan(child_list);
836 FUNCTION_EXIT();
837 }
839 static VOID
840 XenUsb_EvtIoDeviceControl(
841 WDFQUEUE queue,
842 WDFREQUEST request,
843 size_t output_buffer_length,
844 size_t input_buffer_length,
845 ULONG io_control_code)
846 {
847 NTSTATUS status;
848 WDFDEVICE device = WdfIoQueueGetDevice(queue);
849 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
850 //WDF_REQUEST_PARAMETERS wrp;
851 //PURB urb;
852 //xenusb_device_t *usb_device;
854 UNREFERENCED_PARAMETER(queue);
855 UNREFERENCED_PARAMETER(input_buffer_length);
856 UNREFERENCED_PARAMETER(output_buffer_length);
858 FUNCTION_ENTER();
860 status = STATUS_UNSUCCESSFUL;
862 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
863 //WdfRequestGetParameters(request, &wrp);
865 // these are in api\usbioctl.h
866 switch(io_control_code)
867 {
868 #if 0
869 case IOCTL_USB_GET_NODE_INFORMATION:
870 {
871 PUSB_NODE_INFORMATION uni;
872 size_t length;
874 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
875 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
876 // make sure size is >= bDescriptorLength
877 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uni, &length);
878 if (NT_SUCCESS(status))
879 {
880 switch(uni->NodeType)
881 {
882 case UsbHub:
883 KdPrint((__DRIVER_NAME " NodeType = UsbHub\n"));
884 uni->u.HubInformation.HubDescriptor.bDescriptorLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask) + 3;
885 if (output_buffer_length >= FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3)
886 {
887 uni->u.HubInformation.HubDescriptor.bDescriptorType = 0x29;
888 uni->u.HubInformation.HubDescriptor.bNumberOfPorts = 8;
889 uni->u.HubInformation.HubDescriptor.wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
890 uni->u.HubInformation.HubDescriptor.bPowerOnToPowerGood = 1; // 2ms units
891 uni->u.HubInformation.HubDescriptor.bHubControlCurrent = 0;
892 // DeviceRemovable bits (includes an extra bit at the start)
893 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[0] = 0;
894 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[1] = 0;
895 // PortPwrCtrlMask
896 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[2] = 0xFF;
897 uni->u.HubInformation.HubIsBusPowered = TRUE;
898 }
899 WdfRequestSetInformation(request, FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3);
900 break;
901 case UsbMIParent:
902 KdPrint((__DRIVER_NAME " NodeType = UsbMIParent\n"));
903 status = STATUS_UNSUCCESSFUL;
904 break;
905 }
906 }
907 else
908 {
909 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
910 }
911 break;
912 }
913 #endif
914 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
915 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
916 break;
917 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
918 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
919 break;
920 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
921 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
922 break;
923 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
924 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
925 break;
926 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
927 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
928 break;
929 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
930 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
931 break;
932 case IOCTL_USB_GET_HUB_CAPABILITIES:
933 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
934 break;
935 case IOCTL_USB_HUB_CYCLE_PORT:
936 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
937 break;
938 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
939 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
940 break;
941 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
942 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
943 break;
944 case IOCTL_USB_GET_ROOT_HUB_NAME:
945 {
946 PUSB_HCD_DRIVERKEY_NAME uhdn;
947 size_t length;
948 ULONG required_length = 0;
950 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_ROOT_HUB_NAME\n"));
951 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
953 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
954 status = STATUS_BUFFER_TOO_SMALL;
955 else
956 {
957 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
958 if (NT_SUCCESS(status))
959 {
960 WDFSTRING symbolic_link_wdfstring;
961 UNICODE_STRING symbolic_link;
963 uhdn->DriverKeyName[0] = 0;
964 status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolic_link_wdfstring);
965 status = WdfDeviceRetrieveDeviceInterfaceString(xudd->root_hub_device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolic_link_wdfstring);
966 if (NT_SUCCESS(status))
967 {
968 WdfStringGetUnicodeString(symbolic_link_wdfstring, &symbolic_link);
969 /* remove leading \??\ from name */
970 symbolic_link.Buffer += 4;
971 symbolic_link.Length -= 4 * sizeof(WCHAR);
972 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + symbolic_link.Length + sizeof(WCHAR);
973 uhdn->ActualLength = required_length;
974 if (output_buffer_length >= required_length)
975 {
976 memcpy(uhdn->DriverKeyName, symbolic_link.Buffer, symbolic_link.Length);
977 uhdn->DriverKeyName[symbolic_link.Length / 2] = 0;
978 }
979 }
980 else
981 {
982 KdPrint((__DRIVER_NAME " WdfDeviceRetrieveDeviceInterfaceString = %08x\n", status));
983 status = STATUS_INVALID_PARAMETER;
984 }
985 }
986 else
987 {
988 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
989 }
990 KdPrint((__DRIVER_NAME " uhdn->ActualLength = %d\n", uhdn->ActualLength));
991 KdPrint((__DRIVER_NAME " uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName));
992 WdfRequestSetInformation(request, required_length);
993 }
994 break;
995 }
996 case IOCTL_GET_HCD_DRIVERKEY_NAME:
997 {
998 PUSB_HCD_DRIVERKEY_NAME uhdn;
999 size_t length;
1000 ULONG required_length = 0;
1002 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME\n"));
1003 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
1005 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
1006 status = STATUS_BUFFER_TOO_SMALL;
1007 else
1009 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
1010 if (NT_SUCCESS(status))
1012 ULONG key_length;
1013 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName, 0, NULL, &key_length);
1014 KdPrint((__DRIVER_NAME " key_length = %d\n", key_length));
1015 status = STATUS_SUCCESS;
1016 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + key_length;
1017 uhdn->ActualLength = required_length;
1018 if (output_buffer_length >= required_length)
1020 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName,
1021 required_length - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), uhdn->DriverKeyName,
1022 &key_length);
1024 else
1026 uhdn->DriverKeyName[0] = 0;
1029 else
1031 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
1033 KdPrint((__DRIVER_NAME " uhdn->ActualLength = %d\n", uhdn->ActualLength));
1034 KdPrint((__DRIVER_NAME " uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName));
1035 WdfRequestSetInformation(request, required_length);
1037 break;
1039 #if 0
1040 case IOCTL_USB_RESET_HUB:
1041 KdPrint((__DRIVER_NAME " IOCTL_USB_RESET_HUB\n"));
1042 break;
1043 #endif
1044 default:
1045 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
1046 break;
1048 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
1049 WdfRequestComplete(request, status);
1051 FUNCTION_EXIT();
1054 static VOID
1055 XenUsb_EvtIoInternalDeviceControl(
1056 WDFQUEUE queue,
1057 WDFREQUEST request,
1058 size_t output_buffer_length,
1059 size_t input_buffer_length,
1060 ULONG io_control_code)
1062 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
1063 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
1064 PURB urb;
1065 xenusb_device_t *usb_device;
1066 WDF_REQUEST_PARAMETERS wrp;
1068 UNREFERENCED_PARAMETER(queue);
1069 UNREFERENCED_PARAMETER(input_buffer_length);
1070 UNREFERENCED_PARAMETER(output_buffer_length);
1072 //FUNCTION_ENTER();
1074 WDF_REQUEST_PARAMETERS_INIT(&wrp);
1075 WdfRequestGetParameters(request, &wrp);
1077 switch(io_control_code)
1079 case IOCTL_INTERNAL_USB_SUBMIT_URB:
1080 urb = (PURB)wrp.Parameters.Others.Arg1;
1081 ASSERT(urb);
1082 usb_device = urb->UrbHeader.UsbdDeviceHandle;
1083 ASSERT(usb_device);
1084 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
1085 break;
1086 default:
1087 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
1088 WdfRequestComplete(request, WdfRequestGetStatus(request));
1089 break;
1091 //FUNCTION_EXIT();
1094 static VOID
1095 XenUsb_EvtIoDefault(
1096 WDFQUEUE queue,
1097 WDFREQUEST request)
1099 NTSTATUS status;
1100 WDF_REQUEST_PARAMETERS parameters;
1102 FUNCTION_ENTER();
1104 UNREFERENCED_PARAMETER(queue);
1106 status = STATUS_UNSUCCESSFUL;
1108 WDF_REQUEST_PARAMETERS_INIT(&parameters);
1109 WdfRequestGetParameters(request, &parameters);
1111 switch (parameters.Type)
1113 case WdfRequestTypeCreate:
1114 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
1115 break;
1116 case WdfRequestTypeClose:
1117 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
1118 break;
1119 case WdfRequestTypeRead:
1120 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
1121 break;
1122 case WdfRequestTypeWrite:
1123 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
1124 break;
1125 case WdfRequestTypeDeviceControl:
1126 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
1127 break;
1128 case WdfRequestTypeDeviceControlInternal:
1129 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
1130 break;
1131 default:
1132 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
1133 break;
1135 WdfRequestComplete(request, status);
1137 FUNCTION_EXIT();
1140 NTSTATUS
1141 XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
1143 NTSTATUS status;
1144 WDF_CHILD_LIST_CONFIG child_list_config;
1145 WDFDEVICE device;
1146 PXENUSB_DEVICE_DATA xudd;
1147 //UNICODE_STRING reference;
1148 WDF_OBJECT_ATTRIBUTES device_attributes;
1149 PNP_BUS_INFORMATION pbi;
1150 WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
1151 WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
1152 WDF_IO_QUEUE_CONFIG queue_config;
1153 WDF_DMA_ENABLER_CONFIG dma_config;
1154 UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
1156 UNREFERENCED_PARAMETER(driver);
1158 FUNCTION_ENTER();
1160 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
1161 pnp_power_callbacks.EvtDeviceD0Entry = XenUsb_EvtDeviceD0Entry;
1162 pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
1163 pnp_power_callbacks.EvtDeviceD0Exit = XenUsb_EvtDeviceD0Exit;
1164 pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
1165 pnp_power_callbacks.EvtDevicePrepareHardware = XenUsb_EvtDevicePrepareHardware;
1166 pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsb_EvtDeviceReleaseHardware;
1167 pnp_power_callbacks.EvtDeviceQueryRemove = XenUsb_EvtDeviceQueryRemove;
1168 //pnp_power_callbacks.EvtDeviceUsageNotification = XenUsb_EvtDeviceUsageNotification;
1170 WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
1172 status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE,
1173 IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
1174 if (!NT_SUCCESS(status))
1176 return status;
1179 WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER);
1180 WdfDeviceInitSetExclusive(device_init, FALSE);
1182 WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENUSB_PDO_IDENTIFICATION_DESCRIPTION), XenUsb_EvtChildListCreateDevice);
1183 child_list_config.EvtChildListScanForChildren = XenUsb_EvtChildListScanForChildren;
1184 WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES);
1186 WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered);
1188 WdfDeviceInitSetPowerNotPageable(device_init);
1190 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENUSB_DEVICE_DATA);
1191 status = WdfDeviceCreate(&device_init, &device_attributes, &device);
1192 if (!NT_SUCCESS(status))
1194 KdPrint(("Error creating device %08x\n", status));
1195 return status;
1198 xudd = GetXudd(device);
1199 xudd->child_list = WdfFdoGetDefaultChildList(device);
1201 KeInitializeSpinLock(&xudd->urb_ring_lock);
1203 WdfDeviceSetAlignmentRequirement(device, 0);
1204 WDF_DMA_ENABLER_CONFIG_INIT(&dma_config, WdfDmaProfileScatterGather64Duplex, PAGE_SIZE);
1205 status = WdfDmaEnablerCreate(device, &dma_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->dma_enabler);
1206 if (!NT_SUCCESS(status))
1208 KdPrint(("Error creating DMA enabler %08x\n", status));
1209 return status;
1212 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
1213 queue_config.EvtIoDeviceControl = XenUsb_EvtIoDeviceControl;
1214 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl;
1215 queue_config.EvtIoDefault = XenUsb_EvtIoDefault;
1216 status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->io_queue);
1217 if (!NT_SUCCESS(status)) {
1218 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
1219 return status;
1222 WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities);
1223 power_capabilities.DeviceD1 = WdfTrue;
1224 power_capabilities.WakeFromD1 = WdfTrue;
1225 power_capabilities.DeviceWake = PowerDeviceD1;
1226 power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD1;
1227 power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
1228 power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
1229 power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
1230 power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
1231 power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1232 WdfDeviceSetPowerCapabilities(device, &power_capabilities);
1234 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE);
1235 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE);
1236 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE);
1238 pbi.BusTypeGuid = GUID_BUS_TYPE_XEN;
1239 pbi.LegacyBusType = PNPBus;
1240 pbi.BusNumber = 0;
1241 WdfDeviceSetBusInformationForChildren(device, &pbi);
1243 status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL);
1244 if (!NT_SUCCESS(status))
1245 return status;
1247 //status = WdfDeviceOpenRegistryKey(device,
1249 FUNCTION_EXIT();
1250 return status;