[CMAKE]
[reactos.git] / drivers / usb / usbehci / pdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/pdo.c
5 * PURPOSE: USB EHCI device driver.
6 * PROGRAMMERS:
7 * Michael Martin
8 */
9
10 #define INITGUID
11
12 #include "usbehci.h"
13 #include <hubbusif.h>
14 #include <usbbusif.h>
15 #include "usbiffn.h"
16 #include <wdmguid.h>
17 #include <stdio.h>
18 #include <debug.h>
19
20 /* Lifted from Linux with slight changes */
21 const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR [] =
22 {
23 0x12, /* bLength; */
24 USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType; Device */
25 0x00, 0x20, /* bcdUSB; v1.1 */
26 USB_DEVICE_CLASS_HUB, /* bDeviceClass; HUB_CLASSCODE */
27 0x01, /* bDeviceSubClass; */
28 0x00, /* bDeviceProtocol; [ low/full speeds only ] */
29 0x08, /* bMaxPacketSize0; 8 Bytes */
30 /* Fill Vendor and Product in when init root hub */
31 0x00, 0x00, /* idVendor; */
32 0x00, 0x00, /* idProduct; */
33 0x00, 0x00, /* bcdDevice */
34 0x00, /* iManufacturer; */
35 0x00, /* iProduct; */
36 0x00, /* iSerialNumber; */
37 0x01 /* bNumConfigurations; */
38
39 };
40
41 const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
42 {
43 /* one configuration */
44 0x09, /* bLength; */
45 0x02, /* bDescriptorType; Configuration */
46 0x19, 0x00, /* wTotalLength; */
47 0x01, /* bNumInterfaces; (1) */
48 0x23, /* bConfigurationValue; */
49 0x00, /* iConfiguration; */
50 0x40, /* bmAttributes;
51 Bit 7: must be set,
52 6: Self-powered,
53 5: Remote wakeup,
54 4..0: reserved */
55 0x00 /* MaxPower; */
56 };
57
58 const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
59 {
60 /* one interface */
61 0x09, /* bLength: Interface; */
62 0x04, /* bDescriptorType; Interface */
63 0x00, /* bInterfaceNumber; */
64 0x00, /* bAlternateSetting; */
65 0x01, /* bNumEndpoints; */
66 0x09, /* bInterfaceClass; HUB_CLASSCODE */
67 0x01, /* bInterfaceSubClass; */
68 0x00, /* bInterfaceProtocol: */
69 0x00 /* iInterface; */
70 };
71
72 const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
73 {
74 /* one endpoint (status change endpoint) */
75 0x07, /* bLength; */
76 0x05, /* bDescriptorType; Endpoint */
77 0x81, /* bEndpointAddress; IN Endpoint 1 */
78 0x03, /* bmAttributes; Interrupt */
79 0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
80 0xFF /* bInterval; (255ms -- usb 2.0 spec) */
81 };
82
83 /* FIXME: Do something better */
84 VOID NTAPI
85 UrbWorkerThread(PVOID Context)
86 {
87 PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context;
88 NTSTATUS Status;
89 LARGE_INTEGER DueTime;
90 PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer };
91
92 DueTime.QuadPart = 0;
93 KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer);
94 KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL);
95
96 while (TRUE)
97 {
98 Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL);
99
100 if (!PdoDeviceExtension->HaltQueue)
101 KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent);
102 CompletePendingURBRequest(PdoDeviceExtension);
103 }
104
105 DPRINT1("Thread terminated\n");
106 }
107
108 NTSTATUS NTAPI
109 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
110 {
111 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
112 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
113 PIO_STACK_LOCATION Stack = NULL;
114 NTSTATUS Status = STATUS_UNSUCCESSFUL;
115 ULONG_PTR Information = 0;
116
117 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
118 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
119
120 ASSERT(PdoDeviceExtension->Common.IsFdo == FALSE);
121
122 Stack = IoGetCurrentIrpStackLocation(Irp);
123
124 switch(Stack->Parameters.DeviceIoControl.IoControlCode)
125 {
126 case IOCTL_INTERNAL_USB_SUBMIT_URB:
127 {
128 URB *Urb;
129
130 Urb = (PURB) Stack->Parameters.Others.Argument1;
131 DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
132 DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
133 /* Queue all request for now, kernel thread will complete them */
134 QueueURBRequest(PdoDeviceExtension, Irp);
135 Information = 0;
136 IoMarkIrpPending(Irp);
137 Status = STATUS_PENDING;
138 break;
139 }
140 case IOCTL_INTERNAL_USB_CYCLE_PORT:
141 {
142 DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
143 break;
144 }
145 case IOCTL_INTERNAL_USB_ENABLE_PORT:
146 {
147 DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
148 Information = 0;
149 Status = STATUS_SUCCESS;
150 break;
151 }
152 case IOCTL_INTERNAL_USB_GET_BUS_INFO:
153 {
154 DPRINT1("IOCTL_INTERNAL_USB_GET_BUS_INFO\n");
155 break;
156 }
157 case IOCTL_INTERNAL_USB_GET_BUSGUID_INFO:
158 {
159 DPRINT1("IOCTL_INTERNAL_USB_GET_BUSGUID_INFO\n");
160 break;
161 }
162 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
163 {
164 DPRINT1("IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n");
165 break;
166 }
167 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
168 {
169 DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
170 if (Stack->Parameters.Others.Argument1)
171 {
172 /* Return the root hubs devicehandle */
173 DPRINT1("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]);
174 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
175 Status = STATUS_SUCCESS;
176 }
177 else
178 Status = STATUS_INVALID_DEVICE_REQUEST;
179
180 break;
181
182 }
183 case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
184 {
185 DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
186 ASSERT(Stack->Parameters.Others.Argument1 != NULL);
187 if (Stack->Parameters.Others.Argument1)
188 {
189 /* FIXME: Determine the number of hubs between the usb device and root hub */
190 DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1);
191 *(PULONG)Stack->Parameters.Others.Argument1 = 0;
192 }
193 Status = STATUS_SUCCESS;
194 break;
195 }
196 case IOCTL_INTERNAL_USB_GET_HUB_NAME:
197 {
198 DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_NAME\n");
199 break;
200 }
201 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
202 {
203 DPRINT1("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
204 break;
205 }
206 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
207 {
208 DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
209 break;
210 }
211 case IOCTL_INTERNAL_USB_RESET_PORT:
212 {
213 DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
214 break;
215 }
216 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
217 {
218 DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
219
220 if (Stack->Parameters.Others.Argument1)
221 *(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo;
222 if (Stack->Parameters.Others.Argument2)
223 *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
224
225 Information = 0;
226 Status = STATUS_SUCCESS;
227 break;
228 }
229 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
230 {
231 PUSB_IDLE_CALLBACK_INFO CallBackInfo;
232 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
233 /* FIXME: Set Callback for safe power down */
234 CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
235 DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
236 DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext);
237
238 PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback;
239 PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext;
240
241 Information = 0;
242 Status = STATUS_SUCCESS;
243 break;
244 }
245 default:
246 {
247 DPRINT1("Unhandled IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
248 break;
249 }
250 }
251
252 Irp->IoStatus.Information = Information;
253
254 if (Status != STATUS_PENDING)
255 IoCompleteRequest(Irp, IO_NO_INCREMENT);
256
257 return Status;
258 }
259
260 NTSTATUS
261 PdoQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG_PTR* Information)
262 {
263 WCHAR Buffer[256];
264 ULONG Index = 0;
265 ULONG IdType;
266 UNICODE_STRING SourceString;
267 UNICODE_STRING String;
268 NTSTATUS Status;
269
270 IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
271
272 switch (IdType)
273 {
274 case BusQueryDeviceID:
275 {
276 RtlInitUnicodeString(&SourceString, L"USB\\ROOT_HUB20");
277 break;
278 }
279 case BusQueryHardwareIDs:
280 {
281 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
282 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C") + 1;
283 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
284
285 Buffer[Index] = UNICODE_NULL;
286 SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
287 SourceString.Buffer = Buffer;
288 break;
289
290 }
291 case BusQueryCompatibleIDs:
292 {
293 /* We have none */
294 return STATUS_SUCCESS;
295 }
296 case BusQueryInstanceID:
297 {
298 return STATUS_SUCCESS;
299 }
300 default:
301 {
302 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
303 return STATUS_NOT_SUPPORTED;
304 }
305 }
306
307 Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
308 &SourceString,
309 &String);
310
311 *Information = (ULONG_PTR)String.Buffer;
312 return Status;
313 }
314
315 NTSTATUS
316 PdoQueryDeviceRelations(PDEVICE_OBJECT DeviceObject, PDEVICE_RELATIONS* pDeviceRelations)
317 {
318 PDEVICE_RELATIONS DeviceRelations;
319
320 DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
321 if (!DeviceRelations)
322 return STATUS_INSUFFICIENT_RESOURCES;
323
324 DeviceRelations->Count = 1;
325 DeviceRelations->Objects[0] = DeviceObject;
326 ObReferenceObject(DeviceObject);
327
328 *pDeviceRelations = DeviceRelations;
329 return STATUS_SUCCESS;
330 }
331
332 NTSTATUS NTAPI
333 PdoDispatchPnp(
334 IN PDEVICE_OBJECT DeviceObject,
335 IN PIRP Irp)
336 {
337 ULONG MinorFunction;
338 PIO_STACK_LOCATION Stack;
339 ULONG_PTR Information = Irp->IoStatus.Information;
340 NTSTATUS Status = Irp->IoStatus.Status;
341
342 Stack = IoGetCurrentIrpStackLocation(Irp);
343 MinorFunction = Stack->MinorFunction;
344
345 switch (MinorFunction)
346 {
347 case IRP_MN_QUERY_REMOVE_DEVICE:
348 case IRP_MN_REMOVE_DEVICE:
349 case IRP_MN_CANCEL_REMOVE_DEVICE:
350 case IRP_MN_STOP_DEVICE:
351 case IRP_MN_QUERY_STOP_DEVICE:
352 case IRP_MN_CANCEL_STOP_DEVICE:
353 case IRP_MN_QUERY_DEVICE_TEXT:
354 case IRP_MN_SURPRISE_REMOVAL:
355 case IRP_MN_QUERY_RESOURCES:
356 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
357 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
358 {
359 Status = STATUS_SUCCESS;
360 break;
361 }
362
363 case IRP_MN_START_DEVICE:
364 {
365 PUSB_DEVICE RootHubDevice;
366 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
367 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
368 UNICODE_STRING InterfaceSymLinkName;
369 LONG i;
370
371 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
372 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
373
374 /* Create the root hub */
375 RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
376
377 for (i = 0; i < 8; i++)
378 {
379 PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
380 PdoDeviceExtension->Ports[i].PortChange = 0;
381 }
382
383 RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
384 ROOTHUB2_DEVICE_DESCRIPTOR,
385 sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
386
387 RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
388 RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
389
390 /* FIXME: Do something better below */
391
392 RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
393 sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
394 USB_POOL_TAG);
395
396 RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool,
397 sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[4],
398 USB_POOL_TAG);
399
400 RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool,
401 sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[4],
402 USB_POOL_TAG);
403
404 RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool,
405 sizeof(USB_ENDPOINT),
406 USB_POOL_TAG);
407
408 RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
409 RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];
410
411 RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
412 ROOTHUB2_CONFIGURATION_DESCRIPTOR,
413 sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));
414
415 RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor,
416 ROOTHUB2_INTERFACE_DESCRIPTOR,
417 sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR));
418
419 RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor,
420 ROOTHUB2_ENDPOINT_DESCRIPTOR,
421 sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR));
422 RootHubDevice->DeviceSpeed = UsbHighSpeed;
423 RootHubDevice->DeviceType = Usb20Device;
424
425 PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
426
427 /* Create a thread to handle the URB's */
428
429 Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
430 THREAD_ALL_ACCESS,
431 NULL,
432 NULL,
433 NULL,
434 UrbWorkerThread,
435 (PVOID)PdoDeviceExtension);
436
437 if (!NT_SUCCESS(Status))
438 DPRINT1("Failed Thread Creation with Status: %x\n", Status);
439
440 Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName);
441 if (!NT_SUCCESS(Status))
442 {
443 DPRINT1("Failed to register interface\n");
444 ASSERT(FALSE);
445 }
446 else
447 {
448 Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
449 if (!NT_SUCCESS(Status))
450 ASSERT(FALSE);
451 }
452
453 Status = STATUS_SUCCESS;
454 break;
455 }
456 case IRP_MN_QUERY_DEVICE_RELATIONS:
457 {
458 switch (Stack->Parameters.QueryDeviceRelations.Type)
459 {
460 case TargetDeviceRelation:
461 {
462 PDEVICE_RELATIONS DeviceRelations = NULL;
463 Status = PdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
464 Information = (ULONG_PTR)DeviceRelations;
465 break;
466 }
467 case BusRelations:
468 {
469 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
470 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
471
472 DPRINT1("BusRelations!!!!!\n");
473
474 /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
475 has resent this IRP and type, so leave the next SCE request pending until a new device arrives.
476 Is there a better way to do this */
477 ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
478 PdoDeviceExtension->HaltQueue = TRUE;
479 ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
480 }
481 case RemovalRelations:
482 case EjectionRelations:
483 {
484 /* Ignore the request */
485 Information = Irp->IoStatus.Information;
486 Status = Irp->IoStatus.Status;
487 break;
488
489 }
490 default:
491 {
492 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
493 Stack->Parameters.QueryDeviceRelations.Type);
494 Status = STATUS_NOT_SUPPORTED;
495 break;
496 }
497 }
498 break;
499 }
500 case IRP_MN_QUERY_CAPABILITIES:
501 {
502 PDEVICE_CAPABILITIES DeviceCapabilities;
503 ULONG i;
504
505 DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
506
507 DeviceCapabilities->LockSupported = FALSE;
508 DeviceCapabilities->EjectSupported = FALSE;
509 DeviceCapabilities->Removable = FALSE;
510 DeviceCapabilities->DockDevice = FALSE;
511 DeviceCapabilities->UniqueID = FALSE;
512 DeviceCapabilities->SilentInstall = FALSE;
513 DeviceCapabilities->RawDeviceOK = FALSE;
514 DeviceCapabilities->SurpriseRemovalOK = FALSE;
515 DeviceCapabilities->Address = 0;
516 DeviceCapabilities->UINumber = 0;
517 DeviceCapabilities->DeviceD2 = 1;
518
519 /* FIXME */
520 DeviceCapabilities->HardwareDisabled = FALSE;
521 //DeviceCapabilities->NoDisplayInUI = FALSE;
522 DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
523 for (i = 0; i < PowerSystemMaximum; i++)
524 DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
525 DeviceCapabilities->DeviceWake = 0;
526 DeviceCapabilities->D1Latency = 0;
527 DeviceCapabilities->D2Latency = 0;
528 DeviceCapabilities->D3Latency = 0;
529 Information = 0;
530 Status = STATUS_SUCCESS;
531 break;
532 }
533 /*case IRP_MN_QUERY_DEVICE_TEXT:
534 {
535 Status = STATUS_NOT_SUPPORTED;
536 break;
537 }*/
538
539 case IRP_MN_QUERY_ID:
540 {
541 Status = PdoQueryId(DeviceObject, Irp, &Information);
542 break;
543 }
544 case IRP_MN_QUERY_INTERFACE:
545 {
546 UNICODE_STRING GuidString;
547 PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
548 PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
549 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
550 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
551
552 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
553 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
554
555 Status = RtlStringFromGUID(Stack->Parameters.QueryInterface.InterfaceType, &GuidString);
556 if (!NT_SUCCESS(Status))
557 {
558 DPRINT1("Failed to create string from GUID!\n");
559 }
560
561 DPRINT("Interface GUID requested %wZ\n", &GuidString);
562 DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
563 DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
564
565 /* Assume success */
566 Status = STATUS_SUCCESS;
567 Information = 0;
568
569 if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID))
570 {
571 InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
572 InterfaceHub->Version = Stack->Parameters.QueryInterface.Version;
573 if (Stack->Parameters.QueryInterface.Version >= 0)
574 {
575 InterfaceHub->Size = Stack->Parameters.QueryInterface.Size;
576 InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
577 InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
578 InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
579 }
580 if (Stack->Parameters.QueryInterface.Version >= 1)
581 {
582 InterfaceHub->CreateUsbDevice = CreateUsbDevice;
583 InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
584 InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
585 InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
586 InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
587 InterfaceHub->GetPortHackFlags = GetPortHackFlags;
588 InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
589 }
590 if (Stack->Parameters.QueryInterface.Version >= 2)
591 {
592 InterfaceHub->GetControllerInformation = GetControllerInformation;
593 InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
594 InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
595 InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
596 InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
597 InterfaceHub->Initialize20Hub = Initialize20Hub;
598
599 }
600 if (Stack->Parameters.QueryInterface.Version >= 3)
601 {
602 InterfaceHub->RootHubInitNotification = RootHubInitNotification;
603 }
604 if (Stack->Parameters.QueryInterface.Version >= 4)
605 {
606 InterfaceHub->FlushTransfers = FlushTransfers;
607 }
608 if (Stack->Parameters.QueryInterface.Version >= 5)
609 {
610 InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
611 }
612 if (Stack->Parameters.QueryInterface.Version >= 6)
613 {
614 DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
615 }
616 break;
617 }
618
619 if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
620 {
621 InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
622 InterfaceDI->Version = Stack->Parameters.QueryInterface.Version;
623 if (Stack->Parameters.QueryInterface.Version >= 0)
624 {
625 //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
626 InterfaceDI->Size = Stack->Parameters.QueryInterface.Size;
627 InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
628 InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
629 InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
630 InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
631 InterfaceDI->QueryBusTime = QueryBusTime;
632 InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
633 InterfaceDI->QueryBusInformation = QueryBusInformation;
634 }
635 if (Stack->Parameters.QueryInterface.Version >= 1)
636 {
637 InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
638 }
639 if (Stack->Parameters.QueryInterface.Version >= 2)
640 {
641 InterfaceDI->EnumLogEntry = EnumLogEntry;
642 }
643
644 if (Stack->Parameters.QueryInterface.Version >= 3)
645 {
646 DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
647 }
648 break;
649 }
650
651 DPRINT1("GUID Not Supported\n");
652 Status = Irp->IoStatus.Status;
653 Information = Irp->IoStatus.Information;
654
655 break;
656 }
657 case IRP_MN_QUERY_BUS_INFORMATION:
658 {
659 PPNP_BUS_INFORMATION BusInfo;
660
661 BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
662 if (!BusInfo)
663 Status = STATUS_INSUFFICIENT_RESOURCES;
664 else
665 {
666 /* FIXME */
667 /*RtlCopyMemory(
668 &BusInfo->BusTypeGuid,
669 &GUID_DEVINTERFACE_XXX,
670 sizeof(GUID));*/
671
672 BusInfo->LegacyBusType = PNPBus;
673 BusInfo->BusNumber = 0;
674 Information = (ULONG_PTR)BusInfo;
675 Status = STATUS_SUCCESS;
676 }
677 break;
678 }
679 default:
680 {
681 /* We are the PDO. So ignore */
682 DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
683 break;
684 }
685 }
686
687 Irp->IoStatus.Information = Information;
688 Irp->IoStatus.Status = Status;
689 IoCompleteRequest(Irp, IO_NO_INCREMENT);
690 return Status;
691 }