Hello,
I have a small problem in implementing USB suspend mode.
On a test IBM thinkpad notepad am able to put the USB device into suspend mode and again wake him up. Works fine.
With the same notebook attached to a docking station, its not working.
When i submit “IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION” ioctl to bus driver…he(bus driver) doesnt call either callback function nor Completion Routine.
Have anyone seen any issues like this?
Thanks,
Mahee
Sample code
/***********/
nextStack = IoGetNextIrpStackLocation(SuspendCallbackIrp);
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
nextStack->Parameters.DeviceIoControl.Type3InputBuffer = &DevExt->SuspendCallbackInfo;
nextStack->Parameters.DeviceIoControl.InputBufferLength = sizeof(USB_IDLE_CALLBACK_INFO);
IoSetCompletionRoutine(SuspendCallbackIrp,
USB_SuspendDeviceCompletionRoutine,
DevExt,
TRUE,
TRUE,
TRUE);
DbgPrint(“USB_SuspendDeviceWithCallback: Submitting idle IRP 0x%p.\n”, SuspendCallbackIrp);
DevExt->SuspendIrp = SuspendCallbackIrp;
status = IoCallDriver(DevExt->PhysicalDeviceObject, SuspendCallbackIrp);
if (NT_SUCCESS(status))
{
DbrPrint("USB_SuspendDeviceWithCallback: Waiting for suspend idle callback "\
“or completion routine to fire…\n”);
waitObjects[0] = &DevExt->SuspendCallbackCalled;
waitObjects[1] = &DevExt->SuspendCompletionRoutineCalled;
timeout.QuadPart = -5*10*1000*1000; // 5 seconds
status = KeWaitForMultipleObjects(2,
waitObjects,
WaitAny,
Executive,
KernelMode,
FALSE,
&timeout,
NULL);
if (status == STATUS_WAIT_0)
DbgPrint(“USB_SuspendDeviceWithCallback: Suspend callback fired!\n”);
else if (status == STATUS_WAIT_1)
DbgPrint(“USB_SuspendDeviceWithCallback: Completion routine fired!\n”);
else
{
DbgPrint("USB_SuspendDeviceWithCallback: KeWaitForMultipleObjects "\
“returned unknown status 0x%x.\n”, status);
/* I am timing out on the notebook mounted on a docking station else works fine*/
bCancelIrpFlag = IoCancelIrp(DevExt->SuspendIrp);
if (bCancelIrpFlag)
DbgPrint(“USB_SuspendDeviceWithCallback: Cancelled IRP!\n”);
else
DbgPrint(“USB_SuspendDeviceWithCallback: UNABLE to Cancel IRP\n”);
//KdBreakPoint();
}