Problems with uhid device.

Hans Petter Selasky hselasky at c2i.net
Sun Sep 4 04:26:55 PDT 2005


On Saturday 03 September 2005 21:57, John-Paul Andrusky wrote:
> Hi,
>
> Sorry for the long silence. I tried both of the alternatives below with
> no success with either (does exactly the same thing). I've tried to
> isolate the dmesg with hw.usb.uhci.debug=15 (please see bellow). As for
> the version of FreeBSD (I guess I should have mentioned it before), I'm
> running STABLE.
>

> Sep  3 07:58:52 sol kernel: uhci_non_isoc_done: xfer=0xc1cf7800
> pipe=0xc1a8717c transfer done
> Sep  3 07:58:52 sol kernel: uhci_dump_td: TD(0xc1cf79e0) at 1802b9e4 =
> link=0x1802ba04 status=0x1c000004 token=0x00817c69 buffer=0x1802b9d0
> Sep  3 07:58:52 sol kernel: uhci_dump_td: 1802ba04<VF>
> 1c000004<LS>,errcnt=3,actlen=5 pid=69,addr=124,endpt=2,D=0,maxlen=5
> Sep  3 07:58:52 sol kernel: uhci_dump_td: TD(0xc1cf7a00) at 1802ba04 =
> link=0x00000001 status=0x1d500000 token=0x00097c69 buffer=0x1802b9d5
> Sep  3 07:58:52 sol kernel: uhci_dump_td: 1<T>
> 1d500000<BABBLE,STALLED,IOC,LS>,errcnt=3,actlen=1
> pid=69,addr=124,endpt=2,D=1,maxlen=1

I think the problem here is that the uhid driver sets up a too large packet 
for the interrupt endpoint. The above shows that the first packet is 5 bytes 
and the last packet is 1 byte, which makes up the 6 bytes of the interrupt 
structure.

The size of the interrupt packet comes from the function: "hid_report_size()".
"cat /sys/dev/usb/*hid* | more"

        if (id != 0) {
                size += 8;
                       ^^^ maybe this is wrong, hence we are already 
                           adding 7 to the size below ?

                *idp = id;      /* XXX wrong */
        } else
                *idp = 0;
        return ((size + 7) / 8);

A temporary patch might be to add something to the file "/sys/dev/usb/uhid.c"

Where you find:

        sc->sc_isize = hid_report_size(desc, size, hid_input,   &sc->sc_iid);
        sc->sc_osize = hid_report_size(desc, size, hid_output,  &sc->sc_oid);
        sc->sc_fsize = hid_report_size(desc, size, hid_feature, &sc->sc_fid);

Add here:
        if(sc->sc_isize > ed->wMaxPacketSize)
          sc->sc_isize = ed->wMaxPacketSize;

Then try again. You should now only see a single interrupt packet with 
"maxlen=5".

--HPS


More information about the freebsd-usb mailing list