[USBHUB_NEW]
[reactos.git] / drivers / usb / usbhub_new / fdo.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 FDO
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 */
10
11 #define INITGUID
12
13 #define NDEBUG
14 #include "usbhub.h"
15
16 NTSTATUS
17 QueryStatusChangeEndpoint(
18 IN PDEVICE_OBJECT DeviceObject);
19
20 NTSTATUS
21 CreateUsbChildDeviceObject(
22 IN PDEVICE_OBJECT UsbHubDeviceObject,
23 IN LONG PortId,
24 OUT PDEVICE_OBJECT *UsbChildDeviceObject);
25
26 NTSTATUS
27 SubmitRequestToRootHub(
28 IN PDEVICE_OBJECT RootHubDeviceObject,
29 IN ULONG IoControlCode,
30 OUT PVOID OutParameter1,
31 OUT PVOID OutParameter2)
32 {
33 KEVENT Event;
34 PIRP Irp;
35 IO_STATUS_BLOCK IoStatus;
36 NTSTATUS Status;
37 PIO_STACK_LOCATION Stack = NULL;
38
39 KeInitializeEvent(&Event, NotificationEvent, FALSE);
40
41 //
42 // Build Control Request
43 //
44 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
45 RootHubDeviceObject,
46 NULL, 0,
47 NULL, 0,
48 TRUE,
49 &Event,
50 &IoStatus);
51
52 if (Irp == NULL)
53 {
54 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
55 return STATUS_INSUFFICIENT_RESOURCES;
56 }
57
58 //
59 // Initialize the status block before sending the IRP
60 //
61 IoStatus.Status = STATUS_NOT_SUPPORTED;
62 IoStatus.Information = 0;
63
64 //
65 // Get Next Stack Location and Initialize it
66 //
67 Stack = IoGetNextIrpStackLocation(Irp);
68 Stack->Parameters.Others.Argument1 = OutParameter1;
69 Stack->Parameters.Others.Argument2 = OutParameter2;
70
71 //
72 // Call RootHub
73 //
74 Status = IoCallDriver(RootHubDeviceObject, Irp);
75
76 if (Status == STATUS_PENDING)
77 {
78 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
79 Status = IoStatus.Status;
80 }
81
82 return Status;
83 }
84
85 NTSTATUS
86 GetPortStatusAndChange(
87 IN PDEVICE_OBJECT RootHubDeviceObject,
88 IN ULONG PortId,
89 OUT PPORT_STATUS_CHANGE StatusChange)
90 {
91 NTSTATUS Status;
92 PURB Urb;
93
94 //
95 // Allocate URB
96 //
97 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
98 if (!Urb)
99 {
100 DPRINT1("Failed to allocate memory for URB!\n");
101 return STATUS_INSUFFICIENT_RESOURCES;
102 }
103
104 //
105 // Zero it
106 //
107 RtlZeroMemory(Urb, sizeof(URB));
108
109 //
110 // Create URB for getting Port Status
111 //
112 UsbBuildVendorRequest(Urb,
113 URB_FUNCTION_CLASS_OTHER,
114 sizeof(Urb->UrbControlVendorClassRequest),
115 USBD_TRANSFER_DIRECTION_OUT,
116 0,
117 USB_REQUEST_GET_STATUS,
118 0,
119 PortId,
120 StatusChange,
121 0,
122 sizeof(PORT_STATUS_CHANGE),
123 0);
124
125 //
126 // Query the Root Hub
127 //
128 Status = SubmitRequestToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
129
130 //
131 // Free URB
132 //
133 ExFreePool(Urb);
134
135 return Status;
136 }
137
138 NTSTATUS
139 SetPortFeature(
140 IN PDEVICE_OBJECT RootHubDeviceObject,
141 IN ULONG PortId,
142 IN ULONG Feature)
143 {
144 NTSTATUS Status;
145 PURB Urb;
146
147 //
148 // Allocate URB
149 //
150 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
151 if (!Urb)
152 {
153 DPRINT1("Failed to allocate memory for URB!\n");
154 return STATUS_INSUFFICIENT_RESOURCES;
155 }
156
157 //
158 // Zero it
159 //
160 RtlZeroMemory(Urb, sizeof(URB));
161
162 //
163 // Create URB for Clearing Port Reset
164 //
165 UsbBuildVendorRequest(Urb,
166 URB_FUNCTION_CLASS_OTHER,
167 sizeof(Urb->UrbControlVendorClassRequest),
168 USBD_TRANSFER_DIRECTION_IN,
169 0,
170 USB_REQUEST_SET_FEATURE,
171 Feature,
172 PortId,
173 NULL,
174 0,
175 0,
176 0);
177 //
178 // Query the Root Hub
179 //
180 Status = SubmitRequestToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
181
182 //
183 // Free URB
184 //
185 ExFreePool(Urb);
186
187 return Status;
188 }
189
190 NTSTATUS
191 ClearPortFeature(
192 IN PDEVICE_OBJECT RootHubDeviceObject,
193 IN ULONG PortId,
194 IN ULONG Feature)
195 {
196 NTSTATUS Status;
197 PURB Urb;
198
199 //
200 // Allocate a URB
201 //
202 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
203 if (!Urb)
204 {
205 DPRINT1("Failed to allocate memory for URB!\n");
206 return STATUS_INSUFFICIENT_RESOURCES;
207 }
208
209 //
210 // Zero it
211 //
212 RtlZeroMemory(Urb, sizeof(URB));
213
214 //
215 // Create URB for Clearing Port Reset
216 //
217 UsbBuildVendorRequest(Urb,
218 URB_FUNCTION_CLASS_OTHER,
219 sizeof(Urb->UrbControlVendorClassRequest),
220 USBD_TRANSFER_DIRECTION_IN,
221 0,
222 USB_REQUEST_CLEAR_FEATURE,
223 Feature,
224 PortId,
225 NULL,
226 0,
227 0,
228 0);
229 //
230 // Query the Root Hub
231 //
232 Status = SubmitRequestToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
233
234 //
235 // Free URB
236 //
237 ExFreePool(Urb);
238
239 return Status;
240 }
241
242 VOID NTAPI
243 DeviceStatusChangeThread(
244 IN PVOID Context)
245 {
246 NTSTATUS Status;
247 PDEVICE_OBJECT DeviceObject, RootHubDeviceObject;
248 PHUB_DEVICE_EXTENSION HubDeviceExtension;
249 PWORK_ITEM_DATA WorkItemData;
250 PORT_STATUS_CHANGE PortStatus;
251 LONG PortId;
252 DPRINT1("Entered DeviceStatusChangeThread, Context %x\n", Context);
253 static LONG failsafe = 0;
254
255 WorkItemData = (PWORK_ITEM_DATA)Context;
256 DeviceObject = (PDEVICE_OBJECT)WorkItemData->Context;
257 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
258 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
259 //
260 // Loop all ports
261 //
262 for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
263 {
264 //
265 // Get Port Status
266 //
267 Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
268 if (!NT_SUCCESS(Status))
269 {
270 DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
271 // FIXME: Do we really want to halt further SCE requests?
272 return;
273 }
274
275 DPRINT1("Port %d Status %x\n", PortId, PortStatus.Status);
276 DPRINT1("Port %d Change %x\n", PortId, PortStatus.Change);
277
278
279 //
280 // Check for new device connection
281 //
282 if (PortStatus.Change & USB_PORT_STATUS_CONNECT)
283 {
284 //
285 // Clear Port Connect
286 //
287 Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
288 if (!NT_SUCCESS(Status))
289 {
290 DPRINT1("Failed to clear connection change for port %d\n", PortId);
291 }
292
293 //
294 // Is this a connect or disconnect?
295 //
296 if (!(PortStatus.Status & USB_PORT_STATUS_CONNECT))
297 {
298 DPRINT1("Device disconnected from port %d\n", PortId);
299
300 //
301 // FIXME: Remove the device, and deallocate memory
302 //
303 }
304 else
305 {
306 DPRINT1("Device connected from port %d\n", PortId);
307
308 // No SCE completion done for clearing C_PORT_CONNECT
309
310 //
311 // Reset Port
312 //
313 Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
314 if (!NT_SUCCESS(Status))
315 {
316 DPRINT1("Failed to reset port %d\n", PortId);
317 }
318 }
319 }
320 else if (PortStatus.Change & USB_PORT_STATUS_ENABLE)
321 {
322 //
323 // Clear Enable
324 //
325 Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_ENABLE);
326 if (!NT_SUCCESS(Status))
327 {
328 DPRINT1("Failed to clear enable change on port %d\n", PortId);
329 }
330 }
331 else if (PortStatus.Change & USB_PORT_STATUS_RESET)
332 {
333 //
334 // Clear Reset
335 //
336 Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_RESET);
337 if (!NT_SUCCESS(Status))
338 {
339 DPRINT1("Failed to clear reset change on port %d\n", PortId);
340 }
341
342 //
343 // Get Port Status
344 //
345 Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
346 if (!NT_SUCCESS(Status))
347 {
348 DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
349 // FIXME: Do we really want to halt further SCE requests?
350 return;
351 }
352
353 DPRINT1("Port %d Status %x\n", PortId, PortStatus.Status);
354 DPRINT1("Port %d Change %x\n", PortId, PortStatus.Change);
355
356 if(PortStatus.Change & USB_PORT_STATUS_RESET)
357 {
358 DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
359 }
360
361 //
362 // Make sure its Connected and Enabled
363 //
364 if (!(PortStatus.Status & (USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE)))
365 {
366 DPRINT1("Usb Device is not connected and enabled!\n");
367 //
368 // Attempt another reset
369 //
370 Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
371 if (!NT_SUCCESS(Status))
372 {
373 DPRINT1("Failed to reset port %d\n", PortId);
374 }
375 continue;
376 }
377
378 //
379 // Create the device object only if the port manipulation was started by a device connect
380 //
381 if (HubDeviceExtension->PortStatusChange[PortId-1].Status)
382 {
383 HubDeviceExtension->PortStatusChange[PortId-1].Status = 0;
384 Status = CreateUsbChildDeviceObject(DeviceObject, PortId, NULL);
385 }
386 }
387 }
388
389 //
390 // FIXME: Still in testing
391 //
392 failsafe++;
393 if (failsafe > 100)
394 {
395 DPRINT1("SCE completed over 100 times but no action has been taken to clear the Change of any ports.\n");
396 //
397 // Return and dont send any more SCE Requests
398 //
399 return;
400 }
401
402 ExFreePool(WorkItemData);
403
404 //
405 // Send another SCE Request
406 //
407 DPRINT1("Sending another SCE!\n");
408 QueryStatusChangeEndpoint(DeviceObject);
409 }
410
411 NTSTATUS
412 StatusChangeEndpointCompletion(
413 IN PDEVICE_OBJECT DeviceObject,
414 IN PIRP Irp,
415 IN PVOID Context)
416 {
417 PDEVICE_OBJECT RealDeviceObject;
418 PHUB_DEVICE_EXTENSION HubDeviceExtension;
419 PWORK_ITEM_DATA WorkItemData;
420
421 RealDeviceObject = (PDEVICE_OBJECT)Context;
422 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)RealDeviceObject->DeviceExtension;
423
424 //
425 // NOTE: USBPORT frees this IRP
426 //
427 DPRINT1("Received Irp %x, HubDeviceExtension->PendingSCEIrp %x\n", Irp, HubDeviceExtension->PendingSCEIrp);
428 //IoFreeIrp(Irp);
429
430 //
431 // Create and initialize work item data
432 //
433 WorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(WORK_ITEM_DATA), USB_HUB_TAG);
434 if (!WorkItemData)
435 {
436 DPRINT1("Failed to allocate memory!n");
437 return STATUS_INSUFFICIENT_RESOURCES;
438 }
439 WorkItemData->Context = RealDeviceObject;
440 DPRINT1("Initialize work item\n");
441 ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)DeviceStatusChangeThread, (PVOID)WorkItemData);
442
443 //
444 // Queue the work item to handle initializing the device
445 //
446 ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue);
447
448 //
449 // Return more processing required so the IO Manger doesn’t try to mess with IRP just freed
450 //
451 return STATUS_MORE_PROCESSING_REQUIRED;
452 }
453
454 NTSTATUS
455 QueryStatusChangeEndpoint(
456 IN PDEVICE_OBJECT DeviceObject)
457 {
458 NTSTATUS Status;
459 PDEVICE_OBJECT RootHubDeviceObject;
460 PIO_STACK_LOCATION Stack;
461 PHUB_DEVICE_EXTENSION HubDeviceExtension;
462 PURB PendingSCEUrb;
463
464 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
465 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
466
467 //
468 // Allocate a URB
469 //
470 PendingSCEUrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
471
472 //
473 // Initialize URB for Status Change Endpoint request
474 //
475 UsbBuildInterruptOrBulkTransferRequest(PendingSCEUrb,
476 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
477 HubDeviceExtension->PipeHandle,
478 HubDeviceExtension->PortStatusChange,
479 NULL,
480 sizeof(USHORT) * 2 * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
481 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
482 NULL);
483
484 //
485 // Set the device handle to null for roothub
486 //
487 PendingSCEUrb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
488
489 //
490 // Allocate an Irp
491 //
492
493 HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
494 IoSizeOfIrp(RootHubDeviceObject->StackSize),
495 USB_HUB_TAG);
496 /*
497 HubDeviceExtension->PendingSCEIrp = IoAllocateIrp(RootHubDeviceObject->StackSize,
498 FALSE);
499 */
500 DPRINT1("Allocated IRP %x\n", HubDeviceExtension->PendingSCEIrp);
501
502 if (!HubDeviceExtension->PendingSCEIrp)
503 {
504 DPRINT1("USBHUB: Failed to allocate IRP for SCE request!\n");
505 return STATUS_INSUFFICIENT_RESOURCES;
506 }
507
508 //
509 // Initialize the IRP
510 //
511 IoInitializeIrp(HubDeviceExtension->PendingSCEIrp,
512 IoSizeOfIrp(RootHubDeviceObject->StackSize),
513 RootHubDeviceObject->StackSize);
514
515 HubDeviceExtension->PendingSCEIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
516 HubDeviceExtension->PendingSCEIrp->IoStatus.Information = 0;
517 HubDeviceExtension->PendingSCEIrp->Flags = 0;
518 HubDeviceExtension->PendingSCEIrp->UserBuffer = NULL;
519
520 //
521 // Get the Next Stack Location and Initialize it
522 //
523 Stack = IoGetNextIrpStackLocation(HubDeviceExtension->PendingSCEIrp);
524 Stack->DeviceObject = DeviceObject;
525 Stack->Parameters.Others.Argument1 = PendingSCEUrb;
526 Stack->Parameters.Others.Argument2 = NULL;
527 Stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
528 Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
529
530 //
531 // Set the completion routine for when device is connected to root hub
532 //
533 IoSetCompletionRoutine(HubDeviceExtension->PendingSCEIrp,
534 (PIO_COMPLETION_ROUTINE) StatusChangeEndpointCompletion,
535 DeviceObject,
536 TRUE,
537 TRUE,
538 TRUE);
539
540 //
541 // Send to RootHub
542 //
543 DPRINT1("DeviceObject is %x\n", DeviceObject);
544 DPRINT1("Iocalldriver %x with irp %x\n", RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
545 Status = IoCallDriver(RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
546
547 return STATUS_PENDING;
548 }
549
550 NTSTATUS
551 QueryInterface(
552 IN PDEVICE_OBJECT DeviceObject,
553 IN CONST GUID InterfaceType,
554 IN LONG Size,
555 IN LONG Version,
556 OUT PVOID Interface)
557 {
558 KEVENT Event;
559 PIRP Irp;
560 IO_STATUS_BLOCK IoStatus;
561 NTSTATUS Status;
562 PIO_STACK_LOCATION Stack = NULL;
563
564 //
565 // Initialize the Event used to wait for Irp completion
566 //
567 KeInitializeEvent(&Event, NotificationEvent, FALSE);
568
569 //
570 // Build Control Request
571 //
572 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
573 DeviceObject,
574 NULL,
575 0,
576 NULL,
577 &Event,
578 &IoStatus);
579
580 //
581 // Get Next Stack Location and Initialize it.
582 //
583 Stack = IoGetNextIrpStackLocation(Irp);
584 Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
585 Stack->Parameters.QueryInterface.InterfaceType= &InterfaceType;//USB_BUS_INTERFACE_HUB_GUID;
586 Stack->Parameters.QueryInterface.Size = Size;
587 Stack->Parameters.QueryInterface.Version = Version;
588 Stack->Parameters.QueryInterface.Interface = Interface;
589 Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
590
591 Status = IoCallDriver(DeviceObject, Irp);
592
593 if (Status == STATUS_PENDING)
594 {
595 DPRINT("Operation pending\n");
596 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
597 Status = IoStatus.Status;
598 }
599
600 return Status;
601 }
602
603 NTSTATUS
604 GetUsbDeviceDescriptor(
605 IN PDEVICE_OBJECT ChildDeviceObject,
606 IN UCHAR DescriptorType,
607 IN UCHAR Index,
608 IN USHORT LangId,
609 OUT PVOID TransferBuffer,
610 IN ULONG TransferBufferLength)
611 {
612 NTSTATUS Status;
613 PDEVICE_OBJECT RootHubDeviceObject;
614 PURB Urb;
615 PHUB_DEVICE_EXTENSION HubDeviceExtension;
616 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
617
618 //
619 // Get the Hubs Device Extension
620 //
621 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
622 HubDeviceExtension = (PHUB_DEVICE_EXTENSION) ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
623 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
624
625 //
626 // Allocate a URB
627 //
628 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
629 if (!Urb)
630 {
631 DPRINT1("Failed to allocate memory for URB!\n");
632 return STATUS_INSUFFICIENT_RESOURCES;
633 }
634
635 //
636 // Zero it
637 //
638 RtlZeroMemory(Urb, sizeof(URB));
639
640 //
641 // Create URB for getting device descriptor
642 //
643 UsbBuildGetDescriptorRequest(Urb,
644 sizeof(Urb->UrbControlDescriptorRequest),
645 DescriptorType,
646 Index,
647 LangId,
648 TransferBuffer,
649 NULL,
650 TransferBufferLength,
651 NULL);
652
653 //
654 // Set the device handle
655 //
656 Urb->UrbHeader.UsbdDeviceHandle = (PVOID)ChildDeviceExtension->UsbDeviceHandle;
657
658 //
659 // Query the Root Hub
660 //
661 Status = SubmitRequestToRootHub(RootHubDeviceObject,
662 IOCTL_INTERNAL_USB_SUBMIT_URB,
663 Urb,
664 NULL);
665
666 return Status;
667 }
668
669 NTSTATUS
670 GetUsbStringDescriptor(
671 IN PDEVICE_OBJECT ChildDeviceObject,
672 IN UCHAR Index,
673 IN USHORT LangId,
674 OUT PVOID *TransferBuffer)
675 {
676 NTSTATUS Status;
677 PUSB_STRING_DESCRIPTOR StringDesc = NULL;
678 ULONG SizeNeeded;
679
680 StringDesc = ExAllocatePoolWithTag(NonPagedPool,
681 sizeof(USB_STRING_DESCRIPTOR),
682 USB_HUB_TAG);
683 if (!StringDesc)
684 {
685 DPRINT1("Failed to allocate buffer for string!\n");
686 return STATUS_INSUFFICIENT_RESOURCES;
687 }
688
689 //
690 // Get the index string descriptor length
691 //
692 Status = GetUsbDeviceDescriptor(ChildDeviceObject,
693 USB_STRING_DESCRIPTOR_TYPE,
694 Index,
695 0,
696 StringDesc,
697 sizeof(USB_STRING_DESCRIPTOR));
698
699 //
700 // If lenght is 4 only then either this is a bad index or the device is not reporting
701 //
702 if (StringDesc->bLength == 4)
703 {
704 DPRINT1("USBHUB: Device Data Error\n");
705 return STATUS_UNSUCCESSFUL;
706 }
707
708 DPRINT1("StringDesc->bLength %d\n", StringDesc->bLength);
709 SizeNeeded = StringDesc->bLength + sizeof(WCHAR);
710
711 //
712 // Free String
713 //
714 ExFreePool(StringDesc);
715
716 //
717 // Recreate with appropriate size
718 //
719 StringDesc = ExAllocatePoolWithTag(NonPagedPool,
720 SizeNeeded,
721 USB_HUB_TAG);
722 if (!StringDesc)
723 {
724 DPRINT1("Failed to allocate buffer for string!\n");
725 return STATUS_INSUFFICIENT_RESOURCES;
726 }
727 RtlZeroMemory(StringDesc, SizeNeeded);
728 //
729 // Get the string
730 //
731 Status = GetUsbDeviceDescriptor(ChildDeviceObject,
732 USB_STRING_DESCRIPTOR_TYPE,
733 Index,
734 0,
735 StringDesc,
736 SizeNeeded);
737 if (!NT_SUCCESS(Status))
738 {
739 DPRINT1("Failed to get string from device\n");
740 ExFreePool(StringDesc);
741 return Status;
742 }
743
744 //
745 // Allocate Buffer to return
746 //
747 *TransferBuffer = ExAllocatePoolWithTag(NonPagedPool,
748 SizeNeeded,
749 USB_HUB_TAG);
750 if (!*TransferBuffer)
751 {
752 DPRINT1("Failed to allocate buffer for string!\n");
753 ExFreePool(StringDesc);
754 return STATUS_INSUFFICIENT_RESOURCES;
755 }
756
757 RtlZeroMemory(*TransferBuffer, SizeNeeded);
758
759 //
760 // Copy the string to destination
761 //
762 RtlCopyMemory(*TransferBuffer, StringDesc->bString, SizeNeeded - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bLength));
763
764 ExFreePool(StringDesc);
765
766 return STATUS_SUCCESS;
767 }
768
769 NTSTATUS
770 CreateUsbChildDeviceObject(
771 IN PDEVICE_OBJECT UsbHubDeviceObject,
772 IN LONG PortId,
773 OUT PDEVICE_OBJECT *UsbChildDeviceObject)
774 {
775 NTSTATUS Status;
776 PDEVICE_OBJECT RootHubDeviceObject, NewChildDeviceObject;
777 PHUB_DEVICE_EXTENSION HubDeviceExtension;
778 PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
779 PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
780 ULONG ChildDeviceCount, UsbDeviceNumber = 0;
781 WCHAR CharDeviceName[64];
782 UNICODE_STRING DeviceName;
783 ULONG ConfigDescSize, DeviceDescSize;
784 PVOID HubInterfaceBusContext;
785
786 HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbHubDeviceObject->DeviceExtension;
787 HubInterface = &HubDeviceExtension->HubInterface;
788 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
789 HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
790 //
791 // Find an empty slot in the child device array
792 //
793 for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN; ChildDeviceCount++)
794 {
795 if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
796 {
797 DPRINT1("Found unused entry at %d\n", ChildDeviceCount);
798 break;
799 }
800 }
801
802 //
803 // Check if the limit has been reached for maximum usb devices
804 //
805 if (ChildDeviceCount == USB_MAXCHILDREN)
806 {
807 DPRINT1("USBHUB: Too many child devices!\n");
808 return STATUS_UNSUCCESSFUL;
809 }
810
811 while (TRUE)
812 {
813 //
814 // Create a Device Name
815 //
816 swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
817
818 //
819 // Initialize UnicodeString
820 //
821 RtlInitUnicodeString(&DeviceName, CharDeviceName);
822
823 //
824 // Create a DeviceObject
825 //
826
827 Status = IoCreateDevice(UsbHubDeviceObject->DriverObject,
828 sizeof(HUB_CHILDDEVICE_EXTENSION),
829 NULL,
830 FILE_DEVICE_CONTROLLER,
831 FILE_AUTOGENERATED_DEVICE_NAME,
832 FALSE,
833 &NewChildDeviceObject);
834
835 //
836 // Check if the name is already in use
837 //
838 if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
839 {
840 //
841 // Try next name
842 //
843 UsbDeviceNumber++;
844 continue;
845 }
846
847 //
848 // Check for other errors
849 //
850 if (!NT_SUCCESS(Status))
851 {
852 DPRINT1("USBHUB: IoCreateDevice failed with status %x\n", Status);
853 return Status;
854 }
855
856 DPRINT1("USBHUB: Created Device %x\n", NewChildDeviceObject);
857 break;
858 }
859
860 NewChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
861
862 //
863 // Assign the device extensions
864 //
865 UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)NewChildDeviceObject->DeviceExtension;
866 RtlZeroMemory(UsbChildExtension, sizeof(HUB_CHILDDEVICE_EXTENSION));
867 UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
868
869 //
870 // Create the UsbDeviceObject
871 //
872 Status = HubInterface->CreateUsbDevice(HubInterfaceBusContext,
873 (PVOID)&UsbChildExtension->UsbDeviceHandle,
874 HubDeviceExtension->RootHubHandle,
875 0x501, //hack
876 PortId);
877 if (!NT_SUCCESS(Status))
878 {
879 DPRINT1("USBHUB: CreateUsbDevice failed with status %x\n", Status);
880 goto Cleanup;
881 }
882
883 //
884 // Initialize UsbDevice
885 //
886 Status = HubInterface->InitializeUsbDevice(HubInterfaceBusContext, UsbChildExtension->UsbDeviceHandle);
887 if (!NT_SUCCESS(Status))
888 {
889 DPRINT1("USBHUB: InitializeUsbDevice failed with status %x\n", Status);
890 goto Cleanup;
891 }
892
893 DPRINT1("Usb Device Handle %x\n", UsbChildExtension->UsbDeviceHandle);
894
895 ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
896 DeviceDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
897
898 //
899 // Get the descriptors
900 //
901 Status = HubInterface->GetUsbDescriptors(HubInterfaceBusContext,
902 UsbChildExtension->UsbDeviceHandle,
903 (PUCHAR)&UsbChildExtension->DeviceDesc,
904 &DeviceDescSize,
905 (PUCHAR)&UsbChildExtension->ConfigDesc,
906 &ConfigDescSize);
907 if (!NT_SUCCESS(Status))
908 {
909 DPRINT1("USBHUB: GetUsbDescriptors failed with status %x\n", Status);
910 goto Cleanup;
911 }
912
913 DumpDeviceDescriptor(&UsbChildExtension->DeviceDesc);
914
915 //
916 // Allocate memory for DeviceId
917 //
918 UsbChildExtension->DeviceId = ExAllocatePoolWithTag(NonPagedPool, 32 * sizeof(WCHAR), USB_HUB_TAG);
919
920 //
921 // Construct DeviceId from vendor and product values
922 //
923 swprintf(UsbChildExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", UsbChildExtension->DeviceDesc.idVendor, UsbChildExtension->DeviceDesc.idProduct);
924
925 DPRINT1("Usb Device Id %S\n", UsbChildExtension->DeviceId);
926
927 //
928 // FIXME: Handle Lang ids, will use default for now
929 //
930
931 //
932 // Get the product string
933 //
934 Status = GetUsbStringDescriptor(NewChildDeviceObject,
935 UsbChildExtension->DeviceDesc.iProduct,
936 0,
937 (PVOID*)&UsbChildExtension->TextDescription);
938 if (!NT_SUCCESS(Status))
939 {
940 DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
941 goto Cleanup;
942 }
943
944 DPRINT1("Usb TextDescription %S\n", UsbChildExtension->TextDescription);
945
946 Status = GetUsbStringDescriptor(NewChildDeviceObject,
947 UsbChildExtension->DeviceDesc.iSerialNumber,
948 0,
949 (PVOID*)&UsbChildExtension->InstanceId);
950
951 DPRINT1("Usb InstanceId %S\n", UsbChildExtension->InstanceId);
952 if (!NT_SUCCESS(Status))
953 {
954 DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
955 goto Cleanup;
956 }
957
958 HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
959
960 IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
961 return STATUS_SUCCESS;
962
963 Cleanup:
964
965 IoDeleteDevice(NewChildDeviceObject);
966 return Status;
967 }
968
969 NTSTATUS
970 USBHUB_FdoQueryBusRelations(
971 IN PDEVICE_OBJECT DeviceObject,
972 OUT PDEVICE_RELATIONS* pDeviceRelations)
973 {
974 PHUB_DEVICE_EXTENSION HubDeviceExtension;
975 PDEVICE_RELATIONS DeviceRelations;
976 ULONG i;
977 ULONG Children = 0;
978 ULONG NeededSize;
979
980 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
981
982 //
983 // Count the number of children
984 //
985 for (i = 0; i < USB_MAXCHILDREN; i++)
986 {
987
988 if (HubDeviceExtension->ChildDeviceObject[i] == NULL)
989 {
990 continue;
991 }
992 Children++;
993 }
994
995 NeededSize = sizeof(DEVICE_RELATIONS);
996 if (Children > 1)
997 NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
998
999 //
1000 // Allocate DeviceRelations
1001 //
1002 DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool,
1003 NeededSize);
1004
1005 if (!DeviceRelations)
1006 return STATUS_INSUFFICIENT_RESOURCES;
1007 DeviceRelations->Count = Children;
1008 Children = 0;
1009
1010 //
1011 // Fill in return structure
1012 //
1013 for (i = 0; i < USB_MAXCHILDREN; i++)
1014 {
1015 if (HubDeviceExtension->ChildDeviceObject[i])
1016 {
1017 ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
1018 HubDeviceExtension->ChildDeviceObject[i]->Flags &= ~DO_DEVICE_INITIALIZING;
1019 DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i];
1020 }
1021 }
1022
1023 ASSERT(Children == DeviceRelations->Count);
1024 *pDeviceRelations = DeviceRelations;
1025
1026 return STATUS_SUCCESS;
1027 }
1028
1029 VOID
1030 RootHubInitCallbackFunction(
1031 PVOID Context)
1032 {
1033 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
1034
1035 DPRINT1("Sending the initial SCE Request %x\n", DeviceObject);
1036
1037 //
1038 // Send the first SCE Request
1039 //
1040 QueryStatusChangeEndpoint(DeviceObject);
1041 }
1042
1043 NTSTATUS
1044 USBHUB_FdoHandlePnp(
1045 IN PDEVICE_OBJECT DeviceObject,
1046 IN PIRP Irp)
1047 {
1048 PIO_STACK_LOCATION Stack;
1049 NTSTATUS Status = STATUS_SUCCESS;
1050 ULONG_PTR Information = 0;
1051 PHUB_DEVICE_EXTENSION HubDeviceExtension;
1052 PDEVICE_OBJECT RootHubDeviceObject;
1053 PVOID HubInterfaceBusContext , UsbDInterfaceBusContext;
1054
1055 HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
1056
1057 Stack = IoGetCurrentIrpStackLocation(Irp);
1058
1059 switch (Stack->MinorFunction)
1060 {
1061 case IRP_MN_START_DEVICE:
1062 {
1063 PURB Urb;
1064 PUSB_INTERFACE_DESCRIPTOR Pid;
1065 ULONG Result = 0, PortId;
1066 USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
1067 PURB ConfigUrb = NULL;
1068 ULONG HubStatus;
1069
1070 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1071
1072 //
1073 // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
1074 //
1075 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
1076 RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
1077
1078 //
1079 // Get the Root Hub Pdo
1080 //
1081 SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
1082 IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
1083 &HubDeviceExtension->RootHubPhysicalDeviceObject,
1084 &HubDeviceExtension->RootHubFunctionalDeviceObject);
1085
1086 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
1087 ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
1088 ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
1089 DPRINT1("RootPdo %x, RootFdo %x\n",
1090 HubDeviceExtension->RootHubPhysicalDeviceObject,
1091 HubDeviceExtension->RootHubFunctionalDeviceObject);
1092
1093 //
1094 // Send the StartDevice to RootHub
1095 //
1096 Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
1097
1098 if (!NT_SUCCESS(Status))
1099 {
1100 DPRINT1("Failed to start the RootHub PDO\n");
1101 ASSERT(FALSE);
1102 }
1103
1104 //
1105 // Get the current number of hubs
1106 //
1107 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1108 IOCTL_INTERNAL_USB_GET_HUB_COUNT,
1109 &HubDeviceExtension->NumberOfHubs, NULL);
1110
1111 //
1112 // Get the Hub Interface
1113 //
1114 Status = QueryInterface(RootHubDeviceObject,
1115 USB_BUS_INTERFACE_HUB_GUID,
1116 sizeof(USB_BUS_INTERFACE_HUB_V5),
1117 5,
1118 (PVOID)&HubDeviceExtension->HubInterface);
1119
1120 if (!NT_SUCCESS(Status))
1121 {
1122 DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
1123 return STATUS_UNSUCCESSFUL;
1124 }
1125
1126 HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
1127
1128 //
1129 // Get the USBDI Interface
1130 //
1131 Status = QueryInterface(RootHubDeviceObject,
1132 USB_BUS_INTERFACE_USBDI_GUID,
1133 sizeof(USB_BUS_INTERFACE_USBDI_V2),
1134 2,
1135 (PVOID)&HubDeviceExtension->UsbDInterface);
1136
1137 if (!NT_SUCCESS(Status))
1138 {
1139 DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
1140 return Status;
1141 }
1142
1143 UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
1144
1145 //
1146 // Get Root Hub Device Handle
1147 //
1148 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1149 IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
1150 &HubDeviceExtension->RootHubHandle,
1151 NULL);
1152
1153 if (!NT_SUCCESS(Status))
1154 {
1155 DPRINT1("GetRootHubDeviceHandle failed with status 0x%08lx\n", Status);
1156 return Status;
1157 }
1158
1159 //
1160 // Get Hub Device Information
1161 //
1162 Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
1163 HubDeviceExtension->RootHubHandle,
1164 &HubDeviceExtension->DeviceInformation,
1165 sizeof(USB_DEVICE_INFORMATION_0),
1166 &Result);
1167
1168 DPRINT1("Status %x, Result 0x%08lx\n", Status, Result);
1169 DPRINT1("InformationLevel %x\n", HubDeviceExtension->DeviceInformation.InformationLevel);
1170 DPRINT1("ActualLength %x\n", HubDeviceExtension->DeviceInformation.ActualLength);
1171 DPRINT1("PortNumber %x\n", HubDeviceExtension->DeviceInformation.PortNumber);
1172 DPRINT1("DeviceDescriptor %x\n", HubDeviceExtension->DeviceInformation.DeviceDescriptor);
1173 DPRINT1("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress);
1174 DPRINT1("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
1175
1176 //
1177 // Get Root Hubs Device Descriptor
1178 //
1179 UsbBuildGetDescriptorRequest(Urb,
1180 sizeof(Urb->UrbControlDescriptorRequest),
1181 USB_DEVICE_DESCRIPTOR_TYPE,
1182 0,
1183 0,
1184 &HubDeviceExtension->HubDeviceDescriptor,
1185 NULL,
1186 sizeof(USB_DEVICE_DESCRIPTOR),
1187 NULL);
1188
1189 Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
1190
1191 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1192 IOCTL_INTERNAL_USB_SUBMIT_URB,
1193 Urb,
1194 NULL);
1195
1196 if (!NT_SUCCESS(Status))
1197 {
1198 DPRINT1("Failed to get HubDeviceDescriptor!\n");
1199 }
1200
1201 DumpDeviceDescriptor(&HubDeviceExtension->HubDeviceDescriptor);
1202
1203 //
1204 // Get Root Hubs Configuration Descriptor
1205 //
1206 UsbBuildGetDescriptorRequest(Urb,
1207 sizeof(Urb->UrbControlDescriptorRequest),
1208 USB_CONFIGURATION_DESCRIPTOR_TYPE,
1209 0,
1210 0,
1211 &HubDeviceExtension->HubConfigDescriptor,
1212 NULL,
1213 sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
1214 NULL);
1215
1216 DPRINT1("RootHub Handle %x\n", HubDeviceExtension->RootHubHandle);
1217 Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
1218
1219 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1220 IOCTL_INTERNAL_USB_SUBMIT_URB,
1221 Urb,
1222 NULL);
1223
1224 if (!NT_SUCCESS(Status))
1225 {
1226 DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
1227 ASSERT(FALSE);
1228 }
1229 ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength);
1230
1231 DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor);
1232
1233 Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
1234 RootHubDeviceObject,
1235 &HubDeviceExtension->UsbExtHubInfo,
1236 sizeof(USB_EXTHUB_INFORMATION_0),
1237 &Result);
1238 if (!NT_SUCCESS(Status))
1239 {
1240 DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
1241 ASSERT(FALSE);
1242 }
1243
1244 DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
1245
1246 //
1247 // Get the Hub Descriptor
1248 //
1249 UsbBuildVendorRequest(Urb,
1250 URB_FUNCTION_CLASS_DEVICE,
1251 sizeof(Urb->UrbControlVendorClassRequest),
1252 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
1253 0,
1254 USB_REQUEST_GET_DESCRIPTOR,
1255 USB_DEVICE_CLASS_RESERVED,
1256 0,
1257 &HubDeviceExtension->HubDescriptor,
1258 NULL,
1259 sizeof(USB_HUB_DESCRIPTOR),
1260 NULL);
1261
1262 Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
1263
1264 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1265 IOCTL_INTERNAL_USB_SUBMIT_URB,
1266 Urb,
1267 NULL);
1268
1269 DPRINT1("bDescriptorType %x\n", HubDeviceExtension->HubDescriptor.bDescriptorType);
1270
1271 if (!NT_SUCCESS(Status))
1272 {
1273 DPRINT1("Failed to get Hub Descriptor!\n");
1274 ExFreePool(Urb);
1275 return STATUS_UNSUCCESSFUL;
1276 }
1277
1278 HubStatus = 0;
1279 UsbBuildGetStatusRequest(Urb,
1280 URB_FUNCTION_GET_STATUS_FROM_DEVICE,
1281 0,
1282 &HubStatus,
1283 0,
1284 NULL);
1285 Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
1286
1287 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1288 IOCTL_INTERNAL_USB_SUBMIT_URB,
1289 Urb,
1290 NULL);
1291 if (!NT_SUCCESS(Status))
1292 {
1293 DPRINT1("Failed to get Hub Status!\n");
1294 ExFreePool(Urb);
1295 return STATUS_UNSUCCESSFUL;
1296 }
1297
1298 DPRINT1("HubStatus %x\n", HubStatus);
1299
1300 //
1301 // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
1302 //
1303 HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
1304 sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
1305 USB_HUB_TAG);
1306
1307 //
1308 // Get the first Configuration Descriptor
1309 //
1310 Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
1311 &HubDeviceExtension->HubConfigDescriptor,
1312 -1, -1, -1, -1, -1);
1313
1314 ASSERT(Pid != NULL);
1315
1316 InterfaceList[0].InterfaceDescriptor = Pid;
1317 ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
1318 (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
1319 ASSERT(ConfigUrb != NULL);
1320
1321 Status = SubmitRequestToRootHub(RootHubDeviceObject,
1322 IOCTL_INTERNAL_USB_SUBMIT_URB,
1323 ConfigUrb,
1324 NULL);
1325
1326 HubDeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
1327 HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
1328 DPRINT1("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
1329
1330 //
1331 // Initialize the Hub
1332 //
1333 Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
1334 HubDeviceExtension->RootHubHandle, 1);
1335 DPRINT1("Status %x\n", Status);
1336
1337 ExFreePool(ConfigUrb);
1338
1339 //
1340 // Enable power on all ports
1341 //
1342
1343 DPRINT1("Enabling PortPower on all ports!\n");
1344
1345 for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
1346 {
1347 Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
1348 if (!NT_SUCCESS(Status))
1349 DPRINT1("Failed to power on port %d\n", PortId);
1350
1351 Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
1352 if (!NT_SUCCESS(Status))
1353 DPRINT1("Failed to power on port %d\n", PortId);
1354 }
1355
1356 DPRINT1("RootHubInitNotification %x\n", HubDeviceExtension->HubInterface.RootHubInitNotification);
1357 //
1358 //
1359 //
1360 if (HubDeviceExtension->HubInterface.RootHubInitNotification)
1361 {
1362 Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
1363 DeviceObject,
1364 (PRH_INIT_CALLBACK)RootHubInitCallbackFunction);
1365 }
1366 else
1367 {
1368 //
1369 // Send the first SCE Request
1370 //
1371 QueryStatusChangeEndpoint(DeviceObject);
1372 }
1373
1374 if (!NT_SUCCESS(Status))
1375 {
1376 DPRINT1("Failed to set callback\n");
1377 }
1378
1379 ExFreePool(Urb);
1380 break;
1381 }
1382
1383 case IRP_MN_QUERY_DEVICE_RELATIONS:
1384 {
1385 switch (Stack->Parameters.QueryDeviceRelations.Type)
1386 {
1387 case BusRelations:
1388 {
1389 PDEVICE_RELATIONS DeviceRelations = NULL;
1390 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
1391
1392 Status = USBHUB_FdoQueryBusRelations(DeviceObject, &DeviceRelations);
1393
1394 Information = (ULONG_PTR)DeviceRelations;
1395 break;
1396 }
1397 case RemovalRelations:
1398 {
1399 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
1400 return ForwardIrpAndForget(DeviceObject, Irp);
1401 }
1402 default:
1403 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
1404 Stack->Parameters.QueryDeviceRelations.Type);
1405 return ForwardIrpAndForget(DeviceObject, Irp);
1406 }
1407 break;
1408 }
1409 case IRP_MN_QUERY_BUS_INFORMATION:
1410 {
1411 DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
1412 break;
1413 }
1414 case IRP_MN_QUERY_ID:
1415 {
1416 DPRINT1("IRP_MN_QUERY_ID\n");
1417 break;
1418 }
1419 case IRP_MN_QUERY_CAPABILITIES:
1420 {
1421 DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
1422 break;
1423 }
1424 default:
1425 {
1426 DPRINT1(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
1427 return ForwardIrpAndForget(DeviceObject, Irp);
1428 }
1429 }
1430
1431 Irp->IoStatus.Information = Information;
1432 Irp->IoStatus.Status = Status;
1433 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1434 return Status;
1435 }
1436
1437 NTSTATUS
1438 USBHUB_FdoHandleDeviceControl(
1439 IN PDEVICE_OBJECT DeviceObject,
1440 IN PIRP Irp)
1441 {
1442 DPRINT1("FdoHandleDeviceControl\n");
1443 UNIMPLEMENTED
1444 return STATUS_NOT_IMPLEMENTED;
1445 }
1446