[linux-pm] Re: Hotplug events during sleep transition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 25 Dec 2005, Pavel Machek wrote:

> Hi!
> 
> > At this point I'm starting to feel like the proverbial 
> > "man-in-the-middle".  Recently I submitted a patch adding
> 
> Rock and a hard place?

I guess so.  The encryption-attacker simile isn't appropriate...

> > suspend/resume 
> > support to the usblp driver.  Greg objected to it because it added 
> > explicit checks for whether the driver was suspended before starting up 
> > I/O operations.  He said that such checks did not belong in USB drivers, 
> > they belonged in the USB core.  (You can read his original comments in
> > 
> > http://marc.theaimsgroup.com/?l=linux-usb-devel&m=113418897301873&w=2
> > 
> > .)  So now what should we do?
> > 
> > 	Require userspace to rmmod usblp before suspending?
> 
> No.
> 
> > 	Add suspend and resume methods to usblp, but make it so they
> > 	only cancel outstanding I/O, while relying on usbcore to fail
> > 	any new I/O requests?
> 
> It is not *that* bad, actually. In system suspend/resume cases, no new
> I/O requests can happen, because userspace is frozen. Because of
> runtime suspend, you should handle I/O errors properly, but you should
> handle I/O errors properly, anyway, so... looks like a solution to me.

You're right, it's not really all that bad.  Note however that in the PPC
implementation, Ben H. does not freeze userspace before suspend to RAM.

Making the necessary changes to usbcore won't be very difficult.  (With 
the exception of endpoint 0 -- I think we can afford to ignore that 
issue.)

> > Neither of those feels good to me.  The only other options I can think of 
> > are:
> > 
> > 	Unbind usblp in lieu of suspending it.
> 
> If this can be done in reasonable ammount of not-too-ugly code, why
> not? I think that even Patrick can be convinced by nice patch.

This isn't very hard either.  A sample patch is given below.  I haven't 
tested it with vanilla 2.6.15-rc6, but a similar patch works okay on 
Greg's development tree.  Apart from the FIXMEs, it's not bad at all.

> > 	Make usblp check whether it is suspended before submitting any
> > 	I/O requests.
> 
> Ugly.

Alan Stern



Index: linux-2.6.15-rc6/drivers/usb/core/usb.c
===================================================================
--- linux-2.6.15-rc6.orig/drivers/usb/core/usb.c
+++ linux-2.6.15-rc6/drivers/usb/core/usb.c
@@ -1431,8 +1431,17 @@ static int usb_generic_suspend(struct de
 		else
 			mark_quiesced(intf);
 	} else {
-		// FIXME else if there's no suspend method, disconnect...
-		dev_warn(dev, "no %s?\n", "suspend");
+		dev_warn(dev, "no suspend for %s?  unbinding...\n",
+				driver->name);
+		up(&dev->sem);
+
+		/*
+		 * FIXME: You're not supposed to do this without holding
+		 * the USB device lock.  But we can't just grab the lock
+		 * because our caller might already be holding it.
+		 */
+		usb_driver_release_interface(driver, intf);
+		down(&dev->sem);
 		status = 0;
 	}
 	return status;
@@ -1459,9 +1468,22 @@ static int usb_generic_resume(struct dev
 		return usb_resume_device (to_usb_device(dev));
 	}
 
-	if ((dev->driver == NULL) ||
-	    (dev->driver_data == &usb_generic_driver_data))
+	/* try to bind interfaces that have no driver */
+	if (dev->driver == NULL) {
+		up(&dev->sem);
+
+		/*
+		 * FIXME: You're not supposed to do this without holding
+		 * the USB device lock.  But we can't just grab the lock
+		 * because our caller might already be holding it.
+		 */
+		device_attach(dev);
+		down(&dev->sem);
 		return 0;
+	}
+
+	if (dev->driver_data == &usb_generic_driver_data)
+		return 0;		/* Shouldn't happen */
 
 	intf = to_usb_interface(dev);
 	driver = to_usb_driver(dev->driver);
@@ -1481,7 +1503,7 @@ static int usb_generic_resume(struct dev
 			mark_quiesced(intf);
 		}
 	} else
-		dev_warn(dev, "no %s?\n", "resume");
+		dev_warn(dev, "no resume for %s?\n", driver->name);
 	return 0;
 }
 
Index: linux-2.6.15-rc6/drivers/usb/core/hub.c
===================================================================
--- linux-2.6.15-rc6.orig/drivers/usb/core/hub.c
+++ linux-2.6.15-rc6/drivers/usb/core/hub.c
@@ -1838,12 +1838,6 @@ int usb_resume_device(struct usb_device 
 
 	usb_unlock_device(udev);
 
-	/* rebind drivers that had no suspend() */
-	if (status == 0) {
-		usb_lock_all_devices();
-		bus_rescan_devices(&usb_bus_type);
-		usb_unlock_all_devices();
-	}
 	return status;
 }
 


[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux