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.
7 * Michael Martin (michael.martin@reactos.org)
20 /* Lifted from Linux with slight changes */
21 const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR
[] =
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; */
36 0x00, /* iSerialNumber; */
37 0x01 /* bNumConfigurations; */
41 const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR
[] =
43 /* one configuration */
45 0x02, /* bDescriptorType; Configuration */
46 0x19, 0x00, /* wTotalLength; */
47 0x01, /* bNumInterfaces; (1) */
48 0x23, /* bConfigurationValue; */
49 0x00, /* iConfiguration; */
50 0x40, /* bmAttributes; */
54 const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR
[] =
57 0x09, /* bLength: Interface; */
58 0x04, /* bDescriptorType; Interface */
59 0x00, /* bInterfaceNumber; */
60 0x00, /* bAlternateSetting; */
61 0x01, /* bNumEndpoints; */
62 0x09, /* bInterfaceClass; HUB_CLASSCODE */
63 0x01, /* bInterfaceSubClass; */
64 0x00, /* bInterfaceProtocol: */
65 0x00 /* iInterface; */
68 const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR
[] =
70 /* one endpoint (status change endpoint) */
72 0x05, /* bDescriptorType; Endpoint */
73 0x81, /* bEndpointAddress; IN Endpoint 1 */
74 0x03, /* bmAttributes; Interrupt */
75 0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
76 0xFF /* bInterval; (255ms -- usb 2.0 spec) */
80 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
82 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
83 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
84 PIO_STACK_LOCATION Stack
= NULL
;
85 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
86 ULONG_PTR Information
= 0;
87 PEHCI_HOST_CONTROLLER hcd
;
89 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
90 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
) PdoDeviceExtension
->ControllerFdo
->DeviceExtension
;
92 ASSERT(PdoDeviceExtension
->Common
.IsFdo
== FALSE
);
94 hcd
= &FdoDeviceExtension
->hcd
;
95 Stack
= IoGetCurrentIrpStackLocation(Irp
);
97 switch(Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
99 case IOCTL_INTERNAL_USB_SUBMIT_URB
:
101 PUSB_DEVICE UsbDevice
= NULL
;
105 Urb
= (PURB
) Stack
->Parameters
.Others
.Argument1
;
107 UsbDevice
= Urb
->UrbHeader
.UsbdDeviceHandle
;
109 /* If there was no device passed then this URB is for the RootHub */
110 if (UsbDevice
== NULL
)
111 UsbDevice
= PdoDeviceExtension
->UsbDevices
[0];
113 /* Check if it is a Status Change Endpoint (SCE). The Hub Driver sends this request and miniports mark the IRP pending
114 if there is no changes on any of the ports. When the DPC of miniport routine detects changes this IRP will be completed.
115 Based on XEN PV Usb Drivers */
117 if ((Urb
->UrbHeader
.Function
== URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
) &&
118 (UsbDevice
== PdoDeviceExtension
->UsbDevices
[0]))
120 DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER on SCE\n");
121 if (Urb
->UrbBulkOrInterruptTransfer
.PipeHandle
!= &UsbDevice
->ActiveInterface
->EndPoints
[0]->EndPointDescriptor
)
123 DPRINT1("PipeHandle doesnt match SCE PipeHandle\n");
126 /* Queue the Irp first */
127 QueueURBRequest(PdoDeviceExtension
, Irp
);
129 /* Check for port changes */
130 if (EnumControllerPorts(hcd
) == FALSE
)
132 DPRINT("No port change\n");
133 Status
= STATUS_PENDING
;
134 IoMarkIrpPending(Irp
);
138 /* If we reached this point then port status has changed, so check
140 for (i
= 0; i
< hcd
->ECHICaps
.HCSParams
.PortCount
; i
++)
142 if (hcd
->Ports
[i
].PortChange
== 0x01)
144 DPRINT1("On SCE request: Inform hub driver that port %d has changed\n", i
+1);
146 ((PUCHAR
)Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
)[0] = 1 << ((i
+ 1) & 7);
148 Status
= STATUS_SUCCESS
;
149 /* Assume URB success */
150 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
151 /* Set the DeviceHandle to the Internal Device */
152 Urb
->UrbHeader
.UsbdDeviceHandle
= UsbDevice
;
154 /* Request handled, Remove it from the queue */
155 RemoveUrbRequest(PdoDeviceExtension
, Irp
);
159 if (Status
== STATUS_SUCCESS
) break;
161 IoMarkIrpPending(Irp
);
162 Status
= STATUS_PENDING
;
166 Status
= HandleUrbRequest(PdoDeviceExtension
, Irp
);
170 case IOCTL_INTERNAL_USB_CYCLE_PORT
:
172 DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
175 case IOCTL_INTERNAL_USB_ENABLE_PORT
:
177 DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
179 Status
= STATUS_SUCCESS
;
182 case IOCTL_INTERNAL_USB_GET_BUS_INFO
:
184 DPRINT1("IOCTL_INTERNAL_USB_GET_BUS_INFO\n");
187 case IOCTL_INTERNAL_USB_GET_BUSGUID_INFO
:
189 DPRINT1("IOCTL_INTERNAL_USB_GET_BUSGUID_INFO\n");
192 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME
:
194 DPRINT1("IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n");
197 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
:
199 DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", Stack
->Parameters
.Others
.Argument2
);
200 if (Stack
->Parameters
.Others
.Argument1
)
202 /* Return the root hubs devicehandle */
203 DPRINT("Returning RootHub Handle %x\n", PdoDeviceExtension
->UsbDevices
[0]);
204 *(PVOID
*)Stack
->Parameters
.Others
.Argument1
= (PVOID
)PdoDeviceExtension
->UsbDevices
[0];
205 Status
= STATUS_SUCCESS
;
208 Status
= STATUS_INVALID_DEVICE_REQUEST
;
213 case IOCTL_INTERNAL_USB_GET_HUB_COUNT
:
215 DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT
);
216 ASSERT(Stack
->Parameters
.Others
.Argument1
!= NULL
);
217 if (Stack
->Parameters
.Others
.Argument1
)
219 /* FIXME: Determine the number of hubs between the usb device and root hub.
220 For now we have at least one. */
221 *(PULONG
)Stack
->Parameters
.Others
.Argument1
= 1;
223 Status
= STATUS_SUCCESS
;
226 case IOCTL_INTERNAL_USB_GET_HUB_NAME
:
228 DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_NAME\n");
231 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO
:
233 DPRINT1("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
236 case IOCTL_INTERNAL_USB_GET_PORT_STATUS
:
238 DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
241 case IOCTL_INTERNAL_USB_RESET_PORT
:
243 DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
246 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
:
248 DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
249 /* DDK documents that both the PDO and FDO are returned. However, while writing the UsbHub driver it was determine
250 that this was not the case. Windows usbehci driver gives the Pdo in both Arguments. Which makes sense as upper level
251 drivers should not be communicating with FDO. */
252 if (Stack
->Parameters
.Others
.Argument1
)
253 *(PVOID
*)Stack
->Parameters
.Others
.Argument1
= FdoDeviceExtension
->Pdo
;
254 if (Stack
->Parameters
.Others
.Argument2
)
255 *(PVOID
*)Stack
->Parameters
.Others
.Argument2
= FdoDeviceExtension
->Pdo
;
257 Status
= STATUS_SUCCESS
;
260 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
:
262 PUSB_IDLE_CALLBACK_INFO CallBackInfo
;
263 DPRINT1("Ehci: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
264 /* FIXME: Set Callback for safe power down */
265 CallBackInfo
= Stack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
267 PdoDeviceExtension
->IdleCallback
= CallBackInfo
->IdleCallback
;
268 PdoDeviceExtension
->IdleContext
= CallBackInfo
->IdleContext
;
271 Status
= STATUS_SUCCESS
;
276 DPRINT1("Unhandled IoControlCode %x\n", Stack
->Parameters
.DeviceIoControl
.IoControlCode
);
281 Irp
->IoStatus
.Information
= Information
;
283 if (Status
!= STATUS_PENDING
)
284 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
290 PdoQueryId(PDEVICE_OBJECT DeviceObject
, PIRP Irp
, ULONG_PTR
* Information
)
295 UNICODE_STRING SourceString
;
296 UNICODE_STRING String
;
299 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
303 case BusQueryDeviceID
:
305 RtlInitUnicodeString(&SourceString
, L
"USB\\ROOT_HUB20");
308 case BusQueryHardwareIDs
:
310 /* FIXME: Build from Device Vendor and Device ID */
311 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
312 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20&VID8086&PID265C") + 1;
313 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20") + 1;
315 Buffer
[Index
] = UNICODE_NULL
;
316 SourceString
.Length
= SourceString
.MaximumLength
= Index
* sizeof(WCHAR
);
317 SourceString
.Buffer
= Buffer
;
321 case BusQueryCompatibleIDs
:
324 return STATUS_SUCCESS
;
326 case BusQueryInstanceID
:
328 return STATUS_SUCCESS
;
332 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
333 return STATUS_NOT_SUPPORTED
;
337 Status
= DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
341 *Information
= (ULONG_PTR
)String
.Buffer
;
346 PdoQueryDeviceRelations(PDEVICE_OBJECT DeviceObject
, PDEVICE_RELATIONS
* pDeviceRelations
)
348 PDEVICE_RELATIONS DeviceRelations
;
350 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, sizeof(DEVICE_RELATIONS
));
351 if (!DeviceRelations
)
352 return STATUS_INSUFFICIENT_RESOURCES
;
354 DeviceRelations
->Count
= 1;
355 DeviceRelations
->Objects
[0] = DeviceObject
;
356 ObReferenceObject(DeviceObject
);
358 *pDeviceRelations
= DeviceRelations
;
359 return STATUS_SUCCESS
;
364 IN PDEVICE_OBJECT DeviceObject
,
368 PIO_STACK_LOCATION Stack
;
369 ULONG_PTR Information
= Irp
->IoStatus
.Information
;
370 NTSTATUS Status
= Irp
->IoStatus
.Status
;
371 PDEVICE_CAPABILITIES DeviceCapabilities
;
374 Stack
= IoGetCurrentIrpStackLocation(Irp
);
375 MinorFunction
= Stack
->MinorFunction
;
377 switch (MinorFunction
)
379 case IRP_MN_QUERY_REMOVE_DEVICE
:
380 case IRP_MN_REMOVE_DEVICE
:
381 case IRP_MN_CANCEL_REMOVE_DEVICE
:
382 case IRP_MN_STOP_DEVICE
:
383 case IRP_MN_QUERY_STOP_DEVICE
:
384 case IRP_MN_CANCEL_STOP_DEVICE
:
385 case IRP_MN_QUERY_DEVICE_TEXT
:
386 case IRP_MN_SURPRISE_REMOVAL
:
387 case IRP_MN_QUERY_RESOURCES
:
388 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
389 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
391 Status
= STATUS_SUCCESS
;
395 case IRP_MN_START_DEVICE
:
397 PUSB_DEVICE RootHubDevice
;
398 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
399 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
400 UNICODE_STRING InterfaceSymLinkName
;
402 DPRINT1("Ehci: PDO StartDevice\n");
403 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
404 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)PdoDeviceExtension
->ControllerFdo
->DeviceExtension
;
406 /* Create the root hub */
407 RootHubDevice
= InternalCreateUsbDevice(1, 0, NULL
, TRUE
);
409 RtlCopyMemory(&RootHubDevice
->DeviceDescriptor
,
410 ROOTHUB2_DEVICE_DESCRIPTOR
,
411 sizeof(ROOTHUB2_DEVICE_DESCRIPTOR
));
413 RootHubDevice
->DeviceDescriptor
.idVendor
= FdoDeviceExtension
->VendorId
;
414 RootHubDevice
->DeviceDescriptor
.idProduct
= FdoDeviceExtension
->DeviceId
;
416 /* Here config, interfaces and descriptors are stored. This was duplicated from XEN PV Usb Drivers implementation.
417 Not sure that it is really needed as the information can be queueried from the device. */
419 RootHubDevice
->Configs
= ExAllocatePoolWithTag(NonPagedPool
,
420 sizeof(PVOID
) * RootHubDevice
->DeviceDescriptor
.bNumConfigurations
,
423 RootHubDevice
->Configs
[0] = ExAllocatePoolWithTag(NonPagedPool
,
424 sizeof(USB_CONFIGURATION
) + sizeof(PVOID
) * ROOTHUB2_CONFIGURATION_DESCRIPTOR
[4],
427 RootHubDevice
->Configs
[0]->Interfaces
[0] = ExAllocatePoolWithTag(NonPagedPool
,
428 sizeof(USB_INTERFACE
) + sizeof(PVOID
) * ROOTHUB2_INTERFACE_DESCRIPTOR
[4],
431 RootHubDevice
->Configs
[0]->Interfaces
[0]->EndPoints
[0] = ExAllocatePoolWithTag(NonPagedPool
,
432 sizeof(USB_ENDPOINT
),
435 RootHubDevice
->ActiveConfig
= RootHubDevice
->Configs
[0];
436 RootHubDevice
->ActiveInterface
= RootHubDevice
->ActiveConfig
->Interfaces
[0];
438 RtlCopyMemory(&RootHubDevice
->ActiveConfig
->ConfigurationDescriptor
,
439 ROOTHUB2_CONFIGURATION_DESCRIPTOR
,
440 sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR
));
442 RtlCopyMemory(&RootHubDevice
->ActiveConfig
->Interfaces
[0]->InterfaceDescriptor
,
443 ROOTHUB2_INTERFACE_DESCRIPTOR
,
444 sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR
));
446 RtlCopyMemory(&RootHubDevice
->ActiveConfig
->Interfaces
[0]->EndPoints
[0]->EndPointDescriptor
,
447 ROOTHUB2_ENDPOINT_DESCRIPTOR
,
448 sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR
));
449 RootHubDevice
->DeviceSpeed
= UsbHighSpeed
;
450 RootHubDevice
->DeviceType
= Usb20Device
;
452 PdoDeviceExtension
->UsbDevices
[0] = RootHubDevice
;
454 Status
= IoRegisterDeviceInterface(DeviceObject
, &GUID_DEVINTERFACE_USB_HUB
, NULL
, &InterfaceSymLinkName
);
455 if (!NT_SUCCESS(Status
))
457 DPRINT1("Failed to register interface\n");
462 Status
= IoSetDeviceInterfaceState(&InterfaceSymLinkName
, TRUE
);
463 if (!NT_SUCCESS(Status
))
467 Status
= STATUS_SUCCESS
;
470 case IRP_MN_QUERY_DEVICE_RELATIONS
:
472 DPRINT1("Ehci: PDO QueryDeviceRelations\n");
473 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
475 case TargetDeviceRelation
:
477 PDEVICE_RELATIONS DeviceRelations
= NULL
;
478 Status
= PdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
479 Information
= (ULONG_PTR
)DeviceRelations
;
484 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
485 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
487 DPRINT("BusRelations!!!!!\n");
489 /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
490 has sent this IRP and type, so leave the next SCE request pending until a new device arrives.
491 Is there a better way to do this? */
492 ExAcquireFastMutex(&PdoDeviceExtension
->ListLock
);
493 PdoDeviceExtension
->HaltQueue
= TRUE
;
494 ExReleaseFastMutex(&PdoDeviceExtension
->ListLock
);
496 case RemovalRelations
:
497 case EjectionRelations
:
499 /* Ignore the request */
500 Information
= Irp
->IoStatus
.Information
;
501 Status
= Irp
->IoStatus
.Status
;
507 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
508 Stack
->Parameters
.QueryDeviceRelations
.Type
);
509 Status
= STATUS_NOT_SUPPORTED
;
515 case IRP_MN_QUERY_CAPABILITIES
:
517 DPRINT("Ehci: PDO Query Capabilities\n");
519 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
521 DeviceCapabilities
->LockSupported
= FALSE
;
522 DeviceCapabilities
->EjectSupported
= FALSE
;
523 DeviceCapabilities
->Removable
= FALSE
;
524 DeviceCapabilities
->DockDevice
= FALSE
;
525 DeviceCapabilities
->UniqueID
= FALSE
;
526 DeviceCapabilities
->SilentInstall
= FALSE
;
527 DeviceCapabilities
->RawDeviceOK
= FALSE
;
528 DeviceCapabilities
->SurpriseRemovalOK
= FALSE
;
529 DeviceCapabilities
->Address
= 0;
530 DeviceCapabilities
->UINumber
= 0;
531 DeviceCapabilities
->DeviceD2
= 1;
533 /* FIXME: Verify these settings are correct */
534 DeviceCapabilities
->HardwareDisabled
= FALSE
;
535 //DeviceCapabilities->NoDisplayInUI = FALSE;
536 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
;
537 for (i
= 0; i
< PowerSystemMaximum
; i
++)
538 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
;
539 DeviceCapabilities
->DeviceWake
= 0;
540 DeviceCapabilities
->D1Latency
= 0;
541 DeviceCapabilities
->D2Latency
= 0;
542 DeviceCapabilities
->D3Latency
= 0;
544 Status
= STATUS_SUCCESS
;
547 /*case IRP_MN_QUERY_DEVICE_TEXT:
549 Status = STATUS_NOT_SUPPORTED;
553 case IRP_MN_QUERY_ID
:
555 DPRINT("Ehci: PDO Query ID\n");
556 Status
= PdoQueryId(DeviceObject
, Irp
, &Information
);
559 case IRP_MN_QUERY_INTERFACE
:
561 UNICODE_STRING GuidString
;
562 PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub
;
563 PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI
;
564 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
565 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
567 DPRINT("Ehci: PDO Query Interface\n");
569 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
570 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)PdoDeviceExtension
->ControllerFdo
->DeviceExtension
;
572 Status
= RtlStringFromGUID(Stack
->Parameters
.QueryInterface
.InterfaceType
, &GuidString
);
573 if (!NT_SUCCESS(Status
))
575 DPRINT1("Failed to create string from GUID!\n");
579 Status
= STATUS_SUCCESS
;
582 if (IsEqualGUIDAligned(Stack
->Parameters
.QueryInterface
.InterfaceType
, &USB_BUS_INTERFACE_HUB_GUID
))
584 InterfaceHub
= (PUSB_BUS_INTERFACE_HUB_V5
)Stack
->Parameters
.QueryInterface
.Interface
;
585 InterfaceHub
->Version
= Stack
->Parameters
.QueryInterface
.Version
;
586 if (Stack
->Parameters
.QueryInterface
.Version
>= 0)
588 InterfaceHub
->Size
= Stack
->Parameters
.QueryInterface
.Size
;
589 InterfaceHub
->BusContext
= PdoDeviceExtension
->DeviceObject
;
590 InterfaceHub
->InterfaceReference
= (PINTERFACE_REFERENCE
)InterfaceReference
;
591 InterfaceHub
->InterfaceDereference
= (PINTERFACE_DEREFERENCE
)InterfaceDereference
;
593 if (Stack
->Parameters
.QueryInterface
.Version
>= 1)
595 InterfaceHub
->CreateUsbDevice
= CreateUsbDevice
;
596 InterfaceHub
->InitializeUsbDevice
= InitializeUsbDevice
;
597 InterfaceHub
->GetUsbDescriptors
= GetUsbDescriptors
;
598 InterfaceHub
->RemoveUsbDevice
= RemoveUsbDevice
;
599 InterfaceHub
->RestoreUsbDevice
= RestoreUsbDevice
;
600 InterfaceHub
->GetPortHackFlags
= GetPortHackFlags
;
601 InterfaceHub
->QueryDeviceInformation
= QueryDeviceInformation
;
603 if (Stack
->Parameters
.QueryInterface
.Version
>= 2)
605 InterfaceHub
->GetControllerInformation
= GetControllerInformation
;
606 InterfaceHub
->ControllerSelectiveSuspend
= ControllerSelectiveSuspend
;
607 InterfaceHub
->GetExtendedHubInformation
= GetExtendedHubInformation
;
608 InterfaceHub
->GetRootHubSymbolicName
= GetRootHubSymbolicName
;
609 InterfaceHub
->GetDeviceBusContext
= GetDeviceBusContext
;
610 InterfaceHub
->Initialize20Hub
= Initialize20Hub
;
613 if (Stack
->Parameters
.QueryInterface
.Version
>= 3)
615 InterfaceHub
->RootHubInitNotification
= RootHubInitNotification
;
617 if (Stack
->Parameters
.QueryInterface
.Version
>= 4)
619 InterfaceHub
->FlushTransfers
= FlushTransfers
;
621 if (Stack
->Parameters
.QueryInterface
.Version
>= 5)
623 InterfaceHub
->SetDeviceHandleData
= SetDeviceHandleData
;
625 if (Stack
->Parameters
.QueryInterface
.Version
>= 6)
627 DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
632 if (IsEqualGUIDAligned(Stack
->Parameters
.QueryInterface
.InterfaceType
, &USB_BUS_INTERFACE_USBDI_GUID
))
634 InterfaceDI
= (PUSB_BUS_INTERFACE_USBDI_V2
) Stack
->Parameters
.QueryInterface
.Interface
;
635 InterfaceDI
->Version
= Stack
->Parameters
.QueryInterface
.Version
;
636 if (Stack
->Parameters
.QueryInterface
.Version
>= 0)
638 //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
639 InterfaceDI
->Size
= Stack
->Parameters
.QueryInterface
.Size
;
640 InterfaceDI
->BusContext
= PdoDeviceExtension
->DeviceObject
;
641 InterfaceDI
->InterfaceReference
= (PINTERFACE_REFERENCE
)InterfaceReference
;
642 InterfaceDI
->InterfaceDereference
= (PINTERFACE_DEREFERENCE
)InterfaceDereference
;
643 InterfaceDI
->GetUSBDIVersion
= GetUSBDIVersion
;
644 InterfaceDI
->QueryBusTime
= QueryBusTime
;
645 InterfaceDI
->SubmitIsoOutUrb
= SubmitIsoOutUrb
;
646 InterfaceDI
->QueryBusInformation
= QueryBusInformation
;
648 if (Stack
->Parameters
.QueryInterface
.Version
>= 1)
650 InterfaceDI
->IsDeviceHighSpeed
= IsDeviceHighSpeed
;
652 if (Stack
->Parameters
.QueryInterface
.Version
>= 2)
654 InterfaceDI
->EnumLogEntry
= EnumLogEntry
;
657 if (Stack
->Parameters
.QueryInterface
.Version
>= 3)
659 DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
664 DPRINT1("GUID Not Supported\n");
665 Status
= Irp
->IoStatus
.Status
;
666 Information
= Irp
->IoStatus
.Information
;
670 case IRP_MN_QUERY_BUS_INFORMATION
:
672 PPNP_BUS_INFORMATION BusInfo
;
674 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
676 Status
= STATUS_INSUFFICIENT_RESOURCES
;
681 &BusInfo->BusTypeGuid,
682 &GUID_DEVINTERFACE_XXX,
685 BusInfo
->LegacyBusType
= PNPBus
;
686 BusInfo
->BusNumber
= 0;
687 Information
= (ULONG_PTR
)BusInfo
;
688 Status
= STATUS_SUCCESS
;
694 /* We are the PDO. So ignore */
695 DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction
);
700 Irp
->IoStatus
.Information
= Information
;
701 Irp
->IoStatus
.Status
= Status
;
702 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);