USB DDK IO Problem

Hi all,
I’m using the DDK to develop a USB class driver for a CDC ECM device. The attach callback is invoked and collects all the various endpoints & performs a set interface (The device has a altsetting.) and this all works fine. No errors or bad statuses.

Other threads within the driver then setup URB for TX and RX.

I’ve noticed the following odd behaviour:

a) Plug in device.
b) Start driver.

  • everything is detected correctly.
    c) Start bulk RX and TX IO in other threads (After setup.)
    d) TX IO - after two or three sends, the call to udbd_io never returns.
    (I receive no RX data on the receive URB.)

HOWEVER, if I do the following:

a) Start driver.
b) Plug device in…
c) Same as above - callbacks, setup, and threads start IO.

The TX io works, and I get responses from the device (A CDC_ECM device.) consisting of packets coming back and packets going out.

It’s QNX 6.4.1.

There’re no other USB device drivers running.

Why should the order cause an issue? I don’t get any errors when I open the pipes and select the interfaces. If I put timeouts on the USBD_IO, I get timeouts as expected… Could there be some strange timing issue here? Could it be the device? (The same device works fine on Linux - and comparing drivers, I can’t really see much difference apart from the fact that you have to use the usb callbacks to be able to set interface.)

Flapdoodle,

My guess is that in case 1 (the problem case) when the device is plugged in and your driver is not running that the QNX USB driver ignores the USB device entirely (I believe it still supplies power to the device but I am not 100% sure and if it’s not supplying power that would explain a lot). Depending on the device, that may cause it to go to sleep in some manner if nothing is there to talk to it. So that when you do start your driver the device is no longer ready to send/receive (esp if it’s no longer powered).

You might want to try issuing a usbd_reset_device() command in your driver to kick start the device. That may fix your problem.

Tim

Hi Tim,
Thanks for your response - I was working on this today, and did notice that if I plug in the device and use enum-devices/enum-usb to start the driver straight away, it works OK. On the command line, if I leave it a short time then it doesn’t work.

I tried usbd_reset_device but that caused all my usbd_io requests to respond with “file not present”. That was a “quick go” before leaving for home. I suspect I need to put it in the correct place. I’ll try tomorrow when I’m back in the office!

You wouldn’t happen to know if it’s possible to perform a usbd_select_interface outside the “attach” callback? I.E I want to start a driver that scans the USB device and sets itself up. I need the “detach” callback, but not the attach. However, I only get an error to indicate the device is busy. (I’m aware that without the callbacks you don’t get an event thread for certain types of IO…)

Flapdoodle,

Unfortunately I don’t know if you can do a usbd_select_interface call outside the attach routine.

It seems logical that one could do so but you might google around on the internet and look for an answer about switching interfaces on a USB device after attaching to it to find out if it’s legal.

Tim

I’ve tried the same driver with a different device, and still have the same problem - usbd_reset_device doesn’t makes a difference. It seems that if you don’t start the driver sharpish after plugging the devices in (Phones, one ECM, one RNDIS) then IO doesn’t appear possible.

The other device has an urb with USBD_STATUS_NOT_ACCESSED when I try any IO (It times out). However, the same as before - if I start the driver quickly, it works. This seems to imply that the request wasn’t sent to the device at all?

The driver is a generic CDC Class driver that writes/reads on the bulk packets & sets up interrupt pipes for status info.

Not sure if this is a device problem or something I’m not doing.

I’m finding it quite messy using the DDK as I have to respond to two callbacks, open various things and then pass it all on elsewhere. I’d rather just be able to do it all using the “loop” style and not have to worry about callbacks for insertions… A bit like the NetBSD drivers I’ve seen.

Flapdoodle,

Is there a reason you are not starting (attaching) your driver ‘sharpish’ (ie at boot time)?

It’s not you.

My understanding of what’s happening is that no power is being supplied to the USB device because there is no initial driver attaching so the BIOS stops supplying power. So what happens is that without power, the device goes to sleep and can never wake up again unless it’s re-plugged in.

There is unfortunately no option in io-usb to supply power to devices (I am not sure you can supply power to devices in Windows either unless you have a driver for it) unless there happens to be a BIOS option to do so.

Tim

Hi Tim,

Thanks for the information. This is very useful. Until a month ago I’d never even looked at USB class drivers or USB so don’t fully understand what’s going on sometimes. Trying to learn a new OS and develop an application isn’t much fun at times.

At the moment the driver is invoked from enum-devices, which seems to be quick enough to work - except at system startup. However, I think I can overcome this issue now by ensuring the driver is ready and running at startup.

Martin (Flapdoodle.)