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