git: 9front

Download patch

ref: 633a44ecda6cd1a1f6e81ccc13be1405f677d364
parent: fa7643ce531177e8dc0c276ef94f8e6804da6e77
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Aug 27 15:01:41 EDT 2013

usbehci: fix portreset.

Port Reset R/W. 1=Port is in Reset. 0=Port is not in Reset. Default = 0. When
software writes a one to this bit (from a zero), the bus reset sequence as defined in the
USB Specification Revision 2.0 is started. Software writes a zero to this bit to terminate
the bus reset sequence. Software must keep this bit at a one long enough to ensure the
reset sequence, as specified in the USB Specification Revision 2.0, completes. Note:
when software writes this bit to a one, it must also write a zero to the Port Enable bit.
Note that when software writes a zero to this bit there may be a delay before the bit
status changes to a zero. The bit status will not read as a zero until after the reset
has completed.

--- a/sys/src/9/port/usbehci.c
+++ b/sys/src/9/port/usbehci.c
@@ -1690,22 +1690,23 @@
 	if (opio->sts & Shalted)
 		iprint("ehci %#p: halted yet trying to reset port\n",
 			ctlr->capio);
+
 	*portscp = (*portscp & ~Psenable) | Psreset;	/* initiate reset */
-	coherence();
+	delay(10);
+	*portscp &= ~Psreset;
 
 	/*
 	 * usb 2 spec: reset must finish within 20 ms.
 	 * linux says spec says it can take 50 ms. for hubs.
 	 */
+	delay(10);
 	for(i = 0; *portscp & Psreset && i < 10; i++)
 		delay(10);
 	if (*portscp & Psreset)
-		if(0) iprint("ehci %#p: port %d didn't reset within %d ms; sts %#lux\n",
+		iprint("ehci %#p: port %d didn't reset within %d ms; sts %#lux\n",
 			ctlr->capio, port, i * 10, *portscp);
-	*portscp &= ~Psreset;		/* force appearance of reset done */
-	coherence();
-	delay(10);			/* ehci spec: enable within 2 ms. */
 
+	delay(10);			/* ehci spec: enable within 2 ms. */
 	if((*portscp & Psenable) == 0)
 		portlend(ctlr, port, "full");
 
--