ReactOS 0.4.15-dev-7924-g5949c20
fbtdev.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

NTSTATUS NTAPI FreeBT_DispatchCreate (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI FreeBT_DispatchClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI FreeBT_DispatchDevCtrl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI FreeBT_ResetPipe (IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeInfo)
 
NTSTATUS NTAPI FreeBT_ResetDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI FreeBT_GetPortStatus (IN PDEVICE_OBJECT DeviceObject, IN PULONG PortStatus)
 
NTSTATUS NTAPI FreeBT_ResetParentPort (IN IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI SubmitIdleRequestIrp (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI IdleNotificationCallback (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI IdleNotificationRequestComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI CancelSelectSuspend (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI PoIrpCompletionFunc (IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
 
VOID NTAPI PoIrpAsyncCompletionFunc (IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
 
VOID NTAPI WWIrpCompletionFunc (IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
 

Function Documentation

◆ CancelSelectSuspend()

VOID NTAPI CancelSelectSuspend ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 1093 of file fbtdev.c.

1094{
1095 PIRP irp;
1096 KIRQL oldIrql;
1097
1098 FreeBT_DbgPrint(3, ("CancelSelectSuspend: Entered\n"));
1099
1100 irp = NULL;
1101
1102 KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
1103
1104 if(!CanDeviceSuspend(DeviceExtension))
1105 {
1106 FreeBT_DbgPrint(3, ("Device is not idle\n"));
1107 irp = (PIRP) InterlockedExchangePointer((PVOID*)&DeviceExtension->PendingIdleIrp, NULL);
1108
1109 }
1110
1111 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
1112
1113 // since we have a valid Irp ptr,
1114 // we can call IoCancelIrp on it,
1115 // without the fear of the irp
1116 // being freed underneath us.
1117 if(irp)
1118 {
1119 // This routine has the irp pointer.
1120 // It is safe to call IoCancelIrp because we know that
1121 // the compleiton routine will not free this irp unless...
1122 //
1123 //
1124 if(IoCancelIrp(irp))
1125 {
1126 FreeBT_DbgPrint(3, ("IoCancelIrp returns TRUE\n"));
1127
1128 }
1129
1130 else
1131 {
1132 FreeBT_DbgPrint(3, ("IoCancelIrp returns FALSE\n"));
1133
1134 }
1135
1136 // ....we decrement the FreeIdleIrpCount from 2 to 1.
1137 // if completion routine runs ahead of us, then this routine
1138 // decrements the FreeIdleIrpCount from 1 to 0 and hence shall
1139 // free the irp.
1140 if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount))
1141 {
1142 FreeBT_DbgPrint(3, ("CancelSelectSuspend frees the irp\n"));
1143 IoFreeIrp(irp);
1144 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
1145
1146 }
1147
1148 }
1149
1150 FreeBT_DbgPrint(3, ("CancelSelectSuspend: Leaving\n"));
1151
1152 return;
1153
1154}
struct _IRP * PIRP
#define InterlockedDecrement
Definition: armddk.h:52
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN NTAPI CanDeviceSuspend(IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1640
#define FreeBT_DbgPrint(level, _x_)
Definition: fbtusb.h:55
FxIrp * irp
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by FreeBT_DispatchCreate(), and FreeBT_DispatchPnP().

◆ FreeBT_DispatchClose()

NTSTATUS NTAPI FreeBT_DispatchClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 102 of file fbtdev.c.

103{
104 NTSTATUS ntStatus;
105 PFILE_OBJECT fileObject;
106 PDEVICE_EXTENSION deviceExtension;
107 PIO_STACK_LOCATION irpStack;
108 //PFREEBT_PIPE_CONTEXT pipeContext;
109 //PUSBD_PIPE_INFORMATION pipeInformation;
110
111 PAGED_CODE();
112
114 fileObject = irpStack->FileObject;
115 //pipeContext = NULL;
116 //pipeInformation = NULL;
117 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
118
119 FreeBT_DbgPrint(3, ("FreeBT_DispatchClose: Entered\n"));
120
121 ntStatus = STATUS_SUCCESS;
122 Irp->IoStatus.Status = ntStatus;
123 Irp->IoStatus.Information = 0;
125
126 InterlockedDecrement(&deviceExtension->OpenHandleCount);
127
128 FreeBT_DbgPrint(3, ("FreeBT_DispatchClose: Leaving\n"));
129
130 return ntStatus;
131
132}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_SUCCESS
Definition: shellext.h:65
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by DriverEntry().

◆ FreeBT_DispatchCreate()

NTSTATUS NTAPI FreeBT_DispatchCreate ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 23 of file fbtdev.c.

24{
25 //ULONG i;
26 NTSTATUS ntStatus;
27 PFILE_OBJECT fileObject;
28 PDEVICE_EXTENSION deviceExtension;
29 PIO_STACK_LOCATION irpStack;
30 //PFREEBT_PIPE_CONTEXT pipeContext;
32
33 PAGED_CODE();
34
35 FreeBT_DbgPrint(3, ("FreeBT_DispatchCreate: Entered\n"));
36
38 fileObject = irpStack->FileObject;
39 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
40
41 if (deviceExtension->DeviceState != Working)
42 {
44 goto FreeBT_DispatchCreate_Exit;
45
46 }
47
48 if (deviceExtension->UsbInterface)
49 {
50 interface = deviceExtension->UsbInterface;
51
52 }
53
54 else
55 {
56 FreeBT_DbgPrint(1, ("UsbInterface not found\n"));
58 goto FreeBT_DispatchCreate_Exit;
59
60 }
61
62 if (fileObject)
63 {
64 fileObject->FsContext = NULL;
65 }
66
67 else
68 {
69 ntStatus = STATUS_INVALID_PARAMETER;
70 goto FreeBT_DispatchCreate_Exit;
71
72 }
73
74 if (deviceExtension->OpenHandleCount>0)
75 {
76 ntStatus = STATUS_ACCESS_VIOLATION;
77 goto FreeBT_DispatchCreate_Exit;
78
79 }
80
81 // opening a device as opposed to pipe.
82 ntStatus = STATUS_SUCCESS;
83
84 InterlockedIncrement(&deviceExtension->OpenHandleCount);
85
86 // the device is idle if it has no open handles or pending PnP Irps
87 // since we just received an open handle request, cancel idle req.
88 if (deviceExtension->SSEnable)
89 CancelSelectSuspend(deviceExtension);
90
91FreeBT_DispatchCreate_Exit:
92 Irp->IoStatus.Status = ntStatus;
93 Irp->IoStatus.Information = 0;
95
96 FreeBT_DbgPrint(3, ("FreeBT_DispatchCreate: Leaving\n"));
97 return ntStatus;
98
99}
#define InterlockedIncrement
Definition: armddk.h:53
#define interface
Definition: basetyps.h:61
VOID NTAPI CancelSelectSuspend(IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtdev.c:1093
@ Working
Definition: fbtusb.h:82
if(dx< 0)
Definition: linetemp.h:194
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
_In_ WDFUSBINTERFACE UsbInterface
Definition: wdfusb.h:2276

Referenced by DriverEntry().

◆ FreeBT_DispatchDevCtrl()

NTSTATUS NTAPI FreeBT_DispatchDevCtrl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 412 of file fbtdev.c.

413{
414 ULONG code;
415 PVOID ioBuffer;
416 ULONG inputBufferLength;
417 ULONG outputBufferLength;
418 ULONG info;
419 NTSTATUS ntStatus;
420 PDEVICE_EXTENSION deviceExtension;
421 PIO_STACK_LOCATION irpStack;
422
423 info = 0;
425 code = irpStack->Parameters.DeviceIoControl.IoControlCode;
426 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
427
428 ioBuffer = Irp->AssociatedIrp.SystemBuffer;
429 inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
430 outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
431
432 if (deviceExtension->DeviceState != Working)
433 {
434 FreeBT_DbgPrint(1, ("FBTUSB: Invalid device state\n"));
436 goto FreeBT_DispatchDevCtrlExit;
437
438 }
439
440 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchDevCtrl::"));
441
442 // Make sure that any selective suspend request has been completed.
443 if (deviceExtension->SSEnable)
444 {
445 FreeBT_DbgPrint(3, ("Waiting on the IdleReqPendEvent\n"));
446 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
447 Executive,
449 FALSE,
450 NULL);
451
452 }
453
454 switch(code)
455 {
457 FreeBT_DbgPrint(3, ("FBTUSB: IOCTL_FREEBT_HCI_SEND_CMD received\n"));
458 if (inputBufferLength<FBT_HCI_CMD_MIN_SIZE)
459 {
460 ntStatus = STATUS_BUFFER_TOO_SMALL;
461 FreeBT_DbgPrint(3, ("FBTUSB: IOCTL_FREEBT_HCI_SEND_CMD: Buffer too small\n"));
462 goto FreeBT_DispatchDevCtrlExit;
463
464 }
465
466 if (inputBufferLength>FBT_HCI_CMD_MAX_SIZE)
467 {
469 FreeBT_DbgPrint(3, ("FBTUSB: IOCTL_FREEBT_HCI_SEND_CMD: Buffer too long\n"));
470 goto FreeBT_DispatchDevCtrlExit;
471
472 }
473
474 return FreeBT_SendHCICommand(DeviceObject, Irp, ioBuffer, inputBufferLength);
475 break;
476
478 FreeBT_DbgPrint(3, ("FBTUSB: IOCTL_FREEBT_HCI_GET_EVENT received\n"));
479 if (outputBufferLength<FBT_HCI_EVENT_MAX_SIZE)
480 {
481 ntStatus = STATUS_BUFFER_TOO_SMALL;
482 FreeBT_DbgPrint(3, ("FBTUSB: IOCTL_FREEBT_HCI_GET_EVENT: Buffer too small\n"));
483 goto FreeBT_DispatchDevCtrlExit;
484
485 }
486
487 return FreeBT_GetHCIEvent(DeviceObject, Irp, ioBuffer, outputBufferLength);
488 break;
489
490 default:
491 FreeBT_DbgPrint(3, ("FBTUSB: Invalid IOCTL 0x%08x received\n", code));
493 break;
494
495 }
496
497FreeBT_DispatchDevCtrlExit:
498 Irp->IoStatus.Information = 0;
499 Irp->IoStatus.Status = ntStatus;
501
502 return ntStatus;
503}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define FBT_HCI_EVENT_MAX_SIZE
Definition: fbtHciSizes.h:8
#define FBT_HCI_CMD_MIN_SIZE
Definition: fbtHciSizes.h:5
#define FBT_HCI_CMD_MAX_SIZE
Definition: fbtHciSizes.h:6
NTSTATUS NTAPI FreeBT_SendHCICommand(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID IoBuffer, IN ULONG InputBufferLength)
Definition: fbtdev.c:156
NTSTATUS NTAPI FreeBT_GetHCIEvent(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID IoBuffer, IN ULONG InputBufferLength)
Definition: fbtdev.c:310
#define IOCTL_FREEBT_HCI_GET_EVENT
Definition: fbtusr.h:36
#define IOCTL_FREEBT_HCI_SEND_CMD
Definition: fbtusr.h:31
#define KernelMode
Definition: asm.h:34
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
union _IO_STACK_LOCATION::@1564 Parameters
Definition: inflate.c:139
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
@ Executive
Definition: ketypes.h:415

Referenced by DriverEntry().

◆ FreeBT_GetPortStatus()

NTSTATUS NTAPI FreeBT_GetPortStatus ( IN PDEVICE_OBJECT  DeviceObject,
IN PULONG  PortStatus 
)

◆ FreeBT_ResetDevice()

NTSTATUS NTAPI FreeBT_ResetDevice ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 546 of file fbtdev.c.

547{
548 NTSTATUS ntStatus;
549 ULONG portStatus;
550
551 FreeBT_DbgPrint(3, ("FreeBT_ResetDevice: Entered\n"));
552
553 ntStatus = FreeBT_GetPortStatus(DeviceObject, &portStatus);
554
555 if ( (NT_SUCCESS(ntStatus)) && (!(portStatus & USBD_PORT_ENABLED)) && (portStatus & USBD_PORT_CONNECTED))
557
558 FreeBT_DbgPrint(3, ("FreeBT_ResetDevice: Leaving\n"));
559
560 return ntStatus;
561
562}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI FreeBT_GetPortStatus(IN PDEVICE_OBJECT DeviceObject, IN OUT PULONG PortStatus)
Definition: fbtdev.c:565
NTSTATUS NTAPI FreeBT_ResetParentPort(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtdev.c:617
#define USBD_PORT_ENABLED
Definition: usbioctl.h:41
#define USBD_PORT_CONNECTED
Definition: usbioctl.h:42

Referenced by FreeBT_DispatchRead(), FreeBT_DispatchWrite(), FreeBT_GetHCIEvent(), and FreeBT_SendHCICommand().

◆ FreeBT_ResetParentPort()

NTSTATUS NTAPI FreeBT_ResetParentPort ( IN IN PDEVICE_OBJECT  DeviceObject)

◆ FreeBT_ResetPipe()

NTSTATUS NTAPI FreeBT_ResetPipe ( IN PDEVICE_OBJECT  DeviceObject,
IN USBD_PIPE_HANDLE  PipeInfo 
)

Definition at line 506 of file fbtdev.c.

507{
508 PURB urb;
509 NTSTATUS ntStatus;
510 PDEVICE_EXTENSION deviceExtension;
511
512 urb = NULL;
513 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
514
515 urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
516 if (urb)
517 {
518 urb->UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST);
519 urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
520 urb->UrbPipeRequest.PipeHandle = PipeHandle;
521
522 ntStatus = CallUSBD(DeviceObject, urb);
523
524 ExFreePool(urb);
525
526 }
527
528 else
530
531 if(NT_SUCCESS(ntStatus))
532 {
533 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ResetPipe - success\n"));
534 ntStatus = STATUS_SUCCESS;
535
536 }
537
538 else
539 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_ResetPipe - failed\n"));
540
541 return ntStatus;
542
543}
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
NTSTATUS NTAPI CallUSBD(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: fbtpnp.c:701
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
unsigned short USHORT
Definition: pedump.c:61
Definition: usb.h:529
struct _URB_PIPE_REQUEST UrbPipeRequest
Definition: usb.h:534
struct _URB_HEADER UrbHeader
Definition: usb.h:531
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define URB_FUNCTION_RESET_PIPE
Definition: usb.h:151

Referenced by FreeBT_DispatchRead(), FreeBT_DispatchWrite(), and FreeBT_GetHCIEvent().

◆ IdleNotificationCallback()

VOID NTAPI IdleNotificationCallback ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 886 of file fbtdev.c.

887{
888 NTSTATUS ntStatus;
889 POWER_STATE powerState;
890 KEVENT irpCompletionEvent;
891 PIRP_COMPLETION_CONTEXT irpContext;
892
893 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationCallback: Entered\n"));
894
895 //
896 // Dont idle, if the device was just disconnected or being stopped
897 // i.e. return for the following DeviceState(s)
898 // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, Removed
899 //
900
901 if(DeviceExtension->DeviceState != Working) {
902
903 return;
904 }
905
906 //
907 // If there is not already a WW IRP pending, submit one now
908 //
909 if(DeviceExtension->WaitWakeEnable) {
910
911 IssueWaitWake(DeviceExtension);
912 }
913
914
915 //
916 // power down the device
917 //
918
919 irpContext = (PIRP_COMPLETION_CONTEXT)
921 sizeof(IRP_COMPLETION_CONTEXT));
922
923 if(!irpContext) {
924
925 FreeBT_DbgPrint(1, ("FBTUSB: IdleNotificationCallback: Failed to alloc memory for irpContext\n"));
927 }
928 else {
929
930 //
931 // increment the count. In the HoldIoRequestWorkerRoutine, the
932 // count is decremented twice (one for the system Irp and the
933 // other for the device Irp. An increment here compensates for
934 // the sytem irp..The decrement corresponding to this increment
935 // is in the completion function
936 //
937
938 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationCallback::"));
939 FreeBT_IoIncrement(DeviceExtension);
940
941 powerState.DeviceState = (DEVICE_POWER_STATE) DeviceExtension->PowerDownLevel;
942
943 KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE);
944
945 irpContext->DeviceExtension = DeviceExtension;
946 irpContext->Event = &irpCompletionEvent;
947
948 ntStatus = PoRequestPowerIrp(
949 DeviceExtension->PhysicalDeviceObject,
951 powerState,
953 irpContext,
954 NULL);
955
956 if(STATUS_PENDING == ntStatus) {
957
958 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationCallback::"
959 "waiting for the power irp to complete\n"));
960
961 KeWaitForSingleObject(&irpCompletionEvent,
962 Executive,
964 FALSE,
965 NULL);
966 }
967 }
968
969 if(!NT_SUCCESS(ntStatus)) {
970
971 if(irpContext) {
972
973 ExFreePool(irpContext);
974 }
975 }
976
977 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationCallback: Leaving\n"));
978}
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI PoIrpCompletionFunc(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
Definition: fbtdev.c:1156
LONG NTAPI FreeBT_IoIncrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1722
NTSTATUS NTAPI IssueWaitWake(IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpwr.c:887
struct _IRP_COMPLETION_CONTEXT * PIRP_COMPLETION_CONTEXT
@ NotificationEvent
NTSTATUS NTAPI PoRequestPowerIrp(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction, _In_ POWER_STATE PowerState, _In_opt_ PREQUEST_POWER_COMPLETE CompletionFunction, _In_opt_ __drv_aliasesMem PVOID Context, _Outptr_opt_ PIRP *pIrp)
Definition: power.c:659
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
#define STATUS_PENDING
Definition: ntstatus.h:82
PDEVICE_EXTENSION DeviceExtension
Definition: fbtusb.h:254
DEVICE_POWER_STATE DeviceState
Definition: ntpoapi.h:58
#define IRP_MN_SET_POWER
REQUEST_POWER_COMPLETE * PREQUEST_POWER_COMPLETE
Definition: potypes.h:469

Referenced by SubmitIdleRequestIrp().

◆ IdleNotificationRequestComplete()

NTSTATUS NTAPI IdleNotificationRequestComplete ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PDEVICE_EXTENSION  DeviceExtension 
)

Definition at line 981 of file fbtdev.c.

982{
983 NTSTATUS ntStatus;
984 POWER_STATE powerState;
985 KIRQL oldIrql;
986 LARGE_INTEGER dueTime;
987 PIRP idleIrp;
988 PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;
989
990 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationRequestCompete: Entered\n"));
991
992 idleIrp = NULL;
993
994 ntStatus = Irp->IoStatus.Status;
995 if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED)
996 {
997 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationRequestCompete: Idle irp completes with error::"));
998 switch(ntStatus)
999 {
1001 FreeBT_DbgPrint(3, ("STATUS_INVALID_DEVICE_REQUEST\n"));
1002 break;
1003
1004 case STATUS_CANCELLED:
1005 FreeBT_DbgPrint(3, ("STATUS_CANCELLED\n"));
1006 break;
1007
1008 case STATUS_DEVICE_BUSY:
1009 FreeBT_DbgPrint(3, ("STATUS_DEVICE_BUSY\n"));
1010 break;
1011
1013 FreeBT_DbgPrint(3, ("STATUS_POWER_STATE_INVALID\n"));
1014 goto IdleNotificationRequestComplete_Exit;
1015
1016 default:
1017 FreeBT_DbgPrint(3, ("default: status = %X\n", ntStatus));
1018 break;
1019
1020 }
1021
1022 // if in error, issue a SetD0
1023 FreeBT_DbgPrint(3, ("FBTUSB: IdleNotificationRequestComplete::"));
1024 FreeBT_IoIncrement(DeviceExtension);
1025
1026 powerState.DeviceState = PowerDeviceD0;
1027 ntStatus = PoRequestPowerIrp(
1028 DeviceExtension->PhysicalDeviceObject,
1030 powerState,
1032 DeviceExtension,
1033 NULL);
1034
1035 if(!NT_SUCCESS(ntStatus))
1036 FreeBT_DbgPrint(1, ("PoRequestPowerIrp failed\n"));
1037
1038 }
1039
1040IdleNotificationRequestComplete_Exit:
1041 KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
1042 idleCallbackInfo = DeviceExtension->IdleCallbackInfo;
1043 DeviceExtension->IdleCallbackInfo = NULL;
1044
1045 idleIrp = (PIRP) InterlockedExchangePointer((PVOID*)&DeviceExtension->PendingIdleIrp, NULL);
1046 InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
1047
1048 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
1049
1050 if(idleCallbackInfo)
1051 ExFreePool(idleCallbackInfo);
1052
1053 // Since the irp was created using IoAllocateIrp,
1054 // the Irp needs to be freed using IoFreeIrp.
1055 // Also return STATUS_MORE_PROCESSING_REQUIRED so that
1056 // the kernel does not reference this in the near future.
1057 if(idleIrp)
1058 {
1059 FreeBT_DbgPrint(3, ("completion routine has a valid irp and frees it\n"));
1060 IoFreeIrp(Irp);
1061 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
1062
1063 }
1064
1065 else
1066 {
1067 // The CancelSelectiveSuspend routine has grabbed the Irp from the device
1068 // extension. Now the last one to decrement the FreeIdleIrpCount should
1069 // free the irp.
1070 if (0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount))
1071 {
1072 FreeBT_DbgPrint(3, ("completion routine frees the irp\n"));
1073 IoFreeIrp(Irp);
1074 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
1075
1076 }
1077
1078 }
1079
1080 if(DeviceExtension->SSEnable)
1081 {
1082 FreeBT_DbgPrint(3, ("Set the timer to fire DPCs\n"));
1083 dueTime.QuadPart = -10000 * IDLE_INTERVAL; // 5000 ms
1084 KeSetTimerEx(&DeviceExtension->Timer, dueTime, IDLE_INTERVAL, &DeviceExtension->DeferredProcCall);
1085 FreeBT_DbgPrint(3, ("IdleNotificationRequestCompete: Leaving\n"));
1086
1087 }
1088
1090
1091}
#define InterlockedExchange
Definition: armddk.h:54
VOID NTAPI PoIrpAsyncCompletionFunc(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
Definition: fbtdev.c:1179
#define IDLE_INTERVAL
Definition: fbtusb.h:65
@ PowerDeviceD0
Definition: ntpoapi.h:49
#define STATUS_POWER_STATE_INVALID
Definition: ntstatus.h:831
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by SubmitIdleRequestIrp().

◆ PoIrpAsyncCompletionFunc()

VOID NTAPI PoIrpAsyncCompletionFunc ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  MinorFunction,
IN POWER_STATE  PowerState,
IN PVOID  Context,
IN PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 1179 of file fbtdev.c.

1180{
1181 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) Context;
1182 FreeBT_DbgPrint(3, ("PoIrpAsyncCompletionFunc::"));
1183 FreeBT_IoDecrement(DeviceExtension);
1184
1185 return;
1186
1187}
LONG NTAPI FreeBT_IoDecrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1742

Referenced by IdleNotificationRequestComplete().

◆ PoIrpCompletionFunc()

VOID NTAPI PoIrpCompletionFunc ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  MinorFunction,
IN POWER_STATE  PowerState,
IN PVOID  Context,
IN PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 1156 of file fbtdev.c.

1157{
1158 PIRP_COMPLETION_CONTEXT irpContext;
1159 irpContext = NULL;
1160
1161 FreeBT_DbgPrint(3, ("PoIrpCompletionFunc::"));
1162
1163 if(Context)
1164 irpContext = (PIRP_COMPLETION_CONTEXT) Context;
1165
1166 // all we do is set the event and decrement the count
1167 if(irpContext)
1168 {
1169 KeSetEvent(irpContext->Event, 0, FALSE);
1171 ExFreePool(irpContext);
1172
1173 }
1174
1175 return;
1176
1177}

Referenced by IdleNotificationCallback().

◆ SubmitIdleRequestIrp()

NTSTATUS NTAPI SubmitIdleRequestIrp ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 669 of file fbtdev.c.

670{
671 PIRP irp;
672 NTSTATUS ntStatus;
673 KIRQL oldIrql;
674 PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;
675 PIO_STACK_LOCATION nextStack;
676
677 FreeBT_DbgPrint(3, ("SubmitIdleRequest: Entered\n"));
678
679 irp = NULL;
680 idleCallbackInfo = NULL;
681
683
684 if(PowerDeviceD0 != DeviceExtension->DevPower) {
685
687
688 goto SubmitIdleRequestIrp_Exit;
689 }
690
691 KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
692
693 if(InterlockedExchange(&DeviceExtension->IdleReqPend, 1)) {
694
695 FreeBT_DbgPrint(1, ("Idle request pending..\n"));
696
697 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
698
699 ntStatus = STATUS_DEVICE_BUSY;
700
701 goto SubmitIdleRequestIrp_Exit;
702 }
703
704 //
705 // clear the NoIdleReqPendEvent because we are about
706 // to submit an idle request. Since we are so early
707 // to clear this event, make sure that if we fail this
708 // request we set back the event.
709 //
710 KeClearEvent(&DeviceExtension->NoIdleReqPendEvent);
711
712 idleCallbackInfo = (PUSB_IDLE_CALLBACK_INFO)ExAllocatePool(NonPagedPool, sizeof(struct _USB_IDLE_CALLBACK_INFO));
713
714 if(idleCallbackInfo) {
715
716 idleCallbackInfo->IdleCallback = (USB_IDLE_CALLBACK)IdleNotificationCallback;
717
718 idleCallbackInfo->IdleContext = (PVOID)DeviceExtension;
719
720 ASSERT(DeviceExtension->IdleCallbackInfo == NULL);
721
722 DeviceExtension->IdleCallbackInfo = idleCallbackInfo;
723
724 //
725 // we use IoAllocateIrp to create an irp to selectively suspend the
726 // device. This irp lies pending with the hub driver. When appropriate
727 // the hub driver will invoked callback, where we power down. The completion
728 // routine is invoked when we power back.
729 //
730 irp = IoAllocateIrp(DeviceExtension->TopOfStackDeviceObject->StackSize,
731 FALSE);
732
733 if(irp == NULL) {
734
735 FreeBT_DbgPrint(1, ("cannot build idle request irp\n"));
736
737 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
739 FALSE);
740
741 InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
742
743 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
744
745 ExFreePool(idleCallbackInfo);
746
748
749 goto SubmitIdleRequestIrp_Exit;
750 }
751
752 nextStack = IoGetNextIrpStackLocation(irp);
753
754 nextStack->MajorFunction =
756
757 nextStack->Parameters.DeviceIoControl.IoControlCode =
758 IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
759
760 nextStack->Parameters.DeviceIoControl.Type3InputBuffer =
761 idleCallbackInfo;
762
763 nextStack->Parameters.DeviceIoControl.InputBufferLength =
764 sizeof(struct _USB_IDLE_CALLBACK_INFO);
765
766
769 DeviceExtension,
770 TRUE,
771 TRUE,
772 TRUE);
773
774 DeviceExtension->PendingIdleIrp = irp;
775
776 //
777 // we initialize the count to 2.
778 // The reason is, if the CancelSelectSuspend routine manages
779 // to grab the irp from the device extension, then the last of the
780 // CancelSelectSuspend routine/IdleNotificationRequestComplete routine
781 // to execute will free this irp. We need to have this schema so that
782 // 1. completion routine does not attempt to touch the irp freed by
783 // CancelSelectSuspend routine.
784 // 2. CancelSelectSuspend routine doesnt wait for ever for the completion
785 // routine to complete!
786 //
787 DeviceExtension->FreeIdleIrpCount = 2;
788
789 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
790
791 //
792 // check if the device is idle.
793 // A check here ensures that a race condition did not
794 // completely reverse the call sequence of SubmitIdleRequestIrp
795 // and CancelSelectiveSuspend
796 //
797
798 if(!CanDeviceSuspend(DeviceExtension) ||
799 PowerDeviceD0 != DeviceExtension->DevPower) {
800
801 //
802 // IRPs created using IoBuildDeviceIoControlRequest should be
803 // completed by calling IoCompleteRequest and not merely
804 // deallocated.
805 //
806
807 FreeBT_DbgPrint(1, ("Device is not idle\n"));
808
809 KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
810
811 DeviceExtension->IdleCallbackInfo = NULL;
812
813 DeviceExtension->PendingIdleIrp = NULL;
814
815 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
817 FALSE);
818
819 InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
820
821 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
822
823 if(idleCallbackInfo) {
824
825 ExFreePool(idleCallbackInfo);
826 }
827
828 //
829 // it is still safe to touch the local variable "irp" here.
830 // the irp has not been passed down the stack, the irp has
831 // no cancellation routine. The worse position is that the
832 // CancelSelectSuspend has run after we released the spin
833 // lock above. It is still essential to free the irp.
834 //
835 if(irp) {
836
837 IoFreeIrp(irp);
838 }
839
840 ntStatus = STATUS_UNSUCCESSFUL;
841
842 goto SubmitIdleRequestIrp_Exit;
843 }
844
845 FreeBT_DbgPrint(3, ("Cancel the timers\n"));
846 //
847 // Cancel the timer so that the DPCs are no longer fired.
848 // Thus, we are making judicious usage of our resources.
849 // we do not need DPCs because we already have an idle irp pending.
850 // The timers are re-initialized in the completion routine.
851 //
852 KeCancelTimer(&DeviceExtension->Timer);
853
854 ntStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject, irp);
855
856 if(!NT_SUCCESS(ntStatus)) {
857
858 FreeBT_DbgPrint(1, ("IoCallDriver failed\n"));
859
860 goto SubmitIdleRequestIrp_Exit;
861 }
862 }
863 else {
864
865 FreeBT_DbgPrint(1, ("Memory allocation for idleCallbackInfo failed\n"));
866
867 KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
869 FALSE);
870
871 InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
872
873 KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
874
876 }
877
878SubmitIdleRequestIrp_Exit:
879
880 FreeBT_DbgPrint(3, ("SubmitIdleRequest: Leaving\n"));
881
882 return ntStatus;
883}
#define TRUE
Definition: types.h:120
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
NTSTATUS NTAPI IdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtdev.c:981
VOID NTAPI IdleNotificationCallback(IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtdev.c:886
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define ASSERT(a)
Definition: mode.c:44
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
void * PVOID
Definition: typedefs.h:50
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2835
#define IRP_MJ_INTERNAL_DEVICE_CONTROL

Referenced by IdleRequestWorkerRoutine().

◆ WWIrpCompletionFunc()

VOID NTAPI WWIrpCompletionFunc ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  MinorFunction,
IN POWER_STATE  PowerState,
IN PVOID  Context,
IN PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 1189 of file fbtdev.c.

1190{
1191 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) Context;
1192
1193 FreeBT_DbgPrint(3, ("WWIrpCompletionFunc::"));
1194 FreeBT_IoDecrement(DeviceExtension);
1195
1196 return;
1197
1198}

Referenced by WaitWakeCallback().