All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: linux-usb-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] USB and Driver Core patches for 2.6.10
Date: Fri, 7 Jan 2005 21:47:49 -0800	[thread overview]
Message-ID: <11051632692480@kroah.com> (raw)
In-Reply-To: <1105163269810@kroah.com>

ChangeSet 1.1938.446.47, 2004/12/20 15:00:38-08:00, stern@rowland.harvard.edu

[PATCH] USB: Hub driver: several bug fixes and simplifications [11/13]

This patch adds several relatively minor bug fixes and code
simplifications for the hub driver.

	Perhaps most significantly, a test is added to usbfs to prevent
	users from unbinding the hub driver from a hub with children.
	That could cause some bad headaches, and it's best to avoid the
	situation.

	Don't set unused bits in the change_bits and event_bits fields
	(this aids in debugging, nothing more).

	Use the correct spinlock in the hub ioctl routine!

	Add an argument to hub_port_disable, indicating whether the
	device behind the disabled port should be marked NOTATTACHED.
	Normally it should, but for retries during usb_reset_device
	it should not.

	Pass the child device as an argument to hub_port_suspend and
	hub_port_resume rather than making them recalculate it.

	Call usb_set_device_state in the suspend/resume code rather
	than setting udev->state directly.

	Set udev->power.power_state in the suspend/resume code so that
	the correct values are visible in sysfs.

	Recognize during hub_port_resume that the child device udev
	might be NULL (this will happen when a new device is plugged
	into a suspended port).

	Don't allow hub_port_init to drop the usb_address0_sem lock
	while a device on the bus is still using address 0!

	Make khubd acquire a reference to the hub interface rather than
	the hub device.  This simplifies disconnect/unbind testing.

	Don't print a debugging message about hub events while not
	holding some lock to protect the hub.

	Remember to drop the reference acquired above if we fail to
	lock the hub.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>


 drivers/usb/core/devio.c |   11 +++++
 drivers/usb/core/hub.c   |  101 +++++++++++++++++++++++++----------------------
 2 files changed, 66 insertions(+), 46 deletions(-)


diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	2005-01-07 15:42:59 -08:00
+++ b/drivers/usb/core/devio.c	2005-01-07 15:42:59 -08:00
@@ -1122,6 +1122,7 @@
 	int			retval = 0;
 	struct usb_interface    *intf = NULL;
 	struct usb_driver       *driver = NULL;
+	int			i;
 
 	/* get input parameters and alloc buffer */
 	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
@@ -1153,6 +1154,16 @@
 
 	/* disconnect kernel driver from interface */
 	case USBDEVFS_DISCONNECT:
+
+		/* don't allow the user to unbind the hub driver from
+		 * a hub with children to manage */
+		for (i = 0; i < ps->dev->maxchild; ++i) {
+			if (ps->dev->children[i])
+				retval = -EBUSY;
+		}
+		if (retval)
+			break;
+
 		down_write(&usb_bus_type.subsys.rwsem);
 		if (intf->dev.driver) {
 			driver = to_usb_driver(intf->dev.driver);
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	2005-01-07 15:42:59 -08:00
+++ b/drivers/usb/core/hub.c	2005-01-07 15:42:59 -08:00
@@ -465,7 +465,7 @@
 		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 
 	/* scan all ports ASAP */
-	hub->event_bits[0] = ~0;
+	hub->event_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 1;
 	kick_khubd(hub);
 }
 
@@ -688,7 +688,7 @@
 		hub->indicator [0] = INDICATOR_CYCLE;
 
 	hub_power_on(hub);
-	hub->change_bits[0] = ~0;
+	hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts)) - 1;
 	hub_activate(hub);
 	return 0;
 
@@ -816,10 +816,9 @@
 	switch (code) {
 	case USBDEVFS_HUB_PORTINFO: {
 		struct usbdevfs_hub_portinfo *info = user_data;
-		unsigned long flags;
 		int i;
 
-		spin_lock_irqsave(&hub_event_lock, flags);
+		spin_lock_irq(&device_state_lock);
 		if (hdev->devnum <= 0)
 			info->nports = 0;
 		else {
@@ -832,7 +831,7 @@
 						hdev->children[i]->devnum;
 			}
 		}
-		spin_unlock_irqrestore(&hub_event_lock, flags);
+		spin_unlock_irq(&device_state_lock);
 
 		return info->nports + 1;
 		}
@@ -1413,11 +1412,11 @@
 	return status;
 }
 
-static int hub_port_disable(struct usb_device *hdev, int port)
+static int hub_port_disable(struct usb_device *hdev, int port, int set_state)
 {
 	int ret;
 
-	if (hdev->children[port]) {
+	if (hdev->children[port] && set_state) {
 		usb_set_device_state(hdev->children[port],
 				USB_STATE_NOTATTACHED);
 	}
@@ -1439,7 +1438,7 @@
 	struct usb_hub *hub;
 
 	dev_dbg(hubdev(hdev), "logical disconnect on port %d\n", port + 1);
-	hub_port_disable(hdev, port);
+	hub_port_disable(hdev, port, 1);
 
 	/* FIXME let caller ask to power down the port:
 	 *  - some devices won't enumerate without a VBUS power cycle
@@ -1468,12 +1467,11 @@
  * tree above them to deliver data, such as a keypress or packet.  In
  * some cases, this wakes the USB host.
  */
-static int hub_port_suspend(struct usb_device *hdev, int port)
+static int hub_port_suspend(struct usb_device *hdev, int port,
+		struct usb_device *udev)
 {
-	int			status;
-	struct usb_device	*udev;
+	int	status;
 
-	udev = hdev->children[port];
 	// dev_dbg(hubdev(hdev), "suspend port %d\n", port + 1);
 
 	/* enable remote wakeup when appropriate; this lets the device
@@ -1513,7 +1511,7 @@
 	} else {
 		/* device has up to 10 msec to fully suspend */
 		dev_dbg(&udev->dev, "usb suspend\n");
-		udev->state = USB_STATE_SUSPENDED;
+		usb_set_device_state(udev, USB_STATE_SUSPENDED);
 		msleep(10);
 	}
 	return status;
@@ -1620,8 +1618,10 @@
 		} else
 			status = -EOPNOTSUPP;
 	} else
-		status = hub_port_suspend(udev->parent, port);
+		status = hub_port_suspend(udev->parent, port, udev);
 
+	if (status == 0)
+		udev->dev.power.power_state = state;
 	return status;
 }
 EXPORT_SYMBOL(__usb_suspend_device);
@@ -1675,9 +1675,10 @@
 	 * first two on the host side; they'd be inside hub_port_init()
 	 * during many timeouts, but khubd can't suspend until later.
 	 */
-	udev->state = udev->actconfig
-		? USB_STATE_CONFIGURED
-		: USB_STATE_ADDRESS;
+	usb_set_device_state(udev, udev->actconfig
+			? USB_STATE_CONFIGURED
+			: USB_STATE_ADDRESS);
+	udev->dev.power.power_state = PM_SUSPEND_ON;
 
  	/* 10.5.4.5 says be sure devices in the tree are still there.
  	 * For now let's assume the device didn't go crazy on resume,
@@ -1745,12 +1746,10 @@
 }
 
 static int
-hub_port_resume(struct usb_device *hdev, int port)
+hub_port_resume(struct usb_device *hdev, int port, struct usb_device *udev)
 {
-	int			status;
-	struct usb_device	*udev;
+	int	status;
 
-	udev = hdev->children[port];
 	// dev_dbg(hubdev(hdev), "resume port %d\n", port + 1);
 
 	/* see 7.1.7.7; affects power usage, but not budgeting */
@@ -1764,7 +1763,8 @@
 		u16		portchange;
 
 		/* drive resume for at least 20 msec */
-		dev_dbg(&udev->dev, "RESUME\n");
+		if (udev)
+			dev_dbg(&udev->dev, "RESUME\n");
 		msleep(25);
 
 #define LIVE_FLAGS	( USB_PORT_STAT_POWER \
@@ -1788,7 +1788,8 @@
 		} else {
 			/* TRSMRCY = 10 msec */
 			msleep(10);
-			status = finish_port_resume(udev);
+			if (udev)
+				status = finish_port_resume(udev);
 		}
 	}
 	if (status < 0)
@@ -1838,7 +1839,7 @@
 		}
 	} else if (udev->state == USB_STATE_SUSPENDED) {
 		// NOTE this fails if parent is also suspended...
-		status = hub_port_resume(udev->parent, port);
+		status = hub_port_resume(udev->parent, port, udev);
 	} else {
 		status = 0;
 	}
@@ -1937,7 +1938,7 @@
 			continue;
 		down (&udev->serialize);
 		if (portstat & USB_PORT_STAT_SUSPEND)
-			status = hub_port_resume(hdev, port);
+			status = hub_port_resume(hdev, port, udev);
 		else {
 			status = finish_port_resume(udev);
 			if (status < 0) {
@@ -2292,6 +2293,8 @@
 	retval = 0;
 
 fail:
+	if (retval)
+		hub_port_disable(hdev, port, 0);
 	up(&usb_address0_sem);
 	return retval;
 }
@@ -2424,11 +2427,15 @@
 	}
 
 #ifdef  CONFIG_USB_SUSPEND
-	/* If something is connected, but the port is suspended, wake it up.. */
+	/* If something is connected, but the port is suspended, wake it up. */
 	if (portstatus & USB_PORT_STAT_SUSPEND) {
-		status = hub_port_resume(hdev, port);
-		if (status < 0)
-			dev_dbg(hub_dev, "can't clear suspend on port %d; %d\n", port+1, status);
+		status = hub_port_resume(hdev, port, NULL);
+		if (status < 0) {
+			dev_dbg(hub_dev,
+				"can't clear suspend on port %d; %d\n",
+				port+1, status);
+			goto done;
+		}
 	}
 #endif
 
@@ -2474,7 +2481,7 @@
 					&devstat);
 			if (status < 0) {
 				dev_dbg(&udev->dev, "get status %d ?\n", status);
-				goto loop;
+				goto loop_disable;
 			}
 			cpu_to_le16s(&devstat);
 			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
@@ -2487,7 +2494,7 @@
 					schedule_work (&hub->leds);
 				}
 				status = -ENOTCONN;	/* Don't retry */
-				goto loop;
+				goto loop_disable;
 			}
 		}
  
@@ -2527,7 +2534,7 @@
 
 		up (&udev->serialize);
 		if (status)
-			goto loop;
+			goto loop_disable;
 
 		status = hub_power_remaining(hub);
 		if (status)
@@ -2537,8 +2544,9 @@
 
 		return;
 
+loop_disable:
+		hub_port_disable(hdev, port, 1);
 loop:
-		hub_port_disable(hdev, port);
 		ep0_reinit(udev);
 		release_address(udev);
 		usb_put_dev(udev);
@@ -2547,13 +2555,14 @@
 	}
  
 done:
-	hub_port_disable(hdev, port);
+	hub_port_disable(hdev, port, 1);
 }
 
 static void hub_events(void)
 {
 	struct list_head *tmp;
 	struct usb_device *hdev;
+	struct usb_interface *intf;
 	struct usb_hub *hub;
 	struct device *hub_dev;
 	u16 hubstatus;
@@ -2583,10 +2592,8 @@
 
 		hub = list_entry(tmp, struct usb_hub, event_list);
 		hdev = hub->hdev;
-		hub_dev = &hub->intf->dev;
-
-		usb_get_dev(hdev);
-		spin_unlock_irq(&hub_event_lock);
+		intf = hub->intf;
+		hub_dev = &intf->dev;
 
 		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
 				hdev->state, hub->descriptor
@@ -2596,14 +2603,16 @@
 				(u16) hub->change_bits[0],
 				(u16) hub->event_bits[0]);
 
+		usb_get_intf(intf);
+		spin_unlock_irq(&hub_event_lock);
+
 		/* Lock the device, then check to see if we were
 		 * disconnected while waiting for the lock to succeed. */
-		if (locktree(hdev) < 0)
-			break;
-		if (hdev->state != USB_STATE_CONFIGURED ||
-				!hdev->actconfig ||
-				hub != usb_get_intfdata(
-					hdev->actconfig->interface[0]))
+		if (locktree(hdev) < 0) {
+			usb_put_intf(intf);
+			continue;
+		}
+		if (hub != usb_get_intfdata(intf) || hub->quiescing)
 			goto loop;
 
 		if (hub->error) {
@@ -2675,7 +2684,7 @@
 						connect_change = 1;
 				} else {
 					ret = -ENODEV;
-					hub_port_disable(hdev, i);
+					hub_port_disable(hdev, i, 1);
 				}
 				dev_dbg (hub_dev,
 					"resume on port %d, status %d\n",
@@ -2724,7 +2733,7 @@
 
 loop:
 		usb_unlock_device(hdev);
-		usb_put_dev(hdev);
+		usb_put_intf(intf);
 
         } /* end while (1) */
 }


  reply	other threads:[~2005-01-08  6:31 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-08  5:46 [BK PATCH] USB and Driver Core patches for 2.6.10 Greg KH
2005-01-08  5:47 ` [PATCH] " Greg KH
2005-01-08  5:47   ` Greg KH
2005-01-08  5:47     ` Greg KH
2005-01-08  5:47       ` Greg KH
2005-01-08  5:47         ` Greg KH
2005-01-08  5:47           ` Greg KH
2005-01-08  5:47             ` Greg KH
2005-01-08  5:47               ` Greg KH
2005-01-08  5:47                 ` Greg KH
2005-01-08  5:47                   ` Greg KH
2005-01-08  5:47                     ` Greg KH
2005-01-08  5:47                       ` Greg KH
2005-01-08  5:47                         ` Greg KH
2005-01-08  5:47                           ` Greg KH
2005-01-08  5:47                             ` Greg KH
2005-01-08  5:47                               ` Greg KH
2005-01-08  5:47                                 ` Greg KH
2005-01-08  5:47                                   ` Greg KH
2005-01-08  5:47                                     ` Greg KH
2005-01-08  5:47                                       ` Greg KH
2005-01-08  5:47                                         ` Greg KH
2005-01-08  5:47                                           ` Greg KH
2005-01-08  5:47                                             ` Greg KH
2005-01-08  5:47                                               ` Greg KH
2005-01-08  5:47                                                 ` Greg KH
2005-01-08  5:47                                                   ` Greg KH
2005-01-08  5:47                                                     ` Greg KH
2005-01-08  5:47                                                       ` Greg KH
2005-01-08  5:47                                                         ` Greg KH
2005-01-08  5:47                                                           ` Greg KH
2005-01-08  5:47                                                             ` Greg KH
2005-01-08  5:47                                                               ` Greg KH
2005-01-08  5:47                                                                 ` Greg KH
2005-01-08  5:47                                                                   ` Greg KH
2005-01-08  5:47                                                                     ` Greg KH
2005-01-08  5:47                                                                       ` Greg KH
2005-01-08  5:47                                                                         ` Greg KH
2005-01-08  5:47                                                                           ` Greg KH
2005-01-08  5:47                                                                             ` Greg KH
2005-01-08  5:47                                                                               ` Greg KH
2005-01-08  5:47                                                                                 ` Greg KH
2005-01-08  5:47                                                                                   ` Greg KH
2005-01-08  5:47                                                                                     ` Greg KH
2005-01-08  5:47                                                                                       ` Greg KH
2005-01-08  5:47                                                                                         ` Greg KH
2005-01-08  5:47                                                                                           ` Greg KH
2005-01-08  5:47                                                                                             ` Greg KH
2005-01-08  5:47                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                           ` Greg KH
2005-01-08  5:47                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                                           ` Greg KH
2005-01-08  5:47                                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                                                           ` Greg KH
2005-01-08  5:47                                                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                                                                           ` Greg KH
2005-01-08  5:47                                                                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                                                                                           ` Greg KH
2005-01-08  5:47                                                                                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                                                                                     ` Greg KH
2005-01-08  5:47                                                                                                                                                                                       ` Greg KH
2005-01-08  5:47                                                                                                                                                                                         ` Greg KH
2005-01-08  5:47                                                                                                                                                                                           ` Greg KH [this message]
2005-01-08  5:47                                                                                                                                                                                             ` Greg KH
2005-01-08  5:47                                                                                                                                                                                               ` Greg KH
2005-01-08  5:47                                                                                                                                                                                                 ` Greg KH
2005-01-08  5:47                                                                                                                                                                                                   ` Greg KH
2005-01-08  5:47                                                                                                                                                                                                     ` Greg KH
2005-01-08 12:08                                                                                               ` Christoph Hellwig
2005-01-08 22:42                                                                                                 ` Greg KH
2005-01-08 23:33                                                                                                   ` Alessandro Suardi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11051632692480@kroah.com \
    --to=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.