Sync with trunk head (part 1 or 2)
[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 #define NDEBUG
12
13 #include "usbehci.h"
14 #include <wdmguid.h>
15 #include "usbiffn.h"
16 #include <stdio.h>
17 #include <debug.h>
18
19 /* Lifted from Linux with slight changes */
20 const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR [] =
21 {
22 0x12, /* bLength; */
23 USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType; Device */
24 0x00, 0x20, /* bcdUSB; v1.1 */
25 USB_DEVICE_CLASS_HUB, /* bDeviceClass; HUB_CLASSCODE */
26 0x01, /* bDeviceSubClass; */
27 0x00, /* bDeviceProtocol; [ low/full speeds only ] */
28 0x08, /* bMaxPacketSize0; 8 Bytes */
29 /* Fill Vendor and Product in when init root hub */
30 0x00, 0x00, /* idVendor; */
31 0x00, 0x00, /* idProduct; */
32 0x00, 0x00, /* bcdDevice */
33 0x00, /* iManufacturer; */
34 0x00, /* iProduct; */
35 0x00, /* iSerialNumber; */
36 0x01 /* bNumConfigurations; */
37
38 };
39
40 const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
41 {
42 /* one configuration */
43 0x09, /* bLength; */
44 0x02, /* bDescriptorType; Configuration */
45 0x19, 0x00, /* wTotalLength; */
46 0x01, /* bNumInterfaces; (1) */
47 0x23, /* bConfigurationValue; */
48 0x00, /* iConfiguration; */
49 0x40, /* bmAttributes;
50 Bit 7: must be set,
51 6: Self-powered,
52 5: Remote wakeup,
53 4..0: reserved */
54 0x00, /* MaxPower; */
55
56 /* one interface */
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; */
66
67 /* one endpoint (status change endpoint) */
68 0x07, /* bLength; */
69 0x05, /* bDescriptorType; Endpoint */
70 0x81, /* bEndpointAddress; IN Endpoint 1 */
71 0x03, /* bmAttributes; Interrupt */
72 0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
73 0xFF /* bInterval; (255ms -- usb 2.0 spec) */
74 };
75
76 /* FIXME: Do something better */
77 VOID NTAPI
78 UrbWorkerThread(PVOID Context)
79 {
80 PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context;
81
82 while (PdoDeviceExtension->HaltUrbHandling == FALSE)
83 {
84 CompletePendingURBRequest(PdoDeviceExtension);
85 KeStallExecutionProcessor(10);
86 }
87 DPRINT1("Thread terminated\n");
88 }
89
90 /* FIXME: Do something better */
91 PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
92 {
93 PUSB_DEVICE UsbDevicePointer = NULL;
94 UsbDevicePointer = ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE));
95 if (!UsbDevicePointer)
96 {
97 DPRINT1("Out of memory\n");
98 return NULL;
99 }
100
101 if ((Hub) && (!Parent))
102 {
103 DPRINT1("This is the root hub\n");
104 }
105
106 UsbDevicePointer->Address = DeviceNumber;
107 UsbDevicePointer->Port = Port;
108 UsbDevicePointer->ParentDevice = Parent;
109
110 UsbDevicePointer->IsHub = Hub;
111
112 return UsbDevicePointer;
113 }
114
115 NTSTATUS NTAPI
116 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
117 {
118 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
119 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
120 PIO_STACK_LOCATION Stack = NULL;
121 NTSTATUS Status = STATUS_UNSUCCESSFUL;
122 ULONG_PTR Information = 0;
123
124 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
125 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
126
127 ASSERT(PdoDeviceExtension->Common.IsFdo == FALSE);
128
129 Stack = IoGetCurrentIrpStackLocation(Irp);
130
131 switch(Stack->Parameters.DeviceIoControl.IoControlCode)
132 {
133 case IOCTL_INTERNAL_USB_SUBMIT_URB:
134 {
135 URB *Urb;
136
137 Urb = (PURB) Stack->Parameters.Others.Argument1;
138 DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
139 DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
140
141 /* Queue all request for now, kernel thread will complete them */
142 QueueURBRequest(PdoDeviceExtension, Irp);
143 Information = 0;
144 IoMarkIrpPending(Irp);
145 Status = STATUS_PENDING;
146 break;
147 }
148 case IOCTL_INTERNAL_USB_CYCLE_PORT:
149 {
150 DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
151 break;
152 }
153 case IOCTL_INTERNAL_USB_ENABLE_PORT:
154 {
155 DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
156 break;
157 }
158 case IOCTL_INTERNAL_USB_GET_BUS_INFO:
159 {
160 DPRINT1("IOCTL_INTERNAL_USB_GET_BUS_INFO\n");
161 break;
162 }
163 case IOCTL_INTERNAL_USB_GET_BUSGUID_INFO:
164 {
165 DPRINT1("IOCTL_INTERNAL_USB_GET_BUSGUID_INFO\n");
166 break;
167 }
168 case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
169 {
170 DPRINT1("IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n");
171 break;
172 }
173 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
174 {
175 DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
176 if (Stack->Parameters.Others.Argument1)
177 {
178 /* Return the root hubs devicehandle */
179 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
180 }
181 else
182 Status = STATUS_INVALID_DEVICE_REQUEST;
183 break;
184 }
185 case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
186 {
187 DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
188 if (Stack->Parameters.Others.Argument1)
189 {
190 /* FIXME: Determine the number of hubs between the usb device and root hub */
191 /* For now return 1, the root hub */
192 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)1;
193 }
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 = IoGetAttachedDevice(FdoDeviceExtension->DeviceObject);
224
225 Information = 0;
226 Status = STATUS_SUCCESS;
227 break;
228 }
229 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
230 {
231 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
232 break;
233 }
234 default:
235 {
236 DPRINT1("Unhandled IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
237 break;
238 }
239 }
240
241 Irp->IoStatus.Information = Information;
242
243 if (Status != STATUS_PENDING)
244 IoCompleteRequest(Irp, IO_NO_INCREMENT);
245
246 return Status;
247 }
248
249 NTSTATUS
250 PdoQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG_PTR* Information)
251 {
252 WCHAR Buffer[256];
253 ULONG Index = 0;
254 ULONG IdType;
255 UNICODE_STRING SourceString;
256 UNICODE_STRING String;
257 NTSTATUS Status;
258
259 IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
260
261 switch (IdType)
262 {
263 case BusQueryDeviceID:
264 {
265 RtlInitUnicodeString(&SourceString, L"USB\\ROOT_HUB20");
266 break;
267 }
268 case BusQueryHardwareIDs:
269 {
270 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
271 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C") + 1;
272 Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
273
274 Buffer[Index] = UNICODE_NULL;
275 SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
276 SourceString.Buffer = Buffer;
277 break;
278 }
279 case BusQueryCompatibleIDs:
280 {
281 /* We have none */
282 return STATUS_SUCCESS;
283 }
284 case BusQueryInstanceID:
285 {
286 return STATUS_SUCCESS;
287 }
288 default:
289 {
290 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
291 return STATUS_NOT_SUPPORTED;
292 }
293 }
294
295 Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
296 &SourceString,
297 &String);
298
299 *Information = (ULONG_PTR)String.Buffer;
300 return Status;
301 }
302
303 NTSTATUS
304 PdoQueryDeviceRelations(PDEVICE_OBJECT DeviceObject, PDEVICE_RELATIONS* pDeviceRelations)
305 {
306 PDEVICE_RELATIONS DeviceRelations;
307
308 DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
309 if (!DeviceRelations)
310 return STATUS_INSUFFICIENT_RESOURCES;
311
312 DeviceRelations->Count = 1;
313 DeviceRelations->Objects[0] = DeviceObject;
314 ObReferenceObject(DeviceObject);
315
316 *pDeviceRelations = DeviceRelations;
317 return STATUS_SUCCESS;
318 }
319
320 NTSTATUS NTAPI
321 PdoDispatchPnp(
322 IN PDEVICE_OBJECT DeviceObject,
323 IN PIRP Irp)
324 {
325 ULONG MinorFunction;
326 PIO_STACK_LOCATION Stack;
327 ULONG_PTR Information = Irp->IoStatus.Information;
328 NTSTATUS Status = Irp->IoStatus.Status;
329
330 Stack = IoGetCurrentIrpStackLocation(Irp);
331 MinorFunction = Stack->MinorFunction;
332
333 switch (MinorFunction)
334 {
335 case IRP_MN_QUERY_REMOVE_DEVICE:
336 case IRP_MN_REMOVE_DEVICE:
337 case IRP_MN_CANCEL_REMOVE_DEVICE:
338 case IRP_MN_STOP_DEVICE:
339 case IRP_MN_QUERY_STOP_DEVICE:
340 case IRP_MN_CANCEL_STOP_DEVICE:
341 case IRP_MN_QUERY_DEVICE_TEXT:
342 case IRP_MN_SURPRISE_REMOVAL:
343 case IRP_MN_QUERY_RESOURCES:
344 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
345 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
346 {
347 Status = STATUS_SUCCESS;
348 break;
349 }
350
351 case IRP_MN_START_DEVICE:
352 {
353 PUSB_DEVICE RootHubDevice;
354 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
355 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
356 UNICODE_STRING InterfaceSymLinkName;
357 LONG i;
358
359 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
360 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
361
362 /* Create the root hub */
363 RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
364
365 for (i = 0; i < 8; i++)
366 {
367 PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
368 PdoDeviceExtension->Ports[i].PortChange = 0;
369 }
370
371 RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
372 ROOTHUB2_DEVICE_DESCRIPTOR,
373 sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
374
375 RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
376 RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
377
378 RtlCopyMemory(&RootHubDevice->ConfigurationDescriptor,
379 ROOTHUB2_CONFIGURATION_DESCRIPTOR,
380 sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));
381
382 PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
383
384 /* Create a thread to handle the URB's */
385 Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
386 THREAD_ALL_ACCESS,
387 NULL,
388 NULL,
389 NULL,
390 UrbWorkerThread,
391 (PVOID)PdoDeviceExtension);
392
393 if (!NT_SUCCESS(Status))
394 DPRINT1("Failed Thread Creation with Status: %x\n", Status);
395
396 Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName);
397 if (!NT_SUCCESS(Status))
398 {
399 DPRINT1("Failed to register interface\n");
400 }
401 else
402 {
403 Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
404 DPRINT1("Set interface state %x\n", Status);
405 }
406
407
408 Status = STATUS_SUCCESS;
409 break;
410 }
411 case IRP_MN_QUERY_DEVICE_RELATIONS:
412 {
413 switch (Stack->Parameters.QueryDeviceRelations.Type)
414 {
415 case TargetDeviceRelation:
416 {
417 PDEVICE_RELATIONS DeviceRelations = NULL;
418 Status = PdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
419 Information = (ULONG_PTR)DeviceRelations;
420 break;
421 }
422 case BusRelations:
423 DPRINT1("BusRelations!!!!!\n");
424 case RemovalRelations:
425 case EjectionRelations:
426 {
427 /* Ignore the request */
428 Information = Irp->IoStatus.Information;
429 Status = Irp->IoStatus.Status;
430 break;
431
432 }
433 default:
434 {
435 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
436 Stack->Parameters.QueryDeviceRelations.Type);
437 Status = STATUS_NOT_SUPPORTED;
438 break;
439 }
440 }
441 break;
442 }
443 case IRP_MN_QUERY_CAPABILITIES:
444 {
445 PDEVICE_CAPABILITIES DeviceCapabilities;
446 ULONG i;
447
448 DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
449
450 DeviceCapabilities->LockSupported = FALSE;
451 DeviceCapabilities->EjectSupported = FALSE;
452 DeviceCapabilities->Removable = FALSE;
453 DeviceCapabilities->DockDevice = FALSE;
454 DeviceCapabilities->UniqueID = FALSE;
455 DeviceCapabilities->SilentInstall = FALSE;
456 DeviceCapabilities->RawDeviceOK = FALSE;
457 DeviceCapabilities->SurpriseRemovalOK = FALSE;
458 DeviceCapabilities->Address = 0;
459 DeviceCapabilities->UINumber = 0;
460 DeviceCapabilities->DeviceD2 = 1;
461
462 /* FIXME */
463 DeviceCapabilities->HardwareDisabled = FALSE;
464 //DeviceCapabilities->NoDisplayInUI = FALSE;
465 DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
466 for (i = 0; i < PowerSystemMaximum; i++)
467 DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
468 DeviceCapabilities->DeviceWake = 0;
469 DeviceCapabilities->D1Latency = 0;
470 DeviceCapabilities->D2Latency = 0;
471 DeviceCapabilities->D3Latency = 0;
472 Information = 0;
473 Status = STATUS_SUCCESS;
474 break;
475 }
476 /*case IRP_MN_QUERY_DEVICE_TEXT:
477 {
478 Status = STATUS_NOT_SUPPORTED;
479 break;
480 }*/
481
482 case IRP_MN_QUERY_ID:
483 {
484 Status = PdoQueryId(DeviceObject, Irp, &Information);
485 break;
486 }
487 case IRP_MN_QUERY_INTERFACE:
488 {
489 UNICODE_STRING GuidString;
490 PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
491 PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
492 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
493 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
494
495 PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
496 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
497
498 Status = RtlStringFromGUID(Stack->Parameters.QueryInterface.InterfaceType, &GuidString);
499 if (!NT_SUCCESS(Status))
500 {
501 DPRINT1("Failed to create string from GUID!\n");
502 }
503 DPRINT1("Interface GUID requested %wZ\n", &GuidString);
504 DPRINT1("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
505 DPRINT1("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
506
507 Status = STATUS_SUCCESS;
508 Information = 0;
509
510 /* FIXME: Check the actual Guid */
511 if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2) && (Stack->Parameters.QueryInterface.Version == 2))
512 {
513 InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
514 InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
515 InterfaceDI->Version = 2;
516 InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
517 InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
518 InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
519 InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
520 InterfaceDI->QueryBusTime = QueryBusTime;
521 InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
522 InterfaceDI->QueryBusInformation = QueryBusInformation;
523 InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
524 InterfaceDI->EnumLogEntry = EnumLogEntry;
525 }
526 /* FIXME: Check the actual Guid */
527 else if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V5) &&
528 (Stack->Parameters.QueryInterface.Version == 5))
529 {
530 InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
531 InterfaceHub->Version = 5;
532 InterfaceHub->Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
533 InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
534 InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
535 InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
536 InterfaceHub->CreateUsbDevice = CreateUsbDevice;
537 InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
538 InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
539 InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
540 InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
541 InterfaceHub->GetPortHackFlags = GetPortHackFlags;
542 InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
543 InterfaceHub->GetControllerInformation = GetControllerInformation;
544 InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
545 InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
546 InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
547 InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
548 InterfaceHub->Initialize20Hub = Initialize20Hub;
549 InterfaceHub->RootHubInitNotification = RootHubInitNotification;
550 InterfaceHub->FlushTransfers = FlushTransfers;
551 InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
552 }
553 else
554 {
555 DPRINT1("Not Supported\n");
556 Status = Irp->IoStatus.Status;
557 Information = Irp->IoStatus.Information;
558 }
559 break;
560 }
561 case IRP_MN_QUERY_BUS_INFORMATION:
562 {
563 PPNP_BUS_INFORMATION BusInfo;
564
565 BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
566 if (!BusInfo)
567 Status = STATUS_INSUFFICIENT_RESOURCES;
568 else
569 {
570 /* FIXME */
571 /*RtlCopyMemory(
572 &BusInfo->BusTypeGuid,
573 &GUID_DEVINTERFACE_XXX,
574 sizeof(GUID));*/
575
576 BusInfo->LegacyBusType = PNPBus;
577 BusInfo->BusNumber = 0;
578 Information = (ULONG_PTR)BusInfo;
579 Status = STATUS_SUCCESS;
580 }
581 break;
582 }
583 default:
584 {
585 /* We are the PDO. So ignore */
586 DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
587 break;
588 }
589 }
590
591 Irp->IoStatus.Information = Information;
592 Irp->IoStatus.Status = Status;
593 IoCompleteRequest(Irp, IO_NO_INCREMENT);
594 return Status;
595 }
596