[NTFS] - Add some fixes and improvements to attribute.c from CR-123:
[reactos.git] / drivers / usb / usbport / power.c
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 }