Date: Tue, 25 Jan 2005 23:42:53 GMT From: Adam Kropelin <akropel1@rochester.rr.com> To: freebsd-gnats-submit@FreeBSD.org Subject: usb/76687: ugen USB_SET_TIMEOUT panics kernel when timeout ocurrs Message-ID: <200501252342.j0PNgra5069492@www.freebsd.org> Resent-Message-ID: <200501252350.j0PNoHAj030280@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 76687 >Category: usb >Synopsis: ugen USB_SET_TIMEOUT panics kernel when timeout ocurrs >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jan 25 23:50:17 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Adam Kropelin >Release: 6.0-CURRENT >Organization: >Environment: FreeBSD freebsd53.kroptech.com 6.0-CURRENT FreeBSD 6.0-CURRENT #0: Mon Jan 24 22:19:49 EST 2005 root@freebsd53.kroptech.com:/usr/src/sys/i386/compile/GENERIC.adk i386 >Description: My userspace device driver (apcupsd bsd-usb) makes extensive use of ugen ioctls. Occasionally the USB_DO_REQUEST ioctl hangs (seemingly forever) and as a workaround I am attempting to implement timeouts via USB_SET_TIMEOUT. In doing so I am finding that if a request times out and the device still responds afterward, the kernel panics. The backtrace is... usb_transfer_complete+0xcd uhci_abort_xfer+0xcf uhci_timeout_task+0xd usb_task_thread+0x7d fork_exit+0xa4 fork_trampoline+0x8 --- trap 0x1, eip = 0, esp = 0xcc744d7c, ebp = 0 --- ..which corresponds to this code... /* if we allocated the buffer in usbd_transfer() we free it here. */ if (xfer->rqflags & URQ_AUTO_DMABUF) { c059e6d4 <usb_transfer_complete+0xa0> testb $0x10,0x48(%ebx) c059e6d8 <usb_transfer_complete+0xa4> je c059e6f8 <usb_transfer_complete+0xc4> if (!repeat) { c059e6da <usb_transfer_complete+0xa6> cmpl $0x0,0xffffffe8(%ebp) c059e6de <usb_transfer_complete+0xaa> jne c059e714 <usb_transfer_complete+0xe0> struct usbd_bus *bus = pipe->device->bus; c059e6e0 <usb_transfer_complete+0xac> mov 0x4(%esi),%eax c059e6e3 <usb_transfer_complete+0xaf> mov (%eax),%eax bus->methods->freem(bus, dmap); c059e6e5 <usb_transfer_complete+0xb1> mov 0x4(%eax),%edx c059e6e8 <usb_transfer_complete+0xb4> pushl 0xfffffff0(%ebp) c059e6eb <usb_transfer_complete+0xb7> push %eax c059e6ec <usb_transfer_complete+0xb8> call *0x10(%edx) xfer->rqflags &= ~URQ_AUTO_DMABUF; c059e6ef <usb_transfer_complete+0xbb> andl $0xffffffef,0x48(%ebx) c059e6f3 <usb_transfer_complete+0xbf> add $0x8,%esp c059e6f6 <usb_transfer_complete+0xc2> mov %esi,%esi } } if (!repeat) { c059e6f8 <usb_transfer_complete+0xc4> cmpl $0x0,0xffffffe8(%ebp) c059e6fc <usb_transfer_complete+0xc8> jne c059e714 <usb_transfer_complete+0xe0> /* Remove request from queue. */ #ifdef DIAGNOSTIC if (xfer != SIMPLEQ_FIRST(&pipe->queue)) printf("usb_transfer_complete: bad dequeue %p != %p\n", xfer, SIMPLEQ_FIRST(&pipe->queue)); xfer->busy_free = XFER_BUSY; #endif SIMPLEQ_REMOVE_HEAD(&pipe->queue, next); c059e6fe <usb_transfer_complete+0xca> mov 0x14(%esi),%eax c059e701 <usb_transfer_complete+0xcd> mov 0x4c(%eax),%eax c059e704 <usb_transfer_complete+0xd0> mov %eax,0x14(%esi) c059e707 <usb_transfer_complete+0xd3> test %eax,%eax c059e709 <usb_transfer_complete+0xd5> jne c059e714 <usb_transfer_complete+0xe0> c059e70b <usb_transfer_complete+0xd7> lea 0x14(%esi),%eax c059e70e <usb_transfer_complete+0xda> mov %eax,0x18(%esi) c059e711 <usb_transfer_complete+0xdd> lea 0x0(%esi),%esi } >How-To-Repeat: Open a ugen control endpoint, set a very short timeout (say, 1 msec) using USB_SET_TIMEOUT ioctl, and issue a valid USB_DO_REQUEST ioctl. >Fix: >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501252342.j0PNgra5069492>