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
;
523 DPRINT("USBPORT_StartDevice: FdoDevice - %p, UsbPortResources - %p\n",
527 FdoExtension
= FdoDevice
->DeviceExtension
;
528 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
530 Status
= USBPORT_QueryPciBusInterface(FdoDevice
);
531 if (!NT_SUCCESS(Status
))
534 BytesRead
= (*FdoExtension
->BusInterface
.GetBusData
)(FdoExtension
->BusInterface
.Context
,
535 PCI_WHICHSPACE_CONFIG
,
538 PCI_COMMON_HDR_LENGTH
);
540 if (BytesRead
!= PCI_COMMON_HDR_LENGTH
)
542 DPRINT1("USBPORT_StartDevice: Failed to get pci config information!\n");
546 FdoExtension
->VendorID
= PciConfig
.VendorID
;
547 FdoExtension
->DeviceID
= PciConfig
.DeviceID
;
548 FdoExtension
->RevisionID
= PciConfig
.RevisionID
;
549 FdoExtension
->ProgIf
= PciConfig
.ProgIf
;
550 FdoExtension
->SubClass
= PciConfig
.SubClass
;
551 FdoExtension
->BaseClass
= PciConfig
.BaseClass
;
553 RtlZeroMemory(&DeviceDescription
, sizeof(DeviceDescription
));
555 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
556 DeviceDescription
.Master
= TRUE
;
557 DeviceDescription
.ScatterGather
= TRUE
;
558 DeviceDescription
.Dma32BitAddresses
= TRUE
;
559 DeviceDescription
.InterfaceType
= PCIBus
;
560 DeviceDescription
.DmaWidth
= Width32Bits
;
561 DeviceDescription
.DmaSpeed
= Compatible
;
562 DeviceDescription
.MaximumLength
= MAXULONG
;
564 DmaAdapter
= IoGetDmaAdapter(FdoExtension
->CommonExtension
.LowerPdoDevice
,
566 &FdoExtension
->NumberMapRegs
);
568 FdoExtension
->DmaAdapter
= DmaAdapter
;
572 DPRINT1("USBPORT_StartDevice: Failed to get DmaAdapter!\n");
573 Status
= STATUS_INSUFFICIENT_RESOURCES
;
577 Status
= USBPORT_CreateWorkerThread(FdoDevice
);
578 if (!NT_SUCCESS(Status
))
581 Status
= USBPORT_QueryCapabilities(FdoDevice
, &FdoExtension
->Capabilities
);
582 if (!NT_SUCCESS(Status
))
585 FdoExtension
->PciDeviceNumber
= FdoExtension
->Capabilities
.Address
>> 16;
586 FdoExtension
->PciFunctionNumber
= FdoExtension
->Capabilities
.Address
& 0xFFFF;
588 Status
= IoGetDeviceProperty(FdoExtension
->CommonExtension
.LowerPdoDevice
,
589 DevicePropertyBusNumber
,
591 &FdoExtension
->BusNumber
,
594 if (!NT_SUCCESS(Status
))
597 KeInitializeSpinLock(&FdoExtension
->EndpointListSpinLock
);
598 KeInitializeSpinLock(&FdoExtension
->EpStateChangeSpinLock
);
599 KeInitializeSpinLock(&FdoExtension
->EndpointClosedSpinLock
);
600 KeInitializeSpinLock(&FdoExtension
->DeviceHandleSpinLock
);
601 KeInitializeSpinLock(&FdoExtension
->IdleIoCsqSpinLock
);
602 KeInitializeSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
);
603 KeInitializeSpinLock(&FdoExtension
->MapTransferSpinLock
);
604 KeInitializeSpinLock(&FdoExtension
->FlushTransferSpinLock
);
605 KeInitializeSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
);
606 KeInitializeSpinLock(&FdoExtension
->DoneTransferSpinLock
);
607 KeInitializeSpinLock(&FdoExtension
->WorkerThreadEventSpinLock
);
608 KeInitializeSpinLock(&FdoExtension
->MiniportSpinLock
);
609 KeInitializeSpinLock(&FdoExtension
->TimerFlagsSpinLock
);
610 KeInitializeSpinLock(&FdoExtension
->PowerWakeSpinLock
);
611 KeInitializeSpinLock(&FdoExtension
->SetPowerD0SpinLock
);
612 KeInitializeSpinLock(&FdoExtension
->RootHubCallbackSpinLock
);
614 KeInitializeDpc(&FdoExtension
->IsrDpc
, USBPORT_IsrDpc
, FdoDevice
);
616 KeInitializeDpc(&FdoExtension
->TransferFlushDpc
,
617 USBPORT_TransferFlushDpc
,
620 KeInitializeDpc(&FdoExtension
->WorkerRequestDpc
,
621 USBPORT_WorkerRequestDpc
,
624 KeInitializeDpc(&FdoExtension
->HcWakeDpc
,
628 IoCsqInitialize(&FdoExtension
->IdleIoCsq
,
629 USBPORT_InsertIdleIrp
,
630 USBPORT_RemoveIdleIrp
,
631 USBPORT_PeekNextIdleIrp
,
632 USBPORT_AcquireIdleLock
,
633 USBPORT_ReleaseIdleLock
,
634 USBPORT_CompleteCanceledIdleIrp
);
636 IoCsqInitialize(&FdoExtension
->BadRequestIoCsq
,
637 USBPORT_InsertBadRequest
,
638 USBPORT_RemoveBadRequest
,
639 USBPORT_PeekNextBadRequest
,
640 USBPORT_AcquireBadRequestLock
,
641 USBPORT_ReleaseBadRequestLock
,
642 USBPORT_CompleteCanceledBadRequest
);
644 FdoExtension
->IsrDpcCounter
= -1;
645 FdoExtension
->IsrDpcHandlerCounter
= -1;
646 FdoExtension
->IdleLockCounter
= -1;
647 FdoExtension
->BadRequestLockCounter
= -1;
648 FdoExtension
->ChirpRootPortLock
= -1;
650 FdoExtension
->RHInitCallBackLock
= 0;
652 FdoExtension
->UsbAddressBitMap
[0] = 1;
653 FdoExtension
->UsbAddressBitMap
[1] = 0;
654 FdoExtension
->UsbAddressBitMap
[2] = 0;
655 FdoExtension
->UsbAddressBitMap
[3] = 0;
657 USBPORT_GetDefaultBIOSx(FdoDevice
,
658 &FdoExtension
->UsbBIOSx
,
659 &DisableSelectiveSuspend
,
665 if (DisableSelectiveSuspend
)
666 FdoExtension
->Flags
|= USBPORT_FLAG_BIOS_DISABLE_SS
;
668 if (!DisableSelectiveSuspend
&&
669 USBPORT_IsSelectiveSuspendEnabled(FdoDevice
))
671 FdoExtension
->Flags
|= USBPORT_FLAG_SELECTIVE_SUSPEND
;
674 MiniportFlags
= Packet
->MiniPortFlags
;
676 if (MiniportFlags
& USB_MINIPORT_FLAGS_POLLING
)
677 FdoExtension
->Flags
|= USBPORT_FLAG_HC_POLLING
;
679 if (MiniportFlags
& USB_MINIPORT_FLAGS_WAKE_SUPPORT
)
680 FdoExtension
->Flags
|= USBPORT_FLAG_HC_WAKE_SUPPORT
;
682 if (MiniportFlags
& USB_MINIPORT_FLAGS_DISABLE_SS
)
683 FdoExtension
->Flags
= (FdoExtension
->Flags
& ~USBPORT_FLAG_SELECTIVE_SUSPEND
) |
684 USBPORT_FLAG_BIOS_DISABLE_SS
;
686 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
689 L
"EnIdleEndpointSupport",
691 sizeof(IdleEpSupport
));
693 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
696 L
"EnIdleEndpointSupportEx",
698 sizeof(IdleEpSupportEx
));
700 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
707 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
708 FdoExtension
->CommonExtension
.LowerPdoDevice
,
710 L
"CommonBuffer2GBLimit",
711 sizeof(L
"CommonBuffer2GBLimit"),
715 FdoExtension
->CommonBufferLimit
= (Limit2GB
!= 0);
717 if (FdoExtension
->BaseClass
== PCI_CLASS_SERIAL_BUS_CTLR
&&
718 FdoExtension
->SubClass
== PCI_SUBCLASS_SB_USB
&&
719 FdoExtension
->ProgIf
< PCI_INTERFACE_USB_ID_EHCI
)
721 Status
= USBPORT_IsCompanionController(FdoDevice
, &IsCompanion
);
723 if (!NT_SUCCESS(Status
))
727 FdoExtension
->Flags
|= USBPORT_FLAG_COMPANION_HC
;
731 FdoExtension
->Flags
&= ~USBPORT_FLAG_COMPANION_HC
;
738 FdoExtension
->Flags
&= ~USBPORT_FLAG_COMPANION_HC
;
741 TotalBusBandwidth
= Packet
->MiniPortBusBandwidth
;
742 FdoExtension
->TotalBusBandwidth
= TotalBusBandwidth
;
744 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice
,
745 FdoExtension
->CommonExtension
.LowerPdoDevice
,
747 L
"TotalBusBandwidth",
748 sizeof(L
"TotalBusBandwidth"),
750 sizeof(TotalBusBandwidth
));
752 if (TotalBusBandwidth
!= FdoExtension
->TotalBusBandwidth
)
754 FdoExtension
->TotalBusBandwidth
= TotalBusBandwidth
;
757 FdoExtension
->ActiveIrpTable
= ExAllocatePoolWithTag(NonPagedPool
,
758 sizeof(USBPORT_IRP_TABLE
),
761 if (!FdoExtension
->ActiveIrpTable
)
763 DPRINT1("USBPORT_StartDevice: Allocate ActiveIrpTable failed!\n");
767 RtlZeroMemory(FdoExtension
->ActiveIrpTable
, sizeof(USBPORT_IRP_TABLE
));
769 FdoExtension
->PendingIrpTable
= ExAllocatePoolWithTag(NonPagedPool
,
770 sizeof(USBPORT_IRP_TABLE
),
773 if (!FdoExtension
->PendingIrpTable
)
775 DPRINT1("USBPORT_StartDevice: Allocate PendingIrpTable failed!\n");
779 RtlZeroMemory(FdoExtension
->PendingIrpTable
, sizeof(USBPORT_IRP_TABLE
));
781 Status
= IoConnectInterrupt(&FdoExtension
->InterruptObject
,
782 USBPORT_InterruptService
,
785 UsbPortResources
->InterruptVector
,
786 UsbPortResources
->InterruptLevel
,
787 UsbPortResources
->InterruptLevel
,
788 UsbPortResources
->InterruptMode
,
789 UsbPortResources
->ShareVector
,
790 UsbPortResources
->InterruptAffinity
,
794 if (!NT_SUCCESS(Status
))
796 DPRINT1("USBPORT_StartDevice: IoConnectInterrupt failed!\n");
800 FdoExtension
->Flags
&= ~USBPORT_FLAG_INT_CONNECTED
;
802 if (Packet
->MiniPortExtensionSize
)
804 RtlZeroMemory(FdoExtension
->MiniPortExt
, Packet
->MiniPortExtensionSize
);
807 if (Packet
->MiniPortResourcesSize
)
809 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
810 Packet
->MiniPortResourcesSize
);
814 DPRINT1("USBPORT_StartDevice: Failed to AllocateCommonBuffer!\n");
815 Status
= STATUS_INSUFFICIENT_RESOURCES
;
819 UsbPortResources
->StartVA
= (PVOID
)HeaderBuffer
->VirtualAddress
;
820 UsbPortResources
->StartPA
= (PVOID
)HeaderBuffer
->PhysicalAddress
;
822 FdoExtension
->MiniPortCommonBuffer
= HeaderBuffer
;
826 FdoExtension
->MiniPortCommonBuffer
= NULL
;
829 MiniPortStatus
= Packet
->StartController(FdoExtension
->MiniPortExt
,
832 if (UsbPortResources
->LegacySupport
)
834 FdoExtension
->Flags
|= USBPORT_FLAG_LEGACY_SUPPORT
;
842 USBPORT_SetRegistryKeyValue(FdoExtension
->CommonExtension
.LowerPdoDevice
,
845 L
"DetectedLegacyBIOS",
851 DPRINT1("USBPORT_StartDevice: Failed to Start MiniPort. MiniPortStatus - %x\n",
854 if (FdoExtension
->Flags
& USBPORT_FLAG_INT_CONNECTED
)
856 IoDisconnectInterrupt(FdoExtension
->InterruptObject
);
857 FdoExtension
->Flags
&= ~USBPORT_FLAG_INT_CONNECTED
;
860 if (FdoExtension
->MiniPortCommonBuffer
)
862 USBPORT_FreeCommonBuffer(FdoDevice
, FdoExtension
->MiniPortCommonBuffer
);
863 FdoExtension
->MiniPortCommonBuffer
= NULL
;
870 FdoExtension
->MiniPortFlags
|= USBPORT_MPFLAG_INTERRUPTS_ENABLED
;
871 USBPORT_MiniportInterrupts(FdoDevice
, TRUE
);
874 FdoExtension
->TimerValue
= 500;
875 USBPORT_StartTimer((PVOID
)FdoDevice
, 500);
877 Status
= USBPORT_RegisterDeviceInterface(FdoExtension
->CommonExtension
.LowerPdoDevice
,
879 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
,
882 if (!NT_SUCCESS(Status
))
884 DPRINT1("USBPORT_StartDevice: RegisterDeviceInterface failed!\n");
888 USBPORT_CreateLegacySymbolicLink(FdoDevice
);
890 FdoExtension
->Flags
|= USBPORT_FLAG_HC_STARTED
;
892 DPRINT("USBPORT_StartDevice: Exit Status - %p\n", Status
);
896 USBPORT_StopDevice(FdoDevice
);
898 DPRINT1("USBPORT_StartDevice: ExitWithError Status - %lx\n", Status
);
904 USBPORT_ParseResources(IN PDEVICE_OBJECT FdoDevice
,
906 IN PUSBPORT_RESOURCES UsbPortResources
)
908 PCM_RESOURCE_LIST AllocatedResourcesTranslated
;
909 PCM_PARTIAL_RESOURCE_LIST ResourceList
;
910 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
911 PCM_PARTIAL_RESOURCE_DESCRIPTOR PortDescriptor
= NULL
;
912 PCM_PARTIAL_RESOURCE_DESCRIPTOR MemoryDescriptor
= NULL
;
913 PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDescriptor
= NULL
;
914 PIO_STACK_LOCATION IoStack
;
916 NTSTATUS Status
= STATUS_SUCCESS
;
918 DPRINT("USBPORT_ParseResources: ... \n");
920 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
921 AllocatedResourcesTranslated
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
923 if (AllocatedResourcesTranslated
)
925 RtlZeroMemory(UsbPortResources
, sizeof(USBPORT_RESOURCES
));
927 ResourceList
= &AllocatedResourcesTranslated
->List
[0].PartialResourceList
;
929 PartialDescriptor
= &ResourceList
->PartialDescriptors
[0];
931 for (ix
= 0; ix
< ResourceList
->Count
; ++ix
)
933 if (PartialDescriptor
->Type
== CmResourceTypePort
)
936 PortDescriptor
= PartialDescriptor
;
938 else if (PartialDescriptor
->Type
== CmResourceTypeInterrupt
)
940 if (!InterruptDescriptor
)
941 InterruptDescriptor
= PartialDescriptor
;
943 else if (PartialDescriptor
->Type
== CmResourceTypeMemory
)
945 if (!MemoryDescriptor
)
946 MemoryDescriptor
= PartialDescriptor
;
949 PartialDescriptor
+= 1;
954 if (PortDescriptor
->Flags
& CM_RESOURCE_PORT_IO
)
956 UsbPortResources
->ResourceBase
= (PVOID
)PortDescriptor
->u
.Port
.Start
.LowPart
;
960 UsbPortResources
->ResourceBase
= MmMapIoSpace(PortDescriptor
->u
.Port
.Start
,
961 PortDescriptor
->u
.Port
.Length
,
965 UsbPortResources
->IoSpaceLength
= PortDescriptor
->u
.Port
.Length
;
967 if (UsbPortResources
->ResourceBase
)
969 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_PORT
;
973 Status
= STATUS_NONE_MAPPED
;
977 if (MemoryDescriptor
&& NT_SUCCESS(Status
))
979 UsbPortResources
->IoSpaceLength
= MemoryDescriptor
->u
.Memory
.Length
;
981 UsbPortResources
->ResourceBase
= MmMapIoSpace(MemoryDescriptor
->u
.Memory
.Start
,
982 MemoryDescriptor
->u
.Memory
.Length
,
985 if (UsbPortResources
->ResourceBase
)
987 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_MEMORY
;
991 Status
= STATUS_NONE_MAPPED
;
995 if (InterruptDescriptor
&& NT_SUCCESS(Status
))
997 UsbPortResources
->ResourcesTypes
|= USBPORT_RESOURCES_INTERRUPT
;
999 UsbPortResources
->InterruptVector
= InterruptDescriptor
->u
.Interrupt
.Vector
;
1000 UsbPortResources
->InterruptLevel
= InterruptDescriptor
->u
.Interrupt
.Level
;
1001 UsbPortResources
->InterruptAffinity
= InterruptDescriptor
->u
.Interrupt
.Affinity
;
1003 UsbPortResources
->ShareVector
= InterruptDescriptor
->ShareDisposition
==
1004 CmResourceShareShared
;
1006 UsbPortResources
->InterruptMode
= InterruptDescriptor
->Flags
==
1007 CM_RESOURCE_INTERRUPT_LATCHED
;
1012 Status
= STATUS_NONE_MAPPED
;
1020 USBPORT_CreatePdo(IN PDEVICE_OBJECT FdoDevice
,
1021 OUT PDEVICE_OBJECT
*RootHubPdo
)
1023 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1024 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1025 UNICODE_STRING DeviceName
;
1026 ULONG DeviceNumber
= 0;
1027 PDEVICE_OBJECT DeviceObject
= NULL
;
1028 WCHAR CharDeviceName
[64];
1029 NTSTATUS Status
= STATUS_SUCCESS
;
1031 DPRINT("USBPORT_CreatePdo: FdoDevice - %p, RootHubPdo - %p\n",
1035 FdoExtension
= FdoDevice
->DeviceExtension
;
1039 RtlStringCbPrintfW(CharDeviceName
,
1040 sizeof(CharDeviceName
),
1041 L
"\\Device\\USBPDO-%d",
1044 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
1046 DPRINT("USBPORT_CreatePdo: DeviceName - %wZ\n", &DeviceName
);
1048 Status
= IoCreateDevice(FdoExtension
->MiniPortInterface
->DriverObject
,
1049 sizeof(USBPORT_RHDEVICE_EXTENSION
),
1051 FILE_DEVICE_BUS_EXTENDER
,
1058 while (Status
== STATUS_OBJECT_NAME_COLLISION
);
1060 if (!NT_SUCCESS(Status
))
1063 DPRINT1("USBPORT_CreatePdo: Filed create HubPdo!\n");
1069 PdoExtension
= DeviceObject
->DeviceExtension
;
1071 RtlZeroMemory(PdoExtension
, sizeof(USBPORT_RHDEVICE_EXTENSION
));
1073 PdoExtension
->CommonExtension
.SelfDevice
= DeviceObject
;
1074 PdoExtension
->CommonExtension
.IsPDO
= TRUE
;
1076 PdoExtension
->FdoDevice
= FdoDevice
;
1077 PdoExtension
->PdoNameNumber
= DeviceNumber
;
1079 USBPORT_AdjustDeviceCapabilities(FdoDevice
, DeviceObject
);
1081 DeviceObject
->StackSize
= FdoDevice
->StackSize
;
1083 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
1084 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1088 Status
= STATUS_UNSUCCESSFUL
;
1091 if (!NT_SUCCESS(Status
))
1094 *RootHubPdo
= DeviceObject
;
1096 DPRINT("USBPORT_CreatePdo: HubPdo - %p\n", DeviceObject
);
1102 USBPORT_FdoPnP(IN PDEVICE_OBJECT FdoDevice
,
1105 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1106 PUSBPORT_COMMON_DEVICE_EXTENSION FdoCommonExtension
;
1107 PUSBPORT_REGISTRATION_PACKET Packet
;
1108 PUSBPORT_RESOURCES UsbPortResources
;
1109 PIO_STACK_LOCATION IoStack
;
1113 DEVICE_RELATION_TYPE RelationType
;
1114 PDEVICE_RELATIONS DeviceRelations
;
1115 PDEVICE_OBJECT RootHubPdo
;
1117 FdoExtension
= FdoDevice
->DeviceExtension
;
1118 FdoCommonExtension
= &FdoExtension
->CommonExtension
;
1119 UsbPortResources
= &FdoExtension
->UsbPortResources
;
1120 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1122 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1123 Minor
= IoStack
->MinorFunction
;
1125 DPRINT("USBPORT_FdoPnP: FdoDevice - %p, Minor - %x\n", FdoDevice
, Minor
);
1127 RelationType
= IoStack
->Parameters
.QueryDeviceRelations
.Type
;
1131 case IRP_MN_START_DEVICE
:
1132 DPRINT("IRP_MN_START_DEVICE\n");
1134 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1136 IoCopyCurrentIrpStackLocationToNext(Irp
);
1138 IoSetCompletionRoutine(Irp
,
1139 USBPORT_FdoStartCompletion
,
1145 Status
= IoCallDriver(FdoCommonExtension
->LowerDevice
,
1148 if (Status
== STATUS_PENDING
)
1150 KeWaitForSingleObject(&Event
,
1156 Status
= Irp
->IoStatus
.Status
;
1159 if (!NT_SUCCESS(Status
))
1164 Status
= USBPORT_ParseResources(FdoDevice
,
1168 if (!NT_SUCCESS(Status
))
1170 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STOPPED
;
1174 Status
= USBPORT_StartDevice(FdoDevice
, UsbPortResources
);
1176 if (!NT_SUCCESS(Status
))
1178 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STOPPED
;
1182 FdoCommonExtension
->PnpStateFlags
&= ~USBPORT_PNP_STATE_NOT_INIT
;
1183 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_STARTED
;
1185 FdoCommonExtension
->DevicePowerState
= PowerDeviceD0
;
1187 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1189 USBPORT_AddUSB2Fdo(FdoDevice
);
1193 USBPORT_AddUSB1Fdo(FdoDevice
);
1197 Irp
->IoStatus
.Status
= Status
;
1198 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1201 case IRP_MN_QUERY_REMOVE_DEVICE
:
1202 DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
1203 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1205 DPRINT1("USBPORT_FdoPnP: Haction registry write FIXME\n");
1208 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1211 case IRP_MN_REMOVE_DEVICE
:
1212 DPRINT("USBPORT_FdoPnP: IRP_MN_REMOVE_DEVICE\n");
1213 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_FAILED
;
1215 if (FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_STARTED
&&
1216 !(FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_NOT_INIT
))
1218 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1219 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_NOT_INIT
;
1222 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1223 IoSkipCurrentIrpStackLocation(Irp
);
1224 Status
= IoCallDriver(FdoCommonExtension
->LowerDevice
, Irp
);
1226 IoDetachDevice(FdoCommonExtension
->LowerDevice
);
1228 RootHubPdo
= FdoExtension
->RootHubPdo
;
1230 IoDeleteDevice(FdoDevice
);
1234 IoDeleteDevice(RootHubPdo
);
1239 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1240 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1241 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1244 case IRP_MN_STOP_DEVICE
:
1245 DPRINT("IRP_MN_STOP_DEVICE\n");
1246 if (FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_STARTED
)
1248 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1250 FdoCommonExtension
->PnpStateFlags
&= ~USBPORT_PNP_STATE_STARTED
;
1251 FdoCommonExtension
->PnpStateFlags
|= USBPORT_PNP_STATE_NOT_INIT
;
1254 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1257 case IRP_MN_QUERY_STOP_DEVICE
:
1258 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1259 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1262 case IRP_MN_CANCEL_STOP_DEVICE
:
1263 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1264 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1267 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1268 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1269 if (RelationType
== BusRelations
)
1271 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1272 sizeof(DEVICE_RELATIONS
),
1275 if (!DeviceRelations
)
1277 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1278 Irp
->IoStatus
.Status
= Status
;
1279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1283 DeviceRelations
->Count
= 0;
1284 DeviceRelations
->Objects
[0] = NULL
;
1286 if (!FdoExtension
->RootHubPdo
)
1288 Status
= USBPORT_CreatePdo(FdoDevice
,
1289 &FdoExtension
->RootHubPdo
);
1291 if (!NT_SUCCESS(Status
))
1293 ExFreePoolWithTag(DeviceRelations
, USB_PORT_TAG
);
1299 Status
= STATUS_SUCCESS
;
1302 DeviceRelations
->Count
= 1;
1303 DeviceRelations
->Objects
[0] = FdoExtension
->RootHubPdo
;
1305 ObReferenceObject(FdoExtension
->RootHubPdo
);
1306 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1310 if (RelationType
== RemovalRelations
)
1312 DPRINT1("USBPORT_FdoPnP: FIXME IRP_MN_QUERY_DEVICE_RELATIONS/RemovalRelations\n");
1318 Irp
->IoStatus
.Status
= Status
;
1321 case IRP_MN_QUERY_INTERFACE
:
1322 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1325 case IRP_MN_QUERY_CAPABILITIES
:
1326 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1329 case IRP_MN_QUERY_RESOURCES
:
1330 DPRINT("IRP_MN_QUERY_RESOURCES\n");
1333 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1334 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1337 case IRP_MN_QUERY_DEVICE_TEXT
:
1338 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1341 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1342 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1345 case IRP_MN_READ_CONFIG
:
1346 DPRINT("IRP_MN_READ_CONFIG\n");
1349 case IRP_MN_WRITE_CONFIG
:
1350 DPRINT("IRP_MN_WRITE_CONFIG\n");
1354 DPRINT("IRP_MN_EJECT\n");
1357 case IRP_MN_SET_LOCK
:
1358 DPRINT("IRP_MN_SET_LOCK\n");
1361 case IRP_MN_QUERY_ID
:
1362 DPRINT("IRP_MN_QUERY_ID\n");
1365 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1366 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1369 case IRP_MN_QUERY_BUS_INFORMATION
:
1370 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1373 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1374 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1377 case IRP_MN_SURPRISE_REMOVAL
:
1378 DPRINT1("IRP_MN_SURPRISE_REMOVAL\n");
1379 if (!(FdoCommonExtension
->PnpStateFlags
& USBPORT_PNP_STATE_FAILED
))
1381 USBPORT_InvalidateControllerHandler(FdoDevice
,
1382 USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
);
1387 DPRINT("unknown IRP_MN_???\n");
1389 /* forward irp to next device object */
1390 IoSkipCurrentIrpStackLocation(Irp
);
1394 return IoCallDriver(FdoCommonExtension
->LowerDevice
, Irp
);
1399 USBPORT_GetDeviceHwIds(IN PDEVICE_OBJECT FdoDevice
,
1402 IN USHORT RevisionID
)
1404 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1405 PUSBPORT_REGISTRATION_PACKET Packet
;
1407 WCHAR Buffer
[300] = {0};
1409 size_t Remaining
= sizeof(Buffer
);
1412 FdoExtension
= FdoDevice
->DeviceExtension
;
1413 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1415 DPRINT("USBPORT_GetDeviceHwIds: FdoDevice - %p, Packet->MiniPortFlags - %p\n",
1417 Packet
->MiniPortFlags
);
1419 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1421 RtlStringCbPrintfExW(Buffer
,
1426 L
"USB\\ROOT_HUB20&VID%04x&PID%04x&REV%04x",
1432 Remaining
-= sizeof(UNICODE_NULL
);
1434 RtlStringCbPrintfExW(EndBuffer
,
1439 L
"USB\\ROOT_HUB20&VID%04x&PID%04x",
1444 Remaining
-= sizeof(UNICODE_NULL
);
1446 RtlStringCbPrintfExW(EndBuffer
,
1451 L
"USB\\ROOT_HUB20");
1455 RtlStringCbPrintfExW(Buffer
,
1460 L
"USB\\ROOT_HUB&VID%04x&PID%04x&REV%04x",
1466 Remaining
-= sizeof(UNICODE_NULL
);
1468 RtlStringCbPrintfExW(EndBuffer
,
1473 L
"USB\\ROOT_HUB&VID%04x&PID%04x",
1478 Remaining
-= sizeof(UNICODE_NULL
);
1480 RtlStringCbPrintfExW(EndBuffer
,
1488 Length
= (sizeof(Buffer
) - Remaining
+ sizeof(UNICODE_NULL
));
1490 /* for debug only */
1493 DPRINT("Hardware IDs:\n");
1494 USBPORT_DumpingIDs(Buffer
);
1497 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_PORT_TAG
);
1502 RtlMoveMemory(Id
, Buffer
, Length
);
1509 USBPORT_PdoPnP(IN PDEVICE_OBJECT PdoDevice
,
1512 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
1513 PUSBPORT_COMMON_DEVICE_EXTENSION PdoCommonExtension
;
1514 PDEVICE_OBJECT FdoDevice
;
1515 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1516 PIO_STACK_LOCATION IoStack
;
1519 PPNP_BUS_INFORMATION BusInformation
;
1520 PDEVICE_CAPABILITIES DeviceCapabilities
;
1522 PdoExtension
= PdoDevice
->DeviceExtension
;
1523 PdoCommonExtension
= &PdoExtension
->CommonExtension
;
1525 FdoDevice
= PdoExtension
->FdoDevice
;
1526 FdoExtension
= FdoDevice
->DeviceExtension
;
1528 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1529 Minor
= IoStack
->MinorFunction
;
1531 Status
= Irp
->IoStatus
.Status
;
1533 DPRINT("USBPORT_PdoPnP: PdoDevice - %p, Minor - %x\n", PdoDevice
, Minor
);
1537 case IRP_MN_START_DEVICE
:
1538 DPRINT("IRP_MN_START_DEVICE\n");
1540 Status
= USBPORT_RootHubCreateDevice(FdoDevice
, PdoDevice
);
1542 if (NT_SUCCESS(Status
))
1544 Status
= USBPORT_RegisterDeviceInterface(PdoDevice
,
1546 &GUID_DEVINTERFACE_USB_HUB
,
1549 if (NT_SUCCESS(Status
))
1551 PdoCommonExtension
->DevicePowerState
= PowerDeviceD0
;
1552 PdoCommonExtension
->PnpStateFlags
= USBPORT_PNP_STATE_STARTED
;
1558 case IRP_MN_QUERY_REMOVE_DEVICE
:
1559 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_REMOVE_DEVICE\n");
1560 Status
= STATUS_SUCCESS
;
1563 case IRP_MN_REMOVE_DEVICE
:
1564 DPRINT1("USBPORT_PdoPnP: IRP_MN_REMOVE_DEVICE UNIMPLEMENTED. FIXME. \n");
1565 //USBPORT_StopRootHub();
1566 Status
= STATUS_SUCCESS
;
1569 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1570 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1571 Status
= STATUS_SUCCESS
;
1574 case IRP_MN_STOP_DEVICE
:
1575 DPRINT1("USBPORT_PdoPnP: IRP_MN_STOP_DEVICE UNIMPLEMENTED. FIXME. \n");
1576 //USBPORT_StopRootHub();
1577 Status
= STATUS_SUCCESS
;
1580 case IRP_MN_QUERY_STOP_DEVICE
:
1581 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1582 Status
= STATUS_SUCCESS
;
1585 case IRP_MN_CANCEL_STOP_DEVICE
:
1586 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1587 Status
= STATUS_SUCCESS
;
1590 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1592 PDEVICE_RELATIONS DeviceRelations
;
1594 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1595 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1600 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1601 sizeof(DEVICE_RELATIONS
),
1604 if (!DeviceRelations
)
1606 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1607 Irp
->IoStatus
.Information
= 0;
1611 DeviceRelations
->Count
= 1;
1612 DeviceRelations
->Objects
[0] = PdoDevice
;
1614 ObReferenceObject(PdoDevice
);
1616 Status
= STATUS_SUCCESS
;
1617 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1621 case IRP_MN_QUERY_INTERFACE
:
1622 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1623 Status
= USBPORT_PdoQueryInterface(FdoDevice
, PdoDevice
, Irp
);
1626 case IRP_MN_QUERY_CAPABILITIES
:
1627 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1629 DeviceCapabilities
= IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
1631 RtlCopyMemory(DeviceCapabilities
,
1632 &PdoExtension
->Capabilities
,
1633 sizeof(DEVICE_CAPABILITIES
));
1635 Status
= STATUS_SUCCESS
;
1638 case IRP_MN_QUERY_RESOURCES
:
1639 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_RESOURCES\n");
1642 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1643 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1646 case IRP_MN_QUERY_DEVICE_TEXT
:
1647 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1650 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1651 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1654 case IRP_MN_READ_CONFIG
:
1655 DPRINT("IRP_MN_READ_CONFIG\n");
1659 case IRP_MN_WRITE_CONFIG
:
1660 DPRINT("IRP_MN_WRITE_CONFIG\n");
1665 DPRINT("IRP_MN_EJECT\n");
1669 case IRP_MN_SET_LOCK
:
1670 DPRINT("IRP_MN_SET_LOCK\n");
1674 case IRP_MN_QUERY_ID
:
1678 WCHAR Buffer
[64] = {0};
1681 Status
= STATUS_SUCCESS
;
1682 IdType
= IoStack
->Parameters
.QueryId
.IdType
;
1684 DPRINT("IRP_MN_QUERY_ID/Type %x\n", IdType
);
1686 if (IdType
== BusQueryDeviceID
)
1688 PUSBPORT_REGISTRATION_PACKET Packet
;
1689 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1691 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1693 RtlStringCbPrintfW(Buffer
,
1695 L
"USB\\ROOT_HUB20");
1699 RtlStringCbPrintfW(Buffer
,
1704 Length
= (wcslen(Buffer
) + 1);
1706 Id
= ExAllocatePoolWithTag(PagedPool
,
1707 Length
* sizeof(WCHAR
),
1712 RtlZeroMemory(Id
, Length
* sizeof(WCHAR
));
1713 RtlStringCbCopyW(Id
, Length
* sizeof(WCHAR
), Buffer
);
1715 DPRINT("BusQueryDeviceID - %S, TotalLength - %hu\n",
1720 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1724 if (IdType
== BusQueryHardwareIDs
)
1726 Id
= USBPORT_GetDeviceHwIds(FdoDevice
,
1727 FdoExtension
->VendorID
,
1728 FdoExtension
->DeviceID
,
1729 FdoExtension
->RevisionID
);
1731 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1735 if (IdType
== BusQueryCompatibleIDs
||
1736 IdType
== BusQueryInstanceID
)
1738 Irp
->IoStatus
.Information
= 0;
1742 /* IdType == BusQueryDeviceSerialNumber */
1743 Status
= Irp
->IoStatus
.Status
;
1747 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1748 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1749 Status
= STATUS_SUCCESS
;
1752 case IRP_MN_QUERY_BUS_INFORMATION
:
1753 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1755 /* Allocate buffer for bus information */
1756 BusInformation
= ExAllocatePoolWithTag(PagedPool
,
1757 sizeof(PNP_BUS_INFORMATION
),
1760 if (!BusInformation
)
1763 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1767 RtlZeroMemory(BusInformation
, sizeof(PNP_BUS_INFORMATION
));
1770 RtlMoveMemory(&BusInformation
->BusTypeGuid
,
1775 BusInformation
->LegacyBusType
= PNPBus
;
1776 BusInformation
->BusNumber
= 0;
1778 Status
= STATUS_SUCCESS
;
1779 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
1782 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1783 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1786 case IRP_MN_SURPRISE_REMOVAL
:
1787 DPRINT("USBPORT_PdoPnP: IRP_MN_SURPRISE_REMOVAL\n");
1788 Status
= STATUS_SUCCESS
;
1792 DPRINT("unknown IRP_MN_???\n");
1796 Irp
->IoStatus
.Status
= Status
;
1797 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);