svn commit: r208226 - stable/8/sys/dev/usb/controller

Andrew Thompson thompsa at FreeBSD.org
Mon May 17 23:48:52 UTC 2010


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 */
 


More information about the svn-src-all mailing list