1 /*
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>
6 */
7
8 #include "usbport.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #define NDEBUG_USBPORT_CORE
14 #include "usbdebug.h"
15
16 IO_COMPLETION_ROUTINE USBPORT_FdoStartCompletion;
17
18 NTSTATUS
19 NTAPI
USBPORT_FdoStartCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)20 USBPORT_FdoStartCompletion(IN PDEVICE_OBJECT DeviceObject,
21 IN PIRP Irp,
22 IN PVOID Context)
23 {
24 KeSetEvent((PKEVENT)Context, EVENT_INCREMENT, FALSE);
25 return STATUS_MORE_PROCESSING_REQUIRED;
26 }
27
28 NTSTATUS
29 NTAPI
USBPORT_RegisterDeviceInterface(IN PDEVICE_OBJECT PdoDevice,IN PDEVICE_OBJECT DeviceObject,IN CONST GUID * InterfaceClassGuid,IN BOOLEAN Enable)30 USBPORT_RegisterDeviceInterface(IN PDEVICE_OBJECT PdoDevice,
31 IN PDEVICE_OBJECT DeviceObject,
32 IN CONST GUID *InterfaceClassGuid,
33 IN BOOLEAN Enable)
34 {
35 PUSBPORT_RHDEVICE_EXTENSION DeviceExtension;
36 PUNICODE_STRING SymbolicLinkName;
37 NTSTATUS Status;
38
39 DPRINT("USBPORT_RegisterDeviceInterface: Enable - %x\n", Enable);
40
41 DeviceExtension = DeviceObject->DeviceExtension;
42 SymbolicLinkName = &DeviceExtension->CommonExtension.SymbolicLinkName;
43
44 if (Enable)
45 {
46 Status = IoRegisterDeviceInterface(PdoDevice,
47 InterfaceClassGuid,
48 NULL,
49 SymbolicLinkName);
50
51 if (NT_SUCCESS(Status))
52 {
53 DeviceExtension->CommonExtension.IsInterfaceEnabled = 1;
54
55 Status = USBPORT_SetRegistryKeyValue(PdoDevice,
56 FALSE,
57 REG_SZ,
58 L"SymbolicName",
59 SymbolicLinkName->Buffer,
60 SymbolicLinkName->Length);
61
62 if (NT_SUCCESS(Status))
63 {
64 DPRINT("USBPORT_RegisterDeviceInterface: LinkName - %wZ\n",
65 &DeviceExtension->CommonExtension.SymbolicLinkName);
66
67 Status = IoSetDeviceInterfaceState(SymbolicLinkName, TRUE);
68 }
69 }
70 }
71 else
72 {
73 /* Disable device interface */
74 Status = IoSetDeviceInterfaceState(SymbolicLinkName, FALSE);
75
76 if (NT_SUCCESS(Status))
77 {
78 RtlFreeUnicodeString(SymbolicLinkName);
79 DeviceExtension->CommonExtension.IsInterfaceEnabled = 0; // Disabled interface
80 }
81 }
82
83 return Status;
84 }
85
86 BOOLEAN
87 NTAPI
USBPORT_IsSelectiveSuspendEnabled(IN PDEVICE_OBJECT FdoDevice)88 USBPORT_IsSelectiveSuspendEnabled(IN PDEVICE_OBJECT FdoDevice)
89 {
90 PUSBPORT_DEVICE_EXTENSION FdoExtension;
91 ULONG Disabled = 0;
92
93 DPRINT("USBPORT_IsSelectiveSuspendEnabled: ... \n");
94
95 FdoExtension = FdoDevice->DeviceExtension;
96
97 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
98 FdoExtension->CommonExtension.LowerPdoDevice,
99 TRUE,
100 L"HcDisableSelectiveSuspend",
101 sizeof(L"HcDisableSelectiveSuspend"),
102 &Disabled,
103 sizeof(Disabled));
104
105 return (Disabled == 0);
106 }
107
108 NTSTATUS
109 NTAPI
USBPORT_GetConfigValue(IN PWSTR ValueName,IN ULONG ValueType,IN PVOID ValueData,IN ULONG ValueLength,IN PVOID Context,IN PVOID EntryContext)110 USBPORT_GetConfigValue(IN PWSTR ValueName,
111 IN ULONG ValueType,
112 IN PVOID ValueData,
113 IN ULONG ValueLength,
114 IN PVOID Context,
115 IN PVOID EntryContext)
116 {
117 NTSTATUS Status = STATUS_SUCCESS;
118
119 DPRINT("USBPORT_GetConfigValue \n");
120
121 if (ValueType == REG_DWORD)
122 {
123 *(PULONG)EntryContext = *(PULONG)ValueData;
124 }
125 else
126 {
127 Status = STATUS_INVALID_PARAMETER;
128 }
129
130 return Status;
131 }
132
133 NTSTATUS
134 NTAPI
USBPORT_GetDefaultBIOSx(IN PDEVICE_OBJECT FdoDevice,IN PULONG UsbBIOSx,IN PULONG DisableSelectiveSuspend,IN PULONG DisableCcDetect,IN PULONG IdleEpSupport,IN PULONG IdleEpSupportEx,IN PULONG SoftRetry)135 USBPORT_GetDefaultBIOSx(IN PDEVICE_OBJECT FdoDevice,
136 IN PULONG UsbBIOSx,
137 IN PULONG DisableSelectiveSuspend,
138 IN PULONG DisableCcDetect,
139 IN PULONG IdleEpSupport,
140 IN PULONG IdleEpSupportEx,
141 IN PULONG SoftRetry)
142 {
143 RTL_QUERY_REGISTRY_TABLE QueryTable[7];
144
145 DPRINT("USBPORT_GetDefaultBIOS_X: ... \n");
146
147 RtlZeroMemory(QueryTable, sizeof(QueryTable));
148
149 *UsbBIOSx = 2;
150
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);
158
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);
166
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);
174
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);
182
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);
190
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);
198
199 return RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
200 L"usb",
201 QueryTable,
202 NULL,
203 NULL);
204 }
205
206 NTSTATUS
207 NTAPI
USBPORT_IsCompanionController(IN PDEVICE_OBJECT DeviceObject,IN BOOLEAN * IsCompanion)208 USBPORT_IsCompanionController(IN PDEVICE_OBJECT DeviceObject,
209 IN BOOLEAN *IsCompanion)
210 {
211 PDEVICE_OBJECT HighestDevice;
212 PIRP Irp;
213 KEVENT Event;
214 PIO_STACK_LOCATION IoStack;
215 PCI_DEVICE_PRESENT_INTERFACE PciInterface = {0};
216 PCI_DEVICE_PRESENCE_PARAMETERS Parameters = {0};
217 IO_STATUS_BLOCK IoStatusBlock;
218 NTSTATUS Status;
219 BOOLEAN IsPresent;
220
221 DPRINT("USBPORT_IsCompanionController: ... \n");
222
223 *IsCompanion = FALSE;
224
225 KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
226
227 HighestDevice = IoGetAttachedDeviceReference(DeviceObject);
228
229 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
230 HighestDevice,
231 NULL,
232 0,
233 NULL,
234 &Event,
235 &IoStatusBlock);
236
237 if (!Irp)
238 {
239 Status = STATUS_INSUFFICIENT_RESOURCES;
240 ObDereferenceObject(HighestDevice);
241 return Status;
242 }
243
244 IoStack = IoGetNextIrpStackLocation(Irp);
245
246 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
247 Irp->IoStatus.Information = 0;
248
249 IoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
250
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;
256
257 Status = IoCallDriver(HighestDevice, Irp);
258
259 if (Status == STATUS_PENDING)
260 {
261 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
262 Status = IoStatusBlock.Status;
263 }
264
265 if (!NT_SUCCESS(Status))
266 {
267 DPRINT1("USBPORT_IsCompanionController: query interface failed\\n");
268 ObDereferenceObject(HighestDevice);
269 return Status;
270 }
271
272 DPRINT("USBPORT_IsCompanionController: query interface succeeded\n");
273
274 if (PciInterface.Size < sizeof(PCI_DEVICE_PRESENT_INTERFACE))
275 {
276 DPRINT1("USBPORT_IsCompanionController: old version\n");
277 ObDereferenceObject(HighestDevice);
278 return Status;
279 }
280
281 Parameters.Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
282
283 Parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
284 Parameters.SubClass = PCI_SUBCLASS_SB_USB;
285 Parameters.ProgIf = PCI_INTERFACE_USB_ID_EHCI;
286
287 Parameters.Flags = PCI_USE_LOCAL_BUS |
288 PCI_USE_LOCAL_DEVICE |
289 PCI_USE_CLASS_SUBCLASS |
290 PCI_USE_PROGIF;
291
292 IsPresent = (PciInterface.IsDevicePresentEx)(PciInterface.Context,
293 &Parameters);
294
295 if (IsPresent)
296 {
297 DPRINT("USBPORT_IsCompanionController: Present EHCI controller for FDO - %p\n",
298 DeviceObject);
299 }
300 else
301 {
302 DPRINT("USBPORT_IsCompanionController: No EHCI controller for FDO - %p\n",
303 DeviceObject);
304 }
305
306 *IsCompanion = IsPresent;
307
308 (PciInterface.InterfaceDereference)(PciInterface.Context);
309
310 ObDereferenceObject(HighestDevice);
311
312 return Status;
313 }
314
315 NTSTATUS
316 NTAPI
USBPORT_QueryPciBusInterface(IN PDEVICE_OBJECT FdoDevice)317 USBPORT_QueryPciBusInterface(IN PDEVICE_OBJECT FdoDevice)
318 {
319 PUSBPORT_DEVICE_EXTENSION FdoExtension;
320 PBUS_INTERFACE_STANDARD BusInterface;
321 PIO_STACK_LOCATION IoStack;
322 IO_STATUS_BLOCK IoStatusBlock;
323 PDEVICE_OBJECT HighestDevice;
324 KEVENT Event;
325 PIRP Irp;
326 NTSTATUS Status;
327
328 DPRINT("USBPORT_QueryPciBusInterface: ... \n");
329
330 FdoExtension = FdoDevice->DeviceExtension;
331 BusInterface = &FdoExtension->BusInterface;
332
333 RtlZeroMemory(BusInterface, sizeof(BUS_INTERFACE_STANDARD));
334 KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
335 HighestDevice = IoGetAttachedDeviceReference(FdoDevice);
336
337 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
338 HighestDevice,
339 NULL,
340 0,
341 NULL,
342 &Event,
343 &IoStatusBlock);
344
345 if (Irp)
346 {
347 IoStack = IoGetNextIrpStackLocation(Irp);
348
349 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
350 Irp->IoStatus.Information = 0;
351
352 IoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
353
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;
359
360 Status = IoCallDriver(HighestDevice, Irp);
361
362 if (Status == STATUS_PENDING)
363 {
364 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
365 Status = IoStatusBlock.Status;
366 }
367 }
368 else
369 {
370 Status = STATUS_INSUFFICIENT_RESOURCES;
371 }
372
373 ObDereferenceObject(HighestDevice);
374
375 DPRINT("USBPORT_QueryPciBusInterface: return Status - %x\n", Status);
376
377 return Status;
378 }
379
380 NTSTATUS
381 NTAPI
USBPORT_QueryCapabilities(IN PDEVICE_OBJECT FdoDevice,IN PDEVICE_CAPABILITIES Capabilities)382 USBPORT_QueryCapabilities(IN PDEVICE_OBJECT FdoDevice,
383 IN PDEVICE_CAPABILITIES Capabilities)
384 {
385 PUSBPORT_DEVICE_EXTENSION FdoExtention;
386 PIRP Irp;
387 NTSTATUS Status;
388 PIO_STACK_LOCATION IoStack;
389 KEVENT Event;
390
391 DPRINT("USBPORT_QueryCapabilities: ... \n");
392
393 FdoExtention = FdoDevice->DeviceExtension;
394
395 RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
396
397 Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
398 Capabilities->Version = 1;
399 Capabilities->Address = MAXULONG;
400 Capabilities->UINumber = MAXULONG;
401
402 Irp = IoAllocateIrp(FdoExtention->CommonExtension.LowerDevice->StackSize,
403 FALSE);
404
405 if (!Irp)
406 {
407 DPRINT1("USBPORT_QueryCapabilities: No resources - IoAllocateIrp!\n");
408 return STATUS_INSUFFICIENT_RESOURCES;
409 }
410
411 IoStack = IoGetCurrentIrpStackLocation(Irp);
412 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
413
414 IoStack = IoGetNextIrpStackLocation(Irp);
415 IoStack->MajorFunction = IRP_MJ_PNP;
416 IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
417
418 KeInitializeEvent(&Event, NotificationEvent, FALSE);
419
420 IoSetCompletionRoutine(Irp,
421 USBPORT_FdoStartCompletion,
422 &Event,
423 TRUE,
424 TRUE,
425 TRUE);
426
427 IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
428
429 Status = IoCallDriver(FdoExtention->CommonExtension.LowerDevice, Irp);
430
431 if (Status == STATUS_PENDING)
432 {
433 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
434 Status = Irp->IoStatus.Status;
435 }
436
437 if (NT_SUCCESS(Status) && Capabilities)
438 {
439 USBPORT_DumpingCapabilities(Capabilities);
440 }
441
442 IoFreeIrp(Irp);
443
444 return Status;
445 }
446
447 NTSTATUS
448 NTAPI
USBPORT_CreateLegacySymbolicLink(IN PDEVICE_OBJECT FdoDevice)449 USBPORT_CreateLegacySymbolicLink(IN PDEVICE_OBJECT FdoDevice)
450 {
451 PUSBPORT_DEVICE_EXTENSION FdoExtension;
452 WCHAR CharName[255] = {0};
453 WCHAR CharDosName[255] = {0};
454 UNICODE_STRING DeviceName;
455 NTSTATUS Status;
456
457 FdoExtension = FdoDevice->DeviceExtension;
458
459 RtlStringCbPrintfW(CharName,
460 sizeof(CharName),
461 L"\\Device\\USBFDO-%d",
462 FdoExtension->FdoNameNumber);
463
464 RtlInitUnicodeString(&DeviceName, CharName);
465
466 RtlStringCbPrintfW(CharDosName,
467 sizeof(CharDosName),
468 L"\\DosDevices\\HCD%d",
469 FdoExtension->FdoNameNumber);
470
471 RtlInitUnicodeString(&FdoExtension->DosDeviceSymbolicName, CharDosName);
472
473 DPRINT("USBPORT_CreateLegacySymbolicLink: DeviceName - %wZ, DosSymbolicName - %wZ\n",
474 &DeviceName,
475 &FdoExtension->DosDeviceSymbolicName);
476
477 Status = IoCreateSymbolicLink(&FdoExtension->DosDeviceSymbolicName,
478 &DeviceName);
479
480 if (NT_SUCCESS(Status))
481 {
482 FdoExtension->Flags |= USBPORT_FLAG_DOS_SYMBOLIC_NAME;
483 }
484
485 return Status;
486 }
487
488 NTSTATUS
489 NTAPI
USBPORT_StopDevice(IN PDEVICE_OBJECT FdoDevice)490 USBPORT_StopDevice(IN PDEVICE_OBJECT FdoDevice)
491 {
492 DPRINT1("USBPORT_StopDevice: UNIMPLEMENTED. FIXME\n");
493 return STATUS_SUCCESS;
494 }
495
496 NTSTATUS
497 NTAPI
USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_RESOURCES UsbPortResources)498 USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice,
499 IN PUSBPORT_RESOURCES UsbPortResources)
500 {
501 PUSBPORT_DEVICE_EXTENSION FdoExtension;
502 PUSBPORT_REGISTRATION_PACKET Packet;
503 NTSTATUS Status;
504 PCI_COMMON_CONFIG PciConfig;
505 ULONG BytesRead;
506 DEVICE_DESCRIPTION DeviceDescription;
507 PDMA_ADAPTER DmaAdapter = NULL;
508 ULONG MiniPortStatus;
509 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer;
510 ULONG ResultLength;
511 ULONG DisableSelectiveSuspend = 0;
512 ULONG DisableCcDetect = 0;
513 ULONG IdleEpSupport = 0;
514 ULONG IdleEpSupportEx = 0;
515 ULONG SoftRetry = 0;
516 ULONG Limit2GB = 0;
517 ULONG TotalBusBandwidth = 0;
518 BOOLEAN IsCompanion = FALSE;
519 ULONG LegacyBIOS;
520 ULONG MiniportFlags;
521 ULONG ix;
522
523 DPRINT("USBPORT_StartDevice: FdoDevice - %p, UsbPortResources - %p\n",
524 FdoDevice,
525 UsbPortResources);
526
527 FdoExtension = FdoDevice->DeviceExtension;
528 Packet = &FdoExtension->MiniPortInterface->Packet;
529
530 Status = USBPORT_QueryPciBusInterface(FdoDevice);
531 if (!NT_SUCCESS(Status))
532 goto ExitWithError;
533
534 BytesRead = (*FdoExtension->BusInterface.GetBusData)(FdoExtension->BusInterface.Context,
535 PCI_WHICHSPACE_CONFIG,
536 &PciConfig,
537 0,
538 PCI_COMMON_HDR_LENGTH);
539
540 if (BytesRead != PCI_COMMON_HDR_LENGTH)
541 {
542 DPRINT1("USBPORT_StartDevice: Failed to get pci config information!\n");
543 goto ExitWithError;
544 }
545
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;
552
553 RtlZeroMemory(&DeviceDescription, sizeof(DeviceDescription));
554
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;
563
564 DmaAdapter = IoGetDmaAdapter(FdoExtension->CommonExtension.LowerPdoDevice,
565 &DeviceDescription,
566 &FdoExtension->NumberMapRegs);
567
568 FdoExtension->DmaAdapter = DmaAdapter;
569
570 if (!DmaAdapter)
571 {
572 DPRINT1("USBPORT_StartDevice: Failed to get DmaAdapter!\n");
573 Status = STATUS_INSUFFICIENT_RESOURCES;
574 goto ExitWithError;
575 }
576
577 Status = USBPORT_CreateWorkerThread(FdoDevice);
578 if (!NT_SUCCESS(Status))
579 goto ExitWithError;
580
581 Status = USBPORT_QueryCapabilities(FdoDevice, &FdoExtension->Capabilities);
582 if (!NT_SUCCESS(Status))
583 goto ExitWithError;
584
585 FdoExtension->PciDeviceNumber = FdoExtension->Capabilities.Address >> 16;
586 FdoExtension->PciFunctionNumber = FdoExtension->Capabilities.Address & 0xFFFF;
587
588 Status = IoGetDeviceProperty(FdoExtension->CommonExtension.LowerPdoDevice,
589 DevicePropertyBusNumber,
590 sizeof(ULONG),
591 &FdoExtension->BusNumber,
592 &ResultLength);
593
594 if (!NT_SUCCESS(Status))
595 goto ExitWithError;
596
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);
613 KeInitializeSpinLock(&FdoExtension->TtSpinLock);
614
615 KeInitializeDpc(&FdoExtension->IsrDpc, USBPORT_IsrDpc, FdoDevice);
616
617 KeInitializeDpc(&FdoExtension->TransferFlushDpc,
618 USBPORT_TransferFlushDpc,
619 FdoDevice);
620
621 KeInitializeDpc(&FdoExtension->WorkerRequestDpc,
622 USBPORT_WorkerRequestDpc,
623 FdoDevice);
624
625 KeInitializeDpc(&FdoExtension->HcWakeDpc,
626 USBPORT_HcWakeDpc,
627 FdoDevice);
628
629 IoCsqInitialize(&FdoExtension->IdleIoCsq,
630 USBPORT_InsertIdleIrp,
631 USBPORT_RemoveIdleIrp,
632 USBPORT_PeekNextIdleIrp,
633 USBPORT_AcquireIdleLock,
634 USBPORT_ReleaseIdleLock,
635 USBPORT_CompleteCanceledIdleIrp);
636
637 IoCsqInitialize(&FdoExtension->BadRequestIoCsq,
638 USBPORT_InsertBadRequest,
639 USBPORT_RemoveBadRequest,
640 USBPORT_PeekNextBadRequest,
641 USBPORT_AcquireBadRequestLock,
642 USBPORT_ReleaseBadRequestLock,
643 USBPORT_CompleteCanceledBadRequest);
644
645 FdoExtension->IsrDpcCounter = -1;
646 FdoExtension->IsrDpcHandlerCounter = -1;
647 FdoExtension->IdleLockCounter = -1;
648 FdoExtension->BadRequestLockCounter = -1;
649 FdoExtension->ChirpRootPortLock = -1;
650
651 FdoExtension->RHInitCallBackLock = 0;
652
653 FdoExtension->UsbAddressBitMap[0] = 1;
654 FdoExtension->UsbAddressBitMap[1] = 0;
655 FdoExtension->UsbAddressBitMap[2] = 0;
656 FdoExtension->UsbAddressBitMap[3] = 0;
657
658 USBPORT_GetDefaultBIOSx(FdoDevice,
659 &FdoExtension->UsbBIOSx,
660 &DisableSelectiveSuspend,
661 &DisableCcDetect,
662 &IdleEpSupport,
663 &IdleEpSupportEx,
664 &SoftRetry);
665
666 if (DisableSelectiveSuspend)
667 FdoExtension->Flags |= USBPORT_FLAG_BIOS_DISABLE_SS;
668
669 if (!DisableSelectiveSuspend &&
670 USBPORT_IsSelectiveSuspendEnabled(FdoDevice))
671 {
672 FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
673 }
674
675 MiniportFlags = Packet->MiniPortFlags;
676
677 if (MiniportFlags & USB_MINIPORT_FLAGS_POLLING)
678 FdoExtension->Flags |= USBPORT_FLAG_HC_POLLING;
679
680 if (MiniportFlags & USB_MINIPORT_FLAGS_WAKE_SUPPORT)
681 FdoExtension->Flags |= USBPORT_FLAG_HC_WAKE_SUPPORT;
682
683 if (MiniportFlags & USB_MINIPORT_FLAGS_DISABLE_SS)
684 FdoExtension->Flags = (FdoExtension->Flags & ~USBPORT_FLAG_SELECTIVE_SUSPEND) |
685 USBPORT_FLAG_BIOS_DISABLE_SS;
686
687 USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
688 TRUE,
689 REG_DWORD,
690 L"EnIdleEndpointSupport",
691 &IdleEpSupport,
692 sizeof(IdleEpSupport));
693
694 USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
695 TRUE,
696 REG_DWORD,
697 L"EnIdleEndpointSupportEx",
698 &IdleEpSupportEx,
699 sizeof(IdleEpSupportEx));
700
701 USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
702 TRUE,
703 REG_DWORD,
704 L"EnSoftRetry",
705 &SoftRetry,
706 sizeof(SoftRetry));
707
708 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
709 FdoExtension->CommonExtension.LowerPdoDevice,
710 TRUE,
711 L"CommonBuffer2GBLimit",
712 sizeof(L"CommonBuffer2GBLimit"),
713 &Limit2GB,
714 sizeof(Limit2GB));
715
716 FdoExtension->CommonBufferLimit = (Limit2GB != 0);
717
718 if (FdoExtension->BaseClass == PCI_CLASS_SERIAL_BUS_CTLR &&
719 FdoExtension->SubClass == PCI_SUBCLASS_SB_USB &&
720 FdoExtension->ProgIf < PCI_INTERFACE_USB_ID_EHCI)
721 {
722 Status = USBPORT_IsCompanionController(FdoDevice, &IsCompanion);
723
724 if (!NT_SUCCESS(Status))
725 {
726 if (IsCompanion)
727 {
728 FdoExtension->Flags |= USBPORT_FLAG_COMPANION_HC;
729 }
730 else
731 {
732 FdoExtension->Flags &= ~USBPORT_FLAG_COMPANION_HC;
733 }
734 }
735 }
736
737 if (DisableCcDetect)
738 {
739 FdoExtension->Flags &= ~USBPORT_FLAG_COMPANION_HC;
740 }
741
742 TotalBusBandwidth = Packet->MiniPortBusBandwidth;
743 FdoExtension->TotalBusBandwidth = TotalBusBandwidth;
744
745 USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
746 FdoExtension->CommonExtension.LowerPdoDevice,
747 TRUE,
748 L"TotalBusBandwidth",
749 sizeof(L"TotalBusBandwidth"),
750 &TotalBusBandwidth,
751 sizeof(TotalBusBandwidth));
752
753 if (TotalBusBandwidth != FdoExtension->TotalBusBandwidth)
754 {
755 FdoExtension->TotalBusBandwidth = TotalBusBandwidth;
756 }
757
758 for (ix = 0; ix < USB2_FRAMES; ix++)
759 {
760 FdoExtension->Bandwidth[ix] = FdoExtension->TotalBusBandwidth -
761 FdoExtension->TotalBusBandwidth / 10;
762 }
763
764 FdoExtension->ActiveIrpTable = ExAllocatePoolWithTag(NonPagedPool,
765 sizeof(USBPORT_IRP_TABLE),
766 USB_PORT_TAG);
767
768 if (!FdoExtension->ActiveIrpTable)
769 {
770 DPRINT1("USBPORT_StartDevice: Allocate ActiveIrpTable failed!\n");
771 goto ExitWithError;
772 }
773
774 RtlZeroMemory(FdoExtension->ActiveIrpTable, sizeof(USBPORT_IRP_TABLE));
775
776 FdoExtension->PendingIrpTable = ExAllocatePoolWithTag(NonPagedPool,
777 sizeof(USBPORT_IRP_TABLE),
778 USB_PORT_TAG);
779
780 if (!FdoExtension->PendingIrpTable)
781 {
782 DPRINT1("USBPORT_StartDevice: Allocate PendingIrpTable failed!\n");
783 goto ExitWithError;
784 }
785
786 RtlZeroMemory(FdoExtension->PendingIrpTable, sizeof(USBPORT_IRP_TABLE));
787
788 Status = IoConnectInterrupt(&FdoExtension->InterruptObject,
789 USBPORT_InterruptService,
790 (PVOID)FdoDevice,
791 0,
792 UsbPortResources->InterruptVector,
793 UsbPortResources->InterruptLevel,
794 UsbPortResources->InterruptLevel,
795 UsbPortResources->InterruptMode,
796 UsbPortResources->ShareVector,
797 UsbPortResources->InterruptAffinity,
798 0);
799
800
801 if (!NT_SUCCESS(Status))
802 {
803 DPRINT1("USBPORT_StartDevice: IoConnectInterrupt failed!\n");
804 goto ExitWithError;
805 }
806
807 FdoExtension->Flags &= ~USBPORT_FLAG_INT_CONNECTED;
808
809 if (Packet->MiniPortExtensionSize)
810 {
811 RtlZeroMemory(FdoExtension->MiniPortExt, Packet->MiniPortExtensionSize);
812 }
813
814 if (Packet->MiniPortResourcesSize)
815 {
816 HeaderBuffer = USBPORT_AllocateCommonBuffer(FdoDevice,
817 Packet->MiniPortResourcesSize);
818
819 if (!HeaderBuffer)
820 {
821 DPRINT1("USBPORT_StartDevice: Failed to AllocateCommonBuffer!\n");
822 Status = STATUS_INSUFFICIENT_RESOURCES;
823 goto ExitWithError;
824 }
825
826 UsbPortResources->StartVA = HeaderBuffer->VirtualAddress;
827 UsbPortResources->StartPA = HeaderBuffer->PhysicalAddress;
828
829 FdoExtension->MiniPortCommonBuffer = HeaderBuffer;
830 }
831 else
832 {
833 FdoExtension->MiniPortCommonBuffer = NULL;
834 }
835
836 MiniPortStatus = Packet->StartController(FdoExtension->MiniPortExt,
837 UsbPortResources);
838
839 if (UsbPortResources->LegacySupport)
840 {
841 FdoExtension->Flags |= USBPORT_FLAG_LEGACY_SUPPORT;
842 LegacyBIOS = 1;
843 }
844 else
845 {
846 LegacyBIOS = 0;
847 }
848
849 USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
850 FALSE,
851 REG_DWORD,
852 L"DetectedLegacyBIOS",
853 &LegacyBIOS,
854 sizeof(LegacyBIOS));
855
856 if (MiniPortStatus)
857 {
858 DPRINT1("USBPORT_StartDevice: Failed to Start MiniPort. MiniPortStatus - %x\n",
859 MiniPortStatus);
860
861 if (FdoExtension->Flags & USBPORT_FLAG_INT_CONNECTED)
862 {
863 IoDisconnectInterrupt(FdoExtension->InterruptObject);
864 FdoExtension->Flags &= ~USBPORT_FLAG_INT_CONNECTED;
865 }
866
867 if (FdoExtension->MiniPortCommonBuffer)
868 {
869 USBPORT_FreeCommonBuffer(FdoDevice, FdoExtension->MiniPortCommonBuffer);
870 FdoExtension->MiniPortCommonBuffer = NULL;
871 }
872
873 goto ExitWithError;
874 }
875 else
876 {
877 FdoExtension->MiniPortFlags |= USBPORT_MPFLAG_INTERRUPTS_ENABLED;
878 USBPORT_MiniportInterrupts(FdoDevice, TRUE);
879 }
880
881 FdoExtension->TimerValue = 500;
882 USBPORT_StartTimer((PVOID)FdoDevice, 500);
883
884 Status = USBPORT_RegisterDeviceInterface(FdoExtension->CommonExtension.LowerPdoDevice,
885 FdoDevice,
886 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
887 TRUE);
888
889 if (!NT_SUCCESS(Status))
890 {
891 DPRINT1("USBPORT_StartDevice: RegisterDeviceInterface failed!\n");
892 goto ExitWithError;
893 }
894
895 USBPORT_CreateLegacySymbolicLink(FdoDevice);
896
897 FdoExtension->Flags |= USBPORT_FLAG_HC_STARTED;
898
899 DPRINT("USBPORT_StartDevice: Exit Status - %p\n", Status);
900 return Status;
901
902 ExitWithError:
903 USBPORT_StopWorkerThread(FdoDevice);
904 USBPORT_StopDevice(FdoDevice);
905
906 DPRINT1("USBPORT_StartDevice: ExitWithError Status - %lx\n", Status);
907 return Status;
908 }
909
910 NTSTATUS
911 NTAPI
USBPORT_ParseResources(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PUSBPORT_RESOURCES UsbPortResources)912 USBPORT_ParseResources(IN PDEVICE_OBJECT FdoDevice,
913 IN PIRP Irp,
914 IN PUSBPORT_RESOURCES UsbPortResources)
915 {
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;
923 ULONG ix;
924 NTSTATUS Status = STATUS_SUCCESS;
925
926 DPRINT("USBPORT_ParseResources: ... \n");
927
928 IoStack = IoGetCurrentIrpStackLocation(Irp);
929 AllocatedResourcesTranslated = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
930
931 if (AllocatedResourcesTranslated)
932 {
933 RtlZeroMemory(UsbPortResources, sizeof(USBPORT_RESOURCES));
934
935 ResourceList = &AllocatedResourcesTranslated->List[0].PartialResourceList;
936
937 PartialDescriptor = &ResourceList->PartialDescriptors[0];
938
939 for (ix = 0; ix < ResourceList->Count; ++ix)
940 {
941 if (PartialDescriptor->Type == CmResourceTypePort)
942 {
943 if (!PortDescriptor)
944 PortDescriptor = PartialDescriptor;
945 }
946 else if (PartialDescriptor->Type == CmResourceTypeInterrupt)
947 {
948 if (!InterruptDescriptor)
949 InterruptDescriptor = PartialDescriptor;
950 }
951 else if (PartialDescriptor->Type == CmResourceTypeMemory)
952 {
953 if (!MemoryDescriptor)
954 MemoryDescriptor = PartialDescriptor;
955 }
956
957 PartialDescriptor += 1;
958 }
959
960 if (PortDescriptor)
961 {
962 if (PortDescriptor->Flags & CM_RESOURCE_PORT_IO)
963 {
964 UsbPortResources->ResourceBase = (PVOID)(ULONG_PTR)PortDescriptor->u.Port.Start.QuadPart;
965 }
966 else
967 {
968 UsbPortResources->ResourceBase = MmMapIoSpace(PortDescriptor->u.Port.Start,
969 PortDescriptor->u.Port.Length,
970 0);
971 }
972
973 UsbPortResources->IoSpaceLength = PortDescriptor->u.Port.Length;
974
975 if (UsbPortResources->ResourceBase)
976 {
977 UsbPortResources->ResourcesTypes |= USBPORT_RESOURCES_PORT;
978 }
979 else
980 {
981 Status = STATUS_NONE_MAPPED;
982 }
983 }
984
985 if (MemoryDescriptor && NT_SUCCESS(Status))
986 {
987 UsbPortResources->IoSpaceLength = MemoryDescriptor->u.Memory.Length;
988
989 UsbPortResources->ResourceBase = MmMapIoSpace(MemoryDescriptor->u.Memory.Start,
990 MemoryDescriptor->u.Memory.Length,
991 0);
992
993 if (UsbPortResources->ResourceBase)
994 {
995 UsbPortResources->ResourcesTypes |= USBPORT_RESOURCES_MEMORY;
996 }
997 else
998 {
999 Status = STATUS_NONE_MAPPED;
1000 }
1001 }
1002
1003 if (InterruptDescriptor && NT_SUCCESS(Status))
1004 {
1005 UsbPortResources->ResourcesTypes |= USBPORT_RESOURCES_INTERRUPT;
1006
1007 UsbPortResources->InterruptVector = InterruptDescriptor->u.Interrupt.Vector;
1008 UsbPortResources->InterruptLevel = InterruptDescriptor->u.Interrupt.Level;
1009 UsbPortResources->InterruptAffinity = InterruptDescriptor->u.Interrupt.Affinity;
1010
1011 UsbPortResources->ShareVector = InterruptDescriptor->ShareDisposition ==
1012 CmResourceShareShared;
1013
1014 UsbPortResources->InterruptMode = InterruptDescriptor->Flags ==
1015 CM_RESOURCE_INTERRUPT_LATCHED;
1016 }
1017 }
1018 else
1019 {
1020 Status = STATUS_NONE_MAPPED;
1021 }
1022
1023 return Status;
1024 }
1025
1026 NTSTATUS
1027 NTAPI
USBPORT_CreatePdo(IN PDEVICE_OBJECT FdoDevice,OUT PDEVICE_OBJECT * RootHubPdo)1028 USBPORT_CreatePdo(IN PDEVICE_OBJECT FdoDevice,
1029 OUT PDEVICE_OBJECT *RootHubPdo)
1030 {
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;
1038
1039 DPRINT("USBPORT_CreatePdo: FdoDevice - %p, RootHubPdo - %p\n",
1040 FdoDevice,
1041 RootHubPdo);
1042
1043 FdoExtension = FdoDevice->DeviceExtension;
1044
1045 do
1046 {
1047 RtlStringCbPrintfW(CharDeviceName,
1048 sizeof(CharDeviceName),
1049 L"\\Device\\USBPDO-%d",
1050 DeviceNumber);
1051
1052 RtlInitUnicodeString(&DeviceName, CharDeviceName);
1053
1054 DPRINT("USBPORT_CreatePdo: DeviceName - %wZ\n", &DeviceName);
1055
1056 Status = IoCreateDevice(FdoExtension->MiniPortInterface->DriverObject,
1057 sizeof(USBPORT_RHDEVICE_EXTENSION),
1058 &DeviceName,
1059 FILE_DEVICE_BUS_EXTENDER,
1060 0,
1061 FALSE,
1062 &DeviceObject);
1063
1064 ++DeviceNumber;
1065 }
1066 while (Status == STATUS_OBJECT_NAME_COLLISION);
1067
1068 if (!NT_SUCCESS(Status))
1069 {
1070 *RootHubPdo = NULL;
1071 DPRINT1("USBPORT_CreatePdo: Filed create HubPdo!\n");
1072 return Status;
1073 }
1074
1075 if (DeviceObject)
1076 {
1077 PdoExtension = DeviceObject->DeviceExtension;
1078
1079 RtlZeroMemory(PdoExtension, sizeof(USBPORT_RHDEVICE_EXTENSION));
1080
1081 PdoExtension->CommonExtension.SelfDevice = DeviceObject;
1082 PdoExtension->CommonExtension.IsPDO = TRUE;
1083
1084 PdoExtension->FdoDevice = FdoDevice;
1085 PdoExtension->PdoNameNumber = DeviceNumber;
1086
1087 USBPORT_AdjustDeviceCapabilities(FdoDevice, DeviceObject);
1088
1089 DeviceObject->StackSize = FdoDevice->StackSize;
1090
1091 DeviceObject->Flags |= DO_POWER_PAGABLE;
1092 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1093 }
1094 else
1095 {
1096 Status = STATUS_UNSUCCESSFUL;
1097 }
1098
1099 if (!NT_SUCCESS(Status))
1100 *RootHubPdo = NULL;
1101 else
1102 *RootHubPdo = DeviceObject;
1103
1104 DPRINT("USBPORT_CreatePdo: HubPdo - %p\n", DeviceObject);
1105 return Status;
1106 }
1107
1108 NTSTATUS
1109 NTAPI
USBPORT_FdoPnP(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp)1110 USBPORT_FdoPnP(IN PDEVICE_OBJECT FdoDevice,
1111 IN PIRP Irp)
1112 {
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;
1118 UCHAR Minor;
1119 KEVENT Event;
1120 NTSTATUS Status;
1121 DEVICE_RELATION_TYPE RelationType;
1122 PDEVICE_RELATIONS DeviceRelations;
1123 PDEVICE_OBJECT RootHubPdo;
1124
1125 FdoExtension = FdoDevice->DeviceExtension;
1126 FdoCommonExtension = &FdoExtension->CommonExtension;
1127 UsbPortResources = &FdoExtension->UsbPortResources;
1128 Packet = &FdoExtension->MiniPortInterface->Packet;
1129
1130 IoStack = IoGetCurrentIrpStackLocation(Irp);
1131 Minor = IoStack->MinorFunction;
1132
1133 DPRINT("USBPORT_FdoPnP: FdoDevice - %p, Minor - %x\n", FdoDevice, Minor);
1134
1135 RelationType = IoStack->Parameters.QueryDeviceRelations.Type;
1136
1137 switch (Minor)
1138 {
1139 case IRP_MN_START_DEVICE:
1140 DPRINT("IRP_MN_START_DEVICE\n");
1141
1142 KeInitializeEvent(&Event, NotificationEvent, FALSE);
1143
1144 IoCopyCurrentIrpStackLocationToNext(Irp);
1145
1146 IoSetCompletionRoutine(Irp,
1147 USBPORT_FdoStartCompletion,
1148 &Event,
1149 TRUE,
1150 TRUE,
1151 TRUE);
1152
1153 Status = IoCallDriver(FdoCommonExtension->LowerDevice,
1154 Irp);
1155
1156 if (Status == STATUS_PENDING)
1157 {
1158 KeWaitForSingleObject(&Event,
1159 Suspended,
1160 KernelMode,
1161 FALSE,
1162 NULL);
1163
1164 Status = Irp->IoStatus.Status;
1165 }
1166
1167 if (!NT_SUCCESS(Status))
1168 {
1169 goto Exit;
1170 }
1171
1172 Status = USBPORT_ParseResources(FdoDevice,
1173 Irp,
1174 UsbPortResources);
1175
1176 if (!NT_SUCCESS(Status))
1177 {
1178 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_STOPPED;
1179 goto Exit;
1180 }
1181
1182 Status = USBPORT_StartDevice(FdoDevice, UsbPortResources);
1183
1184 if (!NT_SUCCESS(Status))
1185 {
1186 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_STOPPED;
1187 goto Exit;
1188 }
1189
1190 FdoCommonExtension->PnpStateFlags &= ~USBPORT_PNP_STATE_NOT_INIT;
1191 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_STARTED;
1192
1193 FdoCommonExtension->DevicePowerState = PowerDeviceD0;
1194
1195 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1196 {
1197 USBPORT_AddUSB2Fdo(FdoDevice);
1198 }
1199 else
1200 {
1201 USBPORT_AddUSB1Fdo(FdoDevice);
1202 }
1203
1204 Exit:
1205 Irp->IoStatus.Status = Status;
1206 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1207 return Status;
1208
1209 case IRP_MN_QUERY_REMOVE_DEVICE:
1210 DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
1211 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1212 {
1213 DPRINT1("USBPORT_FdoPnP: Haction registry write FIXME\n");
1214 }
1215
1216 Irp->IoStatus.Status = STATUS_SUCCESS;
1217 goto ForwardIrp;
1218
1219 case IRP_MN_REMOVE_DEVICE:
1220 DPRINT("USBPORT_FdoPnP: IRP_MN_REMOVE_DEVICE\n");
1221 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_FAILED;
1222
1223 if (FdoCommonExtension->PnpStateFlags & USBPORT_PNP_STATE_STARTED &&
1224 !(FdoCommonExtension->PnpStateFlags & USBPORT_PNP_STATE_NOT_INIT))
1225 {
1226 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1227 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_NOT_INIT;
1228 }
1229
1230 Irp->IoStatus.Status = STATUS_SUCCESS;
1231 IoSkipCurrentIrpStackLocation(Irp);
1232 Status = IoCallDriver(FdoCommonExtension->LowerDevice, Irp);
1233
1234 IoDetachDevice(FdoCommonExtension->LowerDevice);
1235
1236 RootHubPdo = FdoExtension->RootHubPdo;
1237
1238 IoDeleteDevice(FdoDevice);
1239
1240 if (RootHubPdo)
1241 {
1242 IoDeleteDevice(RootHubPdo);
1243 }
1244
1245 return Status;
1246
1247 case IRP_MN_CANCEL_REMOVE_DEVICE:
1248 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1249 Irp->IoStatus.Status = STATUS_SUCCESS;
1250 goto ForwardIrp;
1251
1252 case IRP_MN_STOP_DEVICE:
1253 DPRINT("IRP_MN_STOP_DEVICE\n");
1254 if (FdoCommonExtension->PnpStateFlags & USBPORT_PNP_STATE_STARTED)
1255 {
1256 DPRINT1("USBPORT_FdoPnP: stop fdo FIXME\n");
1257
1258 FdoCommonExtension->PnpStateFlags &= ~USBPORT_PNP_STATE_STARTED;
1259 FdoCommonExtension->PnpStateFlags |= USBPORT_PNP_STATE_NOT_INIT;
1260 }
1261
1262 Irp->IoStatus.Status = STATUS_SUCCESS;
1263 goto ForwardIrp;
1264
1265 case IRP_MN_QUERY_STOP_DEVICE:
1266 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1267 Irp->IoStatus.Status = STATUS_SUCCESS;
1268 goto ForwardIrp;
1269
1270 case IRP_MN_CANCEL_STOP_DEVICE:
1271 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1272 Irp->IoStatus.Status = STATUS_SUCCESS;
1273 goto ForwardIrp;
1274
1275 case IRP_MN_QUERY_DEVICE_RELATIONS:
1276 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1277 if (RelationType == BusRelations)
1278 {
1279 DeviceRelations = ExAllocatePoolWithTag(PagedPool,
1280 sizeof(DEVICE_RELATIONS),
1281 USB_PORT_TAG);
1282
1283 if (!DeviceRelations)
1284 {
1285 Status = STATUS_INSUFFICIENT_RESOURCES;
1286 Irp->IoStatus.Status = Status;
1287 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1288 return Status;
1289 }
1290
1291 DeviceRelations->Count = 0;
1292 DeviceRelations->Objects[0] = NULL;
1293
1294 if (!FdoExtension->RootHubPdo)
1295 {
1296 Status = USBPORT_CreatePdo(FdoDevice,
1297 &FdoExtension->RootHubPdo);
1298
1299 if (!NT_SUCCESS(Status))
1300 {
1301 ExFreePoolWithTag(DeviceRelations, USB_PORT_TAG);
1302 goto ForwardIrp;
1303 }
1304 }
1305 else
1306 {
1307 Status = STATUS_SUCCESS;
1308 }
1309
1310 DeviceRelations->Count = 1;
1311 DeviceRelations->Objects[0] = FdoExtension->RootHubPdo;
1312
1313 ObReferenceObject(FdoExtension->RootHubPdo);
1314 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
1315 }
1316 else
1317 {
1318 if (RelationType == RemovalRelations)
1319 {
1320 DPRINT1("USBPORT_FdoPnP: FIXME IRP_MN_QUERY_DEVICE_RELATIONS/RemovalRelations\n");
1321 }
1322
1323 goto ForwardIrp;
1324 }
1325
1326 Irp->IoStatus.Status = Status;
1327 goto ForwardIrp;
1328
1329 case IRP_MN_QUERY_INTERFACE:
1330 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1331 goto ForwardIrp;
1332
1333 case IRP_MN_QUERY_CAPABILITIES:
1334 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1335 goto ForwardIrp;
1336
1337 case IRP_MN_QUERY_RESOURCES:
1338 DPRINT("IRP_MN_QUERY_RESOURCES\n");
1339 goto ForwardIrp;
1340
1341 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1342 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1343 goto ForwardIrp;
1344
1345 case IRP_MN_QUERY_DEVICE_TEXT:
1346 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1347 goto ForwardIrp;
1348
1349 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
1350 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1351 goto ForwardIrp;
1352
1353 case IRP_MN_READ_CONFIG:
1354 DPRINT("IRP_MN_READ_CONFIG\n");
1355 goto ForwardIrp;
1356
1357 case IRP_MN_WRITE_CONFIG:
1358 DPRINT("IRP_MN_WRITE_CONFIG\n");
1359 goto ForwardIrp;
1360
1361 case IRP_MN_EJECT:
1362 DPRINT("IRP_MN_EJECT\n");
1363 goto ForwardIrp;
1364
1365 case IRP_MN_SET_LOCK:
1366 DPRINT("IRP_MN_SET_LOCK\n");
1367 goto ForwardIrp;
1368
1369 case IRP_MN_QUERY_ID:
1370 DPRINT("IRP_MN_QUERY_ID\n");
1371 goto ForwardIrp;
1372
1373 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1374 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1375 goto ForwardIrp;
1376
1377 case IRP_MN_QUERY_BUS_INFORMATION:
1378 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1379 goto ForwardIrp;
1380
1381 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
1382 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1383 goto ForwardIrp;
1384
1385 case IRP_MN_SURPRISE_REMOVAL:
1386 DPRINT1("IRP_MN_SURPRISE_REMOVAL\n");
1387 if (!(FdoCommonExtension->PnpStateFlags & USBPORT_PNP_STATE_FAILED))
1388 {
1389 USBPORT_InvalidateControllerHandler(FdoDevice,
1390 USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE);
1391 }
1392 goto ForwardIrp;
1393
1394 default:
1395 DPRINT("unknown IRP_MN_???\n");
1396 ForwardIrp:
1397 /* forward irp to next device object */
1398 IoSkipCurrentIrpStackLocation(Irp);
1399 break;
1400 }
1401
1402 return IoCallDriver(FdoCommonExtension->LowerDevice, Irp);
1403 }
1404
1405 PVOID
1406 NTAPI
USBPORT_GetDeviceHwIds(IN PDEVICE_OBJECT FdoDevice,IN USHORT VendorID,IN USHORT DeviceID,IN USHORT RevisionID)1407 USBPORT_GetDeviceHwIds(IN PDEVICE_OBJECT FdoDevice,
1408 IN USHORT VendorID,
1409 IN USHORT DeviceID,
1410 IN USHORT RevisionID)
1411 {
1412 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1413 PUSBPORT_REGISTRATION_PACKET Packet;
1414 PVOID Id;
1415 WCHAR Buffer[300] = {0};
1416 SIZE_T Length = 0;
1417 size_t Remaining = sizeof(Buffer);
1418 PWCHAR EndBuffer;
1419
1420 FdoExtension = FdoDevice->DeviceExtension;
1421 Packet = &FdoExtension->MiniPortInterface->Packet;
1422
1423 DPRINT("USBPORT_GetDeviceHwIds: FdoDevice - %p, Packet->MiniPortFlags - %p\n",
1424 FdoDevice,
1425 Packet->MiniPortFlags);
1426
1427 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1428 {
1429 RtlStringCbPrintfExW(Buffer,
1430 Remaining,
1431 &EndBuffer,
1432 &Remaining,
1433 0,
1434 L"USB\\ROOT_HUB20&VID%04x&PID%04x&REV%04x",
1435 VendorID,
1436 DeviceID,
1437 RevisionID);
1438
1439 EndBuffer++;
1440 Remaining -= sizeof(UNICODE_NULL);
1441
1442 RtlStringCbPrintfExW(EndBuffer,
1443 Remaining,
1444 &EndBuffer,
1445 &Remaining,
1446 0,
1447 L"USB\\ROOT_HUB20&VID%04x&PID%04x",
1448 VendorID,
1449 DeviceID);
1450
1451 EndBuffer++;
1452 Remaining -= sizeof(UNICODE_NULL);
1453
1454 RtlStringCbPrintfExW(EndBuffer,
1455 Remaining,
1456 NULL,
1457 &Remaining,
1458 0,
1459 L"USB\\ROOT_HUB20");
1460 }
1461 else
1462 {
1463 RtlStringCbPrintfExW(Buffer,
1464 Remaining,
1465 &EndBuffer,
1466 &Remaining,
1467 0,
1468 L"USB\\ROOT_HUB&VID%04x&PID%04x&REV%04x",
1469 VendorID,
1470 DeviceID,
1471 RevisionID);
1472
1473 EndBuffer++;
1474 Remaining -= sizeof(UNICODE_NULL);
1475
1476 RtlStringCbPrintfExW(EndBuffer,
1477 Remaining,
1478 &EndBuffer,
1479 &Remaining,
1480 0,
1481 L"USB\\ROOT_HUB&VID%04x&PID%04x",
1482 VendorID,
1483 DeviceID);
1484
1485 EndBuffer++;
1486 Remaining -= sizeof(UNICODE_NULL);
1487
1488 RtlStringCbPrintfExW(EndBuffer,
1489 Remaining,
1490 NULL,
1491 &Remaining,
1492 0,
1493 L"USB\\ROOT_HUB");
1494 }
1495
1496 Length = (sizeof(Buffer) - Remaining + 2 * sizeof(UNICODE_NULL));
1497
1498 /* for debug only */
1499 if (FALSE)
1500 {
1501 DPRINT("Hardware IDs:\n");
1502 USBPORT_DumpingIDs(Buffer);
1503 }
1504
1505 Id = ExAllocatePoolWithTag(PagedPool, Length, USB_PORT_TAG);
1506
1507 if (!Id)
1508 return NULL;
1509
1510 RtlMoveMemory(Id, Buffer, Length);
1511
1512 return Id;
1513 }
1514
1515 NTSTATUS
1516 NTAPI
USBPORT_PdoPnP(IN PDEVICE_OBJECT PdoDevice,IN PIRP Irp)1517 USBPORT_PdoPnP(IN PDEVICE_OBJECT PdoDevice,
1518 IN PIRP Irp)
1519 {
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;
1525 UCHAR Minor;
1526 NTSTATUS Status;
1527 PPNP_BUS_INFORMATION BusInformation;
1528 PDEVICE_CAPABILITIES DeviceCapabilities;
1529
1530 PdoExtension = PdoDevice->DeviceExtension;
1531 PdoCommonExtension = &PdoExtension->CommonExtension;
1532
1533 FdoDevice = PdoExtension->FdoDevice;
1534 FdoExtension = FdoDevice->DeviceExtension;
1535
1536 IoStack = IoGetCurrentIrpStackLocation(Irp);
1537 Minor = IoStack->MinorFunction;
1538
1539 Status = Irp->IoStatus.Status;
1540
1541 DPRINT("USBPORT_PdoPnP: PdoDevice - %p, Minor - %x\n", PdoDevice, Minor);
1542
1543 switch (Minor)
1544 {
1545 case IRP_MN_START_DEVICE:
1546 DPRINT("IRP_MN_START_DEVICE\n");
1547
1548 Status = USBPORT_RootHubCreateDevice(FdoDevice, PdoDevice);
1549
1550 if (NT_SUCCESS(Status))
1551 {
1552 Status = USBPORT_RegisterDeviceInterface(PdoDevice,
1553 PdoDevice,
1554 &GUID_DEVINTERFACE_USB_HUB,
1555 TRUE);
1556
1557 if (NT_SUCCESS(Status))
1558 {
1559 PdoCommonExtension->DevicePowerState = PowerDeviceD0;
1560 PdoCommonExtension->PnpStateFlags = USBPORT_PNP_STATE_STARTED;
1561 }
1562 }
1563
1564 break;
1565
1566 case IRP_MN_QUERY_REMOVE_DEVICE:
1567 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_REMOVE_DEVICE\n");
1568 Status = STATUS_SUCCESS;
1569 break;
1570
1571 case IRP_MN_REMOVE_DEVICE:
1572 DPRINT1("USBPORT_PdoPnP: IRP_MN_REMOVE_DEVICE UNIMPLEMENTED. FIXME. \n");
1573 //USBPORT_StopRootHub();
1574 Status = STATUS_SUCCESS;
1575 break;
1576
1577 case IRP_MN_CANCEL_REMOVE_DEVICE:
1578 DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
1579 Status = STATUS_SUCCESS;
1580 break;
1581
1582 case IRP_MN_STOP_DEVICE:
1583 DPRINT1("USBPORT_PdoPnP: IRP_MN_STOP_DEVICE UNIMPLEMENTED. FIXME. \n");
1584 //USBPORT_StopRootHub();
1585 Status = STATUS_SUCCESS;
1586 break;
1587
1588 case IRP_MN_QUERY_STOP_DEVICE:
1589 DPRINT("IRP_MN_QUERY_STOP_DEVICE\n");
1590 Status = STATUS_SUCCESS;
1591 break;
1592
1593 case IRP_MN_CANCEL_STOP_DEVICE:
1594 DPRINT("IRP_MN_CANCEL_STOP_DEVICE\n");
1595 Status = STATUS_SUCCESS;
1596 break;
1597
1598 case IRP_MN_QUERY_DEVICE_RELATIONS:
1599 {
1600 PDEVICE_RELATIONS DeviceRelations;
1601
1602 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
1603 if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
1604 {
1605 break;
1606 }
1607
1608 DeviceRelations = ExAllocatePoolWithTag(PagedPool,
1609 sizeof(DEVICE_RELATIONS),
1610 USB_PORT_TAG);
1611
1612 if (!DeviceRelations)
1613 {
1614 Status = STATUS_INSUFFICIENT_RESOURCES;
1615 Irp->IoStatus.Information = 0;
1616 break;
1617 }
1618
1619 DeviceRelations->Count = 1;
1620 DeviceRelations->Objects[0] = PdoDevice;
1621
1622 ObReferenceObject(PdoDevice);
1623
1624 Status = STATUS_SUCCESS;
1625 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
1626 break;
1627 }
1628
1629 case IRP_MN_QUERY_INTERFACE:
1630 DPRINT("IRP_MN_QUERY_INTERFACE\n");
1631 Status = USBPORT_PdoQueryInterface(FdoDevice, PdoDevice, Irp);
1632 break;
1633
1634 case IRP_MN_QUERY_CAPABILITIES:
1635 DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
1636
1637 DeviceCapabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
1638
1639 RtlCopyMemory(DeviceCapabilities,
1640 &PdoExtension->Capabilities,
1641 sizeof(DEVICE_CAPABILITIES));
1642
1643 Status = STATUS_SUCCESS;
1644 break;
1645
1646 case IRP_MN_QUERY_RESOURCES:
1647 DPRINT("USBPORT_PdoPnP: IRP_MN_QUERY_RESOURCES\n");
1648 break;
1649
1650 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1651 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1652 break;
1653
1654 case IRP_MN_QUERY_DEVICE_TEXT:
1655 DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
1656 break;
1657
1658 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
1659 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1660 break;
1661
1662 case IRP_MN_READ_CONFIG:
1663 DPRINT("IRP_MN_READ_CONFIG\n");
1664 ASSERT(FALSE);
1665 break;
1666
1667 case IRP_MN_WRITE_CONFIG:
1668 DPRINT("IRP_MN_WRITE_CONFIG\n");
1669 ASSERT(FALSE);
1670 break;
1671
1672 case IRP_MN_EJECT:
1673 DPRINT("IRP_MN_EJECT\n");
1674 ASSERT(FALSE);
1675 break;
1676
1677 case IRP_MN_SET_LOCK:
1678 DPRINT("IRP_MN_SET_LOCK\n");
1679 ASSERT(FALSE);
1680 break;
1681
1682 case IRP_MN_QUERY_ID:
1683 {
1684 ULONG IdType;
1685 LONG Length;
1686 WCHAR Buffer[64] = {0};
1687 PVOID Id;
1688
1689 Status = STATUS_SUCCESS;
1690 IdType = IoStack->Parameters.QueryId.IdType;
1691
1692 DPRINT("IRP_MN_QUERY_ID/Type %x\n", IdType);
1693
1694 if (IdType == BusQueryDeviceID)
1695 {
1696 PUSBPORT_REGISTRATION_PACKET Packet;
1697 Packet = &FdoExtension->MiniPortInterface->Packet;
1698
1699 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1700 {
1701 RtlStringCbPrintfW(Buffer,
1702 sizeof(Buffer),
1703 L"USB\\ROOT_HUB20");
1704 }
1705 else
1706 {
1707 RtlStringCbPrintfW(Buffer,
1708 sizeof(Buffer),
1709 L"USB\\ROOT_HUB");
1710 }
1711
1712 Length = (LONG)(wcslen(Buffer) + 1);
1713
1714 Id = ExAllocatePoolWithTag(PagedPool,
1715 Length * sizeof(WCHAR),
1716 USB_PORT_TAG);
1717
1718 if (Id)
1719 {
1720 RtlZeroMemory(Id, Length * sizeof(WCHAR));
1721 RtlStringCbCopyW(Id, Length * sizeof(WCHAR), Buffer);
1722
1723 DPRINT("BusQueryDeviceID - %S, TotalLength - %hu\n",
1724 Id,
1725 Length);
1726 }
1727
1728 Irp->IoStatus.Information = (ULONG_PTR)Id;
1729 break;
1730 }
1731
1732 if (IdType == BusQueryHardwareIDs)
1733 {
1734 Id = USBPORT_GetDeviceHwIds(FdoDevice,
1735 FdoExtension->VendorID,
1736 FdoExtension->DeviceID,
1737 FdoExtension->RevisionID);
1738
1739 Irp->IoStatus.Information = (ULONG_PTR)Id;
1740 break;
1741 }
1742
1743 if (IdType == BusQueryCompatibleIDs ||
1744 IdType == BusQueryInstanceID)
1745 {
1746 Irp->IoStatus.Information = 0;
1747 break;
1748 }
1749
1750 /* IdType == BusQueryDeviceSerialNumber */
1751 Status = Irp->IoStatus.Status;
1752 break;
1753 }
1754
1755 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1756 DPRINT("IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1757 Status = STATUS_SUCCESS;
1758 break;
1759
1760 case IRP_MN_QUERY_BUS_INFORMATION:
1761 DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
1762
1763 /* Allocate buffer for bus information */
1764 BusInformation = ExAllocatePoolWithTag(PagedPool,
1765 sizeof(PNP_BUS_INFORMATION),
1766 USB_PORT_TAG);
1767
1768 if (!BusInformation)
1769 {
1770 /* No memory */
1771 Status = STATUS_INSUFFICIENT_RESOURCES;
1772 break;
1773 }
1774
1775 RtlZeroMemory(BusInformation, sizeof(PNP_BUS_INFORMATION));
1776
1777 /* Copy BUS GUID */
1778 RtlMoveMemory(&BusInformation->BusTypeGuid,
1779 &GUID_BUS_TYPE_USB,
1780 sizeof(GUID));
1781
1782 /* Set bus type */
1783 BusInformation->LegacyBusType = PNPBus;
1784 BusInformation->BusNumber = 0;
1785
1786 Status = STATUS_SUCCESS;
1787 Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
1788 break;
1789
1790 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
1791 DPRINT("IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1792 break;
1793
1794 case IRP_MN_SURPRISE_REMOVAL:
1795 DPRINT("USBPORT_PdoPnP: IRP_MN_SURPRISE_REMOVAL\n");
1796 Status = STATUS_SUCCESS;
1797 break;
1798
1799 default:
1800 DPRINT("unknown IRP_MN_???\n");
1801 break;
1802 }
1803
1804 Irp->IoStatus.Status = Status;
1805 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1806 return Status;
1807 }
1808