xref: /reactos/drivers/usb/usbport/iface.c (revision c2c66aff)
1 /*
2  * PROJECT:     ReactOS USB Port Driver
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     USBPort interface functions
5  * COPYRIGHT:   Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6  */
7 
8 #include "usbport.h"
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 VOID
14 USB_BUSIFFN
15 USBI_InterfaceReference(IN PVOID BusContext)
16 {
17     DPRINT("USBI_InterfaceReference \n");
18 }
19 
20 VOID
21 USB_BUSIFFN
22 USBI_InterfaceDereference(IN PVOID BusContext)
23 {
24     DPRINT("USBI_InterfaceDereference \n");
25 }
26 
27 /* USB port driver Interface functions */
28 
29 NTSTATUS
30 USB_BUSIFFN
31 USBHI_CreateUsbDevice(IN PVOID BusContext,
32                       IN OUT PUSB_DEVICE_HANDLE *UsbdDeviceHandle,
33                       IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
34                       IN USHORT PortStatus,
35                       IN USHORT PortNumber)
36 {
37     PDEVICE_OBJECT PdoDevice;
38     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
39     PUSB_DEVICE_HANDLE deviceHandle = NULL;
40     NTSTATUS Status;
41 
42     DPRINT("USBHI_CreateUsbDevice: ... \n");
43 
44     PdoDevice = BusContext;
45     PdoExtension = PdoDevice->DeviceExtension;
46 
47     Status = USBPORT_CreateDevice(&deviceHandle,
48                                   PdoExtension->FdoDevice,
49                                   (PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
50                                   PortStatus,
51                                   PortNumber);
52 
53     *UsbdDeviceHandle = deviceHandle;
54 
55     return Status;
56 }
57 
58 NTSTATUS
59 USB_BUSIFFN
60 USBHI_InitializeUsbDevice(IN PVOID BusContext,
61                           OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
62 {
63     PDEVICE_OBJECT PdoDevice;
64     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
65 
66     DPRINT("USBHI_InitializeUsbDevice \n");
67 
68     PdoDevice = BusContext;
69     PdoExtension = PdoDevice->DeviceExtension;
70 
71     return USBPORT_InitializeDevice((PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
72                                     PdoExtension->FdoDevice);
73 }
74 
75 NTSTATUS
76 USB_BUSIFFN
77 USBHI_GetUsbDescriptors(IN PVOID BusContext,
78                         IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
79                         IN PUCHAR DeviceDescBuffer,
80                         IN PULONG DeviceDescBufferLen,
81                         IN PUCHAR ConfigDescBuffer,
82                         IN PULONG ConfigDescBufferLen)
83 {
84     PDEVICE_OBJECT PdoDevice;
85     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
86     PUSBPORT_DEVICE_HANDLE DeviceHandle;
87 
88     NTSTATUS Status;
89 
90     DPRINT("USBHI_GetUsbDescriptors ...\n");
91 
92     PdoDevice = BusContext;
93     PdoExtension = PdoDevice->DeviceExtension;
94     DeviceHandle = (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle;
95 
96     if (DeviceDescBuffer && *DeviceDescBufferLen)
97     {
98         if (*DeviceDescBufferLen > sizeof(USB_DEVICE_DESCRIPTOR))
99             *DeviceDescBufferLen = sizeof(USB_DEVICE_DESCRIPTOR);
100 
101         RtlCopyMemory(DeviceDescBuffer,
102                       &DeviceHandle->DeviceDescriptor,
103                       *DeviceDescBufferLen);
104     }
105 
106     Status = USBPORT_GetUsbDescriptor(DeviceHandle,
107                                       PdoExtension->FdoDevice,
108                                       USB_CONFIGURATION_DESCRIPTOR_TYPE,
109                                       ConfigDescBuffer,
110                                       ConfigDescBufferLen);
111 
112     USBPORT_DumpingDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescBuffer);
113 
114     return Status;
115 }
116 
117 NTSTATUS
118 USB_BUSIFFN
119 USBHI_RemoveUsbDevice(IN PVOID BusContext,
120                       IN OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle,
121                       IN ULONG Flags)
122 {
123     PDEVICE_OBJECT PdoDevice;
124     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
125 
126     DPRINT("USBHI_RemoveUsbDevice: UsbdDeviceHandle - %p, Flags - %x\n",
127            UsbdDeviceHandle,
128            Flags);
129 
130     PdoDevice = BusContext;
131     PdoExtension = PdoDevice->DeviceExtension;
132 
133     return USBPORT_RemoveDevice(PdoExtension->FdoDevice,
134                                 (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
135                                 Flags);
136 }
137 
138 NTSTATUS
139 USB_BUSIFFN
140 USBHI_RestoreUsbDevice(IN PVOID BusContext,
141                        OUT PUSB_DEVICE_HANDLE OldUsbdDeviceHandle,
142                        OUT PUSB_DEVICE_HANDLE NewUsbdDeviceHandle)
143 {
144     PDEVICE_OBJECT PdoDevice;
145     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
146 
147     DPRINT("USBHI_RestoreUsbDevice: OldUsbdDeviceHandle - %p, NewUsbdDeviceHandle - %x\n",
148            OldUsbdDeviceHandle,
149            NewUsbdDeviceHandle);
150 
151     PdoDevice = BusContext;
152     PdoExtension = PdoDevice->DeviceExtension;
153 
154     return USBPORT_RestoreDevice(PdoExtension->FdoDevice,
155                                 (PUSBPORT_DEVICE_HANDLE)OldUsbdDeviceHandle,
156                                 (PUSBPORT_DEVICE_HANDLE)NewUsbdDeviceHandle);
157 }
158 
159 NTSTATUS
160 USB_BUSIFFN
161 USBHI_QueryDeviceInformation(IN PVOID BusContext,
162                              IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
163                              OUT PVOID DeviceInfoBuffer,
164                              IN ULONG DeviceInfoBufferLen,
165                              OUT PULONG LenDataReturned)
166 {
167     PUSB_DEVICE_INFORMATION_0 DeviceInfo;
168     PUSBPORT_CONFIGURATION_HANDLE ConfigHandle;
169     PLIST_ENTRY InterfaceEntry;
170     PUSBPORT_DEVICE_HANDLE DeviceHandle;
171     ULONG NumberOfOpenPipes = 0;
172     PUSB_PIPE_INFORMATION_0 PipeInfo;
173     PUSBPORT_PIPE_HANDLE PipeHandle;
174     PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
175     ULONG ActualLength;
176     ULONG ix;
177 
178     DPRINT("USBHI_QueryDeviceInformation: ... \n");
179 
180     *LenDataReturned = 0;
181 
182     if (DeviceInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
183     {
184         return STATUS_BUFFER_TOO_SMALL;
185     }
186 
187     DeviceInfo = DeviceInfoBuffer;
188 
189     if (DeviceInfo->InformationLevel > 0)
190     {
191         return STATUS_NOT_SUPPORTED;
192     }
193 
194     DeviceHandle = UsbdDeviceHandle;
195     ConfigHandle = DeviceHandle->ConfigHandle;
196 
197     if (ConfigHandle)
198     {
199         InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
200 
201         while (InterfaceEntry &&
202                InterfaceEntry != &ConfigHandle->InterfaceHandleList)
203         {
204             InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
205                                                 USBPORT_INTERFACE_HANDLE,
206                                                 InterfaceLink);
207 
208             NumberOfOpenPipes += InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
209 
210             InterfaceEntry = InterfaceEntry->Flink;
211         }
212     }
213 
214     ActualLength = sizeof(USB_DEVICE_INFORMATION_0) +
215                    (NumberOfOpenPipes - 1) * sizeof(USB_PIPE_INFORMATION_0);
216 
217     if (DeviceInfoBufferLen < ActualLength)
218     {
219         DeviceInfo->ActualLength = ActualLength;
220         *LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
221 
222         return STATUS_BUFFER_TOO_SMALL;
223     }
224 
225     RtlZeroMemory(DeviceInfo, ActualLength);
226 
227     DeviceInfo->InformationLevel = 0;
228     DeviceInfo->ActualLength = ActualLength;
229     DeviceInfo->DeviceAddress = DeviceHandle->DeviceAddress;
230     DeviceInfo->NumberOfOpenPipes = NumberOfOpenPipes;
231     DeviceInfo->DeviceSpeed = DeviceHandle->DeviceSpeed;
232 
233     RtlCopyMemory(&DeviceInfo->DeviceDescriptor,
234                   &DeviceHandle->DeviceDescriptor,
235                   sizeof(USB_DEVICE_DESCRIPTOR));
236 
237     USBPORT_DumpingDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
238 
239     if (DeviceHandle->DeviceSpeed == UsbFullSpeed ||
240         DeviceHandle->DeviceSpeed == UsbLowSpeed)
241     {
242         DeviceInfo->DeviceType = Usb11Device;
243     }
244     else if (DeviceHandle->DeviceSpeed == UsbHighSpeed)
245     {
246         DeviceInfo->DeviceType = Usb20Device;
247     }
248 
249     DeviceInfo->CurrentConfigurationValue = 0;
250 
251     if (!ConfigHandle)
252     {
253         *LenDataReturned = ActualLength;
254         return STATUS_SUCCESS;
255     }
256 
257     DeviceInfo->CurrentConfigurationValue =
258         ConfigHandle->ConfigurationDescriptor->bConfigurationValue;
259 
260     InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
261 
262     while (InterfaceEntry &&
263            InterfaceEntry != &ConfigHandle->InterfaceHandleList)
264     {
265         InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
266                                             USBPORT_INTERFACE_HANDLE,
267                                             InterfaceLink);
268 
269         if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints > 0)
270         {
271             PipeInfo = &DeviceInfo->PipeList[0];
272             PipeHandle = &InterfaceHandle->PipeHandle[0];
273 
274             for (ix = 0;
275                  ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
276                  ix++)
277             {
278                 if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
279                 {
280                     PipeInfo->ScheduleOffset = 1;
281                 }
282                 else
283                 {
284                     PipeInfo->ScheduleOffset =
285                         PipeHandle->Endpoint->EndpointProperties.ScheduleOffset;
286                 }
287 
288                 RtlCopyMemory(&PipeInfo->EndpointDescriptor,
289                               &PipeHandle->EndpointDescriptor,
290                               sizeof(USB_ENDPOINT_DESCRIPTOR));
291 
292                 PipeInfo += 1;
293                 PipeHandle += 1;
294             }
295         }
296 
297         InterfaceEntry = InterfaceEntry->Flink;
298     }
299 
300     *LenDataReturned = ActualLength;
301 
302     return STATUS_SUCCESS;
303 }
304 
305 NTSTATUS
306 USB_BUSIFFN
307 USBHI_GetControllerInformation(IN PVOID BusContext,
308                                OUT PVOID ControllerInfoBuffer,
309                                IN ULONG ControllerInfoBufferLen,
310                                OUT PULONG LenDataReturned)
311 {
312     PDEVICE_OBJECT PdoDevice;
313     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
314     PDEVICE_OBJECT FdoDevice;
315     PUSBPORT_DEVICE_EXTENSION FdoExtension;
316     PUSB_CONTROLLER_INFORMATION_0 InfoBuffer;
317     NTSTATUS Status;
318 
319     DPRINT("USBHI_GetControllerInformation: ControllerInfoBufferLen - %x\n",
320            ControllerInfoBufferLen);
321 
322     PdoDevice = BusContext;
323     PdoExtension = PdoDevice->DeviceExtension;
324     FdoDevice = PdoExtension->FdoDevice;
325     FdoExtension = FdoDevice->DeviceExtension;
326 
327     InfoBuffer = ControllerInfoBuffer;
328 
329     *LenDataReturned = 0;
330 
331     if (ControllerInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
332     {
333         Status = STATUS_BUFFER_TOO_SMALL;
334         return Status;
335     }
336 
337     *LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
338 
339     if (InfoBuffer->InformationLevel > 0)
340     {
341         Status = STATUS_NOT_SUPPORTED;
342         return Status;
343     }
344 
345     InfoBuffer->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
346 
347     if (ControllerInfoBufferLen >= sizeof(USB_CONTROLLER_INFORMATION_0))
348     {
349         InfoBuffer->SelectiveSuspendEnabled =
350             (FdoExtension->Flags & USBPORT_FLAG_SELECTIVE_SUSPEND) ==
351             USBPORT_FLAG_SELECTIVE_SUSPEND;
352     }
353 
354     *LenDataReturned = sizeof(USB_CONTROLLER_INFORMATION_0);
355 
356     return STATUS_SUCCESS;
357 }
358 
359 NTSTATUS
360 USB_BUSIFFN
361 USBHI_ControllerSelectiveSuspend(IN PVOID BusContext,
362                                  IN BOOLEAN Enable)
363 {
364     PDEVICE_OBJECT PdoDevice;
365     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
366     PDEVICE_OBJECT FdoDevice;
367     PUSBPORT_DEVICE_EXTENSION FdoExtension;
368     ULONG Flags;
369     ULONG HcDisable;
370     NTSTATUS Status;
371 
372     DPRINT("USBHI_ControllerSelectiveSuspend: Enable - %x\n", Enable);
373 
374     PdoDevice = BusContext;
375     PdoExtension = PdoDevice->DeviceExtension;
376     FdoDevice = PdoExtension->FdoDevice;
377     FdoExtension = FdoDevice->DeviceExtension;
378 
379     Flags = FdoExtension->Flags;
380 
381     if (Flags & USBPORT_FLAG_BIOS_DISABLE_SS)
382     {
383         return STATUS_SUCCESS;
384     }
385 
386     if (Enable)
387     {
388         FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
389         HcDisable = 0;
390     }
391     else
392     {
393         FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
394         HcDisable = 1;
395     }
396 
397     Status = USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
398                                          TRUE,
399                                          REG_DWORD,
400                                          L"HcDisableSelectiveSuspend",
401                                          &HcDisable,
402                                          sizeof(HcDisable));
403 
404     if (NT_SUCCESS(Status))
405     {
406         if (Enable)
407             FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
408         else
409             FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
410     }
411 
412     return Status;
413 }
414 
415 NTSTATUS
416 USB_BUSIFFN
417 USBHI_GetExtendedHubInformation(IN PVOID BusContext,
418                                 IN PDEVICE_OBJECT HubPhysicalDeviceObject,
419                                 IN OUT PVOID HubInformationBuffer,
420                                 IN ULONG HubInfoLen,
421                                 IN OUT PULONG LenDataReturned)
422 {
423     PDEVICE_OBJECT PdoDevice;
424     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
425     PDEVICE_OBJECT FdoDevice;
426     PUSBPORT_DEVICE_EXTENSION FdoExtension;
427     PUSBPORT_REGISTRATION_PACKET Packet;
428     ULONG NumPorts;
429     ULONG ix;
430     PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer;
431     USB_PORT_STATUS_AND_CHANGE PortStatus;
432     ULONG PortAttrX;
433 
434     DPRINT("USBHI_GetExtendedHubInformation: ... \n");
435 
436     PdoDevice = BusContext;
437     PdoExtension = PdoDevice->DeviceExtension;
438     FdoDevice = PdoExtension->FdoDevice;
439     FdoExtension = FdoDevice->DeviceExtension;
440     Packet = &FdoExtension->MiniPortInterface->Packet;
441 
442     HubInfoBuffer = HubInformationBuffer;
443     PortStatus.AsUlong32 = 0;
444 
445     if (HubPhysicalDeviceObject != PdoDevice)
446     {
447         *LenDataReturned = 0;
448         return STATUS_NOT_SUPPORTED;
449     }
450 
451     if (HubInfoLen < sizeof(USB_EXTHUB_INFORMATION_0))
452     {
453         *LenDataReturned = 0;
454         return STATUS_BUFFER_TOO_SMALL;
455     }
456 
457     NumPorts = PdoExtension->RootHubDescriptors->Descriptor.bNumberOfPorts;
458     HubInfoBuffer->NumberOfPorts = NumPorts;
459 
460     if (NumPorts == 0)
461     {
462         *LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
463         return STATUS_SUCCESS;
464     }
465 
466     for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
467     {
468         HubInfoBuffer->Port[ix].PhysicalPortNumber = ix + 1;
469         HubInfoBuffer->Port[ix].PortLabelNumber = ix;
470         HubInfoBuffer->Port[ix].VidOverride = 0;
471         HubInfoBuffer->Port[ix].PidOverride = 0;
472         HubInfoBuffer->Port[ix].PortAttributes = 0;
473 
474         if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
475         {
476             HubInfoBuffer->Port[ix].PortAttributes = USB_PORTATTR_SHARED_USB2;
477 
478             Packet->RH_GetPortStatus(FdoExtension->MiniPortExt,
479                                      ix,
480                                      &PortStatus);
481 
482             if (PortStatus.PortStatus.Usb20PortStatus.AsUshort16 & 0x8000)
483             {
484                 HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_OWNED_BY_CC;
485             }
486         }
487         else
488         {
489             if (!(FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC))
490             {
491                 continue;
492             }
493 
494             if (USBPORT_FindUSB2Controller(FdoDevice))
495             {
496                 HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_NO_OVERCURRENT_UI;
497             }
498         }
499     }
500 
501     for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
502     {
503         PortAttrX = 0;
504 
505         USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
506                                             FdoExtension->CommonExtension.LowerPdoDevice,
507                                             FALSE,
508                                             L"PortAttrX",
509                                             sizeof(L"PortAttrX"),
510                                             &PortAttrX,
511                                             sizeof(PortAttrX));
512 
513         HubInfoBuffer->Port[ix].PortAttributes |= PortAttrX;
514     }
515 
516     *LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
517 
518     return STATUS_SUCCESS;
519 }
520 
521 NTSTATUS
522 USB_BUSIFFN
523 USBHI_GetRootHubSymbolicName(IN PVOID BusContext,
524                              IN OUT PVOID HubInfoBuffer,
525                              IN ULONG HubInfoBufferLen,
526                              OUT PULONG HubNameActualLen)
527 {
528     PDEVICE_OBJECT PdoDevice;
529     UNICODE_STRING HubName;
530     PUNICODE_STRING InfoBuffer;
531     NTSTATUS Status;
532 
533     DPRINT("USBHI_GetRootHubSymbolicName: ... \n");
534 
535     PdoDevice = BusContext;
536 
537     Status = USBPORT_GetSymbolicName(PdoDevice, &HubName);
538 
539     if (HubInfoBufferLen < HubName.Length)
540     {
541         InfoBuffer = HubInfoBuffer;
542         InfoBuffer->Length = 0;
543     }
544     else
545     {
546         RtlCopyMemory(HubInfoBuffer, HubName.Buffer, HubName.Length);
547     }
548 
549     *HubNameActualLen = HubName.Length;
550 
551     if (NT_SUCCESS(Status))
552         RtlFreeUnicodeString(&HubName);
553 
554     return Status;
555 }
556 
557 PVOID
558 USB_BUSIFFN
559 USBHI_GetDeviceBusContext(IN PVOID BusContext,
560                           IN PVOID DeviceHandle)
561 {
562     DPRINT1("USBHI_GetDeviceBusContext: UNIMPLEMENTED. FIXME. \n");
563     return NULL;
564 }
565 
566 NTSTATUS
567 USB_BUSIFFN
568 USBHI_Initialize20Hub(IN PVOID BusContext,
569                       IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
570                       IN ULONG TtCount)
571 {
572     PDEVICE_OBJECT PdoDevice;
573     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
574 
575     DPRINT("USBHI_Initialize20Hub: UsbdHubDeviceHandle - %p, TtCount - %x\n",
576            UsbdHubDeviceHandle,
577            TtCount);
578 
579     PdoDevice = BusContext;
580     PdoExtension = PdoDevice->DeviceExtension;
581 
582     return USBPORT_Initialize20Hub(PdoExtension->FdoDevice,
583                                    (PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
584                                    TtCount);
585 }
586 
587 NTSTATUS
588 USB_BUSIFFN
589 USBHI_RootHubInitNotification(IN PVOID BusContext,
590                               IN PVOID CallbackContext,
591                               IN PRH_INIT_CALLBACK CallbackFunction)
592 {
593     PDEVICE_OBJECT PdoDevice;
594     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
595     PDEVICE_OBJECT FdoDevice;
596     PUSBPORT_DEVICE_EXTENSION FdoExtension;
597     KIRQL OldIrql;
598 
599     DPRINT("USBHI_RootHubInitNotification \n");
600 
601     PdoDevice = BusContext;
602     PdoExtension = PdoDevice->DeviceExtension;
603     FdoDevice = PdoExtension->FdoDevice;
604     FdoExtension = FdoDevice->DeviceExtension;
605 
606     KeAcquireSpinLock(&FdoExtension->RootHubCallbackSpinLock, &OldIrql);
607     PdoExtension->RootHubInitContext = CallbackContext;
608     PdoExtension->RootHubInitCallback = CallbackFunction;
609     KeReleaseSpinLock(&FdoExtension->RootHubCallbackSpinLock, OldIrql);
610 
611     return STATUS_SUCCESS;
612 }
613 
614 VOID
615 USB_BUSIFFN
616 USBHI_FlushTransfers(IN PVOID BusContext,
617                      OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
618 {
619     PDEVICE_OBJECT PdoDevice;
620     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
621 
622     DPRINT("USBHI_FlushTransfers: ... \n");
623 
624     PdoDevice = BusContext;
625     PdoExtension = PdoDevice->DeviceExtension;
626 
627     USBPORT_BadRequestFlush(PdoExtension->FdoDevice);
628 }
629 
630 VOID
631 USB_BUSIFFN
632 USBHI_SetDeviceHandleData(IN PVOID BusContext,
633                           IN PVOID DeviceHandle,
634                           IN PDEVICE_OBJECT UsbDevicePdo)
635 {
636     DPRINT1("USBHI_SetDeviceHandleData: UNIMPLEMENTED. FIXME. \n");
637 }
638 
639 /* USB bus driver Interface functions */
640 
641 VOID
642 USB_BUSIFFN
643 USBDI_GetUSBDIVersion(IN PVOID BusContext,
644                       OUT PUSBD_VERSION_INFORMATION VersionInfo,
645                       OUT PULONG HcdCapabilities)
646 {
647     DPRINT1("USBDI_GetUSBDIVersion: UNIMPLEMENTED. FIXME. \n");
648 }
649 
650 NTSTATUS
651 USB_BUSIFFN
652 USBDI_QueryBusTime(IN PVOID BusContext,
653                    OUT PULONG CurrentFrame)
654 {
655     DPRINT1("USBDI_QueryBusTime: UNIMPLEMENTED. FIXME. \n");
656     return STATUS_SUCCESS;
657 }
658 
659 NTSTATUS
660 USB_BUSIFFN
661 USBDI_SubmitIsoOutUrb(IN PVOID BusContext,
662                       IN PURB Urb)
663 {
664     DPRINT1("USBDI_SubmitIsoOutUrb: UNIMPLEMENTED. FIXME. \n");
665     return STATUS_SUCCESS;
666 }
667 
668 NTSTATUS
669 USB_BUSIFFN
670 USBDI_QueryBusInformation(IN PVOID BusContext,
671                           IN ULONG Level,
672                           OUT PVOID BusInfoBuffer,
673                           OUT PULONG BusInfoBufferLen,
674                           OUT PULONG BusInfoActualLen)
675 {
676     PDEVICE_OBJECT PdoDevice;
677     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
678     PDEVICE_OBJECT FdoDevice;
679     PUSBPORT_DEVICE_EXTENSION FdoExtension;
680     SIZE_T Length;
681     PUSB_BUS_INFORMATION_LEVEL_1 Buffer1;
682 
683     DPRINT("USBDI_QueryBusInformation: Level - %p\n", Level);
684 
685     if ((Level != 0) || (Level != 1))
686     {
687         DPRINT1("USBDI_QueryBusInformation: Level should be 0 or 1\n");
688         return STATUS_NOT_SUPPORTED;
689     }
690 
691     PdoDevice = BusContext;
692     PdoExtension = PdoDevice->DeviceExtension;
693     FdoDevice = PdoExtension->FdoDevice;
694     FdoExtension = FdoDevice->DeviceExtension;
695 
696     if (Level == 0)
697     {
698         if (BusInfoActualLen)
699             *BusInfoActualLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
700 
701         if (*BusInfoBufferLen < sizeof(USB_BUS_INFORMATION_LEVEL_0))
702         {
703             return STATUS_BUFFER_TOO_SMALL;
704         }
705 
706         *BusInfoBufferLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
707 
708         //Buffer0 = BusInfoBuffer;
709         DPRINT1("USBDI_QueryBusInformation: LEVEL_0 UNIMPLEMENTED. FIXME\n");
710         //Buffer0->TotalBandwidth = USBPORT_GetTotalBandwidth();
711         //Buffer0->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
712 
713         return STATUS_SUCCESS;
714     }
715 
716     if (Level == 1)
717     {
718         Length = sizeof(USB_BUS_INFORMATION_LEVEL_1) +
719                  FdoExtension->CommonExtension.SymbolicLinkName.Length;
720 
721         if (BusInfoActualLen)
722             *BusInfoActualLen = Length;
723 
724         if (*BusInfoBufferLen < Length)
725         {
726             return STATUS_BUFFER_TOO_SMALL;
727         }
728 
729         *BusInfoBufferLen = Length;
730 
731         Buffer1 = BusInfoBuffer;
732         DPRINT1("USBDI_QueryBusInformation: LEVEL_1 UNIMPLEMENTED. FIXME\n");
733         //Buffer1->TotalBandwidth = USBPORT_GetTotalBandwidth();
734         //Buffer1->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
735         Buffer1->ControllerNameLength = FdoExtension->CommonExtension.SymbolicLinkName.Length;
736 
737         RtlCopyMemory(&Buffer1->ControllerNameUnicodeString,
738                       FdoExtension->CommonExtension.SymbolicLinkName.Buffer,
739                       FdoExtension->CommonExtension.SymbolicLinkName.Length);
740 
741         return STATUS_SUCCESS;
742     }
743 
744     return STATUS_SUCCESS;
745 }
746 
747 BOOLEAN
748 USB_BUSIFFN
749 USBDI_IsDeviceHighSpeed(IN PVOID BusContext)
750 {
751     PDEVICE_OBJECT PdoDevice;
752     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
753     PDEVICE_OBJECT FdoDevice;
754     PUSBPORT_DEVICE_EXTENSION FdoExtension;
755     PUSBPORT_REGISTRATION_PACKET Packet;
756 
757     DPRINT("USBDI_IsDeviceHighSpeed: ... \n");
758 
759     PdoDevice = BusContext;
760     PdoExtension = PdoDevice->DeviceExtension;
761     FdoDevice = PdoExtension->FdoDevice;
762     FdoExtension = FdoDevice->DeviceExtension;
763     Packet = &FdoExtension->MiniPortInterface->Packet;
764 
765     return (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2) != 0;
766 }
767 
768 NTSTATUS
769 USB_BUSIFFN
770 USBDI_EnumLogEntry(IN PVOID BusContext,
771                    IN ULONG DriverTag,
772                    IN ULONG EnumTag,
773                    IN ULONG P1,
774                    IN ULONG P2)
775 {
776     DPRINT1("USBDI_EnumLogEntry: UNIMPLEMENTED. FIXME. \n");
777     return STATUS_SUCCESS;
778 }
779 
780 NTSTATUS
781 NTAPI
782 USBPORT_PdoQueryInterface(IN PDEVICE_OBJECT FdoDevice,
783                           IN PDEVICE_OBJECT PdoDevice,
784                           IN PIRP Irp)
785 {
786     PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
787     PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
788     PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
789     UNICODE_STRING GuidBuffer;
790     NTSTATUS Status;
791 
792     DPRINT("USBPORT_PdoQueryInterface: ... \n");
793 
794     if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
795                            &USB_BUS_INTERFACE_HUB_GUID))
796     {
797         /* Get request parameters */
798         InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface;
799         InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version;
800 
801         /* Check version */
802         if (IoStack->Parameters.QueryInterface.Version >= 6)
803         {
804             DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n",
805                     IoStack->Parameters.QueryInterface.Version);
806 
807             return STATUS_NOT_SUPPORTED; // Version not supported
808         }
809 
810         /* Interface version 0 */
811         InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size;
812         InterfaceHub->BusContext = PdoDevice;
813 
814         InterfaceHub->InterfaceReference = USBI_InterfaceReference;
815         InterfaceHub->InterfaceDereference = USBI_InterfaceDereference;
816 
817         /* Interface version 1 */
818         if (IoStack->Parameters.QueryInterface.Version >= 1)
819         {
820             InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice;
821             InterfaceHub->InitializeUsbDevice = USBHI_InitializeUsbDevice;
822             InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors;
823             InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
824             InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
825             InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation;
826         }
827 
828         /* Interface version 2 */
829         if (IoStack->Parameters.QueryInterface.Version >= 2)
830         {
831             InterfaceHub->GetControllerInformation = USBHI_GetControllerInformation;
832             InterfaceHub->ControllerSelectiveSuspend = USBHI_ControllerSelectiveSuspend;
833             InterfaceHub->GetExtendedHubInformation = USBHI_GetExtendedHubInformation;
834             InterfaceHub->GetRootHubSymbolicName = USBHI_GetRootHubSymbolicName;
835             InterfaceHub->GetDeviceBusContext = USBHI_GetDeviceBusContext;
836             InterfaceHub->Initialize20Hub = USBHI_Initialize20Hub;
837         }
838 
839         /* Interface version 3 */
840         if (IoStack->Parameters.QueryInterface.Version >= 3)
841             InterfaceHub->RootHubInitNotification = USBHI_RootHubInitNotification;
842 
843         /* Interface version 4 */
844         if (IoStack->Parameters.QueryInterface.Version >= 4)
845             InterfaceHub->FlushTransfers = USBHI_FlushTransfers;
846 
847         /* Interface version 5 */
848         if (IoStack->Parameters.QueryInterface.Version >= 5)
849             InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
850 
851         /* Request completed */
852         return STATUS_SUCCESS;
853     }
854     else if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
855                                 &USB_BUS_INTERFACE_USBDI_GUID))
856     {
857         /* Get request parameters */
858         InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2)IoStack->Parameters.QueryInterface.Interface;
859         InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version;
860 
861         /* Check version */
862         if (IoStack->Parameters.QueryInterface.Version >= 3)
863         {
864             DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n",
865                     IoStack->Parameters.QueryInterface.Version);
866 
867             return STATUS_NOT_SUPPORTED; // Version not supported
868         }
869 
870         /* Interface version 0 */
871         InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size;
872         InterfaceDI->BusContext = PdoDevice;
873         InterfaceDI->InterfaceReference = USBI_InterfaceReference;
874         InterfaceDI->InterfaceDereference = USBI_InterfaceDereference;
875         InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion;
876         InterfaceDI->QueryBusTime = USBDI_QueryBusTime;
877         InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb;
878         InterfaceDI->QueryBusInformation = USBDI_QueryBusInformation;
879 
880         /* Interface version 1 */
881         if (IoStack->Parameters.QueryInterface.Version >= 1)
882             InterfaceDI->IsDeviceHighSpeed = USBDI_IsDeviceHighSpeed;
883 
884         /* Interface version 2 */
885         if (IoStack->Parameters.QueryInterface.Version >= 2)
886             InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
887 
888         return STATUS_SUCCESS;
889     }
890     else
891     {
892         /* Convert GUID to string */
893         Status = RtlStringFromGUID(IoStack->Parameters.QueryInterface.InterfaceType,
894                                    &GuidBuffer);
895 
896         if (NT_SUCCESS(Status))
897         {
898             /* Print interface */
899             DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n",
900                     &GuidBuffer,
901                     IoStack->Parameters.QueryInterface.Version);
902 
903             RtlFreeUnicodeString(&GuidBuffer); // Free GUID buffer
904         }
905     }
906 
907     return STATUS_NOT_SUPPORTED;
908 }
909