1 /* 2 * PROJECT: ReactOS USB Port Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: USBPort power handling 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 VOID 14 NTAPI 15 USBPORT_CompletePdoWaitWake(IN PDEVICE_OBJECT FdoDevice) 16 { 17 PUSBPORT_DEVICE_EXTENSION FdoExtension; 18 PDEVICE_OBJECT PdoDevice; 19 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 20 PIRP Irp; 21 KIRQL OldIrql; 22 23 DPRINT("USBPORT_CompletePdoWaitWake: ... \n"); 24 25 FdoExtension = FdoDevice->DeviceExtension; 26 PdoDevice = FdoExtension->RootHubPdo; 27 PdoExtension = PdoDevice->DeviceExtension; 28 29 KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql); 30 31 Irp = PdoExtension->WakeIrp; 32 33 if (Irp && IoSetCancelRoutine(Irp, NULL)) 34 { 35 PdoExtension->WakeIrp = NULL; 36 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 37 38 DPRINT("USBPORT_CompletePdoWaitWake: Complete Irp - %p\n", Irp); 39 40 Irp->IoStatus.Status = STATUS_SUCCESS; 41 Irp->IoStatus.Information = 0; 42 IoCompleteRequest(Irp, IO_NO_INCREMENT); 43 44 return; 45 } 46 47 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 48 } 49 50 VOID 51 NTAPI 52 USBPORT_HcWakeDpc(IN PRKDPC Dpc, 53 IN PVOID DeferredContext, 54 IN PVOID SystemArgument1, 55 IN PVOID SystemArgument2) 56 { 57 DPRINT("USBPORT_HcWakeDpc: ... \n"); 58 USBPORT_CompletePdoWaitWake((PDEVICE_OBJECT)DeferredContext); 59 } 60 61 VOID 62 NTAPI 63 USBPORT_HcQueueWakeDpc(IN PDEVICE_OBJECT FdoDevice) 64 { 65 PUSBPORT_DEVICE_EXTENSION FdoExtension; 66 67 DPRINT("USBPORT_HcQueueWakeDpc: ... \n"); 68 69 FdoExtension = FdoDevice->DeviceExtension; 70 KeInsertQueueDpc(&FdoExtension->HcWakeDpc, NULL, NULL); 71 } 72 73 VOID 74 NTAPI 75 USBPORT_CompletePendingIdleIrp(IN PDEVICE_OBJECT PdoDevice) 76 { 77 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 78 PDEVICE_OBJECT FdoDevice; 79 PUSBPORT_DEVICE_EXTENSION FdoExtension; 80 PIRP Irp; 81 82 DPRINT("USBPORT_CompletePendingIdleIrp: ... \n"); 83 84 PdoExtension = PdoDevice->DeviceExtension; 85 FdoDevice = PdoExtension->FdoDevice; 86 FdoExtension = FdoDevice->DeviceExtension; 87 88 Irp = IoCsqRemoveNextIrp(&FdoExtension->IdleIoCsq, 0); 89 90 if (Irp) 91 { 92 InterlockedDecrement(&FdoExtension->IdleLockCounter); 93 94 DPRINT("USBPORT_CompletePendingIdleIrp: Complete Irp - %p\n", Irp); 95 96 Irp->IoStatus.Status = STATUS_CANCELLED; 97 Irp->IoStatus.Information = 0; 98 IoCompleteRequest(Irp, IO_NO_INCREMENT); 99 } 100 } 101 102 VOID 103 NTAPI 104 USBPORT_DoSetPowerD0(IN PDEVICE_OBJECT FdoDevice) 105 { 106 DPRINT("USBPORT_DoSetPowerD0: FIXME!\n"); 107 return; 108 } 109 110 VOID 111 NTAPI 112 USBPORT_SuspendController(IN PDEVICE_OBJECT FdoDevice) 113 { 114 PUSBPORT_DEVICE_EXTENSION FdoExtension; 115 PUSBPORT_REGISTRATION_PACKET Packet; 116 117 DPRINT1("USBPORT_SuspendController \n"); 118 119 FdoExtension = FdoDevice->DeviceExtension; 120 Packet = &FdoExtension->MiniPortInterface->Packet; 121 122 FdoExtension->TimerFlags |= USBPORT_TMFLAG_RH_SUSPENDED; 123 124 USBPORT_FlushController(FdoDevice); 125 126 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND) 127 { 128 return; 129 } 130 131 FdoExtension->TimerFlags |= USBPORT_TMFLAG_HC_SUSPENDED; 132 133 if (FdoExtension->MiniPortFlags & USBPORT_MPFLAG_INTERRUPTS_ENABLED) 134 { 135 FdoExtension->MiniPortFlags |= USBPORT_MPFLAG_SUSPENDED; 136 137 USBPORT_Wait(FdoDevice, 10); 138 Packet->SuspendController(FdoExtension->MiniPortExt); 139 } 140 141 FdoExtension->Flags |= USBPORT_FLAG_HC_SUSPEND; 142 } 143 144 NTSTATUS 145 NTAPI 146 USBPORT_ResumeController(IN PDEVICE_OBJECT FdoDevice) 147 { 148 NTSTATUS Status = STATUS_UNSUCCESSFUL; 149 PUSBPORT_DEVICE_EXTENSION FdoExtension; 150 PUSBPORT_REGISTRATION_PACKET Packet; 151 KIRQL OldIrql; 152 MPSTATUS MpStatus; 153 154 DPRINT1("USBPORT_ResumeController: ... \n"); 155 156 FdoExtension = FdoDevice->DeviceExtension; 157 Packet = &FdoExtension->MiniPortInterface->Packet; 158 159 if (!(FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND)) 160 { 161 return Status; 162 } 163 164 KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql); 165 166 FdoExtension->TimerFlags &= ~(USBPORT_TMFLAG_HC_SUSPENDED | 167 USBPORT_TMFLAG_RH_SUSPENDED); 168 169 KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql); 170 171 if (!(FdoExtension->MiniPortFlags & USBPORT_MPFLAG_SUSPENDED)) 172 { 173 FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND; 174 return Status; 175 } 176 177 FdoExtension->MiniPortFlags &= ~USBPORT_MPFLAG_SUSPENDED; 178 179 if (!Packet->ResumeController(FdoExtension->MiniPortExt)) 180 { 181 Status = USBPORT_Wait(FdoDevice, 100); 182 183 FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND; 184 return Status; 185 } 186 187 KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql); 188 FdoExtension->TimerFlags |= (USBPORT_TMFLAG_HC_SUSPENDED | 189 USBPORT_TMFLAG_HC_RESUME); 190 KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql); 191 192 USBPORT_MiniportInterrupts(FdoDevice, FALSE); 193 194 Packet->StopController(FdoExtension->MiniPortExt, 1); 195 196 USBPORT_NukeAllEndpoints(FdoDevice); 197 198 RtlZeroMemory(FdoExtension->MiniPortExt, Packet->MiniPortExtensionSize); 199 200 RtlZeroMemory((PVOID)FdoExtension->UsbPortResources.StartVA, 201 Packet->MiniPortResourcesSize); 202 203 FdoExtension->UsbPortResources.IsChirpHandled = TRUE; 204 205 MpStatus = Packet->StartController(FdoExtension->MiniPortExt, 206 &FdoExtension->UsbPortResources); 207 208 FdoExtension->UsbPortResources.IsChirpHandled = FALSE; 209 210 if (!MpStatus) 211 { 212 USBPORT_MiniportInterrupts(FdoDevice, TRUE); 213 } 214 215 KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql); 216 217 FdoExtension->TimerFlags &= ~(USBPORT_TMFLAG_HC_SUSPENDED | 218 USBPORT_TMFLAG_HC_RESUME | 219 USBPORT_TMFLAG_RH_SUSPENDED); 220 221 KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql); 222 223 Status = USBPORT_Wait(FdoDevice, 100); 224 225 FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND; 226 227 return Status; 228 } 229 230 NTSTATUS 231 NTAPI 232 USBPORT_PdoDevicePowerState(IN PDEVICE_OBJECT PdoDevice, 233 IN PIRP Irp) 234 { 235 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 236 PDEVICE_OBJECT FdoDevice; 237 PUSBPORT_DEVICE_EXTENSION FdoExtension; 238 PIO_STACK_LOCATION IoStack; 239 NTSTATUS Status = STATUS_SUCCESS; 240 POWER_STATE State; 241 242 PdoExtension = PdoDevice->DeviceExtension; 243 FdoDevice = PdoExtension->FdoDevice; 244 FdoExtension = FdoDevice->DeviceExtension; 245 IoStack = IoGetCurrentIrpStackLocation(Irp); 246 247 State = IoStack->Parameters.Power.State; 248 249 DPRINT1("USBPORT_PdoDevicePowerState: Irp - %p, State - %x\n", 250 Irp, 251 State.DeviceState); 252 253 if (State.DeviceState == PowerDeviceD0) 254 { 255 if (FdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0) 256 { 257 // FIXME FdoExtension->Flags 258 while (FdoExtension->SetPowerLockCounter) 259 { 260 USBPORT_Wait(FdoDevice, 10); 261 } 262 263 USBPORT_ResumeController(FdoDevice); 264 265 PdoExtension->CommonExtension.DevicePowerState = PowerDeviceD0; 266 267 USBPORT_CompletePdoWaitWake(FdoDevice); 268 USBPORT_CompletePendingIdleIrp(PdoDevice); 269 } 270 else 271 { 272 DPRINT1("USBPORT_PdoDevicePowerState: FdoExtension->Flags - %lx\n", 273 FdoExtension->Flags); 274 275 DbgBreakPoint(); 276 Status = STATUS_UNSUCCESSFUL; 277 } 278 } 279 else if (State.DeviceState == PowerDeviceD1 || 280 State.DeviceState == PowerDeviceD2 || 281 State.DeviceState == PowerDeviceD3) 282 { 283 FdoExtension->TimerFlags |= USBPORT_TMFLAG_WAKE; 284 USBPORT_SuspendController(FdoDevice); 285 PdoExtension->CommonExtension.DevicePowerState = State.DeviceState; 286 } 287 288 return Status; 289 } 290 291 VOID 292 NTAPI 293 USBPORT_CancelPendingWakeIrp(IN PDEVICE_OBJECT PdoDevice, 294 IN PIRP Irp) 295 { 296 PUSBPORT_DEVICE_EXTENSION FdoExtension; 297 KIRQL OldIrql; 298 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 299 300 DPRINT("USBPORT_CancelPendingWakeIrp: ... \n"); 301 302 IoReleaseCancelSpinLock(Irp->CancelIrql); 303 PdoExtension = PdoDevice->DeviceExtension; 304 FdoExtension = PdoExtension->FdoDevice->DeviceExtension; 305 306 KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql); 307 308 if (PdoExtension->WakeIrp == Irp) 309 { 310 PdoExtension->WakeIrp = NULL; 311 } 312 313 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 314 315 Irp->IoStatus.Status = STATUS_CANCELLED; 316 Irp->IoStatus.Information = 0; 317 IoCompleteRequest(Irp, IO_NO_INCREMENT); 318 } 319 320 NTSTATUS 321 NTAPI 322 USBPORT_PdoPower(IN PDEVICE_OBJECT PdoDevice, 323 IN PIRP Irp) 324 { 325 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 326 PDEVICE_OBJECT FdoDevice; 327 PIO_STACK_LOCATION IoStack; 328 PUSBPORT_DEVICE_EXTENSION FdoExtension; 329 NTSTATUS Status; 330 KIRQL OldIrql; 331 332 DPRINT("USBPORT_PdoPower: Irp - %p\n", Irp); 333 334 PdoExtension = PdoDevice->DeviceExtension; 335 FdoDevice = PdoExtension->FdoDevice; 336 FdoExtension = FdoDevice->DeviceExtension; 337 IoStack = IoGetCurrentIrpStackLocation(Irp); 338 339 Status = Irp->IoStatus.Status; 340 341 switch (IoStack->MinorFunction) 342 { 343 case IRP_MN_WAIT_WAKE: 344 DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE\n"); 345 346 if (!(FdoExtension->Flags & USBPORT_FLAG_HC_STARTED)) 347 { 348 /* The device does not support wake-up */ 349 Status = STATUS_NOT_SUPPORTED; 350 break; 351 } 352 353 KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql); 354 355 IoSetCancelRoutine(Irp, USBPORT_CancelPendingWakeIrp); 356 357 /* Check if the IRP has been cancelled */ 358 if (Irp->Cancel) 359 { 360 if (IoSetCancelRoutine(Irp, NULL)) 361 { 362 /* IRP has been cancelled, release cancel spinlock */ 363 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 364 365 DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - STATUS_CANCELLED\n"); 366 367 /* IRP is cancelled */ 368 Status = STATUS_CANCELLED; 369 break; 370 } 371 } 372 373 if (!PdoExtension->WakeIrp) 374 { 375 /* The driver received the IRP 376 and is waiting for the device to signal wake-up. */ 377 378 DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - No WakeIrp\n"); 379 380 IoMarkIrpPending(Irp); 381 PdoExtension->WakeIrp = Irp; 382 383 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 384 return STATUS_PENDING; 385 } 386 else 387 { 388 /* An IRP_MN_WAIT_WAKE request is already pending and must be 389 completed or canceled before another IRP_MN_WAIT_WAKE request 390 can be issued. */ 391 392 if (IoSetCancelRoutine(Irp, NULL)) 393 { 394 DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - STATUS_DEVICE_BUSY\n"); 395 396 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 397 PoStartNextPowerIrp(Irp); 398 Status = STATUS_DEVICE_BUSY; 399 break; 400 } 401 else 402 { 403 ASSERT(FALSE); 404 KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql); 405 return Status; 406 } 407 } 408 409 case IRP_MN_POWER_SEQUENCE: 410 DPRINT("USBPORT_PdoPower: IRP_MN_POWER_SEQUENCE\n"); 411 PoStartNextPowerIrp(Irp); 412 break; 413 414 case IRP_MN_SET_POWER: 415 DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER\n"); 416 417 if (IoStack->Parameters.Power.Type == DevicePowerState) 418 { 419 DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER/DevicePowerState\n"); 420 Status = USBPORT_PdoDevicePowerState(PdoDevice, Irp); 421 PoStartNextPowerIrp(Irp); 422 break; 423 } 424 425 DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER/SystemPowerState \n"); 426 427 if (IoStack->Parameters.Power.State.SystemState == PowerSystemWorking) 428 { 429 FdoExtension->TimerFlags |= USBPORT_TMFLAG_WAKE; 430 } 431 else 432 { 433 FdoExtension->TimerFlags &= ~USBPORT_TMFLAG_WAKE; 434 } 435 436 Status = STATUS_SUCCESS; 437 438 PoStartNextPowerIrp(Irp); 439 break; 440 441 case IRP_MN_QUERY_POWER: 442 DPRINT("USBPORT_PdoPower: IRP_MN_QUERY_POWER\n"); 443 Status = STATUS_SUCCESS; 444 PoStartNextPowerIrp(Irp); 445 break; 446 447 default: 448 DPRINT1("USBPORT_PdoPower: unknown IRP_MN_POWER!\n"); 449 PoStartNextPowerIrp(Irp); 450 break; 451 } 452 453 Irp->IoStatus.Status = Status; 454 Irp->IoStatus.Information = 0; 455 IoCompleteRequest(Irp, IO_NO_INCREMENT); 456 457 return Status; 458 } 459 460 NTSTATUS 461 NTAPI 462 USBPORT_HcWake(IN PDEVICE_OBJECT FdoDevice, 463 IN PIRP Irp) 464 { 465 DPRINT1("USBPORT_HcWake: UNIMPLEMENTED. FIXME. \n"); 466 return STATUS_SUCCESS; 467 } 468 469 NTSTATUS 470 NTAPI 471 USBPORT_DevicePowerState(IN PDEVICE_OBJECT FdoDevice, 472 IN PIRP Irp) 473 { 474 DPRINT1("USBPORT_DevicePowerState: UNIMPLEMENTED. FIXME. \n"); 475 return STATUS_SUCCESS; 476 } 477 478 NTSTATUS 479 NTAPI 480 USBPORT_SystemPowerState(IN PDEVICE_OBJECT FdoDevice, 481 IN PIRP Irp) 482 { 483 DPRINT1("USBPORT_SystemPowerState: UNIMPLEMENTED. FIXME. \n"); 484 return STATUS_SUCCESS; 485 } 486 487 NTSTATUS 488 NTAPI 489 USBPORT_FdoPower(IN PDEVICE_OBJECT FdoDevice, 490 IN PIRP Irp) 491 { 492 PUSBPORT_DEVICE_EXTENSION FdoExtension; 493 PIO_STACK_LOCATION IoStack; 494 NTSTATUS Status; 495 496 DPRINT("USBPORT_FdoPower: ... \n"); 497 498 FdoExtension = FdoDevice->DeviceExtension; 499 IoStack = IoGetCurrentIrpStackLocation(Irp); 500 501 switch (IoStack->MinorFunction) 502 { 503 case IRP_MN_WAIT_WAKE: 504 DPRINT("USBPORT_FdoPower: IRP_MN_WAIT_WAKE\n"); 505 Status = USBPORT_HcWake(FdoDevice, Irp); 506 return Status; 507 508 case IRP_MN_POWER_SEQUENCE: 509 DPRINT("USBPORT_FdoPower: IRP_MN_POWER_SEQUENCE\n"); 510 break; 511 512 case IRP_MN_SET_POWER: 513 DPRINT("USBPORT_FdoPower: IRP_MN_SET_POWER\n"); 514 if (IoStack->Parameters.Power.Type == DevicePowerState) 515 { 516 Status = USBPORT_DevicePowerState(FdoDevice, Irp); 517 } 518 else 519 { 520 Status = USBPORT_SystemPowerState(FdoDevice, Irp); 521 } 522 523 if (Status != STATUS_PENDING) 524 break; 525 526 return Status; 527 528 case IRP_MN_QUERY_POWER: 529 DPRINT("USBPORT_FdoPower: IRP_MN_QUERY_POWER\n"); 530 Irp->IoStatus.Status = STATUS_SUCCESS; 531 break; 532 533 default: 534 DPRINT1("USBPORT_FdoPower: unknown IRP_MN_POWER!\n"); 535 break; 536 } 537 538 IoCopyCurrentIrpStackLocationToNext(Irp); 539 PoStartNextPowerIrp(Irp); 540 return PoCallDriver(FdoExtension->CommonExtension.LowerDevice, Irp); 541 } 542 543 VOID 544 NTAPI 545 USBPORT_DoIdleNotificationCallback(IN PVOID Context) 546 { 547 PIO_STACK_LOCATION IoStack; 548 PDEVICE_OBJECT FdoDevice; 549 PUSBPORT_DEVICE_EXTENSION FdoExtension; 550 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 551 PIRP NextIrp; 552 LARGE_INTEGER CurrentTime = {{0, 0}}; 553 PTIMER_WORK_QUEUE_ITEM IdleQueueItem; 554 PDEVICE_OBJECT PdoDevice; 555 PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo; 556 KIRQL OldIrql; 557 558 DPRINT("USBPORT_DoIdleNotificationCallback \n"); 559 560 IdleQueueItem = Context; 561 562 FdoDevice = IdleQueueItem->FdoDevice; 563 FdoExtension = FdoDevice->DeviceExtension; 564 PdoDevice = FdoExtension->RootHubPdo; 565 PdoExtension = PdoDevice->DeviceExtension; 566 567 KeQuerySystemTime(&CurrentTime); 568 569 if ((FdoExtension->IdleTime.QuadPart == 0) || 570 (((CurrentTime.QuadPart - FdoExtension->IdleTime.QuadPart) / 10000) >= 500)) 571 { 572 if (PdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0 && 573 FdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0) 574 { 575 NextIrp = IoCsqRemoveNextIrp(&FdoExtension->IdleIoCsq, NULL); 576 577 if (NextIrp) 578 { 579 IoStack = IoGetCurrentIrpStackLocation(NextIrp); 580 IdleCallbackInfo = IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 581 582 if (IdleCallbackInfo && IdleCallbackInfo->IdleCallback) 583 { 584 IdleCallbackInfo->IdleCallback(IdleCallbackInfo->IdleContext); 585 } 586 587 if (NextIrp->Cancel) 588 { 589 InterlockedDecrement(&FdoExtension->IdleLockCounter); 590 591 NextIrp->IoStatus.Status = STATUS_CANCELLED; 592 NextIrp->IoStatus.Information = 0; 593 IoCompleteRequest(NextIrp, IO_NO_INCREMENT); 594 } 595 else 596 { 597 IoCsqInsertIrp(&FdoExtension->IdleIoCsq, NextIrp, NULL); 598 } 599 } 600 } 601 } 602 603 KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql); 604 FdoExtension->TimerFlags &= ~USBPORT_TMFLAG_IDLE_QUEUEITEM_ON; 605 KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql); 606 607 ExFreePoolWithTag(IdleQueueItem, USB_PORT_TAG); 608 } 609 610 NTSTATUS 611 NTAPI 612 USBPORT_IdleNotification(IN PDEVICE_OBJECT PdoDevice, 613 IN PIRP Irp) 614 { 615 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 616 PDEVICE_OBJECT FdoDevice; 617 PUSBPORT_DEVICE_EXTENSION FdoExtension; 618 LONG LockCounter; 619 NTSTATUS Status = STATUS_PENDING; 620 621 DPRINT("USBPORT_IdleNotification: Irp - %p\n", Irp); 622 623 PdoExtension = PdoDevice->DeviceExtension; 624 FdoDevice = PdoExtension->FdoDevice; 625 FdoExtension = FdoDevice->DeviceExtension; 626 627 LockCounter = InterlockedIncrement(&FdoExtension->IdleLockCounter); 628 629 if (LockCounter != 0) 630 { 631 if (Status != STATUS_PENDING) 632 { 633 InterlockedDecrement(&FdoExtension->IdleLockCounter); 634 635 Irp->IoStatus.Status = Status; 636 Irp->IoStatus.Information = 0; 637 IoCompleteRequest(Irp, IO_NO_INCREMENT); 638 639 return Status; 640 } 641 642 Status = STATUS_DEVICE_BUSY; 643 } 644 645 if (Status != STATUS_PENDING) 646 { 647 InterlockedDecrement(&FdoExtension->IdleLockCounter); 648 649 Irp->IoStatus.Status = Status; 650 Irp->IoStatus.Information = 0; 651 IoCompleteRequest(Irp, IO_NO_INCREMENT); 652 653 return Status; 654 } 655 656 Irp->IoStatus.Status = STATUS_PENDING; 657 IoMarkIrpPending(Irp); 658 659 KeQuerySystemTime(&FdoExtension->IdleTime); 660 661 IoCsqInsertIrp(&FdoExtension->IdleIoCsq, Irp, 0); 662 663 return Status; 664 } 665 666 VOID 667 NTAPI 668 USBPORT_AdjustDeviceCapabilities(IN PDEVICE_OBJECT FdoDevice, 669 IN PDEVICE_OBJECT PdoDevice) 670 { 671 PUSBPORT_DEVICE_EXTENSION FdoExtension; 672 PUSBPORT_RHDEVICE_EXTENSION PdoExtension; 673 PDEVICE_CAPABILITIES Capabilities; 674 675 DPRINT("USBPORT_AdjustDeviceCapabilities: ... \n"); 676 677 FdoExtension = FdoDevice->DeviceExtension; 678 PdoExtension = PdoDevice->DeviceExtension; 679 Capabilities = &PdoExtension->Capabilities; 680 681 RtlCopyMemory(Capabilities, 682 &FdoExtension->Capabilities, 683 sizeof(DEVICE_CAPABILITIES)); 684 685 Capabilities->DeviceD1 = FALSE; 686 Capabilities->DeviceD2 = TRUE; 687 688 Capabilities->Removable = FALSE; 689 Capabilities->UniqueID = FALSE; 690 691 Capabilities->WakeFromD0 = TRUE; 692 Capabilities->WakeFromD1 = FALSE; 693 Capabilities->WakeFromD2 = TRUE; 694 Capabilities->WakeFromD3 = FALSE; 695 696 Capabilities->Address = 0; 697 Capabilities->UINumber = 0; 698 699 if (Capabilities->SystemWake == PowerSystemUnspecified) 700 Capabilities->SystemWake = PowerSystemWorking; 701 702 Capabilities->DeviceWake = PowerDeviceD2; 703 704 Capabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3; 705 Capabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3; 706 Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 707 Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3; 708 } 709