Problem with USB composite bus driver.

Are you exposing other usb functions other than a modem? Each one of the functions you expose will send down a select config to your driver. It is your responsibility in your generic parent driver to
1 present config descriptor that only contains the functions for a particular child. Basically you have to create a config descriptor per child you enumerate
2 when receiving the select config from the child, convert that to a select interface so that the child’s select config does not mess up the state of all of the other functions

You do not receive wait wake irps in a kmdf driver. I also think you are going about usb ss backwards. Each of your children need to register for idle, you notify them to go idle and once everyone is off, only then do you register for idle with the hub driver.

Both of these tasks are *not* easy, you have a few weeks of work ahead of you and then a lot of testing.

d

tiny phone keyboard + fat thumbs = you do the muth

-----Original Message-----
From: xxxxx@gmail.com
Sent: Tuesday, February 09, 2010 6:24 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with USB composite bus driver.

Hi Doron,

Doron Holan wrote:
>Are you handling the various select confit/select interface calls in your driver? Or is the driver you are >sending all of the urbs to translating the select configs into select interfaces?

I did not understand what you said. You meant selecting interfaces in composite driver. (The same way i did in upper driver(Modem driver))?
In My composite driver i am forwarding all the requests which i got in default queue to the lower driver i.e. usb hub.

I have one more doubt. It is related to selective suspend and remote wake up in composite driver.
i could able to put my composite driver and child driver (Modem Driver )in to sleep state by sending IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION to the parent driver (USB hub) and handling its call back routine.

But When i tried to wake up my driver its getting hung. As i have not handled IRP_MN_WAIT_WAKE yet.
actually i could not find IRP_MN_WAIT_WAKE in a default queue of composite driver.
Where can i receive this irp?

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 ,

1 As of now i am exposing only modem to composite driver, no other functions. Once my composite is a bit stable with one function then i will expose other functions.
So in this case also is it mandatory for me to create a config descriptor per child i enumerate when receiving the select config from the child, convert that to a select interface.

2 As of now as only one child is there so it’s a bit easy as i do not have to wait for all children to go to suspend to put my bus driver in suspend state. So i could able to put both composite as well as modem in suspend. First Modem sends IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request to my composite driver which i am pending first by putting it in my own manual queue.

Then from my composite i am manually sending IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION to usb hub by setting idle notification callback and completion routine for it.

Then idle callback of composite driver idle request is getting called by usb hub , in which i am calling idle callback of modem driver to put it in suspend state first.

After this i am calling PorequestpowerIrp with minor code IRP_MN_SET_POWER and power state PowerDeviceD2 in idle callback of composite driver to put it in suspend state.

In this way i could able to put both drivers in suspend state , but when i try to wake them up it is getting hung as i have not implemented wake up functionality.

So i was thinking of implementing it in same way as given in ddk docs by manually sending IRP_MN_WAIT_WAKE up lower driver and setting call back routine for it .

As you said we do not receive wait wake irps in a kmdf driver. So how will my composite driver get to know that upper driver (Modem driver has sent IRP_MN_WAIT_WAKE)

Amit.

You never *ever* call PoRequestPowerIrp in a KMDF driver that is the power policy owner. Turn on KMDF verifier and you will hit stops very quickly with your current scheme. Look at the PDO callbacks you can register for, one of them is to tell you about wake. What you want to do is register yourself for S0Idle (can wake from S0, not USBSelectiveSuspend) with a very short idle timeout (1ms) and then immediately call WdfDeviceStopIdle(). When the hub below you calls your idle routine, call WdfDeviceResumeIdle and let KMDF power you down. KMDF will send the wake and Dx IRPs.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, February 09, 2010 9:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with USB composite bus driver.

Hi Doron ,

1 As of now i am exposing only modem to composite driver, no other functions. Once my composite is a bit stable with one function then i will expose other functions.
So in this case also is it mandatory for me to create a config descriptor per child i enumerate when receiving the select config from the child, convert that to a select interface.

2 As of now as only one child is there so it’s a bit easy as i do not have to wait for all children to go to suspend to put my bus driver in suspend state. So i could able to put both composite as well as modem in suspend. First Modem sends IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request to my composite driver which i am pending first by putting it in my own manual queue.

Then from my composite i am manually sending IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION to usb hub by setting idle notification callback and completion routine for it.

Then idle callback of composite driver idle request is getting called by usb hub , in which i am calling idle callback of modem driver to put it in suspend state first.

After this i am calling PorequestpowerIrp with minor code IRP_MN_SET_POWER and power state PowerDeviceD2 in idle callback of composite driver to put it in suspend state.

In this way i could able to put both drivers in suspend state , but when i try to wake them up it is getting hung as i have not implemented wake up functionality.

So i was thinking of implementing it in same way as given in ddk docs by manually sending IRP_MN_WAIT_WAKE up lower driver and setting call back routine for it .

As you said we do not receive wait wake irps in a kmdf driver. So how will my composite driver get to know that upper driver (Modem driver has sent IRP_MN_WAIT_WAKE)

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 will try with the way you said.
Actually with out enabling driver verifier my driver was getting crashed when i was calling PoRequestPowerIrp in my bus driver. As by default all function drivers are power policy owner .
And my modem (upper driver in the stack )is also power policy owner. There can be only one power policy owner in a stack. So i set power policy ownership to False in bus driver. That time it was not crashing.

Amit.

Amit Samel wrote:

Actually with out enabling driver verifier my driver was getting
crashed when i was calling PoRequestPowerIrp in my bus driver.
As by default all function drivers are power policy owner . And
my modem (upper driver in the stack )is also power policy owner.
There can be only one power policy owner in a stack. So i set
power policy ownership to False in bus driver. That time it was
not crashing.

You’re pretty far off in the weeds so I don’t think I (or maybe anyone) totally understands your “design”, but I think your bus driver and modem drivers are on different “stacks” altogether, and have separate power policies … I think this is what Doron is trying to tell you…

Hi Chris Aseltine,

In my bus driver i am statically enumerating child devices and creating pdo fro them. I am referring static enumeration example given in ddk. As of now i am creating only one pdo for modem and installing Modem over my bus driver. Then how come modem and bus drivers are on different stacks. ?

Amit.

Your PDO is considered a different pnp stack. If you view by connection in device manager, each node in the tree, including the leafs, is a different pnp stack. If you don’t know this or understand this, writing a bus driver, let alone a usb emulation bus driver, is going to be horrendously hard

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Sunday, February 14, 2010 10:27 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with USB composite bus driver.

Hi Chris Aseltine,

In my bus driver i am statically enumerating child devices and creating pdo fro them. I am referring static enumeration example given in ddk. As of now i am creating only one pdo for modem and installing Modem over my bus driver. Then how come modem and bus drivers are on different stacks. ?

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,
Thanks for your inputs. This information was useful. I will have to brush up few concepts.
Amit.

Hi Doron ,
As you said:
1 present config descriptor that only contains the functions for a particular child. Basically you have to create a config descriptor per child you enumerate
2 when receiving the select config from the child, convert that to a select interface so that the child’s select config does not mess up the state of all of the other functions

I have created configuration descriptor per child while enumerating it. Even i am receiving select config request in my default queue. Actually i am a bit confused about statement 2 of yours: (when receiving the select config from the child, convert that to a select interface ) can you please explain this once. ?What exactly i am suppose to do here? Am i suppose to pend child’s Select Config request and sending my own configuration desc to usb hub?

Amit

xxxxx@gmail.com wrote:

I have created configuration descriptor per child while enumerating it. Even i am receiving select config request in my default queue. Actually i am a bit confused about statement 2 of yours: (when receiving the select config from the child, convert that to a select interface ) can you please explain this once. ?What exactly i am suppose to do here? Am i suppose to pend child’s Select Config request and sending my own configuration desc to usb hub?

You aren’t thinking about your problem. Every driver has two
interfaces: the interface to the world ABOVE, and the interface to the
world BELOW. The job of the driver writer is to translate between the two.

The drivers below you see a single device with multiple interfaces, and
when you send requests down, you must make sure that your requests match
that view of the world. The drivers above you do not know they are
speaking to a multi-interface device. They think they are each talking
to a single-interface device, which they own exclusively. When a child
driver does a select configuration, you can’t pass that through to the
real hardware, because that would trash all of the interfaces. Instead,
you need to send a “select interface” to the hardware that matches the
interface selections that the driver made. You create a brand new URB
to do that. When that URB is completed, you complete the child driver’s
URB on your own.

You won’t ever “send” a configuration descriptor to the hub. That’s
strictly YOUR view of the hardware. When a child device requests its
configuration descriptor, you will simply fill in one of the
per-interface configuration descriptors that you have constructed. That
request will never see the hardware.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,
As you said : You create a brand new URB to do that. When that URB is completed, you complete the child driver’s URB on your own. .

On receiving URB_FUNCTION_SELECT_CONFIGURATION from child driver i am creating urb for URB_FUNCTION_SELECT_INTERFACE.
i am doing following things to create urb.

WDFMEMORY urbMemory;
URB *urbBuffer;

status = WdfMemoryCreate(
WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
0,
sizeof(struct _URB_SELECT_INTERFACE),
&urbMemory,
NULL
);

if (!NT_SUCCESS(status)){
return status;
}
urbBuffer = (PURB) WdfMemoryGetBuffer(
urbMemory,
NULL
);
urbBuffer->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE;
urbBuffer->UrbHeader.Length = sizeof(struct _URB_SELECT_INTERFACE);

But here i am also suppose to give USBD_CONFIGURATION_HANDLE ConfigurationHandle while sending select interface urb ,which i do not have as i do not send select config request down to usb host controller driver, so i will not receive the ConfigurationHandle . As host controller driver returns this handle when the client selects the configuration with an URB_FUNCTION_SELECT_CONFIGURATION request.

As i am pending select config request sent by child driver and trying to send select interface to lower driver .How can i retrieve ConfigurationHandle which is required for sending urb of URB_FUNCTION_SELECT_INTERFACE.?

Amit

Amit Samel wrote:

As i am pending select config request sent by child driver
and trying to send select interface to lower driver .How can
i retrieve ConfigurationHandle which is required for sending
urb of URB_FUNCTION_SELECT_INTERFACE.?

Look, you’re probably making this more complicated than it is. Assuming your device has one configuration, and each interface has one setting (and no alternate settings), then instead of trying to “convert” a select-config URB into a select-interface URB, why don’t you just have your bus driver FDO bring up your device completely (across all interfaces), and *then* start your child devices.

So, when the select-config or select-interface URB comes, just complete it synchronously with success, and don’t bother passing it down. With regards to the configuration handles, the bus driver provides them, which is you … it’s just an opaque value. Provide whatever you want.

You need to take a step back and look at
1 how things work
2 what the structures are
3 think about what you are doing

Instead of just trying to brute force your way throught the problem. Sigh.

You send the select condif when the bus fdo starts. Stash away the config handle. Then you have it later. The select interface urb is an open ended structure, you can’t use sizeof() to allocate it, use the appropriate macro given in the usb headers. Once you do that correctly you must copy the config info from the select config into the select interface struct for each pipe handle and copy the results back and the select i nterface has been sent down the stack

d

tiny phone keyboard + fat thumbs = you do the muth

-----Original Message-----
From: xxxxx@gmail.com
Sent: Wednesday, March 03, 2010 1:52 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with USB composite bus driver.

Hi Tim,
As you said : You create a brand new URB to do that. When that URB is completed, you complete the child driver’s URB on your own. .

On receiving URB_FUNCTION_SELECT_CONFIGURATION from child driver i am creating urb for URB_FUNCTION_SELECT_INTERFACE.
i am doing following things to create urb.

WDFMEMORY urbMemory;
URB *urbBuffer;

status = WdfMemoryCreate(
WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
0,
sizeof(struct _URB_SELECT_INTERFACE),
&urbMemory,
NULL
);

if (!NT_SUCCESS(status)){
return status;
}
urbBuffer = (PURB) WdfMemoryGetBuffer(
urbMemory,
NULL
);
urbBuffer->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE;
urbBuffer->UrbHeader.Length = sizeof(struct _URB_SELECT_INTERFACE);

But here i am also suppose to give USBD_CONFIGURATION_HANDLE ConfigurationHandle while sending select interface urb ,which i do not have as i do not send select config request down to usb host controller driver, so i will not receive the ConfigurationHandle . As host controller driver returns this handle when the client selects the configuration with an URB_FUNCTION_SELECT_CONFIGURATION request.

As i am pending select config request sent by child driver and trying to send select interface to lower driver .How can i retrieve ConfigurationHandle which is required for sending urb of URB_FUNCTION_SELECT_INTERFACE.?

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

xxxxx@gmail.com wrote:

On receiving URB_FUNCTION_SELECT_CONFIGURATION from child driver i am creating urb for URB_FUNCTION_SELECT_INTERFACE.
i am doing following things to create urb.

But here i am also suppose to give USBD_CONFIGURATION_HANDLE ConfigurationHandle while sending select interface urb ,which i do not have as i do not send select config request down to usb host controller driver, so i will not receive the ConfigurationHandle . As host controller driver returns this handle when the client selects the configuration with an URB_FUNCTION_SELECT_CONFIGURATION request.

Yes, you need a configuration handle, so you will have to send a
SELECT_CONFIGURATION on your own at some point, probably during your
initialization.

Remember, you are pretending to be the host controller driver here. The
drivers above you expect certain services to work in a certain way. YOU
have to figure out what information you need to provide those services.
In some cases, you will be able to pass requests straight through, but
in some cases you will be manufacturing your own responses, based on
information that you got from the real hardware.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Guys,
As u said i am creating my own select interface urb , when i receive select config request from child driver. my code is as follows.

size = GET_SELECT_INTERFACE_REQUEST_SIZE(numPipes);
selectInterfaceUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, size,POOL_TAG);
RtlZeroMemory(selectInterfaceUrb, size);
UsbBuildSelectInterfaceRequest(selectInterfaceUrb, size,fdoaData->ConfigHandle,interfaceNum,altSettingIndex);

selectInterfaceUrb->UrbSelectInterface.Interface.Length =
GET_USBD_INTERFACE_SIZE(numPipes);

selectInterfaceUrb->UrbSelectInterface.Interface.Pipes[0].MaximumTransferSize =512;
status = SendAndWaitUrb(fdoaData->FdoDeviceObject, selectInterfaceUrb);
if (NT_SUCCESS(status))
{
setting all info (interface handles,pipe handles etc ) in Interface member of SelectConfig urb received from child drive and then completing request.
}

Even i could see all the pipe info and pipe handle in child driver set by my composite driver .

But still when my child driver tries to read or write from that pipe its failing with NTSTATUS STATUS_INVALID_PARAMETER and USBDSTATUS USBD_STATUS_INVALID_PIPE_HANDLE.

Can any one help me regarding this.?

Amit.

xxxxx@gmail.com wrote:

As u said i am creating my own select interface urb , when i receive select config request from child driver. my code is as follows.

size = GET_SELECT_INTERFACE_REQUEST_SIZE(numPipes);
selectInterfaceUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, size,POOL_TAG);
RtlZeroMemory(selectInterfaceUrb, size);
UsbBuildSelectInterfaceRequest(selectInterfaceUrb, size,fdoaData->ConfigHandle,interfaceNum,altSettingIndex);

selectInterfaceUrb->UrbSelectInterface.Interface.Length =
GET_USBD_INTERFACE_SIZE(numPipes);

selectInterfaceUrb->UrbSelectInterface.Interface.Pipes[0].MaximumTransferSize =512;

That’s wrong, although this value is ignored on XP and beyond, so it
shouldn’t matter. You should just remove that line.
MaximumTransferSize is NOT the same thing as the maximum packet size.

Even i could see all the pipe info and pipe handle in child driver set by my composite driver .

But still when my child driver tries to read or write from that pipe its failing with NTSTATUS STATUS_INVALID_PARAMETER and USBDSTATUS USBD_STATUS_INVALID_PIPE_HANDLE.

Can any one help me regarding this.?

Is your child driver sending its requests through you, or is it sending
them directly to the hub? Have you checked that the pipe handle in the
requests the child driver submits match the one you sent back from the
SelectInterface call?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim ,

Is your child driver sending its requests through you, or is it sending them directly to the hub?

Actually i have registered one default queue for each pdo in my compositr driver . And i am handling select config of child in that default queue.(Sending select interface urb when i receive select config from child.) So Child driver is sending its request through my composite driver.

Have you checked that the pipe handle in the requests the child driver submits match the one you sent >back from the SelectInterface call?
In my child driver i could see the same pipe handle which i set in composite driver.WdfUsbTargetPipeWdmGetPipeHandle(pipe); is giving same vale that i set in composite.

Amit

Hi Tim,

In my child driver i could see the same pipe handle which i set in composite driver.WdfUsbTargetPipeWdmGetPipeHandle(pipe) is giving same vale that i set in composite.

but when i receive URB_FUNCTION_CONTROL_TRANSFER from child in composite , PipeHandle is coming out to be NULL which is not same as i set in composite. can tell me whats going wrong as am able to send pipe handle to child driver successfully .

Amit

xxxxx@gmail.com wrote:

In my child driver i could see the same pipe handle which i set in composite driver.WdfUsbTargetPipeWdmGetPipeHandle(pipe) is giving same vale that i set in composite.

but when i receive URB_FUNCTION_CONTROL_TRANSFER from child in composite , PipeHandle is coming out to be NULL which is not same as i set in composite. can tell me whats going wrong as am able to send pipe handle to child driver successfully .

URB_FUNCTION_CONTROL_TRANSFER does not use a pipe handle. To 3 decimal
places, there are no USB devices that have control pipes other than the
default one, and control transfers to the default pipe don’t need a pipe
handle. Indeed, you don’t even need to select an interface to talk to
the default control pipe.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi All,
Thank you very much all of you for your guidelines. My problem is solved now. There was problem with one flag (USBD_DEFAULT_PIPE_TRANSFER) in URB_FUNCTION_CONTROL_TRANSFER that you need to set for control requests. After setting it control requests are not getting failed.

Amit