Skip to contentSkip to conversation

usbfs: Remove extraneous disconnection checks

PATCH New Greg KH 1 participant 2 messages Dec 16, 2004

Subsystems (2)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/2 usbfs: Remove extraneous disconnection checks

[2 USB patches to be applied to the latest -bk tree, both fixing real bugs. I figured it's easier than creating a whole bk tree for them]

This patch fixes a bug in the usbfs code. The driver is too zealous about checking for disconnected devices before doing things. In particular, it is necessary to reap all outstanding asynchronous URBs and unbind from interfaces when the device file is closed, even if the device is no longer connected.

drivers/usb/core/devio.c +6 -7
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
@@ -523,13 +523,12 @@
 
 	usb_lock_device(dev);
 	list_del_init(&ps->list);
-
-	if (connected(dev)) {
-		for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); ifnum++)
-			if (test_bit(ifnum, &ps->ifclaimed))
-				releaseintf(ps, ifnum);
-		destroy_all_async(ps);
+	for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
+			ifnum++) {
+		if (test_bit(ifnum, &ps->ifclaimed))
+			releaseintf(ps, ifnum);
 	}
+	destroy_all_async(ps);
 	usb_unlock_device(dev);
 	usb_put_dev(dev);
 	ps->dev = NULL;
@@ -1034,7 +1033,7 @@
 	int ret;
 
 	add_wait_queue(&ps->wait, &wait);
-	while (connected(dev)) {
+	for (;;) {
 		__set_current_state(TASK_INTERRUPTIBLE);
 		if ((as = async_getcompleted(ps)))
 			break;
author
#1 lore raw

PATCH 2/2 USB: avoid OHCI autosuspend on some boxes

Don't try autosuspend if we think the hardware won't resume correctly from the OHCI suspend state. This makes the RWC bit serve double duty, but that appears to work OK, and the only penalty is increased power consumption (from OHCI clocks) on boards/chips that don't work right.

For example, the amd756 erratum 4 workaround needs this logic; and at least one ServerWorks box issues spurious resume IRQs (~3x/second!) in the suspend state.

drivers/usb/host/ohci-hub.c +1 -1
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
@@ -305,7 +305,7 @@
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 	int		ports, i, changed = 0, length = 1;
-	int		can_suspend = 1;
+	int		can_suspend = hcd->can_wakeup;
 	unsigned long	flags;
 
 	spin_lock_irqsave (&ohci->lock, flags);