Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Mar 2005 20:34:16 -0500
From:      "Adam Kropelin" <akropel1@rochester.rr.com>
To:        <hselasky@c2i.net>, <freebsd-usb@freebsd.org>
Subject:   Re: ugen & uhci hang on 5.3-RELEASE and 6.0-CURRENT
Message-ID:  <092001c52a91$6ec1b420$03c8a8c0@kroptech.com>
References:  <07f701c529bf$b0f05540$03c8a8c0@kroptech.com> <200503161504.36260.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hans Petter Selasky wrote:
> On Wednesday 16 March 2005 01:32, Adam Kropelin wrote:
>>
>> kernel: usbd_start_next: pipe=0xc1a83c00, xfer=0
>> kernel: usb_transfer_complete: pipe=0xc1f6cb80 xfer=0xc1a9d400
>> status=0 actlen=5
>> kernel: usb_transfer_complete: repeat=1 new head=0xc1a9d400
>> kernel: usb0: host controller process error
>> kernel: usb0: host controller halted
>>
>
> According to your logs, the USB driver stops after a device interrupt
> transfer. This might be an indication that the QH's must be dequeued
> from the schedule before they are updated.
>
> Could you have tried my USB driver and see if the problem goes away?
>
> Download the three files below into a new directory and type
> "make install"  (to uninstall type "make deinstall")
> http://home.c2i.net/hselasky/isdn4bsd/privat/usb/Makefile
> http://home.c2i.net/hselasky/isdn4bsd/privat/usb/new_usb_1_5_4.diff.bz2
> http://home.c2i.net/hselasky/isdn4bsd/privat/usb/new_usb_1_5_4.tar.bz2

I gave your driver a run and it seems all of the USB_DO_REQUEST ioctls are 
now failing with EPERM. I am playing some games with transfer lengths that 
might have an affect on things. I've included the code I use for GetReport 
requests which documents the length munging.

--Adam

/*
 * Fetch a report from a device given an fd for the device's control
 * endpoint, the populated item structure describing the report, and
 * a data buffer in which to store the result. Returns report length
 * (in bytes) on success and -1 on failure.
 */
int hidu_get_report(int fd, hid_item_t* item, unsigned char* data)
{
    int rc, len;
    struct usb_ctl_request req;
    unsigned char buf[100];

    Dmsg4(200, "get_report: id=0x%02x, kind=%d, length=%d pos=%d\n",
        item->report_ID, item->kind, item->report_size, item->pos);

#if 0
    /*
     * Length is report size (in bits) rounded up to nearest
     * byte, plus one additional byte for the report tag.
     */
    len = (item->report_size+7)/8+1;
#else
    /*
     * Some reports seem to be longer than the above calculation says.
     * Either APC has bogus length fields in their descriptors or
     * libusbhid is buggy. The FreeBSD kernel corrupts its memory when
     * this happens, resulting in a panic shortly thereafter. Work around
     * the problem by using a plenty large buffer and letting the transfer
     * return less than was requested.
     */
    len = sizeof(buf);
#endif

    memset(buf, 0, sizeof(buf));

    req.ucr_flags = USBD_SHORT_XFER_OK;
    req.ucr_actlen = 0;
    req.ucr_addr = 0;
    req.ucr_data = buf;
    req.ucr_request.bmRequestType = UT_READ_CLASS_INTERFACE;
    req.ucr_request.bRequest = UR_GET_REPORT;
    USETW(req.ucr_request.wValue, ((item->kind+1) << 8) | item->report_ID);
    USETW(req.ucr_request.wIndex, 0);
    USETW(req.ucr_request.wLength, len);

    Dmsg2(200, "get_report: wValue=0x%04x, wLength=%d\n",
        UGETW(req.ucr_request.wValue), UGETW(req.ucr_request.wLength));

    rc = ioctl(fd, USB_DO_REQUEST, &req);
    if (rc)
    {
        Dmsg1(100, "Error getting report: %s\n", strerror(-rc));
        return -1;
    }

    if (debug_level >= 300)
    {
        printf( "%02x: ", item->report_ID);
        for (rc=0; rc<req.ucr_actlen; rc++)
            printf("%02x,", buf[rc]);
        printf("\n");
    }

    memcpy(data, buf, req.ucr_actlen);
    return req.ucr_actlen;
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?092001c52a91$6ec1b420$03c8a8c0>