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

Hans Petter Selasky hselasky at FreeBSD.org
Sun Apr 3 22:15:00 UTC 2011


Author: hselasky
Date: Sun Apr  3 22:15:00 2011
New Revision: 220309
URL: http://svn.freebsd.org/changeset/base/220309

Log:
  MFC r219845, r219930, r219949 and r219983.
  - Use software to compute EHCI data toggle instead of hardware.
  - Fix EHCI initialisation order with regard to debug prints.
  
  Approved by:	thompsa (mentor)

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)

Modified: stable/8/sys/dev/usb/controller/ehci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/ehci.c	Sun Apr  3 22:01:26 2011	(r220308)
+++ stable/8/sys/dev/usb/controller/ehci.c	Sun Apr  3 22:15:00 2011	(r220309)
@@ -260,6 +260,8 @@ ehci_init(ehci_softc_t *sc)
 	usb_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0);
 	usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0);
 
+	sc->sc_offs = EHCI_CAPLENGTH(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));
+
 #ifdef USB_DEBUG
 	if (ehciiaadbug)
 		sc->sc_flags |= EHCI_SCFLG_IAADBUG;
@@ -270,8 +272,6 @@ ehci_init(ehci_softc_t *sc)
 	}
 #endif
 
-	sc->sc_offs = EHCI_CAPLENGTH(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));
-
 	version = EHCI_HCIVERSION(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));
 	device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
 	    version >> 8, version & 0xff);
@@ -1181,6 +1181,26 @@ _ehci_remove_qh(ehci_qh_t *sqh, ehci_qh_
 	return (last);
 }
 
+static void
+ehci_data_toggle_update(struct usb_xfer *xfer, uint16_t actlen, uint16_t xlen)
+{
+	uint16_t rem;
+	uint8_t dt;
+
+	/* count number of full packets */
+	dt = (actlen / xfer->max_packet_size) & 1;
+
+	/* compute remainder */
+	rem = actlen % xfer->max_packet_size;
+
+	if (rem > 0)
+		dt ^= 1;	/* short packet at the end */
+	else if (actlen != xlen)
+		dt ^= 1;	/* zero length packet at the end */
+
+	xfer->endpoint->toggle_next ^= dt;
+}
+
 static usb_error_t
 ehci_non_isoc_done_sub(struct usb_xfer *xfer)
 {
@@ -1214,7 +1234,10 @@ ehci_non_isoc_done_sub(struct usb_xfer *
 			status |= EHCI_QTD_HALTED;
 		} else if (xfer->aframes != xfer->nframes) {
 			xfer->frlengths[xfer->aframes] += td->len - len;
+			/* manually update data toggle */
+			ehci_data_toggle_update(xfer, td->len - len, td->len);
 		}
+
 		/* Check for last transfer */
 		if (((void *)td) == xfer->td_transfer_last) {
 			td = NULL;
@@ -1296,9 +1319,6 @@ ehci_non_isoc_done(struct usb_xfer *xfer
 
 	status = hc32toh(sc, qh->qh_qtd.qtd_status);
 
-	xfer->endpoint->toggle_next =
-	    (status & EHCI_QTD_TOGGLE_MASK) ? 1 : 0;
-
 	/* reset scanner */
 
 	xfer->td_transfer_cache = xfer->td_transfer_first;
@@ -1877,6 +1897,8 @@ ehci_setup_standard_chain(struct usb_xfe
 	if (xfer->flags_int.control_xfr) {
 		if (xfer->flags_int.control_hdr) {
 
+			xfer->endpoint->toggle_next = 0;
+
 			temp.qtd_status &=
 			    htohc32(temp.sc, EHCI_QTD_SET_CERR(3));
 			temp.qtd_status |= htohc32(temp.sc,


More information about the svn-src-stable mailing list