2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort plug and play functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
13 #define NDEBUG_USBPORT_CORE
16 IO_COMPLETION_ROUTINE USBPORT_FdoStartCompletion
;
20 USBPORT_FdoStartCompletion(IN PDEVICE_OBJECT DeviceObject
,
24 KeSetEvent((PKEVENT
)Context
, EVENT_INCREMENT
, FALSE
);
25 return STATUS_MORE_PROCESSING_REQUIRED
;
30 USBPORT_RegisterDeviceInterface(IN PDEVICE_OBJECT PdoDevice
,
31 IN PDEVICE_OBJECT DeviceObject
,
32 IN CONST GUID
*InterfaceClassGuid
,
35 PUSBPORT_RHDEVICE_EXTENSION DeviceExtension
;
36 PUNICODE_STRING SymbolicLinkName
;
39 DPRINT("USBPORT_RegisterDeviceInterface: Enable - %x\n", Enable
);
41 DeviceExtension
= DeviceObject
->DeviceExtension
;
42 SymbolicLinkName
= &DeviceExtension
->CommonExtension
.SymbolicLinkName
;
46 Status
= IoRegisterDeviceInterface(PdoDevice
,
51 if (NT_SUCCESS(Status
))
53 DeviceExtension
->CommonExtension
.IsInterfaceEnabled
= 1;
55 Status
= USBPORT_SetRegistryKeyValue(PdoDevice
,
59 SymbolicLinkName
->Buffer
,
60 SymbolicLinkName
->Length
);
62 if (NT_SUCCESS(Status
))
64 DPRINT("USBPORT_RegisterDeviceInterface: LinkName - %wZ\n",
65 &DeviceExtension
->CommonExtension
.SymbolicLinkName
);
67 Status
= IoSetDeviceInterfaceState(SymbolicLinkName
, TRUE
);
73 /* Disable device interface */
74 Status
= IoSetDeviceInterfaceState(SymbolicLinkName
, FALSE
);
76 if (NT_SUCCESS(Status
))
78 RtlFreeUnicodeString(SymbolicLinkName
);
79 DeviceExtension
->CommonExtension
.IsInterfaceEnabled
= 0; // Disabled interface
88 USBPORT_IsSelectiveSuspendEnabled(IN PDEVICE_OBJECT FdoDevice
)
90 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
93 DPRINT("USBPORT_IsSelectiveSuspendEnabled: ... \n");
95 FdoExtension
= FdoDevice
->DeviceExtension
;
97 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
98 FdoExtension
->CommonExtension
.LowerPdoDevice
,
100 L
"HcDisableSelectiveSuspend",
101 sizeof(L
"HcDisableSelectiveSuspend"),
105 return (Disabled
== 0);
110 USBPORT_GetConfigValue(IN PWSTR ValueName
,
113 IN ULONG ValueLength
,
115 IN PVOID EntryContext
)
117 NTSTATUS Status
= STATUS_SUCCESS
;
119 DPRINT("USBPORT_GetConfigValue \n");
121 if (ValueType
== REG_DWORD
)
123 *(PULONG
)EntryContext
= *(PULONG
)ValueData
;
127 Status
= STATUS_INVALID_PARAMETER
;
135 USBPORT_GetDefaultBIOSx(IN PDEVICE_OBJECT FdoDevice
,
137 IN PULONG DisableSelectiveSuspend
,
138 IN PULONG DisableCcDetect
,
139 IN PULONG IdleEpSupport
,
140 IN PULONG IdleEpSupportEx
,
143 RTL_QUERY_REGISTRY_TABLE QueryTable
[7];
145 DPRINT("USBPORT_GetDefaultBIOS_X: ... \n");
147 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
151 QueryTable
[0].QueryRoutine
= USBPORT_GetConfigValue
;
152 QueryTable
[0].Flags
= 0;
153 QueryTable
[0].Name
= L
"UsbBIOSx";
154 QueryTable
[0].EntryContext
= UsbBIOSx
;
155 QueryTable
[0].DefaultType
= REG_DWORD
;
156 QueryTable
[0].DefaultData
= UsbBIOSx
;
157 QueryTable
[0].DefaultLength
= sizeof(ULONG
);
159 QueryTable
[1].QueryRoutine
= USBPORT_GetConfigValue
;
160 QueryTable
[1].Flags
= 0;
161 QueryTable
[1].Name
= L
"DisableSelectiveSuspend";
162 QueryTable
[1].EntryContext
= DisableSelectiveSuspend
;
163 QueryTable
[1].DefaultType
= REG_DWORD
;
164 QueryTable
[1].DefaultData
= DisableSelectiveSuspend
;
165 QueryTable
[1].DefaultLength
= sizeof(ULONG
);
167 QueryTable
[2].QueryRoutine
= USBPORT_GetConfigValue
;
168 QueryTable
[2].Flags
= 0;
169 QueryTable
[2].Name
= L
"DisableCcDetect";
170 QueryTable
[2].EntryContext
= DisableCcDetect
;
171 QueryTable
[2].DefaultType
= REG_DWORD
;
172 QueryTable
[2].DefaultData
= DisableCcDetect
;
173 QueryTable
[2].DefaultLength
= sizeof(ULONG
);
175 QueryTable
[3].QueryRoutine
= USBPORT_GetConfigValue
;
176 QueryTable
[3].Flags
= 0;
177 QueryTable
[3].Name
= L
"EnIdleEndpointSupport";
178 QueryTable
[3].EntryContext
= IdleEpSupport
;
179 QueryTable
[3].DefaultType
= REG_DWORD
;
180 QueryTable
[3].DefaultData
= IdleEpSupport
;
181 QueryTable
[3].DefaultLength
= sizeof(ULONG
);
183 QueryTable
[4].QueryRoutine
= USBPORT_GetConfigValue
;
184 QueryTable
[4].Flags
= 0;
185 QueryTable
[4].Name
= L
"EnIdleEndpointSupportEx";
186 QueryTable
[4].EntryContext
= IdleEpSupportEx
;
187 QueryTable
[4].DefaultType
= REG_DWORD
;
188 QueryTable
[4].DefaultData
= IdleEpSupportEx
;
189 QueryTable
[4].DefaultLength
= sizeof(ULONG
);
191 QueryTable
[5].QueryRoutine
= USBPORT_GetConfigValue
;
192 QueryTable
[5].Flags
= 0;
193 QueryTable
[5].Name
= L
"EnSoftRetry";
194 QueryTable
[5].EntryContext
= SoftRetry
;
195 QueryTable
[5].DefaultType
= REG_DWORD
;
196 QueryTable
[5].DefaultData
= SoftRetry
;
197 QueryTable
[5].DefaultLength
= sizeof(ULONG
);
199 return RtlQueryRegistryValues(RTL_REGISTRY_SERVICES
,
208 USBPORT_IsCompanionController(IN PDEVICE_OBJECT DeviceObject
,
209 IN BOOLEAN
*IsCompanion
)
211 PDEVICE_OBJECT HighestDevice
;
214 PIO_STACK_LOCATION IoStack
;
215 PCI_DEVICE_PRESENT_INTERFACE PciInterface
= {0};
216 PCI_DEVICE_PRESENCE_PARAMETERS Parameters
= {0};
217 IO_STATUS_BLOCK IoStatusBlock
;
221 DPRINT("USBPORT_IsCompanionController: ... \n");
223 *IsCompanion
= FALSE
;
225 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
227 HighestDevice
= IoGetAttachedDeviceReference(DeviceObject
);
229 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
239 Status
= STATUS_INSUFFICIENT_RESOURCES
;
240 ObDereferenceObject(HighestDevice
);
244 IoStack
= IoGetNextIrpStackLocation(Irp
);
246 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
247 Irp
->IoStatus
.Information
= 0;
249 IoStack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
251 IoStack
->Parameters
.QueryInterface
.InterfaceType
= &GUID_PCI_DEVICE_PRESENT_INTERFACE
;
252 IoStack
->Parameters
.QueryInterface
.Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
253 IoStack
->Parameters
.QueryInterface
.Version
= 1;
254 IoStack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)&PciInterface
;
255 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= 0;
257 Status
= IoCallDriver(HighestDevice
, Irp
);
259 if (Status
== STATUS_PENDING
)
261 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
262 Status
= IoStatusBlock
.Status
;
265 if (!NT_SUCCESS(Status
))
267 DPRINT1("USBPORT_IsCompanionController: query interface failed\\n");
268 ObDereferenceObject(HighestDevice
);
272 DPRINT("USBPORT_IsCompanionController: query interface succeeded\n");
274 if (PciInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
276 DPRINT1("USBPORT_IsCompanionController: old version\n");
277 ObDereferenceObject(HighestDevice
);
281 Parameters
.Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
283 Parameters
.BaseClass
= PCI_CLASS_SERIAL_BUS_CTLR
;
284 Parameters
.SubClass
= PCI_SUBCLASS_SB_USB
;
285 Parameters
.ProgIf
= PCI_INTERFACE_USB_ID_EHCI
;
287 Parameters
.Flags
= PCI_USE_LOCAL_BUS
|
288 PCI_USE_LOCAL_DEVICE
|
289 PCI_USE_CLASS_SUBCLASS
|
292 IsPresent
= (PciInterface
.IsDevicePresentEx
)(PciInterface
.Context
,
297 DPRINT("USBPORT_IsCompanionController: Present EHCI controller for FDO - %p\n",
302 DPRINT("USBPORT_IsCompanionController: No EHCI controller for FDO - %p\n",
306 *IsCompanion
= IsPresent
;
308 (PciInterface
.InterfaceDereference
)(PciInterface
.Context
);
310 ObDereferenceObject(HighestDevice
);
317 USBPORT_QueryPciBusInterface(IN PDEVICE_OBJECT FdoDevice
)
319 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
320 PBUS_INTERFACE_STANDARD BusInterface
;
321 PIO_STACK_LOCATION IoStack
;
322 IO_STATUS_BLOCK IoStatusBlock
;
323 PDEVICE_OBJECT HighestDevice
;
328 DPRINT("USBPORT_QueryPciBusInterface: ... \n");
330 FdoExtension
= FdoDevice
->DeviceExtension
;
331 BusInterface
= &FdoExtension
->BusInterface
;
333 RtlZeroMemory(BusInterface
, sizeof(BUS_INTERFACE_STANDARD
));
334 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
335 HighestDevice
= IoGetAttachedDeviceReference(FdoDevice
);
337 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
347 IoStack
= IoGetNextIrpStackLocation(Irp
);
349 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
350 Irp
->IoStatus
.Information
= 0;
352 IoStack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
354 IoStack
->Parameters
.QueryInterface
.InterfaceType
= &GUID_BUS_INTERFACE_STANDARD
;
355 IoStack
->Parameters
.QueryInterface
.Size
= sizeof(BUS_INTERFACE_STANDARD
);
356 IoStack
->Parameters
.QueryInterface
.Version
= 1;
357 IoStack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)BusInterface
;
358 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= 0;
360 Status
= IoCallDriver(HighestDevice
, Irp
);
362 if (Status
== STATUS_PENDING
)
364 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
365 Status
= IoStatusBlock
.Status
;
370 Status
= STATUS_INSUFFICIENT_RESOURCES
;
373 ObDereferenceObject(HighestDevice
);
375 DPRINT("USBPORT_QueryPciBusInterface: return Status - %x\n", Status
);
382 USBPORT_QueryCapabilities(IN PDEVICE_OBJECT FdoDevice
,
383 IN PDEVICE_CAPABILITIES Capabilities
)
385 PUSBPORT_DEVICE_EXTENSION FdoExtention
;
388 PIO_STACK_LOCATION IoStack
;
391 DPRINT("USBPORT_QueryCapabilities: ... \n");
393 FdoExtention
= FdoDevice
->DeviceExtension
;
395 RtlZeroMemory(Capabilities
, sizeof(DEVICE_CAPABILITIES
));
397 Capabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
398 Capabilities
->Version
= 1;
399 Capabilities
->Address
= MAXULONG
;
400 Capabilities
->UINumber
= MAXULONG
;
402 Irp
= IoAllocateIrp(FdoExtention
->CommonExtension
.LowerDevice
->StackSize
,
407 DPRINT1("USBPORT_QueryCapabilities: No resources - IoAllocateIrp!\n");
408 return STATUS_INSUFFICIENT_RESOURCES
;
411 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
412 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
414 IoStack
= IoGetNextIrpStackLocation(Irp
);
415 IoStack
->MajorFunction
= IRP_MJ_PNP
;
416 IoStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
418 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
420 IoSetCompletionRoutine(Irp
,
421 USBPORT_FdoStartCompletion
,
427 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
= Capabilities
;
429 Status
= IoCallDriver(FdoExtention
->CommonExtension
.LowerDevice
, Irp
);
431 if (Status
== STATUS_PENDING
)
433 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
434 Status
= Irp
->IoStatus
.Status
;
437 if (NT_SUCCESS(Status
) && Capabilities
)
439 USBPORT_DumpingCapabilities(Capabilities
);
449 USBPORT_CreateLegacySymbolicLink(IN PDEVICE_OBJECT FdoDevice
)
451 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
452 WCHAR CharName
[255] = {0};
453 WCHAR CharDosName
[255] = {0};
454 UNICODE_STRING DeviceName
;
457 FdoExtension
= FdoDevice
->DeviceExtension
;
459 RtlStringCbPrintfW(CharName
,
461 L
"\\Device\\USBFDO-%d",
462 FdoExtension
->FdoNameNumber
);
464 RtlInitUnicodeString(&DeviceName
, CharName
);
466 RtlStringCbPrintfW(CharDosName
,
468 L
"\\DosDevices\\HCD%d",
469 FdoExtension
->FdoNameNumber
);
471 RtlInitUnicodeString(&FdoExtension
->DosDeviceSymbolicName
, CharDosName
);
473 DPRINT("USBPORT_CreateLegacySymbolicLink: DeviceName - %wZ, DosSymbolicName - %wZ\n",
475 &FdoExtension
->DosDeviceSymbolicName
);
477 Status
= IoCreateSymbolicLink(&FdoExtension
->DosDeviceSymbolicName
,
480 if (NT_SUCCESS(Status
))
482 FdoExtension
->Flags
|= USBPORT_FLAG_DOS_SYMBOLIC_NAME
;
490 USBPORT_StopDevice(IN PDEVICE_OBJECT FdoDevice
)
492 DPRINT1("USBPORT_StopDevice: UNIMPLEMENTED. FIXME\n");
494 return STATUS_SUCCESS
;
499 USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice
,
500 IN PUSBPORT_RESOURCES UsbPortResources
)
502 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
503 PUSBPORT_REGISTRATION_PACKET Packet
;
505 PCI_COMMON_CONFIG PciConfig
;
507 DEVICE_DESCRIPTION DeviceDescription
;
508 PDMA_ADAPTER DmaAdapter
= NULL
;
509 ULONG MiniPortStatus
;
510 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
512 ULONG DisableSelectiveSuspend
= 0;
513 ULONG DisableCcDetect
= 0;
514 ULONG IdleEpSupport
= 0;
515 ULONG IdleEpSupportEx
= 0;
518 ULONG TotalBusBandwidth
= 0;
519 BOOLEAN IsCompanion
= FALSE
;
524 DPRINT("USBPORT_StartDevice: FdoDevice - %p, UsbPortResources - %p\n",
528 FdoExtension
= FdoDevice
->DeviceExtension
;
529 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
531 Status
= USBPORT_QueryPciBusInterface(FdoDevice
);
532 if (!NT_SUCCESS(Status
))
535 BytesRead
= (*FdoExtension
->BusInterface
.GetBusData
)(FdoExtension
->BusInterface
.Context
,
536 PCI_WHICHSPACE_CONFIG
,
539 PCI_COMMON_HDR_LENGTH
);
541 if (BytesRead
!= PCI_COMMON_HDR_LENGTH
)
543 DPRINT1("USBPORT_StartDevice: Failed to get pci config information!\n");
547 FdoExtension
->VendorID
= PciConfig
.VendorID
;
548 FdoExtension
->DeviceID
= PciConfig
.DeviceID
;
549 FdoExtension
->RevisionID
= PciConfig
.RevisionID
;
550 FdoExtension
->ProgIf
= PciConfig
.ProgIf
;
551 FdoExtension
->SubClass
= PciConfig
.SubClass
;
552 FdoExtension
->BaseClass
= PciConfig
.BaseClass
;
554 RtlZeroMemory(&DeviceDescription
, sizeof(DeviceDescription
));
556 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
557 DeviceDescription
.Master
= TRUE
;
558 DeviceDescription
.ScatterGather
= TRUE
;
559 DeviceDescription
.Dma32BitAddresses
= TRUE
;
560 DeviceDescription
.InterfaceType
= PCIBus
;
561 DeviceDescription
.DmaWidth
= Width32Bits
;
562 DeviceDescription
.DmaSpeed
= Compatible
;
563 DeviceDescription
.MaximumLength
= MAXULONG
;
565 DmaAdapter
= IoGetDmaAdapter(FdoExtension
->CommonExtension
.LowerPdoDevice
,
567 &FdoExtension
->NumberMapRegs
);
569 FdoExtension
->DmaAdapter
= DmaAdapter
;
573 DPRINT1("USBPORT_StartDevice: Failed to get DmaAdapter!\n");
574 Status
= STATUS_INSUFFICIENT_RESOURCES
;
578 Status
= USBPORT_CreateWorkerThread(FdoDevice
);
579 if (!NT_SUCCESS(Status
))
582 Status
= USBPORT_QueryCapabilities(FdoDevice
, &FdoExtension
->Capabilities
);
583 if (!NT_SUCCESS(Status
))
586 FdoExtension
->PciDeviceNumber
= FdoExtension
->Capabilities
.Address
>> 16;
587 FdoExtension
->PciFunctionNumber
= FdoExtension
->Capabilities
.Address
& 0xFFFF;
589 Status
= IoGetDeviceProperty(FdoExtension
->CommonExtension
.LowerPdoDevice
,
590 DevicePropertyBusNumber
,
592 &FdoExtension
->BusNumber
,
595 if (!NT_SUCCESS(Status
))
598 KeInitializeSpinLock(&FdoExtension
->EndpointListSpinLock
);
599 KeInitializeSpinLock(&FdoExtension
->EpStateChangeSpinLock
);
600 KeInitializeSpinLock(&FdoExtension
->EndpointClosedSpinLock
);
601 KeInitializeSpinLock(&FdoExtension
->DeviceHandleSpinLock
);
602 KeInitializeSpinLock(&FdoExtension
->IdleIoCsqSpinLock
);
603 KeInitializeSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
);
604 KeInitializeSpinLock(&FdoExtension
->MapTransferSpinLock
);
605 KeInitializeSpinLock(&FdoExtension
->FlushTransferSpinLock
);
606 KeInitializeSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
);
607 KeInitializeSpinLock(&FdoExtension
->DoneTransferSpinLock
);
608 KeInitializeSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
);
609 KeInitializeSpinLock(&FdoExtension
->MiniportSpinLock
);
610 KeInitializeSpinLock(&FdoExtension
->TimerFlagsSpinLock
);
611 KeInitializeSpinLock(&FdoExtension
->PowerWakeSpinLock
);
612 KeInitializeSpinLock(&FdoExtension
->SetPowerD0SpinLock
);
613 KeInitializeSpinLock(&FdoExtension
->RootHubCallbackSpinLock
);
614 KeInitializeSpinLock(&FdoExtension
->TtSpinLock
);
616 KeInitializeDpc(&FdoExtension
->IsrDpc
, USBPORT_IsrDpc
, FdoDevice
);
618 KeInitializeDpc(&FdoExtension
->TransferFlushDpc
,
619 USBPORT_TransferFlushDpc
,
622 KeInitializeDpc(&FdoExtension
->WorkerRequestDpc
,
623 USBPORT_WorkerRequestDpc
,
626 KeInitializeDpc(&FdoExtension
->HcWakeDpc
,
630 IoCsqInitialize(&FdoExtension
->IdleIoCsq
,
631 USBPORT_InsertIdleIrp
,
632 USBPORT_RemoveIdleIrp
,
633 USBPORT_PeekNextIdleIrp
,
634 USBPORT_AcquireIdleLock
,
635 USBPORT_ReleaseIdleLock
,
636 USBPORT_CompleteCanceledIdleIrp
);
638 IoCsqInitialize(&FdoExtension
->BadRequestIoCsq
,
639 USBPORT_InsertBadRequest
,
640 USBPORT_RemoveBadRequest
,
641 USBPORT_PeekNextBadRequest
,
642 USBPORT_AcquireBadRequestLock
,
643 USBPORT_ReleaseBadRequestLock
,
644 USBPORT_CompleteCanceledBadRequest
);
646 FdoExtension
->IsrDpcCounter
= -1;
647 FdoExtension
->IsrDpcHandlerCounter
= -1;
648 FdoExtension
->IdleLockCounter
= -1;
649 FdoExtension
->BadRequestLockCounter
= -1;
650 FdoExtension
->ChirpRootPortLock
= -1;
652 FdoExtension
->RHInitCallBackLock
= 0;
654 FdoExtension
->UsbAddressBitMap
[0] = 1;
655 FdoExtension
->UsbAddressBitMap
[1] = 0;
656 FdoExtension
->UsbAddressBitMap
[2] = 0;
657 FdoExtension
->UsbAddressBitMap
[3] = 0;
659 USBPORT_GetDefaultBIOSx(FdoDevice
,
660 &FdoExtension
->UsbBIOSx
,
661 &DisableSelectiveSuspend
,
667 if (DisableSelectiveSuspend
)
668 FdoExtension
->Flags
|= USBPORT_FLAG_BIOS_DISABLE_SS
;
670 if (!DisableSelectiveSuspend
&&
671 USBPORT_IsSelectiveSuspendEnabled(FdoDevice
))
673 FdoExtension
->Flags
|= USBPORT_FLAG_SELECTIVE_SUSPEND
;
676 MiniportFlags
= Packet
->MiniPortFlags
;
678 if (MiniportFlags
& USB_MINIPORT_FLAGS_POLLING
)
679 FdoExtension
->Flags
|= USBPORT_FLAG_HC_POLLING
;
681 if (MiniportFlags
& USB_MINIPORT_FLAGS_WAKE_SUPPORT
)
682 FdoExtension
->Flags
|= USBPORT_FLAG_HC_WAKE_SUPPORT
;
684 if (MiniportFlags
& USB_MINIPORT_FLAGS_DISABLE_SS
)
685 FdoExtension
->Flags
= (FdoExtension
->Flags
& ~USBPORT_FLAG_SELECTIVE_SUSPEND
) |
686 USBPORT_FLAG_BIOS_DISABLE_SS
;
688 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
691 L
"EnIdleEndpointSupport",
693 sizeof(IdleEpSupport
));
695 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
698 L
"EnIdleEndpointSupportEx",
700 sizeof(IdleEpSupportEx
));
702 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
709 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
710 FdoExtension
->CommonExtension
.LowerPdoDevice
,
712 L
"CommonBuffer2GBLimit",
713 sizeof(L
"CommonBuffer2GBLimit"),
717 FdoExtension
->CommonBufferLimit
= (Limit2GB
!= 0);
719 if (FdoExtension
->BaseClass
== PCI_CLASS_SERIAL_BUS_CTLR
&&
720 FdoExtension
->SubClass
== PCI_SUBCLASS_SB_USB
&&
721 FdoExtension
->ProgIf
< PCI_INTERFACE_USB_ID_EHCI
)
723 Status
= USBPORT_IsCompanionController(FdoDevice
, &IsCompanion
);
725 if (!NT_SUCCESS(Status
))
729 FdoExtension
->Flags
|= USBPORT_FLAG_COMPANION_HC
;
733 FdoExtension
->Flags
&= ~USBPORT_FLAG_COMPANION_HC
;
740 FdoExtension
->Flags
&= ~USBPORT_FLAG_COMPANION_HC
;
743 TotalBusBandwidth
= Packet
->MiniPortBusBandwidth
;
744 FdoExtension
->TotalBusBandwidth
= TotalBusBandwidth
;
746 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
747 FdoExtension
->CommonExtension
.LowerPdoDevice
,
749 L
"TotalBusBandwidth",
750 sizeof(L
"TotalBusBandwidth"),
752 sizeof(TotalBusBandwidth
));
754 if (TotalBusBandwidth
!= FdoExtension
->TotalBusBandwidth
)
756 FdoExtension
->TotalBusBandwidth
= TotalBusBandwidth
;
759 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
761 FdoExtension
->Bandwidth
[ix
] = FdoExtension
->TotalBusBandwidth
-
762 FdoExtension
->TotalBusBandwidth
/ 10;
765 FdoExtension
->ActiveIrpTable
= ExAllocatePoolWithTag(NonPagedPool
,
766 sizeof(USBPORT_IRP_TABLE
),
769 if (!FdoExtension
->ActiveIrpTable
)
771 DPRINT1("USBPORT_StartDevice: Allocate ActiveIrpTable failed!\n");
775 RtlZeroMemory(FdoExtension
->ActiveIrpTable
, sizeof(USBPORT_IRP_TABLE
));
777 FdoExtension
->PendingIrpTable
= ExAllocatePoolWithTag(NonPagedPool
,
778 sizeof(USBPORT_IRP_TABLE
),
781 if (!FdoExtension
->PendingIrpTable
)
783 DPRINT1("USBPORT_StartDevice: Allocate PendingIrpTable failed!\n");
787 RtlZeroMemory(FdoExtension
->PendingIrpTable
, sizeof(USBPORT_IRP_TABLE
));
789 Status
= IoConnectInterrupt(&FdoExtension
->InterruptObject
,
790 USBPORT_InterruptService
,
793 UsbPortResources
->InterruptVector
,
794 UsbPortResources
->InterruptLevel
,
795 UsbPortResources
->InterruptLevel
,
796 UsbPortResources
->InterruptMode
,
797 UsbPortResources
->ShareVector
,
798 UsbPortResources
->InterruptAffinity
,
802 if (!NT_SUCCESS(Status
))
804 DPRINT1("USBPORT_StartDevice: IoConnectInterrupt failed!\n");
808 FdoExtension
->Flags
&= ~USBPORT_FLAG_INT_CONNECTED
;
810 if (Packet
->MiniPortExtensionSize
)
812 RtlZeroMemory(FdoExtension
->MiniPortExt
, Packet
->MiniPortExtensionSize
);
815 if (Packet
->MiniPortResourcesSize
)
817 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
818 Packet
->MiniPortResourcesSize
);
822 DPRINT1("USBPORT_StartDevice: Failed to AllocateCommonBuffer!\n");
823 Status
= STATUS_INSUFFICIENT_RESOURCES
;
827 UsbPortResources
->StartVA
= (PVOID
)HeaderBuffer
->VirtualAddress
;
828 UsbPortResources
->StartPA
= (PVOID
)HeaderBuffer
->PhysicalAddress
;
830 FdoExtension
->MiniPortCommonBuffer
= HeaderBuffer
;
834 FdoExtension
->MiniPortCommonBuffer
= NULL
;
837 MiniPortStatus
= Packet
->StartController(FdoExtension
->MiniPortExt
,
840 if (UsbPortResources
->LegacySupport
)
842 FdoExtension
->Flags
|= USBPORT_FLAG_LEGACY_SUPPORT
;
850 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
853 L
"DetectedLegacyBIOS",
859 DPRINT1("USBPORT_StartDevice: Failed to Start MiniPort. MiniPortStatus - %x\n",
862 if (FdoExtension
->Flags
& USBPORT_FLAG_INT_CONNECTED
)
864 IoDisconnectInterrupt(FdoExtension
->InterruptObject
);
865 FdoExtension
->Flags
&= ~USBPORT_FLAG_INT_CONNECTED
;
868 if (FdoExtension
->MiniPortCommonBuffer
)
870 USBPORT_FreeCommonBuffer(FdoDevice
, FdoExtension
->MiniPortCommonBuffer
);
871 FdoExtension
->MiniPortCommonBuffer
= NULL
;
878 FdoExtension
->MiniPortFlags
|= USBPORT_MPFLAG_INTERRUPTS_ENABLED
;
879 USBPORT_MiniportInterrupts(FdoDevice
, TRUE
);
882 FdoExtension
->TimerValue
= 500;
883 USBPORT_StartTimer((PVOID
)FdoDevice
, 500);
885 Status
= USBPORT_RegisterDeviceInterface(FdoExtension
->CommonExtension
.LowerPdoDevice
,
887 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
,
890 if (!NT_SUCCESS(Status
))
892 DPRINT1("USBPORT_StartDevice: RegisterDeviceInterface failed!\n");
896 USBPORT_CreateLegacySymbolicLink(FdoDevice
);
898 FdoExtension
->Flags
|= USBPORT_FLAG_HC_STARTED
;
900 DPRINT("USBPORT_StartDevice: Exit Status - %p\n", Status
);
904 USBPORT_StopDevice(FdoDevice
);
906 DPRINT1("USBPORT_StartDevice: ExitWithError Status - %lx\n", Status
);
912 USBPORT_ParseResources(IN PDEVICE_OBJECT FdoDevice
,
914 IN PUSBPORT_RESOURCES UsbPortResources
)
916 PCM_RESOURCE_LIST AllocatedResourcesTranslated
;
917 PCM_PARTIAL_RESOURCE_LIST ResourceList
;
918 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
919 PCM_PARTIAL_RESOURCE_DESCRIPTOR PortDescriptor
= NULL
;
920 PCM_PARTIAL_RESOURCE_DESCRIPTOR MemoryDescriptor
= NULL
;
921 PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDescriptor
= NULL
;
922 PIO_STACK_LOCATION IoStack
;
924 NTSTATUS Status
= STATUS_SUCCESS
;
926 DPRINT("USBPORT_ParseResources: ... \n");
928 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
929 AllocatedResourcesTranslated
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
931 if (AllocatedResourcesTranslated
)
933 RtlZeroMemory(UsbPortResources
, sizeof(USBPORT_RESOURCES
));
935 ResourceList
= &AllocatedResourcesTranslated
->List
[0].PartialResourceList
;
937 PartialDescriptor
= &ResourceList
->PartialDescriptors
[0];
939 for (ix
= 0; ix
< ResourceList
->Count
; ++ix
)
941 if (PartialDescriptor
->Type
== CmResourceTypePort
)
944 PortDescriptor
= PartialDescriptor
;
946 else if (PartialDescriptor
->Type
== CmResourceTypeInterrupt
)
948 if (!InterruptDescriptor
)
949 InterruptDescriptor
= PartialDescriptor
;
951 else if (PartialDescriptor
->Type
== CmResourceTypeMemory
)
953 if (!MemoryDescriptor
)
954 MemoryDescriptor
= PartialDescriptor
;
957 PartialDescriptor
+= 1;
962 if (PortDescriptor
->Flags
& CM_RESOURCE_PORT_IO
)
964 UsbPortResources
->ResourceBase
= (PVOID
)PortDescriptor
->u
.Port
.Start
.LowPart
;
968 UsbPortResources
->ResourceBase
= MmMapIoSpace(PortDescriptor
->u
.Port
.Start
,
969 PortDescriptor
->u
.Port
.Length
,
973 UsbPortResources
->IoSpaceLength
= PortDescriptor
->u
.Port
.Length
;
975 if (UsbPortResources
->ResourceBase
)
977 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_PORT
;
981 Status
= STATUS_NONE_MAPPED
;
985 if (MemoryDescriptor
&& NT_SUCCESS(Status
))
987 UsbPortResources
->IoSpaceLength
= MemoryDescriptor
->u
.Memory
.Length
;
989 UsbPortResources
->ResourceBase
= MmMapIoSpace(MemoryDescriptor
->u
.Memory
.Start
,
990 MemoryDescriptor
->u
.Memory
.Length
,
993 if (UsbPortResources
->ResourceBase
)
995 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_MEMORY
;
999 Status
= STATUS_NONE_MAPPED
;
1003 if (InterruptDescriptor
&& NT_SUCCESS(Status
))
1005 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_INTERRUPT
;
1007 UsbPortResources
->InterruptVector
= InterruptDescriptor
->u
.Interrupt
.Vector
;
1008 UsbPortResources
->InterruptLevel
= InterruptDescriptor
->u
.Interrupt
.Level
;
1009 UsbPortResources
->InterruptAffinity
= InterruptDescriptor
->u
.Interrupt
.Affinity
;
1011 UsbPortResources
->ShareVector
= InterruptDescriptor
->ShareDisposition
==
1012 CmResourceShareShared
;
1014 UsbPortResources
->InterruptMode
= InterruptDescriptor
->Flags
==
1015 CM_RESOURCE_INTERRUPT_LATCHED
;
1020 Status
= STATUS_NONE_MAPPED
;
1028 USBPORT_CreatePdo(IN PDEVICE_OBJECT FdoDevice
,
1029 OUT PDEVICE_OBJECT
*RootHubPdo
)
1031 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1032 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1033 UNICODE_STRING DeviceName
;
1034 ULONG DeviceNumber
= 0;
1035 PDEVICE_OBJECT DeviceObject
= NULL
;
1036 WCHAR CharDeviceName
[64];
1037 NTSTATUS Status
= STATUS_SUCCESS
;
1039 DPRINT("USBPORT_CreatePdo: FdoDevice - %p, RootHubPdo - %p\n",
1043 FdoExtension
= FdoDevice
->DeviceExtension
;
1047 RtlStringCbPrintfW(CharDeviceName
,
1048 sizeof(CharDeviceName
),
1049 L
"\\Device\\USBPDO-%d",
1052 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
1054 DPRINT("USBPORT_CreatePdo: DeviceName - %wZ\n", &DeviceName
);
1056 Status
= IoCreateDevice(FdoExtension
->MiniPortInterface
->DriverObject
,
1057 sizeof(USBPORT_RHDEVICE_EXTENSION
),
1059 FILE_DEVICE_BUS_EXTENDER
,
1066 while (Status
== STATUS_OBJECT_NAME_COLLISION
);
1068 if (!NT_SUCCESS(Status
))
1071 DPRINT1("USBPORT_CreatePdo: Filed create HubPdo!\n");
1077 PdoExtension
= DeviceObject
->DeviceExtension
;
1079 RtlZeroMemory(PdoExtension
, sizeof(USBPORT_RHDEVICE_EXTENSION
));
1081 PdoExtension
->CommonExtension
.SelfDevice
= DeviceObject
;
1082 PdoExtension
->CommonExtension
.IsPDO
= TRUE
;
1084 PdoExtension
->FdoDevice
= FdoDevice
;
1085 PdoExtension
->PdoNameNumber
= DeviceNumber
;
1087 USBPORT_AdjustDeviceCapabilities(FdoDevice
, DeviceObject
);
1089 DeviceObject
->StackSize
= FdoDevice
->StackSize
;
1091 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
1092 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1096 Status
= STATUS_UNSUCCESSFUL
;
1099 if (!NT_SUCCESS(Status
))
1102 *RootHubPdo
= DeviceObject
;
1104 DPRINT("USBPORT_CreatePdo: HubPdo - %p\n", DeviceObject
);
1110 USBPORT_FdoPnP(IN PDEVICE_OBJECT FdoDevice
,
1113 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1114 PUSBPORT_COMMON_DEVICE_EXTENSION FdoCommonExtension
;
1115 PUSBPORT_REGISTRATION_PACKET Packet
;
1116 PUSBPORT_RESOURCES UsbPortResources
;
1117 PIO_STACK_LOCATION IoStack
;
1121 DEVICE_RELATION_TYPE RelationType
;
1122 PDEVICE_RELATIONS DeviceRelations
;
1123 PDEVICE_OBJECT RootHubPdo
;
1125 FdoExtension
= FdoDevice
->DeviceExtension
;
1126 FdoCommonExtension
= &FdoExtension
->CommonExtension
;
1127 UsbPortResources
= &FdoExtension
->UsbPortResources
;
1128 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1130 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1131 Minor
= IoStack
->MinorFunction
;
1133 DPRINT("USBPORT_FdoPnP: FdoDevice - %p, Minor - %x\n", FdoDevice
, Minor
);
1135 RelationType
= IoStack
->Parameters
.QueryDeviceRelations
.Type
;
1139 case IRP_MN_START_DEVICE
:
1140 DPRINT("IRP_MN_START_DEVICE\n");
1142 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1144 IoCopyCurrentIrpStackLocationToNext(Irp
);
1146 IoSetCompletionRoutine(Irp
,
1147 USBPORT_FdoStartCompletion
,
1153 Status
= IoCallDriver(FdoCommonExtension
->LowerDevice
,
1156 if (Status
== STATUS_PENDING
)
1158 KeWaitForSingleObject(&Event
,
1164 Status
= Irp
->IoStatus
.Status
;
1167 if (!NT_SUCCESS(Status
))
1172 Status
= USBPORT_ParseResources(FdoDevice
,
1176 if (!NT_SUCCESS(Status
))
1178 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STOPPED
;
1182 Status
= USBPORT_StartDevice(FdoDevice
, UsbPortResources
);
1184 if (!NT_SUCCESS(Status
))
1186 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STOPPED
;
1190 FdoCommonExtension
->PnpStateFlags
&= ~USBPORT_PNP_STATE_NOT_INIT
;
1191 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STARTED
;
1193 FdoCommonExtension
->DevicePowerState
= PowerDeviceD0
;
1195 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1197 USBPORT_AddUSB2Fdo(FdoDevice
);
1201 USBPORT_AddUSB1Fdo(FdoDevice
);
1205 Irp
->IoStatus
.Status
= Status
;
1206 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1209 case IRP_MN_QUERY_REMOVE_DEVICE
:
1210 DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
1211 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1213 DPRINT1("USBPORT_FdoPnP: Haction registry write FIXME\n");
1216 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1219 case IRP_MN_REMOVE_DEVICE
:
1220 DPRINT("USBPORT_FdoPnP: IRP_MN_REMOVE_DEVICE\n");
1221 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_FAILED
;
1223 if (FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_STARTED
&&
1224 !(FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_NOT_INIT
))
1226 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1227 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_NOT_INIT
;
1230 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1231 IoSkipCurrentIrpStackLocation(Irp
);
1232 Status
= IoCallDriver(FdoCommonExtension
->LowerDevice
, Irp
);
1234 IoDetachDevice(FdoCommonExtension
->LowerDevice
);
1236 RootHubPdo
= FdoExtension
->RootHubPdo
;
1238 IoDeleteDevice(FdoDevice
);
1242 IoDeleteDevice(RootHubPdo
);
1247 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1248 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1249 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1252 case IRP_MN_STOP_DEVICE
:
1253 DPRINT("IRP_MN_STOP_DEVICE\n");
1254 if (FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_STARTED
)
1256 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1258 FdoCommonExtension
->PnpStateFlags
&= ~USBPORT_PNP_STATE_STARTED
;
1259 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_NOT_INIT
;
1262 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1265 case IRP_MN_QUERY_STOP_DEVICE
:
1266 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1267 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1270 case IRP_MN_CANCEL_STOP_DEVICE
:
1271 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1272 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1275 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1276 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1277 if (RelationType
== BusRelations
)
1279 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1280 sizeof(DEVICE_RELATIONS
),
1283 if (!DeviceRelations
)
1285 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1286 Irp
->IoStatus
.Status
= Status
;
1287 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1291 DeviceRelations
->Count
= 0;
1292 DeviceRelations
->Objects
[0] = NULL
;
1294 if (!FdoExtension
->RootHubPdo
)
1296 Status
= USBPORT_CreatePdo(FdoDevice
,
1297 &FdoExtension
->RootHubPdo
);
1299 if (!NT_SUCCESS(Status
))
1301 ExFreePoolWithTag(DeviceRelations
, USB_PORT_TAG
);
1307 Status
= STATUS_SUCCESS
;
1310 DeviceRelations
->Count
= 1;
1311 DeviceRelations
->Objects
[0] = FdoExtension
->RootHubPdo
;
1313 ObReferenceObject(FdoExtension
->RootHubPdo
);
1314 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1318 if (RelationType
== RemovalRelations
)
1320 DPRINT1("USBPORT_FdoPnP: FIXME IRP_MN_QUERY_DEVICE_RELATIONS/RemovalRelations\n");
1326 Irp
->IoStatus
.Status
= Status
;
1329 case IRP_MN_QUERY_INTERFACE
:
1330 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1333 case IRP_MN_QUERY_CAPABILITIES
:
1334 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1337 case IRP_MN_QUERY_RESOURCES
:
1338 DPRINT("IRP_MN_QUERY_RESOURCES\n");
1341 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1342 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1345 case IRP_MN_QUERY_DEVICE_TEXT
:
1346 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1349 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1350 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1353 case IRP_MN_READ_CONFIG
:
1354 DPRINT("IRP_MN_READ_CONFIG\n");
1357 case IRP_MN_WRITE_CONFIG
:
1358 DPRINT("IRP_MN_WRITE_CONFIG\n");
1362 DPRINT("IRP_MN_EJECT\n");
1365 case IRP_MN_SET_LOCK
:
1366 DPRINT("IRP_MN_SET_LOCK\n");
1369 case IRP_MN_QUERY_ID
:
1370 DPRINT("IRP_MN_QUERY_ID\n");
1373 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1374 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1377 case IRP_MN_QUERY_BUS_INFORMATION
:
1378 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1381 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1382 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1385 case IRP_MN_SURPRISE_REMOVAL
:
1386 DPRINT1("IRP_MN_SURPRISE_REMOVAL\n");
1387 if (!(FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_FAILED
))
1389 USBPORT_InvalidateControllerHandler(FdoDevice
,
1390 USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
);
1395 DPRINT("unknown IRP_MN_???\n");
1397 /* forward irp to next device object */
1398 IoSkipCurrentIrpStackLocation(Irp
);
1402 return IoCallDriver(FdoCommonExtension
->LowerDevice
, Irp
);
1407 USBPORT_GetDeviceHwIds(IN PDEVICE_OBJECT FdoDevice
,
1410 IN USHORT RevisionID
)
1412 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1413 PUSBPORT_REGISTRATION_PACKET Packet
;
1415 WCHAR Buffer
[300] = {0};
1417 size_t Remaining
= sizeof(Buffer
);
1420 FdoExtension
= FdoDevice
->DeviceExtension
;
1421 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1423 DPRINT("USBPORT_GetDeviceHwIds: FdoDevice - %p, Packet->MiniPortFlags - %p\n",
1425 Packet
->MiniPortFlags
);
1427 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1429 RtlStringCbPrintfExW(Buffer
,
1434 L
"USB\\ROOT_HUB20&VID%04x&PID%04x&REV%04x",
1440 Remaining
-= sizeof(UNICODE_NULL
);
1442 RtlStringCbPrintfExW(EndBuffer
,
1447 L
"USB\\ROOT_HUB20&VID%04x&PID%04x",
1452 Remaining
-= sizeof(UNICODE_NULL
);
1454 RtlStringCbPrintfExW(EndBuffer
,
1459 L
"USB\\ROOT_HUB20");
1463 RtlStringCbPrintfExW(Buffer
,
1468 L
"USB\\ROOT_HUB&VID%04x&PID%04x&REV%04x",
1474 Remaining
-= sizeof(UNICODE_NULL
);
1476 RtlStringCbPrintfExW(EndBuffer
,
1481 L
"USB\\ROOT_HUB&VID%04x&PID%04x",
1486 Remaining
-= sizeof(UNICODE_NULL
);
1488 RtlStringCbPrintfExW(EndBuffer
,
1496 Length
= (sizeof(Buffer
) - Remaining
+ sizeof(UNICODE_NULL
));
1498 /* for debug only */
1501 DPRINT("Hardware IDs:\n");
1502 USBPORT_DumpingIDs(Buffer
);
1505 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_PORT_TAG
);
1510 RtlMoveMemory(Id
, Buffer
, Length
);
1517 USBPORT_PdoPnP(IN PDEVICE_OBJECT PdoDevice
,
1520 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1521 PUSBPORT_COMMON_DEVICE_EXTENSION PdoCommonExtension
;
1522 PDEVICE_OBJECT FdoDevice
;
1523 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1524 PIO_STACK_LOCATION IoStack
;
1527 PPNP_BUS_INFORMATION BusInformation
;
1528 PDEVICE_CAPABILITIES DeviceCapabilities
;
1530 PdoExtension
= PdoDevice
->DeviceExtension
;
1531 PdoCommonExtension
= &PdoExtension
->CommonExtension
;
1533 FdoDevice
= PdoExtension
->FdoDevice
;
1534 FdoExtension
= FdoDevice
->DeviceExtension
;
1536 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1537 Minor
= IoStack
->MinorFunction
;
1539 Status
= Irp
->IoStatus
.Status
;
1541 DPRINT("USBPORT_PdoPnP: PdoDevice - %p, Minor - %x\n", PdoDevice
, Minor
);
1545 case IRP_MN_START_DEVICE
:
1546 DPRINT("IRP_MN_START_DEVICE\n");
1548 Status
= USBPORT_RootHubCreateDevice(FdoDevice
, PdoDevice
);
1550 if (NT_SUCCESS(Status
))
1552 Status
= USBPORT_RegisterDeviceInterface(PdoDevice
,
1554 &GUID_DEVINTERFACE_USB_HUB
,
1557 if (NT_SUCCESS(Status
))
1559 PdoCommonExtension
->DevicePowerState
= PowerDeviceD0
;
1560 PdoCommonExtension
->PnpStateFlags
= USBPORT_PNP_STATE_STARTED
;
1566 case IRP_MN_QUERY_REMOVE_DEVICE
:
1567 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_REMOVE_DEVICE\n");
1568 Status
= STATUS_SUCCESS
;
1571 case IRP_MN_REMOVE_DEVICE
:
1572 DPRINT1("USBPORT_PdoPnP: IRP_MN_REMOVE_DEVICE UNIMPLEMENTED. FIXME. \n");
1573 //USBPORT_StopRootHub();
1574 Status
= STATUS_SUCCESS
;
1577 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1578 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1579 Status
= STATUS_SUCCESS
;
1582 case IRP_MN_STOP_DEVICE
:
1583 DPRINT1("USBPORT_PdoPnP: IRP_MN_STOP_DEVICE UNIMPLEMENTED. FIXME. \n");
1584 //USBPORT_StopRootHub();
1585 Status
= STATUS_SUCCESS
;
1588 case IRP_MN_QUERY_STOP_DEVICE
:
1589 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1590 Status
= STATUS_SUCCESS
;
1593 case IRP_MN_CANCEL_STOP_DEVICE
:
1594 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1595 Status
= STATUS_SUCCESS
;
1598 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1600 PDEVICE_RELATIONS DeviceRelations
;
1602 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1603 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1608 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1609 sizeof(DEVICE_RELATIONS
),
1612 if (!DeviceRelations
)
1614 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1615 Irp
->IoStatus
.Information
= 0;
1619 DeviceRelations
->Count
= 1;
1620 DeviceRelations
->Objects
[0] = PdoDevice
;
1622 ObReferenceObject(PdoDevice
);
1624 Status
= STATUS_SUCCESS
;
1625 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1629 case IRP_MN_QUERY_INTERFACE
:
1630 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1631 Status
= USBPORT_PdoQueryInterface(FdoDevice
, PdoDevice
, Irp
);
1634 case IRP_MN_QUERY_CAPABILITIES
:
1635 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1637 DeviceCapabilities
= IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
1639 RtlCopyMemory(DeviceCapabilities
,
1640 &PdoExtension
->Capabilities
,
1641 sizeof(DEVICE_CAPABILITIES
));
1643 Status
= STATUS_SUCCESS
;
1646 case IRP_MN_QUERY_RESOURCES
:
1647 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_RESOURCES\n");
1650 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1651 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1654 case IRP_MN_QUERY_DEVICE_TEXT
:
1655 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1658 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1659 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1662 case IRP_MN_READ_CONFIG
:
1663 DPRINT("IRP_MN_READ_CONFIG\n");
1667 case IRP_MN_WRITE_CONFIG
:
1668 DPRINT("IRP_MN_WRITE_CONFIG\n");
1673 DPRINT("IRP_MN_EJECT\n");
1677 case IRP_MN_SET_LOCK
:
1678 DPRINT("IRP_MN_SET_LOCK\n");
1682 case IRP_MN_QUERY_ID
:
1686 WCHAR Buffer
[64] = {0};
1689 Status
= STATUS_SUCCESS
;
1690 IdType
= IoStack
->Parameters
.QueryId
.IdType
;
1692 DPRINT("IRP_MN_QUERY_ID/Type %x\n", IdType
);
1694 if (IdType
== BusQueryDeviceID
)
1696 PUSBPORT_REGISTRATION_PACKET Packet
;
1697 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1699 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1701 RtlStringCbPrintfW(Buffer
,
1703 L
"USB\\ROOT_HUB20");
1707 RtlStringCbPrintfW(Buffer
,
1712 Length
= (wcslen(Buffer
) + 1);
1714 Id
= ExAllocatePoolWithTag(PagedPool
,
1715 Length
* sizeof(WCHAR
),
1720 RtlZeroMemory(Id
, Length
* sizeof(WCHAR
));
1721 RtlStringCbCopyW(Id
, Length
* sizeof(WCHAR
), Buffer
);
1723 DPRINT("BusQueryDeviceID - %S, TotalLength - %hu\n",
1728 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1732 if (IdType
== BusQueryHardwareIDs
)
1734 Id
= USBPORT_GetDeviceHwIds(FdoDevice
,
1735 FdoExtension
->VendorID
,
1736 FdoExtension
->DeviceID
,
1737 FdoExtension
->RevisionID
);
1739 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1743 if (IdType
== BusQueryCompatibleIDs
||
1744 IdType
== BusQueryInstanceID
)
1746 Irp
->IoStatus
.Information
= 0;
1750 /* IdType == BusQueryDeviceSerialNumber */
1751 Status
= Irp
->IoStatus
.Status
;
1755 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1756 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1757 Status
= STATUS_SUCCESS
;
1760 case IRP_MN_QUERY_BUS_INFORMATION
:
1761 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1763 /* Allocate buffer for bus information */
1764 BusInformation
= ExAllocatePoolWithTag(PagedPool
,
1765 sizeof(PNP_BUS_INFORMATION
),
1768 if (!BusInformation
)
1771 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1775 RtlZeroMemory(BusInformation
, sizeof(PNP_BUS_INFORMATION
));
1778 RtlMoveMemory(&BusInformation
->BusTypeGuid
,
1783 BusInformation
->LegacyBusType
= PNPBus
;
1784 BusInformation
->BusNumber
= 0;
1786 Status
= STATUS_SUCCESS
;
1787 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
1790 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1791 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1794 case IRP_MN_SURPRISE_REMOVAL
:
1795 DPRINT("USBPORT_PdoPnP: IRP_MN_SURPRISE_REMOVAL\n");
1796 Status
= STATUS_SUCCESS
;
1800 DPRINT("unknown IRP_MN_???\n");
1804 Irp
->IoStatus
.Status
= Status
;
1805 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);