win-pvdrivers

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