unable to wake up from suspend in composite bus driver

Hi all,

I am trying to write a composite bus driver in which i also want to implement selective suspend and remote wake up functionality. As of now i could able to put composite driver as well as it’s child pdos to suspend state but i could not wake them up by external event.

I am not using usbccgp.sys as i want to use this driver for xp.

For implementing selective suspend i have done following things:

1 When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION , initially i am pending it by putting it in queue.

2 i am registering composite fdo for WdfDeviceAssignS0IdleSettings with IdleUsbSelectiveSuspend power capability and a small idle time out of 1ms. and WdfDeviceAssignSxWakeSettings for wake at sx.

3 Immediately after this i am calling WdfDeviceStopidle.

  1. I have created my own i IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION and registered idle callback for that. And sending this irp to down.(usb hub)

5 In the idle callback routine i have called idle callback of actual IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION which i pended initially. So child driver is going to suspend immediately after that.

6 After that i have called WdfDeviceresumeidle() to put composite fdo in idle state.

But after this i could not wake this up. Even drivers are not getting uninstalled. Even if i open port of child(Modem driver ) through hyper terminal its not getting opened getting hung at that time.

Can any one give some suggestions regarding this problem.

Amit

Hi Amit,

Usbccgp supports selective suspend on XPSP1 and newer.

I’m pasting from http://www.microsoft.com/whdc/connect/usb/USBFAQ_intermed.mspx:

What are the major restrictions imposed by Usbccgp.sys?
The major restrictions imposed on hardware devices and drivers by Usbccgp.sys are:
? Usbccgp supports only the default configuration, configuration 0.

? Usbccgp does not support Selective Suspend in Windows XP and Windows Server 2003. This feature is supported only in Windows Vista and later versions of Windows.
? Note: Usbccgp supports Selective Suspend in Windows XP SP1 and later versions of Windows XP, but with limited features. For these versions of Windows, the composite device is put into Selective Suspend only if each child function of the device has a pending Idle IRP. Usbccgp does not support Selective Suspend in Windows XP RTM.

By the way, why do you need to write your own composite bus driver?

Ilias


From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] on behalf of xxxxx@gmail.com [xxxxx@gmail.com]
Sent: Friday, April 30, 2010 2:40 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] unable to wake up from suspend in composite bus driver

Hi all,

I am trying to write a composite bus driver in which i also want to implement selective suspend and remote wake up functionality. As of now i could able to put composite driver as well as it’s child pdos to suspend state but i could not wake them up by external event.

I am not using usbccgp.sys as i want to use this driver for xp.

For implementing selective suspend i have done following things:

1 When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION , initially i am pending it by putting it in queue.

2 i am registering composite fdo for WdfDeviceAssignS0IdleSettings with IdleUsbSelectiveSuspend power capability and a small idle time out of 1ms. and WdfDeviceAssignSxWakeSettings for wake at sx.

3 Immediately after this i am calling WdfDeviceStopidle.

  1. I have created my own i IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION and registered idle callback for that. And sending this irp to down.(usb hub)

5 In the idle callback routine i have called idle callback of actual IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION which i pended initially. So child driver is going to suspend immediately after that.

6 After that i have called WdfDeviceresumeidle() to put composite fdo in idle state.

But after this i could not wake this up. Even drivers are not getting uninstalled. Even if i open port of child(Modem driver ) through hyper terminal its not getting opened getting hung at that time.

Can any one give some suggestions regarding this problem.

Amit


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> 2 i am registering composite fdo for WdfDeviceAssignS0IdleSettings with IdleUsbSelectiveSuspend power capability and a small idle time out of 1ms. and WdfDeviceAssignSxWakeSettings for wake at sx.

If you are implementing usb SS (as indicated in 1) by sending the idle IOCTL) on your own, you do not want to tell KMDF to use selective suspend because it will send the idle IOCTL as well. you want to pass IdleCanWakeFromS0 to WdfDeviceAssignS0IdleSettings() instead. This will tell KMDF to send the wait wake and Dx irps when idle w/out the idle notification irp being sent by KMDF since you took care of that.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, April 30, 2010 2:41 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] unable to wake up from suspend in composite bus driver

Hi all,

I am trying to write a composite bus driver in which i also want to implement selective suspend and remote wake up functionality. As of now i could able to put composite driver as well as it’s child pdos to suspend state but i could not wake them up by external event.

I am not using usbccgp.sys as i want to use this driver for xp.

For implementing selective suspend i have done following things:

1 When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION , initially i am pending it by putting it in queue.

2 i am registering composite fdo for WdfDeviceAssignS0IdleSettings with IdleUsbSelectiveSuspend power capability and a small idle time out of 1ms. and WdfDeviceAssignSxWakeSettings for wake at sx.

3 Immediately after this i am calling WdfDeviceStopidle.

  1. I have created my own i IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION and registered idle callback for that. And sending this irp to down.(usb hub)

5 In the idle callback routine i have called idle callback of actual IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION which i pended initially. So child driver is going to suspend immediately after that.

6 After that i have called WdfDeviceresumeidle() to put composite fdo in idle state.

But after this i could not wake this up. Even drivers are not getting uninstalled. Even if i open port of child(Modem driver ) through hyper terminal its not getting opened getting hung at that time.

Can any one give some suggestions regarding this problem.

Amit


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Maybe usgccgp supports SS since XP SP1 but in my experience it doesn’t
work. The same composite device which works at Vista RTM and above
including Win7 using the same drivers can be suspended but cannon be
awakened at XP anySP. The only way how to make it working is to disable
SS on all interfaces.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com http:</http:>]


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ilias
Tsigkogiannis
Sent: Tuesday, May 04, 2010 12:01 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unable to wake up from suspend in composite
bus driver

Hi Amit,

Usbccgp supports selective suspend on XPSP1 and newer.

I’m pasting from
http://www.microsoft.com/whdc/connect/usb/USBFAQ_intermed.mspx:

What are the major restrictions imposed by Usbccgp.sys?
The major restrictions imposed on hardware devices and drivers
by Usbccgp.sys are:
* Usbccgp supports only the default configuration, configuration
0.

* Usbccgp does not support Selective Suspend in Windows XP and
Windows Server 2003. This feature is supported only in Windows Vista and
later versions of Windows.
* Note: Usbccgp supports Selective Suspend in Windows XP SP1 and
later versions of Windows XP, but with limited features. For these
versions of Windows, the composite device is put into Selective Suspend
only if each child function of the device has a pending Idle IRP.
Usbccgp does not support Selective Suspend in Windows XP RTM.

By the way, why do you need to write your own composite bus
driver?

Ilias


From: xxxxx@lists.osr.com
[xxxxx@lists.osr.com] on behalf of xxxxx@gmail.com
[xxxxx@gmail.com]
Sent: Friday, April 30, 2010 2:40 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] unable to wake up from suspend in composite bus
driver

Hi all,

I am trying to write a composite bus driver in which i also want
to implement selective suspend and remote wake up functionality. As of
now i could able to put composite driver as well as it’s child pdos to
suspend state but i could not wake them up by external event.

I am not using usbccgp.sys as i want to use this driver for xp.

For implementing selective suspend i have done following things:

1 When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION ,
initially i am pending it by putting it in queue.

2 i am registering composite fdo for
WdfDeviceAssignS0IdleSettings with IdleUsbSelectiveSuspend power
capability and a small idle time out of 1ms. and
WdfDeviceAssignSxWakeSettings for wake at sx.

3 Immediately after this i am calling WdfDeviceStopidle.

  1. I have created my own i
    IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION and registered idle callback
    for that. And sending this irp to down.(usb hub)

5 In the idle callback routine i have called idle callback of
actual IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION which i pended
initially. So child driver is going to suspend immediately after that.

6 After that i have called WdfDeviceresumeidle() to put
composite fdo in idle state.

But after this i could not wake this up. Even drivers are not
getting uninstalled. Even if i open port of child(Modem driver ) through
hyper terminal its not getting opened getting hung at that time.

Can any one give some suggestions regarding this problem.

Amit


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars
visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars
visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hi Ilias Tsigkogiannis,

I am not using usbccgp as in my requirement i need to combine several interfaces as one pdo with the help of UFD union function descriptors which says which interfaces to combine . which usbccgp does not do in xp, where it is enumerating each interface as a separate pdo.

Even vista own wards i can do following things to use usbccgp.sys

  1. Implement the enumeration callback routine (USBC_START_DEVICE_CALLBACK).
  2. Supply a pointer to the callback routine in the USB device configuration interface (StartDeviceCallback member of USBC_DEVICE_CONFIGURATION_INTERFACE_V1).
  3. Provide an INF file that matches the device ID of the composite device and explicitly
    loads both the USB generic parent driver and the filter driver.

This code does not even get compiled in xp.
That is why i want to write my own composite driver for xp.
Amit

Hi Doron,

If you are implementing usb SS (as indicated in 1) by sending the idle IOCTL) on your own, you do >not want to tell KMDF to use selective suspend because it will send the idle IOCTL as well. you >want to pass IdleCanWakeFromS0 to WdfDeviceAssignS0IdleSettings() instead. This will tell KMDF >to send the wait wake and Dx irps when idle w/out the idle notification irp being sent by KMDF >since you took care >of that.

Initially i did the same way you said. I registered composite with WdfDeviceAssignS0IdleSettings and capability IdleCanWakeFromS0 . After that i immediately called WdfDevicestopIdle.

But after receiving IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION i was calling idle callback provided by child driver with irp IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION. but that callback was not returning and it was getting hung.

So is there any other way by which i can put child in to suspend state and then can call WdfDeviceResumeIdle() on composite to put composite in idle state.

Amit

Did you debug why the child callback hung? My guess it was in the middle of powering down and either you did not support cancelation or mishandled the power down path. Did you configure a sync or execution level for the pdo?

d

sent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@gmail.com
Sent: May 03, 2010 10:38 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] unable to wake up from suspend in composite bus driver

Hi Doron,

>If you are implementing usb SS (as indicated in 1) by sending the idle IOCTL) on your own, you do >not want to tell KMDF to use selective suspend because it will send the idle IOCTL as well. you >want to pass IdleCanWakeFromS0 to WdfDeviceAssignS0IdleSettings() instead. This will tell KMDF >to send the wait wake and Dx irps when idle w/out the idle notification irp being sent by KMDF >since you took care >of that.

Initially i did the same way you said. I registered composite with WdfDeviceAssignS0IdleSettings and capability IdleCanWakeFromS0 . After that i immediately called WdfDevicestopIdle.

But after receiving IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION i was calling idle callback provided by child driver with irp IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION. but that callback was not returning and it was getting hung.

So is there any other way by which i can put child in to suspend state and then can call WdfDeviceResumeIdle() on composite to put composite in idle state.

Amit


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hi Doron,

I have specified synchronization scope and execution level .

For composite fdo synchronization scope is WdfSynchronisationScopeDevice.

For child pdo synchronization scope is WdfSynchronisationScopeInheritfromParent and execution level is WdfExecutionLevelInheritfromParent .

I did not debug it i will try to debug it.

Amit
.

Hi Doron,

I tried this in a bit different way but i still could not wake up the driver from suspend.

Here are the following things that i have tried.

  1. Registering composite driver with WdfDeviceAssignS0IdleSettings with IdleCanWakeFromS0 capability and default idle timeout in prepare hardware…
    2.When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION from child driver i am pending it by putting it in my own manual queue.
    3.Then i am creating my own IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION irp and sending it down .
    irp = IoAllocateIrp ( WdfDeviceWdmGetDeviceObject(Device)->StackSize, FALSE);
    nextStack = IoGetNextIrpStackLocation (irp);
    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
    nextStack->Parameters.DeviceIoControl.InputBufferLength =sizeof(struct _USB_IDLE_CALLBACK_INFO);
    idleCallbackInfo = (PUSB_IDLE_CALLBACK_INFO)ExAllocatePoolWithTag (NonPagedPool,sizeof(struct _USB_IDLE_CALLBACK_INFO),POOL_TAG);
    idleCallbackInfo->IdleCallback = QvIdleNotificationCallback;
    // Put a pointer to the device extension in member IdleContext
    idleCallbackInfo->IdleContext = (PVOID) deviceData;
    nextStack->Parameters.DeviceIoControl.Type3InputBuffer =idleCallbackInfo;

IoSetCompletionRoutine (irp,
QvIdleNotificationRequestComplete,
deviceData,
TRUE,
TRUE,
TRUE);
targetDeviceObj=WdfDeviceWdmGetPhysicalDevice(Device);
ASSERT(targetDeviceObj);
status = IoCallDriver (targetDeviceObj, irp);
4. When this idle callback gets called by usb hub driver i am calling idle callback of IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request that i have pended and received from child driver.

5 in this way child driver is going to suspend.
6 after returning from callback composite is also going to suspend.
7 but when i tried to wake it up by opening port of mnodem (child driver) in hyperterminal or by disabling modem its getting hung. Even when i tried to unplug device but still it was showing my driver in device manager. System is not getting hung.

Please give me some suggestions regarding this.

Amit

once you get into the hung state, esp on the pnp disable case, you need to break into the debugger and start poking around. !wdfkd.wdfdevice fff will help tell you the state. !locks will tell you what thread has a hung pnp disable operation. !poaction/!poreqlist can you show outstanding allocated power irps (which may be hung).

d

________________________________________
From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] on behalf of xxxxx@gmail.com [xxxxx@gmail.com]
Sent: Monday, May 10, 2010 10:57 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] unable to wake up from suspend in composite bus driver

Hi Doron,

I tried this in a bit different way but i still could not wake up the driver from suspend.

Here are the following things that i have tried.

1. Registering composite driver with WdfDeviceAssignS0IdleSettings with IdleCanWakeFromS0 capability and default idle timeout in prepare hardware…
2.When i receive IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION from child driver i am pending it by putting it in my own manual queue.
3.Then i am creating my own IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION irp and sending it down .
irp = IoAllocateIrp ( WdfDeviceWdmGetDeviceObject(Device)->StackSize, FALSE);
nextStack = IoGetNextIrpStackLocation (irp);
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
nextStack->Parameters.DeviceIoControl.InputBufferLength =sizeof(struct _USB_IDLE_CALLBACK_INFO);
idleCallbackInfo = (PUSB_IDLE_CALLBACK_INFO)ExAllocatePoolWithTag (NonPagedPool,sizeof(struct _USB_IDLE_CALLBACK_INFO),POOL_TAG);
idleCallbackInfo->IdleCallback = QvIdleNotificationCallback;
// Put a pointer to the device extension in member IdleContext
idleCallbackInfo->IdleContext = (PVOID) deviceData;
nextStack->Parameters.DeviceIoControl.Type3InputBuffer =idleCallbackInfo;

IoSetCompletionRoutine (irp,
QvIdleNotificationRequestComplete,
deviceData,
TRUE,
TRUE,
TRUE);
targetDeviceObj=WdfDeviceWdmGetPhysicalDevice(Device);
ASSERT(targetDeviceObj);
status = IoCallDriver (targetDeviceObj, irp);
4. When this idle callback gets called by usb hub driver i am calling idle callback of IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request that i have pended and received from child driver.

5 in this way child driver is going to suspend.
6 after returning from callback composite is also going to suspend.
7 but when i tried to wake it up by opening port of mnodem (child driver) in hyperterminal or by disabling modem its getting hung. Even when i tried to unplug device but still it was showing my driver in device manager. System is not getting hung.

Please give me some suggestions regarding this.

Amit


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hi Doron,

With my second approach (sending IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION from composite) , problem is solved. Actually there was problem with floating requests.

Previously what i was doing is when idle callback gets called by usb hub driver i was calling idle callback of IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request that i have pended and received from child driver. so after removing from queue i was keeping requests floating. Generally IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION gets canceled when bus driver gets any wake up event till that time it keeps this request pending.

So after calling idle callback of child request i re queued that request and canceling it when i receive wake event so its started working for me.
But still i am confused how did it start working after just re queuing request.

Amit