Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Mar 2012 08:11:04 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232448 - head/sys/dev/usb/controller
Message-ID:  <201203030811.q238B42p070810@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Sat Mar  3 08:11:04 2012
New Revision: 232448
URL: http://svn.freebsd.org/changeset/base/232448

Log:
  Make sure that the USB system suspend event is executed synchronously
  and not asynchronously. This fixes problems related to USB system
  suspend and resume.  It is assumed that we are always allowed to sleep
  from the device_suspend() method.
  
  MFC after:	1 week
  Submitted by:	jkim

Modified:
  head/sys/dev/usb/controller/usb_controller.c

Modified: head/sys/dev/usb/controller/usb_controller.c
==============================================================================
--- head/sys/dev/usb/controller/usb_controller.c	Sat Mar  3 07:10:38 2012	(r232447)
+++ head/sys/dev/usb/controller/usb_controller.c	Sat Mar  3 08:11:04 2012	(r232448)
@@ -89,10 +89,15 @@ TUNABLE_INT("hw.usb.no_boot_wait", &usb_
 SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
     "No USB device enumerate waiting at boot.");
 
+static int usb_no_suspend_wait = 0;
+TUNABLE_INT("hw.usb.no_suspend_wait", &usb_no_suspend_wait);
+SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RW|CTLFLAG_TUN,
+    &usb_no_suspend_wait, 0, "No USB device waiting at system suspend.");
+
 static int usb_no_shutdown_wait = 0;
 TUNABLE_INT("hw.usb.no_shutdown_wait", &usb_no_shutdown_wait);
-SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RW|CTLFLAG_TUN, &usb_no_shutdown_wait, 0,
-    "No USB device waiting at system shutdown.");
+SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RW|CTLFLAG_TUN,
+    &usb_no_shutdown_wait, 0, "No USB device waiting at system shutdown.");
 
 static devclass_t usb_devclass;
 
@@ -240,6 +245,11 @@ usb_suspend(device_t dev)
 	USB_BUS_LOCK(bus);
 	usb_proc_msignal(&bus->explore_proc,
 	    &bus->suspend_msg[0], &bus->suspend_msg[1]);
+	if (usb_no_suspend_wait == 0) {
+		/* wait for suspend callback to be executed */
+		usb_proc_mwait(&bus->explore_proc,
+		    &bus->suspend_msg[0], &bus->suspend_msg[1]);
+	}
 	USB_BUS_UNLOCK(bus);
 
 	return (0);
@@ -407,6 +417,15 @@ usb_bus_suspend(struct usb_proc_msg *pm)
 
 	USB_BUS_UNLOCK(bus);
 
+	/*
+	 * We use the shutdown event here because the suspend and
+	 * resume events are reserved for the USB port suspend and
+	 * resume. The USB system suspend is implemented like full
+	 * shutdown and all connected USB devices will be disconnected
+	 * subsequently. At resume all USB devices will be
+	 * re-connected again.
+	 */
+
 	bus_generic_shutdown(bus->bdev);
 
 	usbd_enum_lock(udev);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203030811.q238B42p070810>