[USBHUB][USBUHCI][CDROM_NEW]
[reactos.git] / reactos / drivers / usb / usbhub / pdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Hub Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbhub/fdo.c
5 * PURPOSE: Handle PDO
6 * PROGRAMMERS:
7 * Hervé Poussineau (hpoussin@reactos.org)
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
10 */
11
12 #include "usbhub.h"
13
14 #include <wdmguid.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
20
21 NTSTATUS
22 NTAPI
23 UrbCompletion(
24 PDEVICE_OBJECT DeviceObject,
25 PIRP Irp,
26 PVOID Context)
27 {
28 PIRP OriginalIrp;
29 DPRINT("Entered Urb Completion\n");
30
31 //
32 // Get the original Irp
33 //
34 OriginalIrp = (PIRP)Context;
35
36 //
37 // Update it to match what was returned for the IRP that was passed to RootHub
38 //
39 OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
40 OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
41 DPRINT("Status %x, Information %x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
42
43 //
44 // Complete the original Irp
45 //
46 IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);
47
48 //
49 // Return this status so the IO Manager doesnt mess with the Irp
50 //
51 return STATUS_MORE_PROCESSING_REQUIRED;
52 }
53
54 NTSTATUS
55 FowardUrbToRootHub(
56 PDEVICE_OBJECT RootHubDeviceObject,
57 IN ULONG IoControlCode,
58 PIRP Irp,
59 OUT PVOID OutParameter1,
60 OUT PVOID OutParameter2)
61 {
62 PIRP ForwardIrp;
63 IO_STATUS_BLOCK IoStatus;
64 PIO_STACK_LOCATION ForwardStack, CurrentStack;
65 PURB Urb;
66
67 //
68 // Get the current stack location for the Irp
69 //
70 CurrentStack = IoGetCurrentIrpStackLocation(Irp);
71 ASSERT(CurrentStack);
72
73 //
74 // Pull the Urb from that stack, it will be reused in the Irp sent to RootHub
75 //
76 Urb = (PURB)CurrentStack->Parameters.Others.Argument1;
77 ASSERT(Urb);
78
79 //
80 // Create the Irp to forward to RootHub
81 //
82 ForwardIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_SHUTDOWN,
83 RootHubDeviceObject,
84 NULL,
85 0,
86 0,
87 &IoStatus);
88 if (!ForwardIrp)
89 {
90 DPRINT1("Failed to allocate IRP\n");
91 return STATUS_INSUFFICIENT_RESOURCES;
92 }
93
94 //
95 // Get the new Irps next stack
96 //
97 ForwardStack = IoGetNextIrpStackLocation(ForwardIrp);
98
99 //
100 // Copy the stack for the current irp into the next stack of new irp
101 //
102 RtlCopyMemory(ForwardStack, CurrentStack, sizeof(IO_STACK_LOCATION));
103
104 IoStatus.Status = STATUS_NOT_SUPPORTED;
105 IoStatus.Information = 0;
106
107 //
108 // Mark the Irp from upper driver as pending
109 //
110 IoMarkIrpPending(Irp);
111
112 //
113 // Now set the completion routine for the new Irp.
114 //
115 IoSetCompletionRoutine(ForwardIrp,
116 UrbCompletion,
117 Irp,
118 TRUE,
119 TRUE,
120 TRUE);
121
122 IoCallDriver(RootHubDeviceObject, ForwardIrp);
123
124 //
125 // Always return pending as the completion routine will take care of it
126 //
127 return STATUS_PENDING;
128 }
129
130 BOOLEAN
131 IsValidPDO(
132 IN PDEVICE_OBJECT DeviceObject)
133 {
134 ULONG Index;
135 PHUB_DEVICE_EXTENSION HubDeviceExtension;
136 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
137
138
139 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
140 ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
141 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
142
143 for(Index = 0; Index < USB_MAXCHILDREN; Index++)
144 {
145 if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
146 {
147 /* PDO exists */
148 return TRUE;
149 }
150 }
151
152 /* invalid pdo */
153 return FALSE;
154 }
155
156
157 NTSTATUS
158 USBHUB_PdoHandleInternalDeviceControl(
159 IN PDEVICE_OBJECT DeviceObject,
160 IN PIRP Irp)
161 {
162 NTSTATUS Status;
163 PIO_STACK_LOCATION Stack;
164 ULONG_PTR Information = 0;
165 PHUB_DEVICE_EXTENSION HubDeviceExtension;
166 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
167 PDEVICE_OBJECT RootHubDeviceObject;
168 PURB Urb;
169
170 //DPRINT1("UsbhubInternalDeviceControlPdo(%x) called\n", DeviceObject);
171
172 //
173 // get current stack location
174 //
175 Stack = IoGetCurrentIrpStackLocation(Irp);
176 ASSERT(Stack);
177
178 //
179 // Set default status
180 //
181 Status = Irp->IoStatus.Status;
182
183 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
184 ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
185 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
186 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
187
188 if(!IsValidPDO(DeviceObject))
189 {
190 DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
191 Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
192 Irp->IoStatus.Information = 0;
193 IoCompleteRequest(Irp, IO_NO_INCREMENT);
194 return STATUS_DEVICE_NOT_CONNECTED;
195 }
196
197 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
198 {
199 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
200 {
201 DPRINT("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
202 if (Irp->AssociatedIrp.SystemBuffer == NULL
203 || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
204 {
205 Status = STATUS_INVALID_PARAMETER;
206 }
207 else
208 {
209 PVOID* pHubPointer;
210
211 pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
212 // FIXME
213 *pHubPointer = NULL;
214 Information = sizeof(PVOID);
215 Status = STATUS_SUCCESS;
216 }
217 break;
218 }
219 case IOCTL_INTERNAL_USB_SUBMIT_URB:
220 {
221 //DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
222
223 //
224 // Get the Urb
225 //
226 Urb = (PURB)Stack->Parameters.Others.Argument1;
227 ASSERT(Urb);
228
229 //
230 // Set the real device handle
231 //
232 //DPRINT("UsbdDeviceHandle %x, ChildDeviceHandle %x\n", Urb->UrbHeader.UsbdDeviceHandle, ChildDeviceExtension->UsbDeviceHandle);
233
234 Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
235
236 //
237 // Submit to RootHub
238 //
239 switch (Urb->UrbHeader.Function)
240 {
241 //
242 // Debugging only
243 //
244 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
245 DPRINT("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
246 break;
247 case URB_FUNCTION_CLASS_DEVICE:
248 DPRINT("URB_FUNCTION_CLASS_DEVICE\n");
249 break;
250 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
251 DPRINT("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
252 break;
253 case URB_FUNCTION_SELECT_CONFIGURATION:
254 DPRINT("URB_FUNCTION_SELECT_CONFIGURATION\n");
255 break;
256 case URB_FUNCTION_SELECT_INTERFACE:
257 DPRINT("URB_FUNCTION_SELECT_INTERFACE\n");
258 break;
259 case URB_FUNCTION_CLASS_OTHER:
260 DPRINT("URB_FUNCTION_CLASS_OTHER\n");
261 break;
262 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
263 {
264 /*
265 DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
266 DPRINT1("PipeHandle %x\n", Urb->UrbBulkOrInterruptTransfer.PipeHandle);
267 DPRINT1("TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
268 DPRINT1("Buffer %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
269 DPRINT1("BufferMDL %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
270 DPRINT1("Length %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
271 DPRINT1("UrbLink %x\n", Urb->UrbBulkOrInterruptTransfer.UrbLink);
272 DPRINT1("hca %x\n", Urb->UrbBulkOrInterruptTransfer.hca);
273 if (Urb->UrbBulkOrInterruptTransfer.TransferFlags == USBD_SHORT_TRANSFER_OK)
274 {
275 }
276 */
277 break;
278
279 }
280 case URB_FUNCTION_CLASS_INTERFACE:
281 DPRINT("URB_FUNCTION_CLASS_INTERFACE\n");
282 break;
283 case URB_FUNCTION_VENDOR_DEVICE:
284 DPRINT("URB_FUNCTION_VENDOR_DEVICE\n");
285 break;
286 default:
287 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
288 break;
289 }
290 Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
291 //DPRINT1("Stack->CompletionRoutine %x\n", Stack->CompletionRoutine);
292 //
293 // Send the request to RootHub
294 //
295 Status = FowardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
296 return Status;
297 }
298 //
299 // FIXME: Can these be sent to RootHub?
300 //
301 case IOCTL_INTERNAL_USB_RESET_PORT:
302 DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
303 break;
304 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
305 {
306 PORT_STATUS_CHANGE PortStatus;
307 LONG PortId;
308 PUCHAR PortStatusBits;
309
310 PortStatusBits = (PUCHAR)Stack->Parameters.Others.Argument1;
311 //
312 // USBD_PORT_ENABLED (bit 0) or USBD_PORT_CONNECTED (bit 1)
313 //
314 DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
315 DPRINT("Arg1 %x\n", *PortStatusBits);
316 *PortStatusBits = 0;
317 if (Stack->Parameters.Others.Argument1)
318 {
319 for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
320 {
321 Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
322 if (NT_SUCCESS(Status))
323 {
324 DPRINT("Connect %x\n", ((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2));
325 DPRINT("Enable %x\n", ((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
326 *PortStatusBits +=
327 (((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2)) +
328 (((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
329
330 }
331 }
332 }
333
334 DPRINT1("Arg1 %x\n", *PortStatusBits);
335 Status = STATUS_SUCCESS;
336 break;
337 }
338 case IOCTL_INTERNAL_USB_ENABLE_PORT:
339 DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
340 break;
341 case IOCTL_INTERNAL_USB_CYCLE_PORT:
342 DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
343 break;
344 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
345 {
346 DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
347 if (Stack->Parameters.Others.Argument1)
348 {
349 // store device handle
350 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)ChildDeviceExtension->UsbDeviceHandle;
351 Status = STATUS_SUCCESS;
352 }
353 else
354 {
355 // invalid parameter
356 Status = STATUS_INVALID_PARAMETER;
357 }
358 break;
359 }
360 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
361 {
362 if (Stack->Parameters.Others.Argument1)
363 {
364 // inform caller that it is a real usb hub
365 *(PVOID *)Stack->Parameters.Others.Argument1 = NULL;
366 }
367
368 if (Stack->Parameters.Others.Argument2)
369 {
370 // output device object
371 *(PVOID *)Stack->Parameters.Others.Argument2 = DeviceObject;
372 }
373
374 // done
375 Status = STATUS_SUCCESS;
376 break;
377 }
378 default:
379 {
380 DPRINT1("Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
381 Information = Irp->IoStatus.Information;
382 Status = Irp->IoStatus.Status;
383 }
384 }
385
386 if (Status != STATUS_PENDING)
387 {
388 Irp->IoStatus.Information = Information;
389 Irp->IoStatus.Status = Status;
390 IoCompleteRequest(Irp, IO_NO_INCREMENT);
391 }
392 return Status;
393 }
394
395 NTSTATUS
396 USBHUB_PdoStartDevice(
397 IN PDEVICE_OBJECT DeviceObject,
398 IN PIRP Irp)
399 {
400 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
401 //NTSTATUS Status;
402 DPRINT("USBHUB_PdoStartDevice %x\n", DeviceObject);
403 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
404
405 //
406 // This should be a PDO
407 //
408 ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
409
410 //
411 // FIXME: Fow now assume success
412 //
413
414 UNIMPLEMENTED
415 return STATUS_SUCCESS;
416 }
417
418 NTSTATUS
419 USBHUB_PdoQueryId(
420 IN PDEVICE_OBJECT DeviceObject,
421 IN PIRP Irp,
422 OUT ULONG_PTR* Information)
423 {
424 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
425 ULONG IdType;
426 PUNICODE_STRING SourceString = NULL;
427 PWCHAR ReturnString = NULL;
428 NTSTATUS Status = STATUS_SUCCESS;
429
430 IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
431 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
432
433 switch (IdType)
434 {
435 case BusQueryDeviceID:
436 {
437 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
438 SourceString = &ChildDeviceExtension->usDeviceId;
439 break;
440 }
441 case BusQueryHardwareIDs:
442 {
443 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
444 SourceString = &ChildDeviceExtension->usHardwareIds;
445 break;
446 }
447 case BusQueryCompatibleIDs:
448 {
449 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
450 SourceString = &ChildDeviceExtension->usCompatibleIds;
451 break;
452 }
453 case BusQueryInstanceID:
454 {
455 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
456 SourceString = &ChildDeviceExtension->usInstanceId;
457 break;
458 }
459 default:
460 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
461 return STATUS_NOT_SUPPORTED;
462 }
463
464 if (SourceString)
465 {
466 //
467 // allocate buffer
468 //
469 ReturnString = ExAllocatePool(PagedPool, SourceString->MaximumLength);
470 if (!ReturnString)
471 {
472 //
473 // no memory
474 //
475 return STATUS_INSUFFICIENT_RESOURCES;
476 }
477
478 //
479 // copy buffer
480 //
481 RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->MaximumLength);
482 }
483
484 *Information = (ULONG_PTR)ReturnString;
485
486 return Status;
487 }
488
489 NTSTATUS
490 USBHUB_PdoQueryDeviceText(
491 IN PDEVICE_OBJECT DeviceObject,
492 IN PIRP Irp,
493 OUT ULONG_PTR* Information)
494 {
495 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
496 DEVICE_TEXT_TYPE DeviceTextType;
497 PUNICODE_STRING SourceString = NULL;
498 PWCHAR ReturnString = NULL;
499 NTSTATUS Status = STATUS_SUCCESS;
500
501 DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
502 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
503
504 //
505 // FIXME: LocaleId
506 //
507
508 switch (DeviceTextType)
509 {
510 case DeviceTextDescription:
511 case DeviceTextLocationInformation:
512 {
513 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
514
515 //
516 // does the device provide a text description
517 //
518 if (ChildDeviceExtension->usTextDescription.Buffer && ChildDeviceExtension->usTextDescription.Length)
519 {
520 //
521 // use device text
522 //
523 SourceString = &ChildDeviceExtension->usTextDescription;
524 }
525 break;
526 }
527 default:
528 {
529 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
530 Status = STATUS_NOT_SUPPORTED;
531 break;
532 }
533 }
534
535 if (SourceString)
536 {
537 ReturnString = ExAllocatePool(PagedPool, SourceString->MaximumLength);
538 RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->MaximumLength);
539 DPRINT1("%S\n", ReturnString);
540 *Information = (ULONG_PTR)ReturnString;
541 }
542
543 return Status;
544 }
545
546 NTSTATUS
547 USBHUB_PdoHandlePnp(
548 IN PDEVICE_OBJECT DeviceObject,
549 IN PIRP Irp)
550 {
551 NTSTATUS Status;
552 ULONG MinorFunction;
553 PIO_STACK_LOCATION Stack;
554 ULONG_PTR Information = 0;
555 PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
556 ULONG Index;
557 ULONG bFound;
558 PDEVICE_RELATIONS DeviceRelation;
559 PDEVICE_OBJECT ParentDevice;
560
561 UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
562 Stack = IoGetCurrentIrpStackLocation(Irp);
563 MinorFunction = Stack->MinorFunction;
564
565 switch (MinorFunction)
566 {
567 case IRP_MN_START_DEVICE:
568 {
569 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
570 Status = USBHUB_PdoStartDevice(DeviceObject, Irp);
571 break;
572 }
573 case IRP_MN_QUERY_CAPABILITIES:
574 {
575 PDEVICE_CAPABILITIES DeviceCapabilities;
576 ULONG i;
577 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
578
579 DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
580 // FIXME: capabilities can change with connected device
581 DeviceCapabilities->LockSupported = FALSE;
582 DeviceCapabilities->EjectSupported = FALSE;
583 DeviceCapabilities->Removable = TRUE;
584 DeviceCapabilities->DockDevice = FALSE;
585 DeviceCapabilities->UniqueID = FALSE;
586 DeviceCapabilities->SilentInstall = FALSE;
587 DeviceCapabilities->RawDeviceOK = FALSE;
588 DeviceCapabilities->SurpriseRemovalOK = FALSE;
589 DeviceCapabilities->HardwareDisabled = FALSE;
590 //DeviceCapabilities->NoDisplayInUI = FALSE;
591 DeviceCapabilities->Address = UsbChildExtension->PortNumber;
592 DeviceCapabilities->UINumber = 0;
593 DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
594 for (i = 1; i < PowerSystemMaximum; i++)
595 DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
596 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
597 DeviceCapabilities->D1Latency = 0;
598 DeviceCapabilities->D2Latency = 0;
599 DeviceCapabilities->D3Latency = 0;
600 Status = STATUS_SUCCESS;
601 break;
602 }
603 case IRP_MN_QUERY_RESOURCES:
604 {
605 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
606
607 Information = Irp->IoStatus.Information;
608 Status = Irp->IoStatus.Status;
609 break;
610 }
611 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
612 {
613 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
614
615 Information = Irp->IoStatus.Information;
616 Status = Irp->IoStatus.Status;
617 break;
618 }
619 case IRP_MN_QUERY_DEVICE_TEXT:
620 {
621 Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
622 break;
623 }
624 case IRP_MN_QUERY_ID:
625 {
626 Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
627 break;
628 }
629 case IRP_MN_QUERY_BUS_INFORMATION:
630 {
631 PPNP_BUS_INFORMATION BusInfo;
632 BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
633 RtlCopyMemory(&BusInfo->BusTypeGuid,
634 &GUID_BUS_TYPE_USB,
635 sizeof(BusInfo->BusTypeGuid));
636 BusInfo->LegacyBusType = PNPBus;
637 // FIXME
638 BusInfo->BusNumber = 0;
639 Information = (ULONG_PTR)BusInfo;
640 Status = STATUS_SUCCESS;
641 break;
642 }
643 case IRP_MN_REMOVE_DEVICE:
644 {
645 PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
646 PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
647 ParentDevice = UsbChildExtension->ParentDeviceObject;
648
649 DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
650
651 /* remove us from pdo list */
652 bFound = FALSE;
653 for(Index = 0; Index < USB_MAXCHILDREN; Index++)
654 {
655 if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
656 {
657 /* Remove the device */
658 Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
659
660 /* FIXME handle error */
661 ASSERT(Status == STATUS_SUCCESS);
662
663 /* remove us */
664 HubDeviceExtension->ChildDeviceObject[Index] = NULL;
665 bFound = TRUE;
666 break;
667 }
668 }
669
670 /* Complete the IRP */
671 Irp->IoStatus.Status = STATUS_SUCCESS;
672 IoCompleteRequest(Irp, IO_NO_INCREMENT);
673
674 /* delete device */
675 IoDeleteDevice(DeviceObject);
676
677 if (bFound)
678 {
679 /* invalidate device relations */
680 IoInvalidateDeviceRelations(ParentDevice, BusRelations);
681 }
682
683 return STATUS_SUCCESS;
684 }
685 case IRP_MN_QUERY_DEVICE_RELATIONS:
686 {
687 /* only target relations are supported */
688 if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
689 {
690 /* not supported */
691 Status = Irp->IoStatus.Status;
692 break;
693 }
694
695 /* allocate device relations */
696 DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS));
697 if (!DeviceRelation)
698 {
699 /* no memory */
700 Status = STATUS_INSUFFICIENT_RESOURCES;
701 break;
702 }
703
704 /* init device relation */
705 DeviceRelation->Count = 1;
706 DeviceRelation->Objects[0] = DeviceObject;
707 ObReferenceObject(DeviceRelation->Objects[0]);
708
709 /* store result */
710 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
711 Status = STATUS_SUCCESS;
712 break;
713 }
714 case IRP_MN_QUERY_STOP_DEVICE:
715 case IRP_MN_QUERY_REMOVE_DEVICE:
716 {
717 /* Sure, no problem */
718 Status = STATUS_SUCCESS;
719 Information = 0;
720 break;
721 }
722 case IRP_MN_QUERY_INTERFACE:
723 {
724 DPRINT1("IRP_MN_QUERY_INTERFACE\n");
725 if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
726 {
727 DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
728 RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
729 Status = STATUS_SUCCESS;
730 break;
731 }
732
733 // pass irp down
734 IoSkipCurrentIrpStackLocation(Irp);
735 return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
736 }
737 case IRP_MN_SURPRISE_REMOVAL:
738 {
739 DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
740 Status = STATUS_SUCCESS;
741 break;
742 }
743 default:
744 {
745 DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
746 Information = Irp->IoStatus.Information;
747 Status = Irp->IoStatus.Status;
748 }
749 }
750
751 Irp->IoStatus.Information = Information;
752 Irp->IoStatus.Status = Status;
753 IoCompleteRequest(Irp, IO_NO_INCREMENT);
754 return Status;
755 }
756