svn commit: r224280 - stable/8/sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Sat Jul 23 08:55:06 UTC 2011


Author: hselasky
Date: Sat Jul 23 08:55:05 2011
New Revision: 224280
URL: http://svn.freebsd.org/changeset/base/224280

Log:
  MFC r224095:
  Fix for VirtualBox 4.x and other virtual machines that fail
  to generate a port reset change event.

Modified:
  stable/8/sys/dev/usb/usb_request.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/usb_request.c
==============================================================================
--- stable/8/sys/dev/usb/usb_request.c	Fri Jul 22 21:45:28 2011	(r224279)
+++ stable/8/sys/dev/usb/usb_request.c	Sat Jul 23 08:55:05 2011	(r224280)
@@ -779,10 +779,17 @@ usbd_req_reset_port(struct usb_device *u
 	uint16_t pr_recovery_delay;
 
 #endif
-	err = usbd_req_set_port_feature(udev, mtx, port, UHF_PORT_RESET);
-	if (err) {
+	/* clear any leftover port reset changes first */
+	usbd_req_clear_port_feature(
+	    udev, mtx, port, UHF_C_PORT_RESET);
+
+	/* assert port reset on the given port */
+	err = usbd_req_set_port_feature(
+	    udev, mtx, port, UHF_PORT_RESET);
+
+	/* check for errors */
+	if (err)
 		goto done;
-	}
 #ifdef USB_DEBUG
 	/* range check input parameters */
 	pr_poll_delay = usb_pr_poll_delay;
@@ -798,6 +805,9 @@ usbd_req_reset_port(struct usb_device *u
 #endif
 	n = 0;
 	while (1) {
+		uint16_t status;
+		uint16_t change;
+
 #ifdef USB_DEBUG
 		/* wait for the device to recover from reset */
 		usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
@@ -811,14 +821,25 @@ usbd_req_reset_port(struct usb_device *u
 		if (err) {
 			goto done;
 		}
+		status = UGETW(ps.wPortStatus);
+		change = UGETW(ps.wPortChange);
+
 		/* if the device disappeared, just give up */
-		if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) {
+		if (!(status & UPS_CURRENT_CONNECT_STATUS))
 			goto done;
-		}
+
 		/* check if reset is complete */
-		if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) {
+		if (change & UPS_C_PORT_RESET)
 			break;
-		}
+
+		/*
+		 * Some Virtual Machines like VirtualBox 4.x fail to
+		 * generate a port reset change event. Check if reset
+		 * is no longer asserted.
+		 */
+		if (!(status & UPS_RESET))
+			break;
+
 		/* check for timeout */
 		if (n > 1000) {
 			n = 0;


More information about the svn-src-all mailing list