devu-uhci never replies.

Here is a fragment of code from my USB driver:


if((rc=usbd_setup_vendor(urb, URB_DIR_OUT,
byte,
USB_TYPE_CLASS|USB_RECIPIENT_INTERFACE,
0, 0, NULL, 0)) != 0) {
return rc;
}

if(rc=usbd_io(urb, ep, NULL, NULL, 10)) {
return rc;
}

The call to usbd_io will block indefinately, fairly repeatably,
if I remove the USB device while everything is running. Note
that while the call being used is a usbd_setup_vendor, I am not
doing any kind of vendor setup. This should, in fact, be a
usbd_setup_control call, but since the usbd library has no
usbd_setup_control function, I have had to use usbd_setup_vendor
which seems to cause the data transfer that I expect to happen.

This is a fatal error, as I cannot recover from this. Is there
anyway to get around this ? I can’t use TimerTimeout since there
is no guarantee that usbd_io is a single kernel call. Is there
any newer library that has usbd_setup_control ? Is usbd_setup_vendor
expected to have odd behavior when called repeatedly ?

Rennie

Rennie Allen wrote:

Here is a fragment of code from my USB driver:


if((rc=usbd_setup_vendor(urb, URB_DIR_OUT,
byte,
USB_TYPE_CLASS|USB_RECIPIENT_INTERFACE,
0, 0, NULL, 0)) != 0) {
return rc;
}

if(rc=usbd_io(urb, ep, NULL, NULL, 10)) {
return rc;
}

The call to usbd_io will block indefinately, fairly repeatably,
if I remove the USB device while everything is running. Note
that while the call being used is a usbd_setup_vendor, I am not
doing any kind of vendor setup. This should, in fact, be a
usbd_setup_control call, but since the usbd library has no
usbd_setup_control function, I have had to use usbd_setup_vendor
which seems to cause the data transfer that I expect to happen.

This is a fatal error, as I cannot recover from this. Is there
anyway to get around this ? I can’t use TimerTimeout since there
is no guarantee that usbd_io is a single kernel call. Is there
any newer library that has usbd_setup_control ? Is usbd_setup_vendor
expected to have odd behavior when called repeatedly ?

Rennie

Actually, the usbd_io call above, is not the problem. Unfortunately
the problem exists between the usbd library and devu-uhci, and there
is nothing that I can do to work around it. I really need a fix for
this. What do I have to to do to get one ?

details:

here is a snapshot of the thread that is reply blocked on devu-uhci.
Since it is not in my code, I can only assume that this is in the
usbd library…

(gdb) sym ./devu-sync_g
Reading symbols from ./devu-sync_g…done.
(gdb) attach 131083
Attaching to process 131083
Reading symbols from /x86/lib/libc.so.2…done.
Loaded symbols for /x86/lib/libc.so.2
0xb0329ea5 in SignalAction () from /x86/lib/libc.so.2
(gdb) info threads
8 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from /x86/lib/libc.so.2
7 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from /x86/lib/libc.so.2
6 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from /x86/lib/libc.so.2
5 process 131083 (state = 0x06) 0xb03296fd in MsgSendv () from /x86/lib/libc.so.2
4 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from /x86/lib/libc.so.2
3 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from /x86/lib/libc.so.2
2 process 131083 (state = 0x0e) 0xb0329f99 in SignalKill () from /x86/lib/libc.so.2
1 process 131083 (state = 0x0b) 0xb0329ea5 in SignalAction () from /x86/lib/libc.so.2
(gdb) thread 5
[Switching to thread 5 (process 131083 (state = 0x06))]#0 0xb03296fd in MsgSendv ()
from /x86/lib/libc.so.2
(gdb) backtrace
#0 0xb03296fd in MsgSendv () from /x86/lib/libc.so.2
#1 0x0804e540 in eventloop ()
(gdb) ^^^^^^^^^’
no eventloop in my code

Rennie,

The thread you see block on the USB stack is created by the usbdi lib and is
used
for insertion/removal and URB completion notification for bulk,int and isoch
tranfers.
It remains reply block on the stack untill such events occur.

Control Transfers(vendor) are synchronous calls to the USB stack. I dont
see
any other thread in the MsgSend

Henry

Rennie Allen <rallen@csical.com> wrote in message
news:4068954F.70903@csical.com

Rennie Allen wrote:
Here is a fragment of code from my USB driver:


if((rc=usbd_setup_vendor(urb, URB_DIR_OUT,
byte,
USB_TYPE_CLASS|USB_RECIPIENT_INTERFACE,
0, 0, NULL, 0)) != 0) {
return rc;
}

if(rc=usbd_io(urb, ep, NULL, NULL, 10)) {
return rc;
}

The call to usbd_io will block indefinately, fairly repeatably,
if I remove the USB device while everything is running. Note
that while the call being used is a usbd_setup_vendor, I am not
doing any kind of vendor setup. This should, in fact, be a
usbd_setup_control call, but since the usbd library has no
usbd_setup_control function, I have had to use usbd_setup_vendor
which seems to cause the data transfer that I expect to happen.

This is a fatal error, as I cannot recover from this. Is there
anyway to get around this ? I can’t use TimerTimeout since there
is no guarantee that usbd_io is a single kernel call. Is there
any newer library that has usbd_setup_control ? Is usbd_setup_vendor
expected to have odd behavior when called repeatedly ?

Rennie


Actually, the usbd_io call above, is not the problem. Unfortunately
the problem exists between the usbd library and devu-uhci, and there
is nothing that I can do to work around it. I really need a fix for
this. What do I have to to do to get one ?

details:

here is a snapshot of the thread that is reply blocked on devu-uhci.
Since it is not in my code, I can only assume that this is in the
usbd library…

(gdb) sym ./devu-sync_g
Reading symbols from ./devu-sync_g…done.
(gdb) attach 131083
Attaching to process 131083
Reading symbols from /x86/lib/libc.so.2…done.
Loaded symbols for /x86/lib/libc.so.2
0xb0329ea5 in SignalAction () from /x86/lib/libc.so.2
(gdb) info threads
8 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from
/x86/lib/libc.so.2
7 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from
/x86/lib/libc.so.2
6 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from
/x86/lib/libc.so.2
5 process 131083 (state = 0x06) 0xb03296fd in MsgSendv () from
/x86/lib/libc.so.2
4 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from
/x86/lib/libc.so.2
3 process 131083 (state = 0x05) 0xb0329281 in MsgRead_r () from
/x86/lib/libc.so.2
2 process 131083 (state = 0x0e) 0xb0329f99 in SignalKill () from
/x86/lib/libc.so.2
1 process 131083 (state = 0x0b) 0xb0329ea5 in SignalAction () from
/x86/lib/libc.so.2
(gdb) thread 5
[Switching to thread 5 (process 131083 (state = 0x06))]#0 0xb03296fd in
MsgSendv ()
from /x86/lib/libc.so.2
(gdb) backtrace
#0 0xb03296fd in MsgSendv () from /x86/lib/libc.so.2
#1 0x0804e540 in eventloop ()
(gdb) ^^^^^^^^^’
no eventloop in my code

Henry VanDyke wrote:

Rennie,

The thread you see block on the USB stack is created by the usbdi lib and is
used
for insertion/removal and URB completion notification for bulk,int and isoch
tranfers.
It remains reply block on the stack untill such events occur.

Control Transfers(vendor) are synchronous calls to the USB stack. I dont
see
any other thread in the MsgSend

Henry,

Thanks for replying. I suspected that the thread that is created by the usbd
library does a MsgSend to the USB stack. The problem is that the stack is
never replying. Now, I have set up the USB_DIR_* transfers to TIME_INFINITE,
but there is data arriving, and there is also data going out (which should
be completing the USB_DIR_OUT transfers). Once the device has been unplugged,
or has had the power removed, the USB stack never again calls any of my driver
callbacks (once the power is restored, of course). If I leave the device
powered, the device will run indefinately (and my driver will continue to get
callbacks as expected).

Perhaps I am doing something wrong, but since I don’t have any direct control
over the USB controller, I don’t know what I can do to re-instate my callbacks
(and as you know, I can’t do much if my callbacks don’t get called - basically
all a USB driver does is submit and collect URBs). My driver continues to
submit URBs, but can’t collect them since the completion callbacks never
happen.

Is there any call I can make to cause the USB host controller to cut power to
the device ? Perhaps the device is in the weeds (this particular device is
so simple - it has no commands at all - there is nothing I can do to cause it
to reset, and, in general, if a device is in the weeds it probably won’t
respond to commands anyway, so it seems that there should be some mechanism
to depower a device from the host controller).

I can provide the driver source if necessary, it is a fairly simple driver.

Thanks again,

Rennie

Rennie Allen <rallen@csical.com> wrote in message
news:40699E02.8000700@csical.com

Henry VanDyke wrote:
Rennie,

The thread you see block on the USB stack is created by the usbdi lib
and is
used
for insertion/removal and URB completion notification for bulk,int and
isoch
tranfers.
It remains reply block on the stack untill such events occur.

Control Transfers(vendor) are synchronous calls to the USB stack. I
dont
see
any other thread in the MsgSend


Henry,

Thanks for replying. I suspected that the thread that is created by the
usbd
library does a MsgSend to the USB stack. The problem is that the stack is
never replying. Now, I have set up the USB_DIR_* transfers to
TIME_INFINITE,
but there is data arriving, and there is also data going out (which should
be completing the USB_DIR_OUT transfers). Once the device has been
unplugged,
or has had the power removed, the USB stack never again calls any of my
driver
callbacks (once the power is restored, of course). If I leave the device
powered, the device will run indefinately (and my driver will continue to
get
callbacks as expected).

Are you getting removal/insertion callbacks when the device is removed and
re-inserted ?

Perhaps I am doing something wrong, but since I don’t have any direct
control
over the USB controller, I don’t know what I can do to re-instate my
callbacks
(and as you know, I can’t do much if my callbacks don’t get called -
basically
all a USB driver does is submit and collect URBs). My driver continues to
submit URBs, but can’t collect them since the completion callbacks never
happen.

Is there any call I can make to cause the USB host controller to cut power
to
the device ? Perhaps the device is in the weeds (this particular device
is
so simple - it has no commands at all - there is nothing I can do to cause
it
to reset, and, in general, if a device is in the weeds it probably won’t
respond to commands anyway, so it seems that there should be some
mechanism
to depower a device from the host controller).

Is the device respoding to when you run the usb utility ?
there is a usbd_reset_device()

I can provide the driver source if necessary, it is a fairly simple
driver.

Yes please do so.

Thanks again,

Rennie

Henry VanDyke wrote:

Are you getting removal/insertion callbacks when the device is removed and
re-inserted ?

I have just re-verified this. Once the condition occurs, there are no
longer any removal/insertion callbacks. FWIW I have 2 identical devices
(for redundancy) in this application, and with one of the devices in
this state, the other continues to operate perfectly (i.e. my driver
de-registers/registers the devices name each time it is pulled in/out).
Since the same code (in my driver) is used for each device, the only
difference is the data (i.e. there is a different instance of the
same object allocated for each device). This also means that devu-uhci
is working correctly for the other device (exactly the same hardware),
it is simply not working correctly for the device in question (and it
can - randomly - be either device instance).

btw1: just in case you’re wondering I gdb’d the driver, and verified
that the insertion/removal is not getting called (rather than
simply rely on the name appearing/disappearing under /dev).

btw2: the big problem is the cessation of URB callbacks, I could live
without the insertion/removal callbacks for a while, however,
there is a reasonable possibility that the lack of insertion/
removal callbacks is related to the lack of URB callbacks…

Is the device respoding to when you run the usb utility ?

Yes. It shows up in the list of devices when it is plugged in (but
the insertion callback does not happen).

there is a usbd_reset_device()

I have tried this, but as the documentation is rather nebulous about
what it actually does, I am not sure how effective it is. Basically,
I can reliably detect the fault condition, and I have added code that
allows me to call usbd_reset_device(), to no avail.

Yes please do so.

I am mailing a copy to henry@qnx.com. It is a tar/gzip archive rooted
at DDK-6.2.1, and it will expand into usb/* (overwriting mouse and
printer in the process). It will also create a file at:
DDK-6.2.1/usr/include/sys/dcmd_heartbeat.h, you’ll need to link this
into /usr/include/sys.

LATE BREAKING NEWS: just as I was checking the last few facts before
sending this, devu-uhci cored. I am attaching the core to this message
(it is relatively small) and to the email.

Thanks,

Rennie

Rennie Allen <rallen@csical.com> wrote in message
news:406A109D.4050407@csical.com

Henry VanDyke wrote:

Are you getting removal/insertion callbacks when the device is removed
and
re-inserted ?

I have just re-verified this. Once the condition occurs, there are no
longer any removal/insertion callbacks. FWIW I have 2 identical devices
(for redundancy) in this application, and with one of the devices in
this state, the other continues to operate perfectly (i.e. my driver
de-registers/registers the devices name each time it is pulled in/out).
Since the same code (in my driver) is used for each device, the only
difference is the data (i.e. there is a different instance of the
same object allocated for each device). This also means that devu-uhci
is working correctly for the other device (exactly the same hardware),
it is simply not working correctly for the device in question (and it
can - randomly - be either device instance).

does this happen after a random amount of insertion/removals, the first time
or
after a specific number of times ?

If you only run with one device connected and insert/remove it does it
always work correctly ?

btw1: just in case you’re wondering I gdb’d the driver, and verified
that the insertion/removal is not getting called (rather than
simply rely on the name appearing/disappearing under /dev).

btw2: the big problem is the cessation of URB callbacks, I could live
without the insertion/removal callbacks for a while, however,
there is a reasonable possibility that the lack of insertion/
removal callbacks is related to the lack of URB callbacks…

You wouldn’t be able to enqueued URBs for a device until you got
notified that the device is available.


Is the device respoding to when you run the usb utility ?

Yes. It shows up in the list of devices when it is plugged in (but
the insertion callback does not happen).

there is a usbd_reset_device()

I have tried this, but as the documentation is rather nebulous about
what it actually does, I am not sure how effective it is. Basically,
I can reliably detect the fault condition, and I have added code that
allows me to call usbd_reset_device(), to no avail.

Yes please do so.

I am mailing a copy to > henry@qnx.com> . It is a tar/gzip archive rooted
at DDK-6.2.1, and it will expand into usb/* (overwriting mouse and
printer in the process). It will also create a file at:
DDK-6.2.1/usr/include/sys/dcmd_heartbeat.h, you’ll need to link this
into /usr/include/sys.

LATE BREAKING NEWS: just as I was checking the last few facts before
sending this, devu-uhci cored. I am attaching the core to this message
(it is relatively small) and to the email.

Looks to be a bug that was previously fixed.(Fixed 6.30)

Thanks,

Rennie

Henry VanDyke wrote:

does this happen after a random amount of insertion/removals, the first time
or
after a specific number of times ?

Random. In fact, a insertion/removal does not need to occur at all, just
some amount of run-time can result in the condition. The easiest way to
reproduce the condition is to depower (not unplug) the device.

If you only run with one device connected and insert/remove it does it
always work correctly ?

No. Even a single device can get into this condition. I simply thought
that it was interesting that one device could be functional while the
other was non-functional (and that is why I mentioned it).

You wouldn’t be able to enqueued URBs for a device until you got
notified that the device is available.

Yes, of course, the insertion callback would need to operate at least
once (which it currently does quite reliably - work the first time,
that is).

Looks to be a bug that was previously fixed.(Fixed 6.30)

What was the bug ? Could it be related to the cessation of callbacks ?

Is it possible to run this new version of devu-uhci with 6.2.1B ? (i.e.
are there any library dependencies). If so, I would be happy to test
it for you to let you know if it behaves any differently under my tests.

Rennie