ReactOS 0.4.15-dev-7942-gd23573b
fbtdev.c File Reference
#include "fbtusb.h"
#include "fbtpnp.h"
#include "fbtpwr.h"
#include "fbtdev.h"
#include "fbtwmi.h"
#include "fbtrwr.h"
#include "fbtusr.h"
Include dependency graph for fbtdev.c:

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_HCISendCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI FreeBT_SendHCICommand (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID IoBuffer, IN ULONG InputBufferLength)
 
NTSTATUS NTAPI FreeBT_HCIEventCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI FreeBT_GetHCIEvent (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID IoBuffer, IN ULONG InputBufferLength)
 
NTSTATUS NTAPI FreeBT_DispatchDevCtrl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI FreeBT_ResetPipe (IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
 
NTSTATUS NTAPI FreeBT_ResetDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI FreeBT_GetPortStatus (IN PDEVICE_OBJECT DeviceObject, IN OUT PULONG PortStatus)
 
NTSTATUS NTAPI FreeBT_ResetParentPort (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_GetHCIEvent()

NTSTATUS NTAPI FreeBT_GetHCIEvent ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  IoBuffer,
IN ULONG  InputBufferLength 
)

Definition at line 310 of file fbtdev.c.

311{
312 PDEVICE_EXTENSION deviceExtension;
313 PURB urb;
314 NTSTATUS ntStatus;
315 PIO_STACK_LOCATION nextStack;
316
317 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent: Entered\n"));
318
319 urb = NULL;
320 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
321
323 if (urb==NULL)
324 {
325 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_GetHCIEvent: Failed to alloc mem for urb\n"));
327 goto FreeBT_GetHCIEvent_Exit;
328
329 }
330
332 urb,
333 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
334 deviceExtension->EventPipe.PipeHandle,
335 IoBuffer,
336 NULL,
339 NULL);
340
341 // use the original irp as an internal device control irp, which we send down to the
342 // USB class driver in order to get our request out on the wire
343 nextStack = IoGetNextIrpStackLocation(Irp);
345 nextStack->Parameters.Others.Argument1 = (PVOID) urb;
347
349 Irp,
351 urb,
352 TRUE,
353 TRUE,
354 TRUE);
355
356 // We return STATUS_PENDING; call IoMarkIrpPending.
358
359 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent::"));
360 FreeBT_IoIncrement(deviceExtension);
361
362 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
363 if (!NT_SUCCESS(ntStatus))
364 {
365 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent: IoCallDriver fails with status %X\n", ntStatus));
366
367 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent::"));
368 FreeBT_IoDecrement(deviceExtension);
369
370 // If the device was surprise removed out, the pipeInformation field is invalid.
371 // similarly if the request was cancelled, then we need not reset the pipe.
372 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED))
373 {
374 ntStatus = FreeBT_ResetPipe(DeviceObject, deviceExtension->EventPipe.PipeHandle);
375 if(!NT_SUCCESS(ntStatus))
376 {
377 FreeBT_DbgPrint(1, ("FreeBT_ResetPipe failed\n"));
379
380 }
381
382 }
383
384 else
385 {
386 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n"));
387
388 }
389
390 goto FreeBT_GetHCIEvent_Exit;
391
392 }
393
394 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent: Leaving\n"));
395
396 // Return STATUS_PENDING, when the lower driver completes the request,
397 // the FreeBT_HCIEventCompletion completion routine.
398 return STATUS_PENDING;
399
400FreeBT_GetHCIEvent_Exit:
401 Irp->IoStatus.Status=ntStatus;
402 Irp->IoStatus.Information=0;
403
404 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetHCIEvent: Failure (0x%08x), completing IRP\n", ntStatus));
406
407 return ntStatus;
408
409}
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NonPagedPool
Definition: env_spec_w32.h:307
NTSTATUS NTAPI FreeBT_ResetPipe(IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
Definition: fbtdev.c:506
NTSTATUS NTAPI FreeBT_HCIEventCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fbtdev.c:284
NTSTATUS NTAPI FreeBT_ResetDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtdev.c:546
LONG NTAPI FreeBT_IoDecrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1742
LONG NTAPI FreeBT_IoIncrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1722
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _IO_STACK_LOCATION::@3978::@4017 Others
Definition: usb.h:529
void * PVOID
Definition: typedefs.h:50
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
#define UsbBuildInterruptOrBulkTransferRequest(urb, length, pipeHandle, transferBuffer, transferBufferMDL, transferBufferLength, transferFlags, link)
Definition: usbdlib.h:12
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
__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 FreeBT_DispatchDevCtrl().

◆ FreeBT_GetPortStatus()

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

Definition at line 565 of file fbtdev.c.

566{
567 NTSTATUS ntStatus;
569 PIRP irp;
570 IO_STATUS_BLOCK ioStatus;
571 PIO_STACK_LOCATION nextStack;
572 PDEVICE_EXTENSION deviceExtension;
573
574 FreeBT_DbgPrint(3, ("FreeBT_GetPortStatus: Entered\n"));
575
576 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
577 *PortStatus = 0;
578
582 deviceExtension->TopOfStackDeviceObject,
583 NULL,
584 0,
585 NULL,
586 0,
587 TRUE,
588 &event,
589 &ioStatus);
590
591 if (NULL == irp)
592 {
593 FreeBT_DbgPrint(1, ("memory alloc for irp failed\n"));
595
596 }
597
598 nextStack = IoGetNextIrpStackLocation(irp);
599 ASSERT(nextStack != NULL);
600 nextStack->Parameters.Others.Argument1 = PortStatus;
601
602 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
603 if (STATUS_PENDING==ntStatus)
605
606 else
607 ioStatus.Status = ntStatus;
608
609 ntStatus = ioStatus.Status;
610 FreeBT_DbgPrint(3, ("FreeBT_GetPortStatus: Leaving\n"));
611
612 return ntStatus;
613
614}
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _cl_event * event
Definition: glext.h:7739
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
#define ASSERT(a)
Definition: mode.c:44
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44

Referenced by FreeBT_ResetDevice().

◆ FreeBT_HCIEventCompletion()

NTSTATUS NTAPI FreeBT_HCIEventCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 284 of file fbtdev.c.

285{
286 //ULONG stageLength;
287 NTSTATUS ntStatus;
288 PIO_STACK_LOCATION nextStack;
289 PURB urb;
290
291 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_HCIEventCompletion, status=0x%08X\n", Irp->IoStatus.Status));
292
293 if (Irp->PendingReturned)
295
296 // initialize variables
297 urb=(PURB)Context;
298 ntStatus = Irp->IoStatus.Status;
299 Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
300 nextStack = IoGetNextIrpStackLocation(Irp);
301
303 FreeBT_IoDecrement(DeviceObject->DeviceExtension);
304
305 return ntStatus;
306
307}
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer
Definition: usb.h:543
struct _URB * PURB

Referenced by FreeBT_GetHCIEvent().

◆ FreeBT_HCISendCompletion()

NTSTATUS NTAPI FreeBT_HCISendCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 135 of file fbtdev.c.

136{
137 //ULONG stageLength;
138 NTSTATUS ntStatus;
139
140 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_HCISendCompletion, status=0x%08X\n", Irp->IoStatus.Status));
141
142 if (Irp->PendingReturned)
144
146 FreeBT_IoDecrement(DeviceObject->DeviceExtension);
147 ntStatus = Irp->IoStatus.Status;
148 Irp->IoStatus.Information = 0;
149
150 return ntStatus;
151
152}

Referenced by FreeBT_SendHCICommand().

◆ 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}
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 PDEVICE_OBJECT  DeviceObject)

Definition at line 617 of file fbtdev.c.

618{
619 NTSTATUS ntStatus;
621 PIRP irp;
622 IO_STATUS_BLOCK ioStatus;
623 PIO_STACK_LOCATION nextStack;
624 PDEVICE_EXTENSION deviceExtension;
625
626 FreeBT_DbgPrint(3, ("FreeBT_ResetParentPort: Entered\n"));
627
628 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
629
633 deviceExtension->TopOfStackDeviceObject,
634 NULL,
635 0,
636 NULL,
637 0,
638 TRUE,
639 &event,
640 &ioStatus);
641
642 if (NULL == irp)
643 {
644 FreeBT_DbgPrint(1, ("memory alloc for irp failed\n"));
646
647 }
648
649 nextStack = IoGetNextIrpStackLocation(irp);
650 ASSERT(nextStack != NULL);
651
652 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
653 if(STATUS_PENDING == ntStatus)
655
656 else
657 ioStatus.Status = ntStatus;
658
659
660 ntStatus = ioStatus.Status;
661
662 FreeBT_DbgPrint(3, ("FreeBT_ResetParentPort: Leaving\n"));
663
664 return ntStatus;
665
666}
#define IOCTL_INTERNAL_USB_RESET_PORT
Definition: usbioctl.h:35

Referenced by FreeBT_ResetDevice().

◆ FreeBT_ResetPipe()

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

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
NTSTATUS NTAPI CallUSBD(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: fbtpnp.c:701
unsigned short USHORT
Definition: pedump.c:61
struct _URB_PIPE_REQUEST UrbPipeRequest
Definition: usb.h:534
struct _URB_HEADER UrbHeader
Definition: usb.h:531
#define URB_FUNCTION_RESET_PIPE
Definition: usb.h:151

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

◆ FreeBT_SendHCICommand()

NTSTATUS NTAPI FreeBT_SendHCICommand ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  IoBuffer,
IN ULONG  InputBufferLength 
)

Definition at line 156 of file fbtdev.c.

157{
158 PDEVICE_EXTENSION deviceExtension;
159 //ULONG urbFlags;
160 //ULONG stageLength;
161 //PVOID pBuffer;
162 PURB urb;
163 NTSTATUS ntStatus;
164 PIO_STACK_LOCATION nextStack;
165 //PFBT_HCI_CMD_HEADER pHCICommand;
166 //LARGE_INTEGER delay;
167
168 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
169 if (!deviceExtension)
170 {
172 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_SendHCICommand: Failed to get DeviceExtension\n"));
173 Irp->IoStatus.Status = ntStatus;
174 Irp->IoStatus.Information = 0;
176 return ntStatus;
177
178 }
179
180 // The user is doing a reset, reset all the pipes as well, so that any
181 // old events or data are removed
182 /*pHCICommand=(PFBT_HCI_CMD_HEADER)IoBuffer;
183 if (pHCICommand->OpCode==FBT_HCI_CMD_RESET)
184 {
185 FreeBT_ResetPipe(DeviceObject, deviceExtension->EventPipe.PipeHandle);
186 FreeBT_ResetPipe(DeviceObject, deviceExtension->DataInPipe.PipeHandle);
187 FreeBT_ResetPipe(DeviceObject, deviceExtension->DataOutPipe.PipeHandle);
188 FreeBT_ResetPipe(DeviceObject, deviceExtension->AudioInPipe.PipeHandle);
189 FreeBT_ResetPipe(DeviceObject, deviceExtension->AudioOutPipe.PipeHandle);
190
191 // Wait a second for the device to recover
192 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_SendHCICommand: Sleeping\n"));
193 delay.QuadPart = -10000 * 5000; // 5s
194 KeWaitForSingleObject(&deviceExtension->DelayEvent,
195 Executive,
196 UserMode,
197 FALSE,
198 &delay);
199
200 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_SendHCICommand: Finished sleeping\n"));
201
202
203 }*/
204
205 // Create the URB
207 if(urb == NULL)
208 {
209 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_SendHCICommand: Failed to alloc mem for urb\n"));
211 Irp->IoStatus.Status = ntStatus;
212 Irp->IoStatus.Information = 0;
214 return ntStatus;
215
216 }
217
219 urb,
220 URB_FUNCTION_CLASS_DEVICE, // This works, for CSR and Silicon Wave
222 0,
223 0,
224 0,
225 0,
226 0,
227 IoBuffer,
228 NULL,
230 NULL);
231
232 // use the original irp as an internal device control irp
233 nextStack = IoGetNextIrpStackLocation(Irp);
235 nextStack->Parameters.Others.Argument1 = (PVOID) urb;
237
239 Irp,
241 urb,
242 TRUE,
243 TRUE,
244 TRUE);
245
246 // We return STATUS_PENDING; call IoMarkIrpPending.
248
249 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand::"));
250 FreeBT_IoIncrement(deviceExtension);
251
252 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand: Sending IRP %X to underlying driver\n", Irp));
253 ntStatus=IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
254 if(!NT_SUCCESS(ntStatus))
255 {
256 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand: IoCallDriver fails with status %X\n", ntStatus));
257
258 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand::"));
259 FreeBT_IoDecrement(deviceExtension);
260
261 // If the device was surprise removed out, the pipeInformation field is invalid.
262 // similarly if the request was cancelled, then we need not reset the device.
263 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED))
265
266 else
267 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n"));
268
269 Irp->IoStatus.Status = ntStatus;
270 Irp->IoStatus.Information = 0;
272
273 return ntStatus;
274
275 }
276
277 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SendHCICommand: Completed successfully\n"));
278
279 return STATUS_PENDING;
280
281}
NTSTATUS NTAPI FreeBT_HCISendCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fbtdev.c:135
#define URB_FUNCTION_CLASS_DEVICE
Definition: usb.h:112
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68

Referenced by FreeBT_DispatchDevCtrl().

◆ 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}
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
NTSTATUS NTAPI IssueWaitWake(IN PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpwr.c:887
struct _IRP_COMPLETION_CONTEXT * PIRP_COMPLETION_CONTEXT
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
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
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}

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 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
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

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().