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>