Date: Mon, 17 May 2010 23:48:51 +0000 (UTC) From: Andrew Thompson <thompsa@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r208226 - stable/8/sys/dev/usb/controller Message-ID: <201005172348.o4HNmpvE075528@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: thompsa Date: Mon May 17 23:48:51 2010 New Revision: 208226 URL: http://svn.freebsd.org/changeset/base/208226 Log: MFC r208014 Back out r203140 which was causing problems when the first and the last microframe slot was not in the smask. The problem was that the EHCI driver was then thinking that the transfer was immediately complete in some cases. Which could lead to freeze-like situations, which can be recovered by unplugging the USB device. Modified: stable/8/sys/dev/usb/controller/ehci.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/dev/usb/controller/ehci.c ============================================================================== --- stable/8/sys/dev/usb/controller/ehci.c Mon May 17 23:48:03 2010 (r208225) +++ stable/8/sys/dev/usb/controller/ehci.c Mon May 17 23:48:51 2010 (r208226) @@ -1352,22 +1352,32 @@ ehci_check_transfer(struct usb_xfer *xfe } } else if (methods == &ehci_device_isoc_hs_methods) { ehci_itd_t *td; - uint8_t n = (xfer->nframes & 7); /* isochronous high speed transfer */ /* check last transfer */ td = xfer->td_transfer_last; usb_pc_cpu_invalidate(td->page_cache); - if (n == 0) - status = td->itd_status[7]; - else - status = td->itd_status[n-1]; + status = td->itd_status[0]; + status |= td->itd_status[1]; + status |= td->itd_status[2]; + status |= td->itd_status[3]; + status |= td->itd_status[4]; + status |= td->itd_status[5]; + status |= td->itd_status[6]; + status |= td->itd_status[7]; /* also check first transfer */ td = xfer->td_transfer_first; usb_pc_cpu_invalidate(td->page_cache); status |= td->itd_status[0]; + status |= td->itd_status[1]; + status |= td->itd_status[2]; + status |= td->itd_status[3]; + status |= td->itd_status[4]; + status |= td->itd_status[5]; + status |= td->itd_status[6]; + status |= td->itd_status[7]; /* if no transactions are active we continue */ if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) { @@ -2799,14 +2809,15 @@ ehci_device_isoc_hs_enter(struct usb_xfe uint8_t x; uint8_t td_no; uint8_t page_no; + uint8_t shift = usbd_xfer_get_fps_shift(xfer); #ifdef USB_DEBUG uint8_t once = 1; #endif - DPRINTFN(6, "xfer=%p next=%d nframes=%d\n", - xfer, xfer->endpoint->isoc_next, xfer->nframes); + DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", + xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift); /* get the current frame index */ @@ -2820,7 +2831,7 @@ ehci_device_isoc_hs_enter(struct usb_xfe (EHCI_VIRTUAL_FRAMELIST_COUNT - 1); if ((xfer->endpoint->is_synced == 0) || - (buf_offset < ((xfer->nframes + 7) / 8))) { + (buf_offset < (((xfer->nframes << shift) + 7) / 8))) { /* * If there is data underflow or the pipe queue is empty we * schedule the transfer a few frames ahead of the current @@ -2844,7 +2855,7 @@ ehci_device_isoc_hs_enter(struct usb_xfe */ xfer->isoc_time_complete = usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset + - ((xfer->nframes + 7) / 8); + (((xfer->nframes << shift) + 7) / 8); /* get the real number of frames */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201005172348.o4HNmpvE075528>