Subject: Re: USB control endpoint stalled
To: Edgar =?iso-8859-1?Q?Fu=DF?= <efnbl06@bn2.maus.net>
From: Terry Moore <tmm@mcci.com>
List: tech-kern
Date: 03/14/2007 18:42:08
Comments below...

At 06:42 PM 3/14/2007 +0100, Edgar Fu=DF wrote:
...
>The following problem arises while trying to talk to a Masterguard UPS.
>The problem, once it occurs, seems to persists until we unplug (and replug)
>the USB cable.
>Possibly, its not primarily a fault of NetBSD's USB stack, but some sort
>of misbehaviour of the client that the stack doesn't cope well with.
>
> >From reading the sources, what happens is that the control endpoint=
 stalls
>(whatever "stalls" exactly means). In ohci_softintr, after the "cc =3D"
>line, the else clause seems to be executed. I don't undestand enough of
>USB to see what's going on there.

Oversimplifying slightly: control endpoints=20
transactions are basically remote procedure=20
calls.  An 8-byte SETUP packet contains 1 byte of=20
type information, one byte indicating the op-code=20
(as it were), two 16-bit general arguments, and a=20
16-bit payload length argument (wLength).  If=20
wLength is non-zero, this is followed by an=20
attempt to move wLength bytes to or from the=20
device.  Finally, a status handshake is=20
exchanged.  The device can return a STALL handshake to indicate an error.

Looking at your trace, the app is issuing a request:

>ohci_device_control type=3D0x42, request=3D0x0d,=20
>wValue=3D0x0000, wIndex=3D0x0000 len=3D3, addr=3D2, endpt=3D0

Because the type is 0x42, this is a=20
"host-to-device, vendor-specific request directed=20
at an endpoint", where the endpoint is specified=20
by the low 8 bits of wIndex.  The request code is 0x0D.

This request fails.  Since this is a vendor=20
request, it's seems likely that you're running=20
software that doesn't actually know how to talk to your device.

...

>TD(0xffff80004dc4d5d0) at 082b45d0: f2e00000<SETTOGGLE> delay=3D7 ec=3D0=
 cc=3D15
>cbp=3D0x07b9df40 nexttd=3D0x082b46c0 be=3D0x07b9df47

this sends the setup.

>TD(0xffff80004dc4d6c0) at 082b46c0:=20
>f3ec0000<R,OUT,TOG1,SETTOGGLE> delay=3D7 ec=3D0 cc=3D15
>cbp=3D0x07b9dec0 nexttd=3D0x082b4710 be=3D0x07b9dec2

this sends the two bytes of data

>TD(0xffff80004dc4d710) at 082b4710:=20
>f3300000<IN,TOG1,SETTOGGLE> delay=3D1 ec=3D0 cc=3D15

this is to get the status.

...


>ohci_process_done: len=3D0, flags=3D0x0
>ohci_process_done: std=3D0xffff80004dc4d6c0=20
>xfer=3D0xffff80000a05fd00 hcpriv=3D0xffff80004dc4d5d0
>ohci_process_done: len=3D0, flags=3D0x2
>ohci_process_done: error cc=3D4 (STALL)

this means that the OUT transfer (immediately=20
after the SETUP) failed.  This usually means that=20
your device doesn't understand the request.

...

>ohci_device_control type=3D0x82, request=3D0x00,=20
>wValue=3D0x0000, wIndex=3D0x0000 len=3D2, addr=3D2, endpt=3D0

Your driver, or the stack issues this.  Standard=20
command, GET_STATUS(EP) for endpoint 0.

It's not strictly required, but it doesn't hurt.

It also seems to complete without errors, which=20
means the device is NOT stuck in the STALL state.

...

>ohci_process_done: len=3D0, flags=3D0x0
>ohci_process_done: std=3D0xffff80004dc4d710=20
>xfer=3D0xffff80000a05fd00 hcpriv=3D0xffff80004dc4d760
>ohci_process_done: len=3D2, flags=3D0x2
>ohci_process_done: std=3D0xffff80004dc4d5d0=20
>xfer=3D0xffff80000a05fd00 hcpriv=3D0xffff80004dc4d760
>ohci_process_done: len=3D0, flags=3D0x1

...
Then the app gives up and closes ugen:

>ugenclose: flag=3D2, mode=3D8192, unit=3D0, endpt=3D0
>ugenclose: close control
>ugenclose: flag=3D1, mode=3D8192, unit=3D0, endpt=3D1
>ugenclose: endpt=3D1 dir=3D1 sce=3D0xffff8000091164b8

...

Then the app reopens.

>ugenopen: flag=3D3, mode=3D8192, unit=3D0 endpt=3D0
>ugenioctl: cmd=3D80045502

The app does the same thing over and over?  Seems=20
like the app is the problem, not the device.

--Terry=20