win-pvdrivers

view xenusb/xenusb_fdo.c @ 965:63bdd096d8d1

Fix KeInitializeCrashDumpHeader - buffer was too small under newer systems
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 10 12:11:30 2012 +1100 (2012-01-10)
parents 19d7c9dd9f5c
children 1306945ecc59
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 // STATUS_UNSUCCESSFUL -> STATUS_BAD_INITIAL_PC
22 #include "xenusb.h"
24 /* Not really necessary but keeps PREfast happy */
25 static EVT_WDF_DEVICE_D0_ENTRY XenUsb_EvtDeviceD0Entry;
26 static EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
27 static EVT_WDF_DEVICE_D0_EXIT XenUsb_EvtDeviceD0Exit;
28 static EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
29 static EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsb_EvtDevicePrepareHardware;
30 static EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsb_EvtDeviceReleaseHardware;
31 static EVT_WDF_DEVICE_QUERY_REMOVE XenUsb_EvtDeviceQueryRemove;
32 static EVT_WDFDEVICE_WDM_IRP_PREPROCESS XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE;
33 static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL XenUsb_EvtIoDeviceControl;
34 static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl;
35 static EVT_WDF_IO_QUEUE_IO_DEFAULT XenUsb_EvtIoDefault;
36 //static EVT_WDF_PROGRAM_DMA XenUsb_ExecuteRequestCallback;
38 NTSTATUS
39 XenUsb_ExecuteRequest(
40 PXENUSB_DEVICE_DATA xudd,
41 usbif_shadow_t *shadow,
42 PVOID transfer_buffer,
43 PMDL transfer_buffer_mdl,
44 ULONG transfer_buffer_length)
45 {
46 NTSTATUS status = STATUS_SUCCESS;
47 KIRQL old_irql;
48 PMDL mdl;
49 int i;
50 int notify;
51 ULONG remaining;
52 USHORT offset;
54 FUNCTION_ENTER();
55 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
57 KdPrint((__DRIVER_NAME " transfer_buffer = %p\n", transfer_buffer));
58 KdPrint((__DRIVER_NAME " transfer_buffer_mdl = %p\n", transfer_buffer_mdl));
59 KdPrint((__DRIVER_NAME " transfer_buffer_length = %d\n", transfer_buffer_length));
60 shadow->total_length = 0;
61 if (!transfer_buffer_length)
62 {
63 shadow->mdl = NULL;
64 shadow->req.nr_buffer_segs = 0;
65 shadow->req.buffer_length = 0;
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);
77 FUNCTION_EXIT();
78 return STATUS_SUCCESS;
79 }
80 ASSERT(transfer_buffer || transfer_buffer_mdl);
81 if (transfer_buffer)
82 {
83 mdl = IoAllocateMdl(transfer_buffer, transfer_buffer_length, FALSE, FALSE, NULL);
84 ASSERT(mdl);
85 MmBuildMdlForNonPagedPool(mdl);
86 shadow->mdl = mdl;
87 }
88 else
89 {
90 mdl = transfer_buffer_mdl;
91 shadow->mdl = NULL;
92 }
94 ASSERT(mdl);
95 ASSERT(transfer_buffer_length);
97 FUNCTION_MSG("MmGetMdlVirtualAddress = %p\n", MmGetMdlVirtualAddress(mdl));
98 FUNCTION_MSG("MmGetMdlByteCount = %d\n", MmGetMdlByteCount(mdl));
99 FUNCTION_MSG("MmGetMdlByteOffset = %d\n", MmGetMdlByteOffset(mdl));
101 remaining = MmGetMdlByteCount(mdl);
102 offset = (USHORT)MmGetMdlByteOffset(mdl);
103 shadow->req.buffer_length = (USHORT)MmGetMdlByteCount(mdl);
104 shadow->req.nr_buffer_segs = (USHORT)ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(mdl), MmGetMdlByteCount(mdl));
105 for (i = 0; i < shadow->req.nr_buffer_segs; i++)
106 {
107 shadow->req.seg[i].gref = xudd->vectors.GntTbl_GrantAccess(xudd->vectors.context, 0,
108 (ULONG)MmGetMdlPfnArray(mdl)[i], FALSE, INVALID_GRANT_REF, (ULONG)'XUSB');
109 shadow->req.seg[i].offset = (USHORT)offset;
110 shadow->req.seg[i].length = (USHORT)min(remaining, PAGE_SIZE);
111 offset = 0;
112 remaining -= shadow->req.seg[i].length;
113 KdPrint((__DRIVER_NAME " seg = %d\n", i));
114 KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[i].gref));
115 KdPrint((__DRIVER_NAME " offset = %d\n", shadow->req.seg[i].offset));
116 KdPrint((__DRIVER_NAME " length = %d\n", shadow->req.seg[i].length));
117 }
118 KdPrint((__DRIVER_NAME " buffer_length = %d\n", shadow->req.buffer_length));
119 KdPrint((__DRIVER_NAME " nr_buffer_segs = %d\n", shadow->req.nr_buffer_segs));
121 KeAcquireSpinLock(&xudd->urb_ring_lock, &old_irql);
122 *RING_GET_REQUEST(&xudd->urb_ring, xudd->urb_ring.req_prod_pvt) = shadow->req;
123 xudd->urb_ring.req_prod_pvt++;
124 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
125 if (notify)
126 {
127 //KdPrint((__DRIVER_NAME " Notifying\n"));
128 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
129 }
130 KeReleaseSpinLock(&xudd->urb_ring_lock, old_irql);
132 FUNCTION_EXIT();
133 return status;
134 }
136 NTSTATUS
137 XenUsb_EvtDeviceQueryRemove(WDFDEVICE device)
138 {
139 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
140 NTSTATUS status = STATUS_SUCCESS;
142 UNREFERENCED_PARAMETER(device);
144 FUNCTION_ENTER();
145 FUNCTION_EXIT();
146 return status;
147 }
149 static NTSTATUS
150 XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
151 {
152 PIO_STACK_LOCATION stack;
154 FUNCTION_ENTER();
156 stack = IoGetCurrentIrpStackLocation(irp);
158 if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
159 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_HUB_GUID\n"));
160 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
161 KdPrint((__DRIVER_NAME " USB_BUS_INTERFACE_USBDI_GUID\n"));
162 else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_TRANSLATOR_INTERFACE_STANDARD, sizeof(GUID)) == 0)
163 KdPrint((__DRIVER_NAME " GUID_TRANSLATOR_INTERFACE_STANDARD\n"));
164 else
165 KdPrint((__DRIVER_NAME " GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
166 stack->Parameters.QueryInterface.InterfaceType->Data1,
167 stack->Parameters.QueryInterface.InterfaceType->Data2,
168 stack->Parameters.QueryInterface.InterfaceType->Data3,
169 (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
170 stack->Parameters.QueryInterface.InterfaceType->Data4[1],
171 stack->Parameters.QueryInterface.InterfaceType->Data4[2],
172 stack->Parameters.QueryInterface.InterfaceType->Data4[3],
173 stack->Parameters.QueryInterface.InterfaceType->Data4[4],
174 stack->Parameters.QueryInterface.InterfaceType->Data4[5],
175 stack->Parameters.QueryInterface.InterfaceType->Data4[6],
176 stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
178 KdPrint((__DRIVER_NAME " Size = %d\n", stack->Parameters.QueryInterface.Size));
179 KdPrint((__DRIVER_NAME " Version = %d\n", stack->Parameters.QueryInterface.Version));
180 KdPrint((__DRIVER_NAME " Interface = %p\n", stack->Parameters.QueryInterface.Interface));
183 IoSkipCurrentIrpStackLocation(irp);
185 FUNCTION_EXIT();
187 return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
188 }
190 /* called at DISPATCH_LEVEL */
191 static BOOLEAN
192 XenUsb_HandleEvent(PVOID context)
193 {
194 PXENUSB_DEVICE_DATA xudd = context;
195 RING_IDX prod, cons;
196 usbif_urb_response_t *urb_rsp;
197 usbif_conn_response_t *conn_rsp;
198 usbif_conn_request_t *conn_req;
199 int more_to_do;
200 usbif_shadow_t *complete_head = NULL, *complete_tail = NULL;
201 usbif_shadow_t *shadow;
202 BOOLEAN port_changed = FALSE;
204 FUNCTION_ENTER();
206 more_to_do = TRUE;
207 KeAcquireSpinLockAtDpcLevel(&xudd->urb_ring_lock);
208 while (more_to_do)
209 {
210 prod = xudd->urb_ring.sring->rsp_prod;
211 KeMemoryBarrier();
212 for (cons = xudd->urb_ring.rsp_cons; cons != prod; cons++)
213 {
214 urb_rsp = RING_GET_RESPONSE(&xudd->urb_ring, cons);
215 shadow = &xudd->shadows[urb_rsp->id];
216 ASSERT(shadow->callback);
217 shadow->rsp = *urb_rsp;
218 shadow->next = NULL;
219 shadow->total_length += urb_rsp->actual_length;
221 KdPrint((__DRIVER_NAME " urb_ring rsp id = %d\n", shadow->rsp.id));
222 KdPrint((__DRIVER_NAME " urb_ring rsp start_frame = %d\n", shadow->rsp.start_frame));
223 KdPrint((__DRIVER_NAME " urb_ring rsp status = %d\n", shadow->rsp.status));
224 KdPrint((__DRIVER_NAME " urb_ring rsp actual_length = %d\n", shadow->rsp.actual_length));
225 KdPrint((__DRIVER_NAME " urb_ring rsp error_count = %d\n", shadow->rsp.error_count));
226 KdPrint((__DRIVER_NAME " urb_ring total_length = %d\n", shadow->total_length));
228 if (complete_tail)
229 {
230 complete_tail->next = shadow;
231 }
232 else
233 {
234 complete_head = shadow;
235 }
236 complete_tail = shadow;
237 }
239 xudd->urb_ring.rsp_cons = cons;
240 if (cons != xudd->urb_ring.req_prod_pvt)
241 {
242 RING_FINAL_CHECK_FOR_RESPONSES(&xudd->urb_ring, more_to_do);
243 }
244 else
245 {
246 xudd->urb_ring.sring->rsp_event = cons + 1;
247 more_to_do = FALSE;
248 }
249 }
250 KeReleaseSpinLockFromDpcLevel(&xudd->urb_ring_lock);
252 more_to_do = TRUE;
253 KeAcquireSpinLockAtDpcLevel(&xudd->conn_ring_lock);
254 while (more_to_do)
255 {
256 prod = xudd->conn_ring.sring->rsp_prod;
257 KeMemoryBarrier();
258 for (cons = xudd->conn_ring.rsp_cons; cons != prod; cons++)
259 {
260 conn_rsp = RING_GET_RESPONSE(&xudd->conn_ring, cons);
261 KdPrint((__DRIVER_NAME " conn_rsp->portnum = %d\n", conn_rsp->portnum));
262 KdPrint((__DRIVER_NAME " conn_rsp->speed = %d\n", conn_rsp->speed));
264 xudd->ports[conn_rsp->portnum - 1].port_type = conn_rsp->speed;
265 xudd->ports[conn_rsp->portnum - 1].port_status &= ~((1 << PORT_LOW_SPEED) | (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION));
266 switch (conn_rsp->speed)
267 {
268 case USB_PORT_TYPE_NOT_CONNECTED:
269 //xudd->ports[conn_rsp->portnum - 1].port_status |= 0;
270 break;
271 case USB_PORT_TYPE_LOW_SPEED:
272 xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION);
273 break;
274 case USB_PORT_TYPE_FULL_SPEED:
275 xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_CONNECTION);
276 break;
277 case USB_PORT_TYPE_HIGH_SPEED:
278 xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION);
279 break;
280 }
281 xudd->ports[conn_rsp->portnum - 1].port_change |= (1 << PORT_CONNECTION);
282 port_changed = TRUE;
283 conn_req = RING_GET_REQUEST(&xudd->conn_ring, xudd->conn_ring.req_prod_pvt);
284 conn_req->id = conn_rsp->id;
285 xudd->conn_ring.req_prod_pvt++;
286 }
288 xudd->conn_ring.rsp_cons = cons;
289 if (cons != xudd->conn_ring.req_prod_pvt)
290 {
291 RING_FINAL_CHECK_FOR_RESPONSES(&xudd->conn_ring, more_to_do);
292 }
293 else
294 {
295 xudd->conn_ring.sring->rsp_event = cons + 1;
296 more_to_do = FALSE;
297 }
298 }
299 KeReleaseSpinLockFromDpcLevel(&xudd->conn_ring_lock);
301 shadow = complete_head;
302 while (shadow != NULL)
303 {
304 if (shadow->req.buffer_length)
305 {
306 int i;
307 for (i = 0; i < shadow->req.nr_buffer_segs; i++)
308 {
309 xudd->vectors.GntTbl_EndAccess(xudd->vectors.context,
310 shadow->req.seg[i].gref, FALSE, (ULONG)'XUSB');
311 }
312 // free grant refs
313 if (shadow->mdl)
314 {
315 IoFreeMdl(shadow->mdl);
316 }
317 shadow->callback(shadow);
318 }
319 else
320 {
321 shadow->callback(shadow);
322 }
323 shadow = shadow->next;
324 }
326 if (port_changed)
327 {
328 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(xudd->root_hub_device);
329 XenUsbHub_ProcessHubInterruptEvent(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]);
330 }
332 FUNCTION_EXIT();
334 return TRUE;
335 }
337 static NTSTATUS
338 XenUsb_StartXenbusInit(PXENUSB_DEVICE_DATA xudd)
339 {
340 PUCHAR ptr;
341 USHORT type;
342 PCHAR setting, value, value2;
344 xudd->urb_sring = NULL;
345 xudd->event_channel = 0;
347 ptr = xudd->config_page;
348 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
349 {
350 switch(type)
351 {
352 case XEN_INIT_TYPE_READ_STRING_BACK:
353 case XEN_INIT_TYPE_READ_STRING_FRONT:
354 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
355 break;
356 case XEN_INIT_TYPE_VECTORS:
357 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
358 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
359 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
360 {
361 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
362 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
363 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
364 return STATUS_BAD_INITIAL_PC;
365 }
366 else
367 memcpy(&xudd->vectors, value, sizeof(XENPCI_VECTORS));
368 break;
369 case XEN_INIT_TYPE_STATE_PTR:
370 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
371 xudd->device_state = (PXENPCI_DEVICE_STATE)value;
372 break;
373 #if 0
374 case XEN_INIT_TYPE_GRANT_ENTRIES:
375 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
376 memcpy(xudd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
377 break;
378 #endif
379 default:
380 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
381 break;
382 }
383 }
385 return STATUS_SUCCESS;
386 }
388 static NTSTATUS
389 XenUsb_CompleteXenbusInit(PXENUSB_DEVICE_DATA xudd)
390 {
391 PUCHAR ptr;
392 USHORT type;
393 PCHAR setting, value, value2;
394 ULONG i;
396 ptr = xudd->config_page;
397 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
398 {
399 switch(type)
400 {
401 case XEN_INIT_TYPE_RING: /* frontend ring */
402 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
403 if (strcmp(setting, "urb-ring-ref") == 0)
404 {
405 xudd->urb_sring = (usbif_urb_sring_t *)value;
406 FRONT_RING_INIT(&xudd->urb_ring, xudd->urb_sring, PAGE_SIZE);
407 }
408 if (strcmp(setting, "conn-ring-ref") == 0)
409 {
410 xudd->conn_sring = (usbif_conn_sring_t *)value;
411 FRONT_RING_INIT(&xudd->conn_ring, xudd->conn_sring, PAGE_SIZE);
412 }
413 break;
414 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
415 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL_DPC - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
416 if (strcmp(setting, "event-channel") == 0)
417 {
418 xudd->event_channel = PtrToUlong(value);
419 }
420 break;
421 case XEN_INIT_TYPE_READ_STRING_BACK:
422 case XEN_INIT_TYPE_READ_STRING_FRONT:
423 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
424 break;
425 default:
426 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
427 break;
428 }
429 }
430 if (xudd->urb_sring == NULL || xudd->conn_sring == NULL || xudd->event_channel == 0)
431 {
432 KdPrint((__DRIVER_NAME " Missing settings\n"));
433 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
434 return STATUS_BAD_INITIAL_PC;
435 }
437 xudd->shadow_free = 0;
438 memset(xudd->shadows, 0, sizeof(usbif_shadow_t) * SHADOW_ENTRIES);
439 for (i = 0; i < SHADOW_ENTRIES; i++)
440 {
441 xudd->shadows[i].id = (uint16_t)i;
442 put_shadow_on_freelist(xudd, &xudd->shadows[i]);
443 }
445 return STATUS_SUCCESS;
446 }
448 NTSTATUS
449 XenUsb_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
450 {
451 NTSTATUS status = STATUS_SUCCESS;
452 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
453 PCM_PARTIAL_RESOURCE_DESCRIPTOR raw_descriptor, translated_descriptor;
454 ULONG i;
455 PUCHAR ptr;
457 FUNCTION_ENTER();
459 ASSERT(WdfCmResourceListGetCount(resources_raw) == WdfCmResourceListGetCount(resources_translated));
461 for (i = 0; i < WdfCmResourceListGetCount(resources_raw); i++)
462 {
463 raw_descriptor = WdfCmResourceListGetDescriptor(resources_raw, i);
464 translated_descriptor = WdfCmResourceListGetDescriptor(resources_translated, i);
465 switch (raw_descriptor->Type) {
466 case CmResourceTypePort:
467 KdPrint((__DRIVER_NAME " IoPort Address(%x) Length: %d\n", translated_descriptor->u.Port.Start.LowPart, translated_descriptor->u.Port.Length));
468 break;
469 case CmResourceTypeMemory:
470 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));
471 KdPrint((__DRIVER_NAME " Memory flags = %04X\n", translated_descriptor->Flags));
472 xudd->config_page = MmMapIoSpace(translated_descriptor->u.Memory.Start, translated_descriptor->u.Memory.Length, MmNonCached);
473 KdPrint((__DRIVER_NAME " Memory mapped to %p\n", xudd->config_page));
474 break;
475 case CmResourceTypeInterrupt:
476 KdPrint((__DRIVER_NAME " irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector));
477 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", translated_descriptor->u.Interrupt.Vector));
478 KdPrint((__DRIVER_NAME " irq_level = %03x\n", translated_descriptor->u.Interrupt.Level));
479 break;
480 case CmResourceTypeDevicePrivate:
481 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]));
482 break;
483 default:
484 KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", translated_descriptor->Type));
485 break;
486 }
487 }
489 status = XenUsb_StartXenbusInit(xudd);
491 ptr = xudd->config_page;
492 //ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
493 //ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
494 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "urb-ring-ref", NULL, NULL);
495 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "conn-ring-ref", NULL, NULL);
496 #pragma warning(suppress:4054)
497 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenUsb_HandleEvent, xudd);
498 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
499 __ADD_XEN_INIT_UCHAR(&ptr, 0); /* no pre-connect required */
500 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
501 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
502 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
503 __ADD_XEN_INIT_UCHAR(&ptr, 20);
504 __ADD_XEN_INIT_UCHAR(&ptr, 0);
505 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
506 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
507 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
508 __ADD_XEN_INIT_UCHAR(&ptr, 50);
509 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
510 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
511 __ADD_XEN_INIT_UCHAR(&ptr, 50);
512 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
513 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
514 __ADD_XEN_INIT_UCHAR(&ptr, 50);
515 __ADD_XEN_INIT_UCHAR(&ptr, 0);
516 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
517 status = xudd->vectors.XenPci_XenConfigDevice(xudd->vectors.context);
519 status = XenUsb_CompleteXenbusInit(xudd);
521 FUNCTION_EXIT();
523 return status;
524 }
526 NTSTATUS
527 XenUsb_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
528 {
529 NTSTATUS status = STATUS_SUCCESS;
530 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
531 ULONG i;
532 int notify;
533 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
535 UNREFERENCED_PARAMETER(device);
537 FUNCTION_ENTER();
539 switch (previous_state)
540 {
541 case WdfPowerDeviceD0:
542 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
543 break;
544 case WdfPowerDeviceD1:
545 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
546 break;
547 case WdfPowerDeviceD2:
548 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
549 break;
550 case WdfPowerDeviceD3:
551 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
552 break;
553 case WdfPowerDeviceD3Final:
554 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
555 break;
556 case WdfPowerDevicePrepareForHibernation:
557 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
558 break;
559 default:
560 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", previous_state));
561 break;
562 }
564 /* fill conn ring with requests */
565 for (i = 0; i < USB_CONN_RING_SIZE; i++)
566 {
567 usbif_conn_request_t *req = RING_GET_REQUEST(&xudd->conn_ring, i);
568 req->id = (uint16_t)i;
569 }
570 xudd->conn_ring.req_prod_pvt = i;
572 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->urb_ring, notify);
573 if (notify)
574 {
575 xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
576 }
578 FUNCTION_EXIT();
580 return status;
581 }
583 NTSTATUS
584 XenUsb_EvtDeviceD0EntryPostInterruptsEnabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
585 {
586 NTSTATUS status = STATUS_SUCCESS;
587 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
589 UNREFERENCED_PARAMETER(device);
590 UNREFERENCED_PARAMETER(previous_state);
592 FUNCTION_ENTER();
594 FUNCTION_EXIT();
596 return status;
597 }
599 NTSTATUS
600 XenUsb_EvtDeviceD0ExitPreInterruptsDisabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
601 {
602 NTSTATUS status = STATUS_SUCCESS;
604 UNREFERENCED_PARAMETER(device);
606 FUNCTION_ENTER();
608 switch (target_state)
609 {
610 case WdfPowerDeviceD0:
611 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
612 break;
613 case WdfPowerDeviceD1:
614 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
615 break;
616 case WdfPowerDeviceD2:
617 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
618 break;
619 case WdfPowerDeviceD3:
620 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
621 break;
622 case WdfPowerDeviceD3Final:
623 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
624 break;
625 case WdfPowerDevicePrepareForHibernation:
626 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
627 break;
628 default:
629 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
630 break;
631 }
633 FUNCTION_EXIT();
635 return status;
636 }
638 NTSTATUS
639 XenUsb_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
640 {
641 NTSTATUS status = STATUS_SUCCESS;
642 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
644 FUNCTION_ENTER();
646 UNREFERENCED_PARAMETER(device);
648 switch (target_state)
649 {
650 case WdfPowerDeviceD0:
651 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
652 break;
653 case WdfPowerDeviceD1:
654 KdPrint((__DRIVER_NAME " WdfPowerDeviceD1\n"));
655 break;
656 case WdfPowerDeviceD2:
657 KdPrint((__DRIVER_NAME " WdfPowerDeviceD2\n"));
658 break;
659 case WdfPowerDeviceD3:
660 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3\n"));
661 break;
662 case WdfPowerDeviceD3Final:
663 KdPrint((__DRIVER_NAME " WdfPowerDeviceD3Final\n"));
664 break;
665 case WdfPowerDevicePrepareForHibernation:
666 KdPrint((__DRIVER_NAME " WdfPowerDevicePrepareForHibernation\n"));
667 break;
668 default:
669 KdPrint((__DRIVER_NAME " Unknown WdfPowerDevice state %d\n", target_state));
670 break;
671 }
673 FUNCTION_EXIT();
675 return status;
676 }
678 NTSTATUS
679 XenUsb_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
680 {
681 NTSTATUS status = STATUS_SUCCESS;
683 UNREFERENCED_PARAMETER(device);
684 UNREFERENCED_PARAMETER(resources_translated);
686 FUNCTION_ENTER();
687 FUNCTION_EXIT();
689 return status;
690 }
692 VOID
693 XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list)
694 {
695 NTSTATUS status;
696 PXENUSB_DEVICE_DATA xudd = GetXudd(WdfChildListGetDevice(child_list));
697 XENUSB_PDO_IDENTIFICATION_DESCRIPTION child_description;
698 CHAR path[128];
699 PCHAR err;
700 PCHAR value;
701 ULONG i;
703 FUNCTION_ENTER();
705 WdfChildListBeginScan(child_list);
707 // hold the queue on each device and set each device to a pending state
708 // read backend/num_ports
709 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/num-ports", xudd->vectors.backend_path);
710 err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
711 if (err)
712 {
713 XenPci_FreeMem(err);
714 WdfChildListEndScan(child_list);
715 KdPrint((__DRIVER_NAME " Failed to read num-ports\n"));
716 return;
717 }
718 xudd->num_ports = (ULONG)parse_numeric_string(value);
719 XenPci_FreeMem(value);
720 KdPrint((__DRIVER_NAME " num-ports = %d\n", xudd->num_ports));
722 for (i = 0; i < 8; i++)
723 {
724 xudd->ports[i].port_number = i + 1;
725 xudd->ports[i].port_type = USB_PORT_TYPE_NOT_CONNECTED;
726 xudd->ports[i].port_status = 0; //1 << PORT_ENABLE;
727 xudd->ports[i].port_change = 0x0000;
728 }
730 /* only a single root hub is enumerated */
731 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description));
733 child_description.device_number = 0; //TODO: get the proper index from parent
735 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL);
736 if (!NT_SUCCESS(status))
737 {
738 KdPrint((__DRIVER_NAME " WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status));
739 }
741 WdfChildListEndScan(child_list);
743 FUNCTION_EXIT();
744 }
746 static VOID
747 XenUsb_EvtIoDeviceControl(
748 WDFQUEUE queue,
749 WDFREQUEST request,
750 size_t output_buffer_length,
751 size_t input_buffer_length,
752 ULONG io_control_code)
753 {
754 NTSTATUS status;
755 WDFDEVICE device = WdfIoQueueGetDevice(queue);
756 PXENUSB_DEVICE_DATA xudd = GetXudd(device);
757 //WDF_REQUEST_PARAMETERS wrp;
758 //PURB urb;
759 //xenusb_device_t *usb_device;
761 UNREFERENCED_PARAMETER(queue);
762 UNREFERENCED_PARAMETER(input_buffer_length);
763 UNREFERENCED_PARAMETER(output_buffer_length);
765 FUNCTION_ENTER();
767 status = STATUS_BAD_INITIAL_PC;
769 //WDF_REQUEST_PARAMETERS_INIT(&wrp);
770 //WdfRequestGetParameters(request, &wrp);
772 // these are in api\usbioctl.h
773 switch(io_control_code)
774 {
775 #if 0
776 case IOCTL_USB_GET_NODE_INFORMATION:
777 {
778 PUSB_NODE_INFORMATION uni;
779 size_t length;
781 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_INFORMATION\n"));
782 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
783 // make sure size is >= bDescriptorLength
784 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uni, &length);
785 if (NT_SUCCESS(status))
786 {
787 switch(uni->NodeType)
788 {
789 case UsbHub:
790 KdPrint((__DRIVER_NAME " NodeType = UsbHub\n"));
791 uni->u.HubInformation.HubDescriptor.bDescriptorLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask) + 3;
792 if (output_buffer_length >= FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3)
793 {
794 uni->u.HubInformation.HubDescriptor.bDescriptorType = 0x29;
795 uni->u.HubInformation.HubDescriptor.bNumberOfPorts = xudd->num_ports;
796 uni->u.HubInformation.HubDescriptor.wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
797 uni->u.HubInformation.HubDescriptor.bPowerOnToPowerGood = 1; // 2ms units
798 uni->u.HubInformation.HubDescriptor.bHubControlCurrent = 0;
799 // DeviceRemovable bits (includes an extra bit at the start)
800 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[0] = 0;
801 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[1] = 0;
802 // PortPwrCtrlMask
803 uni->u.HubInformation.HubDescriptor.bRemoveAndPowerMask[2] = 0xFF;
804 uni->u.HubInformation.HubIsBusPowered = TRUE;
805 }
806 WdfRequestSetInformation(request, FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3);
807 break;
808 case UsbMIParent:
809 KdPrint((__DRIVER_NAME " NodeType = UsbMIParent\n"));
810 status = STATUS_BAD_INITIAL_PC;
811 break;
812 }
813 }
814 else
815 {
816 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
817 }
818 break;
819 }
820 #endif
821 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
822 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"));
823 break;
824 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
825 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n"));
826 break;
827 case IOCTL_USB_GET_NODE_CONNECTION_NAME:
828 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_NAME\n"));
829 break;
830 case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
831 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_ON\n"));
832 break;
833 case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
834 KdPrint((__DRIVER_NAME " IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n"));
835 break;
836 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
837 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n"));
838 break;
839 case IOCTL_USB_GET_HUB_CAPABILITIES:
840 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_HUB_CAPABILITIES\n"));
841 break;
842 case IOCTL_USB_HUB_CYCLE_PORT:
843 KdPrint((__DRIVER_NAME " IOCTL_USB_HUB_CYCLE_PORT\n"));
844 break;
845 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
846 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n"));
847 break;
848 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
849 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n"));
850 break;
851 case IOCTL_USB_GET_ROOT_HUB_NAME:
852 {
853 PUSB_HCD_DRIVERKEY_NAME uhdn;
854 size_t length;
855 ULONG required_length = sizeof(USB_HCD_DRIVERKEY_NAME);
857 KdPrint((__DRIVER_NAME " IOCTL_USB_GET_ROOT_HUB_NAME\n"));
858 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
860 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
861 {
862 status = STATUS_BUFFER_TOO_SMALL;
863 }
864 else
865 {
866 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
867 if (NT_SUCCESS(status))
868 {
869 WDFSTRING symbolic_link_wdfstring;
870 UNICODE_STRING symbolic_link;
872 uhdn->DriverKeyName[0] = 0;
873 status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolic_link_wdfstring);
874 status = WdfDeviceRetrieveDeviceInterfaceString(xudd->root_hub_device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolic_link_wdfstring);
875 if (NT_SUCCESS(status))
876 {
877 WdfStringGetUnicodeString(symbolic_link_wdfstring, &symbolic_link);
878 /* remove leading \??\ from name */
879 symbolic_link.Buffer += 4;
880 symbolic_link.Length -= 4 * sizeof(WCHAR);
881 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + symbolic_link.Length + sizeof(WCHAR);
882 FUNCTION_MSG("output_buffer_length = %d\n", output_buffer_length);
883 FUNCTION_MSG("required_length = %d\n", required_length);
884 if (output_buffer_length >= required_length)
885 {
886 uhdn->ActualLength = required_length;
887 memcpy(uhdn->DriverKeyName, symbolic_link.Buffer, symbolic_link.Length);
888 uhdn->DriverKeyName[symbolic_link.Length / 2] = 0;
889 WdfRequestSetInformation(request, required_length);
890 }
891 else
892 {
893 uhdn->ActualLength = required_length;
894 uhdn->DriverKeyName[0] = 0;
895 status = STATUS_SUCCESS;
896 WdfRequestSetInformation(request, output_buffer_length);
897 }
898 }
899 else
900 {
901 KdPrint((__DRIVER_NAME " WdfDeviceRetrieveDeviceInterfaceString = %08x\n", status));
902 status = STATUS_INVALID_PARAMETER;
903 }
904 }
905 else
906 {
907 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
908 }
909 KdPrint((__DRIVER_NAME " uhdn->ActualLength = %d\n", uhdn->ActualLength));
910 KdPrint((__DRIVER_NAME " uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName));
911 }
912 break;
913 }
914 case IOCTL_GET_HCD_DRIVERKEY_NAME:
915 {
916 PUSB_HCD_DRIVERKEY_NAME uhdn;
917 size_t length;
918 ULONG required_length = sizeof(USB_HCD_DRIVERKEY_NAME);
920 KdPrint((__DRIVER_NAME " IOCTL_GET_HCD_DRIVERKEY_NAME\n"));
921 KdPrint((__DRIVER_NAME " output_buffer_length = %d\n", output_buffer_length));
923 if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME))
924 status = STATUS_BUFFER_TOO_SMALL;
925 else
926 {
927 status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
928 if (NT_SUCCESS(status))
929 {
930 ULONG key_length;
931 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName, 0, NULL, &key_length);
932 KdPrint((__DRIVER_NAME " key_length = %d\n", key_length));
933 status = STATUS_SUCCESS;
934 required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + key_length + 2;
935 uhdn->ActualLength = required_length;
936 FUNCTION_MSG("output_buffer_length = %d\n", output_buffer_length);
937 FUNCTION_MSG("required_length = %d\n", required_length);
938 if (output_buffer_length >= required_length)
939 {
940 status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName,
941 required_length - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), uhdn->DriverKeyName,
942 &key_length);
943 WdfRequestSetInformation(request, required_length);
944 }
945 else
946 {
947 uhdn->DriverKeyName[0] = 0;
948 status = STATUS_SUCCESS;
949 WdfRequestSetInformation(request, output_buffer_length);
950 }
951 FUNCTION_MSG(" uhdn->ActualLength = %d\n", uhdn->ActualLength);
952 FUNCTION_MSG(" uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName);
953 }
954 else
955 {
956 KdPrint((__DRIVER_NAME " WdfRequestRetrieveOutputBuffer = %08x\n", status));
957 }
958 }
959 break;
960 }
961 #if 0
962 case IOCTL_USB_RESET_HUB:
963 KdPrint((__DRIVER_NAME " IOCTL_USB_RESET_HUB\n"));
964 break;
965 #endif
966 default:
967 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
968 break;
969 }
970 KdPrint((__DRIVER_NAME " Calling WdfRequestComplete with status = %08x\n", status));
971 WdfRequestComplete(request, status);
973 FUNCTION_EXIT();
974 }
976 static VOID
977 XenUsb_EvtIoInternalDeviceControl(
978 WDFQUEUE queue,
979 WDFREQUEST request,
980 size_t output_buffer_length,
981 size_t input_buffer_length,
982 ULONG io_control_code)
983 {
984 //WDFDEVICE device = WdfIoQueueGetDevice(queue);
985 //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
986 PURB urb;
987 xenusb_device_t *usb_device;
988 WDF_REQUEST_PARAMETERS wrp;
990 UNREFERENCED_PARAMETER(queue);
991 UNREFERENCED_PARAMETER(input_buffer_length);
992 UNREFERENCED_PARAMETER(output_buffer_length);
994 FUNCTION_ENTER();
996 WDF_REQUEST_PARAMETERS_INIT(&wrp);
997 WdfRequestGetParameters(request, &wrp);
999 switch(io_control_code)
1001 case IOCTL_INTERNAL_USB_SUBMIT_URB:
1002 FUNCTION_MSG("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
1003 urb = (PURB)wrp.Parameters.Others.Arg1;
1004 FUNCTION_MSG("urb = %p\n", urb);
1005 ASSERT(urb);
1006 usb_device = urb->UrbHeader.UsbdDeviceHandle;
1007 FUNCTION_MSG("usb_device = %p\n", usb_device);
1008 ASSERT(usb_device);
1009 if (usb_device == (xenusb_device_t *)((ULONG_PTR)0 - 1))
1010 WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
1011 else
1012 WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
1013 break;
1014 default:
1015 KdPrint((__DRIVER_NAME " Unknown IOCTL %08x\n", io_control_code));
1016 WdfRequestComplete(request, WdfRequestGetStatus(request));
1017 break;
1019 FUNCTION_EXIT();
1022 static VOID
1023 XenUsb_EvtIoDefault(
1024 WDFQUEUE queue,
1025 WDFREQUEST request)
1027 NTSTATUS status;
1028 WDF_REQUEST_PARAMETERS parameters;
1030 FUNCTION_ENTER();
1032 UNREFERENCED_PARAMETER(queue);
1034 status = STATUS_BAD_INITIAL_PC;
1036 WDF_REQUEST_PARAMETERS_INIT(&parameters);
1037 WdfRequestGetParameters(request, &parameters);
1039 switch (parameters.Type)
1041 case WdfRequestTypeCreate:
1042 KdPrint((__DRIVER_NAME " WdfRequestTypeCreate\n"));
1043 break;
1044 case WdfRequestTypeClose:
1045 KdPrint((__DRIVER_NAME " WdfRequestTypeClose\n"));
1046 break;
1047 case WdfRequestTypeRead:
1048 KdPrint((__DRIVER_NAME " WdfRequestTypeRead\n"));
1049 break;
1050 case WdfRequestTypeWrite:
1051 KdPrint((__DRIVER_NAME " WdfRequestTypeWrite\n"));
1052 break;
1053 case WdfRequestTypeDeviceControl:
1054 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControl\n"));
1055 break;
1056 case WdfRequestTypeDeviceControlInternal:
1057 KdPrint((__DRIVER_NAME " WdfRequestTypeDeviceControlInternal\n"));
1058 break;
1059 default:
1060 KdPrint((__DRIVER_NAME " Unknown type %x\n", parameters.Type));
1061 break;
1063 WdfRequestComplete(request, status);
1065 FUNCTION_EXIT();
1068 NTSTATUS
1069 XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
1071 NTSTATUS status;
1072 WDF_CHILD_LIST_CONFIG child_list_config;
1073 WDFDEVICE device;
1074 PXENUSB_DEVICE_DATA xudd;
1075 //UNICODE_STRING reference;
1076 WDF_OBJECT_ATTRIBUTES device_attributes;
1077 PNP_BUS_INFORMATION pbi;
1078 WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
1079 WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
1080 WDF_IO_QUEUE_CONFIG queue_config;
1081 UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
1082 DECLARE_CONST_UNICODE_STRING(symbolicname_name, L"SymbolicName");
1083 WDFSTRING symbolicname_value_wdfstring;
1084 WDFKEY device_key;
1085 UNICODE_STRING symbolicname_value;
1087 UNREFERENCED_PARAMETER(driver);
1089 FUNCTION_ENTER();
1091 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
1092 pnp_power_callbacks.EvtDeviceD0Entry = XenUsb_EvtDeviceD0Entry;
1093 pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
1094 pnp_power_callbacks.EvtDeviceD0Exit = XenUsb_EvtDeviceD0Exit;
1095 pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
1096 pnp_power_callbacks.EvtDevicePrepareHardware = XenUsb_EvtDevicePrepareHardware;
1097 pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsb_EvtDeviceReleaseHardware;
1098 pnp_power_callbacks.EvtDeviceQueryRemove = XenUsb_EvtDeviceQueryRemove;
1099 //pnp_power_callbacks.EvtDeviceUsageNotification = XenUsb_EvtDeviceUsageNotification;
1101 WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
1103 status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE,
1104 IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
1105 if (!NT_SUCCESS(status))
1107 return status;
1110 WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER);
1111 WdfDeviceInitSetExclusive(device_init, FALSE);
1113 WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENUSB_PDO_IDENTIFICATION_DESCRIPTION), XenUsb_EvtChildListCreateDevice);
1114 child_list_config.EvtChildListScanForChildren = XenUsb_EvtChildListScanForChildren;
1115 WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES);
1117 WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered);
1119 WdfDeviceInitSetPowerNotPageable(device_init);
1121 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENUSB_DEVICE_DATA);
1122 status = WdfDeviceCreate(&device_init, &device_attributes, &device);
1123 if (!NT_SUCCESS(status))
1125 KdPrint(("Error creating device %08x\n", status));
1126 return status;
1129 xudd = GetXudd(device);
1130 xudd->child_list = WdfFdoGetDefaultChildList(device);
1132 KeInitializeSpinLock(&xudd->urb_ring_lock);
1134 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
1135 queue_config.PowerManaged = FALSE; /* ? */
1136 queue_config.EvtIoDeviceControl = XenUsb_EvtIoDeviceControl;
1137 queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl;
1138 queue_config.EvtIoDefault = XenUsb_EvtIoDefault;
1139 status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->io_queue);
1140 if (!NT_SUCCESS(status)) {
1141 KdPrint((__DRIVER_NAME " Error creating io_queue 0x%x\n", status));
1142 return status;
1145 WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities);
1146 power_capabilities.DeviceD1 = WdfTrue;
1147 power_capabilities.WakeFromD1 = WdfTrue;
1148 power_capabilities.DeviceWake = PowerDeviceD1;
1149 power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD0;
1150 power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
1151 power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
1152 power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
1153 power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
1154 power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1155 WdfDeviceSetPowerCapabilities(device, &power_capabilities);
1157 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE);
1158 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE);
1159 WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE);
1161 pbi.BusTypeGuid = GUID_BUS_TYPE_XEN;
1162 pbi.LegacyBusType = PNPBus;
1163 pbi.BusNumber = 0;
1164 WdfDeviceSetBusInformationForChildren(device, &pbi);
1166 status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL);
1167 if (!NT_SUCCESS(status))
1168 return status;
1170 /* USB likes to have a registry key with the symbolic link name in it */
1171 status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolicname_value_wdfstring);
1172 status = WdfDeviceRetrieveDeviceInterfaceString(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, symbolicname_value_wdfstring);
1173 if (!NT_SUCCESS(status))
1174 return status;
1175 WdfStringGetUnicodeString(symbolicname_value_wdfstring, &symbolicname_value);
1176 status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &device_key);
1177 WdfRegistryAssignUnicodeString(device_key, &symbolicname_name, &symbolicname_value);
1179 FUNCTION_EXIT();
1180 return status;