win-pvdrivers

view xenusb/xenusb_fdo.c @ 840:c750a369bce5

Added tag 0.11.0.252 for changeset e48c6f765e5f
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 03 14:26:04 2011 +1100 (2011-02-03)
parents bbc6c94b9621
children 3aa213de2a31
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenusb.h"
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_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
610 __ADD_XEN_INIT_UCHAR(&ptr, 0); /* no pre-connect required */
611 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
612 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
613 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
614 __ADD_XEN_INIT_UCHAR(&ptr, 20);
615 __ADD_XEN_INIT_UCHAR(&ptr, 0);
616 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
617 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
618 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
619 __ADD_XEN_INIT_UCHAR(&ptr, 50);
620 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
621 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
622 __ADD_XEN_INIT_UCHAR(&ptr, 50);
623 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
624 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
625 __ADD_XEN_INIT_UCHAR(&ptr, 50);
626 __ADD_XEN_INIT_UCHAR(&ptr, 0);
627 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
628 status = xudd->vectors.XenPci_XenConfigDevice(xudd->vectors.context);
630 status = XenUsb_CompleteXenbusInit(xudd);
632 FUNCTION_EXIT();
634 return status;
635 }
637 NTSTATUS
638 XenUsb_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
639 {
640 NTSTATUS status = STATUS_SUCCESS;
641 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
642 ULONG i;
643 int notify;
644 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
646 UNREFERENCED_PARAMETER(device);
648 FUNCTION_ENTER();
650 switch (previous_state)
651 {
652 case WdfPowerDeviceD0:
653 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
654 break;
655 case WdfPowerDeviceD1:
656 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
657 break;
658 case WdfPowerDeviceD2:
659 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
660 break;
661 case WdfPowerDeviceD3:
662 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
663 break;
664 case WdfPowerDeviceD3Final:
665 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
666 break;
667 case WdfPowerDevicePrepareForHibernation:
668 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
669 break;
670 default:
671 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
672 break;
673 }
675 /* fill conn ring with requests */
676 for (i = 0; i < USB_CONN_RING_SIZE; i++)
677 {
678 usbif_conn_request_t *req = RING_GET_REQUEST(&xudd->conn_ring, i);
679 req->id = (uint16_t)i;
680 }
681 xudd->conn_ring.req_prod_pvt = i;
683 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
684 if (notify)
685 {
686 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
687 }
689 FUNCTION_EXIT();
691 return status;
692 }
694 NTSTATUS
695 XenUsb_EvtDeviceD0EntryPostInterruptsEnabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
696 {
697 NTSTATUS status = STATUS_SUCCESS;
698 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
700 UNREFERENCED_PARAMETER(device);
701 UNREFERENCED_PARAMETER(previous_state);
703 FUNCTION_ENTER();
705 FUNCTION_EXIT();
707 return status;
708 }
710 NTSTATUS
711 XenUsb_EvtDeviceD0ExitPreInterruptsDisabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
712 {
713 NTSTATUS status = STATUS_SUCCESS;
715 UNREFERENCED_PARAMETER(device);
717 FUNCTION_ENTER();
719 switch (target_state)
720 {
721 case WdfPowerDeviceD0:
722 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
723 break;
724 case WdfPowerDeviceD1:
725 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
726 break;
727 case WdfPowerDeviceD2:
728 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
729 break;
730 case WdfPowerDeviceD3:
731 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
732 break;
733 case WdfPowerDeviceD3Final:
734 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
735 break;
736 case WdfPowerDevicePrepareForHibernation:
737 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
738 break;
739 default:
740 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
741 break;
742 }
744 FUNCTION_EXIT();
746 return status;
747 }
749 NTSTATUS
750 XenUsb_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
751 {
752 NTSTATUS status = STATUS_SUCCESS;
753 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
755 FUNCTION_ENTER();
757 UNREFERENCED_PARAMETER(device);
759 switch (target_state)
760 {
761 case WdfPowerDeviceD0:
762 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
763 break;
764 case WdfPowerDeviceD1:
765 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
766 break;
767 case WdfPowerDeviceD2:
768 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
769 break;
770 case WdfPowerDeviceD3:
771 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
772 break;
773 case WdfPowerDeviceD3Final:
774 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
775 break;
776 case WdfPowerDevicePrepareForHibernation:
777 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
778 break;
779 default:
780 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
781 break;
782 }
784 FUNCTION_EXIT();
786 return status;
787 }
789 NTSTATUS
790 XenUsb_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
791 {
792 NTSTATUS status = STATUS_SUCCESS;
794 UNREFERENCED_PARAMETER(device);
795 UNREFERENCED_PARAMETER(resources_translated);
797 FUNCTION_ENTER();
798 FUNCTION_EXIT();
800 return status;
801 }
803 VOID
804 XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list)
805 {
806 NTSTATUS status;
807 PXENUSB_DEVICE_DATA xudd = GetXudd(WdfChildListGetDevice(child_list));
808 XENUSB_PDO_IDENTIFICATION_DESCRIPTION child_description;
809 CHAR path[128];
810 PCHAR err;
811 PCHAR value;
812 ULONG i;
814 FUNCTION_ENTER();
816 WdfChildListBeginScan(child_list);
818 // hold the queue on each device and set each device to a pending state
819 // read backend/num_ports
820 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/num-ports", xudd->vectors.backend_path);
821 err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
822 if (err)
823 {
824 XenPci_FreeMem(err);
825 WdfChildListEndScan(child_list);
826 KdPrint((__DRIVER_NAME " Failed to read num-ports\n"));
827 return;
828 }
829 xudd->num_ports = (ULONG)parse_numeric_string(value);
830 XenPci_FreeMem(value);
831 KdPrint((__DRIVER_NAME " num-ports = %d\n", xudd->num_ports));
833 for (i = 0; i < 8; i++)
834 {
835 xudd->ports[i].port_number = i + 1;
836 xudd->ports[i].port_type = USB_PORT_TYPE_NOT_CONNECTED;
837 xudd->ports[i].port_status = 1 << PORT_ENABLE;
838 xudd->ports[i].port_change = 0x0000;
839 }
841 /* only a single root hub is enumerated */
842 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description));
844 child_description.device_number = 0; //TODO: get the proper index from parent
846 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL);
847 if (!NT_SUCCESS(status))
848 {
849 KdPrint((__DRIVER_NAME " WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status));
850 }
852 WdfChildListEndScan(child_list);
854 FUNCTION_EXIT();
855 }
857 static VOID
858 XenUsb_EvtIoDeviceControl(
859 WDFQUEUE queue,
860 WDFREQUEST request,
861 size_t output_buffer_length,
862 size_t input_buffer_length,
863 ULONG io_control_code)
864 {
865 NTSTATUS status;
866 WDFDEVICE device = WdfIoQueueGetDevice(queue);
867 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
868 //WDF_REQUEST_PARAMETERS wrp;
869 //PURB urb;
870 //xenusb_device_t *usb_device;
872 UNREFERENCED_PARAMETER(queue);
873 UNREFERENCED_PARAMETER(input_buffer_length);
874 UNREFERENCED_PARAMETER(output_buffer_length);
876 FUNCTION_ENTER();
878 status = STATUS_UNSUCCESSFUL;
880 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
881 //WdfRequestGetParameters(request, &wrp);
883 // these are in api\usbioctl.h
884 switch(io_control_code)
885 {
886 #if 0
887 case IOCTL_USB_GET_NODE_INFORMATION:
888 {
889 PUSB_NODE_INFORMATION uni;
890 size_t length;
892 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
893 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
894 // make sure size is >= bDescriptorLength
895 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uni, &length);
896 if (NT_SUCCESS(status))
897 {
898 switch(uni->NodeType)
899 {
900 case UsbHub:
901 KdPrint((__DRIVER_NAME " NodeType = UsbHub\n"));
902 uni->u.HubInformation.HubDescriptor.bDescriptorLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask) + 3;
903 if (output_buffer_length >= FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3)
904 {
905 uni->u.HubInformation.HubDescriptor.bDescriptorType = 0x29;
906 uni->u.HubInformation.HubDescriptor.bNumberOfPorts = 8;
907 uni->u.HubInformation.HubDescriptor.wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
908 uni->u.HubInformation.HubDescriptor.bPowerOnToPowerGood = 1; // 2ms units
909 uni->u.HubInformation.HubDescriptor.bHubControlCurrent = 0;
910 // DeviceRemovable bits (includes an extra bit at the start)
911 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[0] = 0;
912 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[1] = 0;
913 // PortPwrCtrlMask
914 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[2] = 0xFF;
915 uni->u.HubInformation.HubIsBusPowered = TRUE;
916 }
917 WdfRequestSetInformation(request, FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3);
918 break;
919 case UsbMIParent:
920 KdPrint((__DRIVER_NAME " NodeType = UsbMIParent\n"));
921 status = STATUS_UNSUCCESSFUL;
922 break;
923 }
924 }
925 else
926 {
927 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
928 }
929 break;
930 }
931 #endif
932 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
933 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
934 break;
935 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
936 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
937 break;
938 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
939 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
940 break;
941 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
942 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
943 break;
944 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
945 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
946 break;
947 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
948 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
949 break;
950 case IOCTL_USB_GET_HUB_CAPABILITIES:
951 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
952 break;
953 case IOCTL_USB_HUB_CYCLE_PORT:
954 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
955 break;
956 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
957 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
958 break;
959 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
960 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
961 break;
962 case IOCTL_USB_GET_ROOT_HUB_NAME:
963 {
964 PUSB_HCD_DRIVERKEY_NAME uhdn;
965 size_t length;
966 ULONG required_length = 0;
968 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_ROOT_HUB_NAME\n"));
969 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
971 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
972 status = STATUS_BUFFER_TOO_SMALL;
973 else
974 {
975 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
976 if (NT_SUCCESS(status))
977 {
978 WDFSTRING symbolic_link_wdfstring;
979 UNICODE_STRING symbolic_link;
981 uhdn->DriverKeyName[0] = 0;
982 status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolic_link_wdfstring);
983 status = WdfDeviceRetrieveDeviceInterfaceString(xudd->root_hub_device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolic_link_wdfstring);
984 if (NT_SUCCESS(status))
985 {
986 WdfStringGetUnicodeString(symbolic_link_wdfstring, &symbolic_link);
987 /* remove leading \??\ from name */
988 symbolic_link.Buffer += 4;
989 symbolic_link.Length -= 4 * sizeof(WCHAR);
990 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + symbolic_link.Length + sizeof(WCHAR);
991 uhdn->ActualLength = required_length;
992 if (output_buffer_length >= required_length)
993 {
994 memcpy(uhdn->DriverKeyName, symbolic_link.Buffer, symbolic_link.Length);
995 uhdn->DriverKeyName[symbolic_link.Length / 2] = 0;
996 }
997 }
998 else
999 {
1000 KdPrint((__DRIVER_NAME " WdfDeviceRetrieveDeviceInterfaceString = %08x\n", status));
1001 status = STATUS_INVALID_PARAMETER;
1004 else
1006 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
1008 KdPrint((__DRIVER_NAME " uhdn->ActualLength = %d\n", uhdn->ActualLength));
1009 KdPrint((__DRIVER_NAME " uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName));
1010 WdfRequestSetInformation(request, required_length);
1012 break;
1014 case IOCTL_GET_HCD_DRIVERKEY_NAME:
1016 PUSB_HCD_DRIVERKEY_NAME uhdn;
1017 size_t length;
1018 ULONG required_length = 0;
1020 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME\n"));
1021 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
1023 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
1024 status = STATUS_BUFFER_TOO_SMALL;
1025 else
1027 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
1028 if (NT_SUCCESS(status))
1030 ULONG key_length;
1031 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName, 0, NULL, &key_length);
1032 KdPrint((__DRIVER_NAME " key_length = %d\n", key_length));
1033 status = STATUS_SUCCESS;
1034 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + key_length;
1035 uhdn->ActualLength = required_length;
1036 if (output_buffer_length >= required_length)
1038 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName,
1039 required_length - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), uhdn->DriverKeyName,
1040 &key_length);
1042 else
1044 uhdn->DriverKeyName[0] = 0;
1047 else
1049 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
1051 KdPrint((__DRIVER_NAME " uhdn->ActualLength = %d\n", uhdn->ActualLength));
1052 KdPrint((__DRIVER_NAME " uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName));
1053 WdfRequestSetInformation(request, required_length);
1055 break;
1057 #if 0
1058 case IOCTL_USB_RESET_HUB:
1059 KdPrint((__DRIVER_NAME " IOCTL_USB_RESET_HUB\n"));
1060 break;
1061 #endif
1062 default:
1063 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
1064 break;
1066 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
1067 WdfRequestComplete(request, status);
1069 FUNCTION_EXIT();
1072 static VOID
1073 XenUsb_EvtIoInternalDeviceControl(
1074 WDFQUEUE queue,
1075 WDFREQUEST request,
1076 size_t output_buffer_length,
1077 size_t input_buffer_length,
1078 ULONG io_control_code)
1080 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
1081 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
1082 PURB urb;
1083 xenusb_device_t *usb_device;
1084 WDF_REQUEST_PARAMETERS wrp;
1086 UNREFERENCED_PARAMETER(queue);
1087 UNREFERENCED_PARAMETER(input_buffer_length);
1088 UNREFERENCED_PARAMETER(output_buffer_length);
1090 //FUNCTION_ENTER();
1092 WDF_REQUEST_PARAMETERS_INIT(&wrp);
1093 WdfRequestGetParameters(request, &wrp);
1095 switch(io_control_code)
1097 case IOCTL_INTERNAL_USB_SUBMIT_URB:
1098 urb = (PURB)wrp.Parameters.Others.Arg1;
1099 ASSERT(urb);
1100 usb_device = urb->UrbHeader.UsbdDeviceHandle;
1101 ASSERT(usb_device);
1102 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
1103 break;
1104 default:
1105 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
1106 WdfRequestComplete(request, WdfRequestGetStatus(request));
1107 break;
1109 //FUNCTION_EXIT();
1112 static VOID
1113 XenUsb_EvtIoDefault(
1114 WDFQUEUE queue,
1115 WDFREQUEST request)
1117 NTSTATUS status;
1118 WDF_REQUEST_PARAMETERS parameters;
1120 FUNCTION_ENTER();
1122 UNREFERENCED_PARAMETER(queue);
1124 status = STATUS_UNSUCCESSFUL;
1126 WDF_REQUEST_PARAMETERS_INIT(&parameters);
1127 WdfRequestGetParameters(request, &parameters);
1129 switch (parameters.Type)
1131 case WdfRequestTypeCreate:
1132 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
1133 break;
1134 case WdfRequestTypeClose:
1135 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
1136 break;
1137 case WdfRequestTypeRead:
1138 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
1139 break;
1140 case WdfRequestTypeWrite:
1141 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
1142 break;
1143 case WdfRequestTypeDeviceControl:
1144 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
1145 break;
1146 case WdfRequestTypeDeviceControlInternal:
1147 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
1148 break;
1149 default:
1150 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
1151 break;
1153 WdfRequestComplete(request, status);
1155 FUNCTION_EXIT();
1158 NTSTATUS
1159 XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
1161 NTSTATUS status;
1162 WDF_CHILD_LIST_CONFIG child_list_config;
1163 WDFDEVICE device;
1164 PXENUSB_DEVICE_DATA xudd;
1165 //UNICODE_STRING reference;
1166 WDF_OBJECT_ATTRIBUTES device_attributes;
1167 PNP_BUS_INFORMATION pbi;
1168 WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
1169 WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
1170 WDF_IO_QUEUE_CONFIG queue_config;
1171 WDF_DMA_ENABLER_CONFIG dma_config;
1172 UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
1174 UNREFERENCED_PARAMETER(driver);
1176 FUNCTION_ENTER();
1178 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
1179 pnp_power_callbacks.EvtDeviceD0Entry = XenUsb_EvtDeviceD0Entry;
1180 pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
1181 pnp_power_callbacks.EvtDeviceD0Exit = XenUsb_EvtDeviceD0Exit;
1182 pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
1183 pnp_power_callbacks.EvtDevicePrepareHardware = XenUsb_EvtDevicePrepareHardware;
1184 pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsb_EvtDeviceReleaseHardware;
1185 pnp_power_callbacks.EvtDeviceQueryRemove = XenUsb_EvtDeviceQueryRemove;
1186 //pnp_power_callbacks.EvtDeviceUsageNotification = XenUsb_EvtDeviceUsageNotification;
1188 WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
1190 status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE,
1191 IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
1192 if (!NT_SUCCESS(status))
1194 return status;
1197 WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER);
1198 WdfDeviceInitSetExclusive(device_init, FALSE);
1200 WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENUSB_PDO_IDENTIFICATION_DESCRIPTION), XenUsb_EvtChildListCreateDevice);
1201 child_list_config.EvtChildListScanForChildren = XenUsb_EvtChildListScanForChildren;
1202 WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES);
1204 WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered);
1206 WdfDeviceInitSetPowerNotPageable(device_init);
1208 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENUSB_DEVICE_DATA);
1209 status = WdfDeviceCreate(&device_init, &device_attributes, &device);
1210 if (!NT_SUCCESS(status))
1212 KdPrint(("Error creating device %08x\n", status));
1213 return status;
1216 xudd = GetXudd(device);
1217 xudd->child_list = WdfFdoGetDefaultChildList(device);
1219 KeInitializeSpinLock(&xudd->urb_ring_lock);
1221 WdfDeviceSetAlignmentRequirement(device, 0);
1222 WDF_DMA_ENABLER_CONFIG_INIT(&dma_config, WdfDmaProfileScatterGather64Duplex, PAGE_SIZE);
1223 status = WdfDmaEnablerCreate(device, &dma_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->dma_enabler);
1224 if (!NT_SUCCESS(status))
1226 KdPrint(("Error creating DMA enabler %08x\n", status));
1227 return status;
1230 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
1231 queue_config.EvtIoDeviceControl = XenUsb_EvtIoDeviceControl;
1232 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl;
1233 queue_config.EvtIoDefault = XenUsb_EvtIoDefault;
1234 status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->io_queue);
1235 if (!NT_SUCCESS(status)) {
1236 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
1237 return status;
1240 WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities);
1241 power_capabilities.DeviceD1 = WdfTrue;
1242 power_capabilities.WakeFromD1 = WdfTrue;
1243 power_capabilities.DeviceWake = PowerDeviceD1;
1244 power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD1;
1245 power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
1246 power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
1247 power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
1248 power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
1249 power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1250 WdfDeviceSetPowerCapabilities(device, &power_capabilities);
1252 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE);
1253 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE);
1254 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE);
1256 pbi.BusTypeGuid = GUID_BUS_TYPE_XEN;
1257 pbi.LegacyBusType = PNPBus;
1258 pbi.BusNumber = 0;
1259 WdfDeviceSetBusInformationForChildren(device, &pbi);
1261 status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL);
1262 if (!NT_SUCCESS(status))
1263 return status;
1265 //status = WdfDeviceOpenRegistryKey(device,
1267 FUNCTION_EXIT();
1268 return status;