From: Greg KH <greg@kroah.com>
To: torvalds@transmeta.com
Cc: linux-usb-devel@lists.sourceforge.net
Subject: [PATCH 6 of 6] USB usb_make_path addition

Hi,

Here's a patch against 2.5.3-pre5 that adds the usb_make_path function
to the USB core code.  This is needed by the new input driver changes.

thanks,

greg k-h



diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c	Fri Jan 25 10:29:59 2002
+++ b/drivers/usb/usb.c	Fri Jan 25 10:29:59 2002
@@ -2513,6 +2516,53 @@
 	return err;
 }
 
+/**
+ * usb_make_path - returns device path in the hub tree
+ * @dev: the device whose path is being constructed
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ *
+ * Returns length of the string (>= 0) or out of memory status (< 0).
+ */
+int usb_make_path(struct usb_device *dev, char *buf, size_t size)
+{
+	struct usb_device *pdev = dev->parent;
+	char *tmp;
+	char *port;
+	int i;
+
+	if (!(port = kmalloc(size, GFP_KERNEL)))
+		return -ENOMEM;
+	if (!(tmp = kmalloc(size, GFP_KERNEL))) {
+		kfree(port);
+		return -ENOMEM;
+	}
+
+	*port = 0;
+	while (pdev) {
+		for (i = 0; i < pdev->maxchild; i++)
+			if (pdev->children[i] == dev)
+				break;
+
+		if (pdev->children[i] != dev) {
+			kfree(port);
+			kfree(tmp);
+			return -ENODEV;
+		}
+
+		strcpy(tmp, port);
+		snprintf(port, size, strlen(port) ? "%d.%s" : "%d", i + 1, tmp);
+
+		dev = pdev;
+		pdev = dev->parent;
+	}
+
+	snprintf(buf, size, "usb%d:%s", dev->bus->busnum, port);
+	kfree(port);
+	kfree(tmp);
+	return strlen(buf);
+}
+
 /*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
@@ -2762,5 +2812,6 @@
 EXPORT_SYMBOL(usb_set_configuration);
 EXPORT_SYMBOL(usb_set_interface);
 
+EXPORT_SYMBOL(usb_make_path);
 EXPORT_SYMBOL(usb_devfs_handle);
 MODULE_LICENSE("GPL");
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Fri Jan 25 10:29:58 2002
+++ b/include/linux/usb.h	Fri Jan 25 10:29:58 2002
@@ -881,6 +883,7 @@
 	char *buf, size_t size);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
+extern int usb_make_path(struct usb_device *dev, char *buf, size_t size);
 
 /*
  * timeouts, in seconds, used for sending/receiving control messages
