# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.623 -> 1.624
# drivers/usb/core/hub.c 1.28 -> 1.29
# drivers/usb/core/usb.c 1.64 -> 1.65
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/07/05 [EMAIL PROTECTED] 1.624
# [PATCH] usb driverfs, +misc
#
# This fixes a couple issues I noted when I finally spent some time
# looking at the first version of driverfs support for usb:
#
# - "name" fields (really descriptions) aren't very useful.
#
# * for devices, they always said "USB device 0000:0000"
# --> Now they'll only say that when there's
# nothing better to be said ...
# --> ... and it's really device 0000:0000! It was
# using device descriptor fields before they were
# fetched from the device.
# --> Uses product and/or manufacturer strings, which
# most devices have, much like PCI uses the PCI ID
# database (when it's compiled in)
#
# * for interfaces, it was "figure out some name..."
# --> Now it combines the strings used in the
# usb_make_path() call with interface number
# --> Or in the remote chance a device provides
# an interface string, that's preferred.
# --> In general, I think the driver for each
# interface is best suited to describe it;
# I modified the hub driver to do so.
#
# - "bus_id" field
#
# * For hub ports, it was wasting code: we know the port
# already, no need to search for it. Plus, it used
# 0-index ids not the 1-index ones matching physical
# labels on hubs, and other user-visible diagnostics.
#
# * For interfaces, it mixed the device address with the
# interface number ... producing unstable IDs that were
# moreover rather cryptic. Changed: "if0" now, using
# the interface ID (not index).
#
# * For busses, left "usb_bus" alone ... :)
#
# - Adds two files exposing current configuration (for devices)
# and altsetting (for interfaces).
#
# - I was getting a useless diagnostic from the hub driver,
# now it's less useless (it fully identifies the hub)
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Sun Jul 7 12:36:16 2002
+++ b/drivers/usb/core/hub.c Sun Jul 7 12:36:16 2002
@@ -490,8 +490,11 @@
list_add(&hub->hub_list, &hub_list);
spin_unlock_irqrestore(&hub_event_lock, flags);
- if (usb_hub_configure(hub, endpoint) >= 0)
+ if (usb_hub_configure(hub, endpoint) >= 0) {
+ strcpy (dev->actconfig->interface[i].dev.name,
+ "Hub/Port Status Changes");
return hub;
+ }
err("hub configuration failed for device at %s", dev->devpath);
@@ -637,7 +640,8 @@
if (portsts) {
ret = usb_get_port_status(hub, port + 1, portsts);
if (ret < 0)
- err("%s(%s) failed (err = %d)", __FUNCTION__, hub->devpath,
ret);
+ err("%s(%s-%s) failed (err = %d)", __FUNCTION__,
+ hub->bus->bus_name, hub->devpath, ret);
else {
*status = le16_to_cpu(portsts->wPortStatus);
*change = le16_to_cpu(portsts->wPortChange);
@@ -884,19 +888,11 @@
info("new USB device %s-%s, assigned address %d",
dev->bus->bus_name, dev->devpath, dev->devnum);
- /* put the device in the global device tree */
+ /* put the device in the global device tree. the hub port
+ * is the "bus_id"; hubs show in hierarchy like bridges
+ */
dev->dev.parent = &dev->parent->dev;
- sprintf (&dev->dev.name[0], "USB device %04x:%04x",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct);
- /* find the number of the port this device is connected to */
- sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum);
- for (i = 0; i < USB_MAXCHILDREN; ++i) {
- if (dev->parent->children[i] == dev) {
- sprintf (&dev->dev.bus_id[0], "%02d", i);
- break;
- }
- }
+ sprintf (&dev->dev.bus_id[0], "%d", port + 1);
/* Run it through the hoops (find a driver, etc) */
if (!usb_new_device(dev))
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Sun Jul 7 12:36:16 2002
+++ b/drivers/usb/core/usb.c Sun Jul 7 12:36:16 2002
@@ -748,6 +748,46 @@
#endif /* CONFIG_HOTPLUG */
+/* driverfs files */
+
+/* devices have one current configuration, with one
+ * or more interfaces that are used concurrently
+ */
+static ssize_t
+show_config (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct usb_device *udev;
+
+ if (off)
+ return 0;
+ udev = list_entry (dev, struct usb_device, dev);
+ return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
+}
+static struct driver_file_entry usb_config_entry = {
+ name: "configuration",
+ mode: S_IRUGO,
+ show: show_config,
+};
+
+/* interfaces have one current setting; alternates
+ * can have different endpoints and class info.
+ */
+static ssize_t
+show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct usb_interface *interface;
+
+ if (off)
+ return 0;
+ interface = list_entry (dev, struct usb_interface, dev);
+ return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
+}
+static struct driver_file_entry usb_altsetting_entry = {
+ name: "altsetting",
+ mode: S_IRUGO,
+ show: show_altsetting,
+};
+
/*
* This entrypoint gets called for each new device.
@@ -760,15 +800,35 @@
unsigned rejected = 0;
unsigned claimed = 0;
+ /* FIXME should get called for each new configuration not just the
+ * first one for a device. switching configs (or altesettings) should
+ * undo driverfs and HCD state for the previous interfaces.
+ */
for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
struct usb_interface *interface = &dev->actconfig->interface[ifnum];
+ struct usb_interface_descriptor *desc = interface->altsetting;
/* register this interface with driverfs */
interface->dev.parent = &dev->dev;
interface->dev.bus = &usb_bus_type;
- sprintf (&interface->dev.bus_id[0], "%03d%03d", dev->devnum,ifnum);
- sprintf (&interface->dev.name[0], "figure out some name...");
+ sprintf (&interface->dev.bus_id[0], "if%d",
+ interface->altsetting->bInterfaceNumber);
+ if (!desc->iInterface
+ || usb_string (dev, desc->iInterface,
+ interface->dev.name,
+ sizeof interface->dev.name) <= 0) {
+ /* typically devices won't bother with interface
+ * descriptions; this is the normal case. an
+ * interface's driver might describe it better.
+ * (also: iInterface is per-altsetting ...)
+ */
+ sprintf (&interface->dev.name[0],
+ "usb-%s-%s interface %d",
+ dev->bus->bus_name, dev->devpath,
+ interface->altsetting->bInterfaceNumber);
+ }
device_register (&interface->dev);
+ device_create_file (&interface->dev, &usb_altsetting_entry);
/* if this interface hasn't already been claimed */
if (!usb_interface_claimed(interface)) {
@@ -1081,10 +1141,6 @@
}
}
-/*
- * These are the actual routines to send
- * and receive control messages.
- */
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally, for usb_new_device()
@@ -1096,6 +1152,64 @@
}
+/* improve on the default device description, if we can ... and
+ * while we're at it, maybe show the vendor and product strings.
+ */
+static void set_device_description (struct usb_device *dev)
+{
+ char *buf, *here, *end;
+ int mfgr = dev->descriptor.iManufacturer;
+ int prod = dev->descriptor.iProduct;
+
+ /* set default; keep it if there are no strings */
+ sprintf (dev->dev.name, "USB device %04x:%04x",
+ dev->descriptor.idVendor,
+ dev->descriptor.idProduct);
+ if (!mfgr && !prod)
+ return;
+
+ if (!(buf = kmalloc(256, GFP_KERNEL)))
+ return;
+ here = dev->dev.name;
+ end = here + sizeof dev->dev.name - 2;
+ *end = 0;
+
+ /* much like pci ... describe as either:
+ * - both strings: 'product descr (vendor descr)'
+ * - product only: 'product descr (USB device vvvv:pppp)'
+ * - vendor only: 'USB device vvvv:pppp (vendor descr)'
+ * - neither string: 'USB device vvvv:pppp'
+ */
+ if (prod && usb_string (dev, prod, buf, 256) > 0) {
+ strncpy (here, buf, end - here);
+#ifdef DEBUG
+ printk (KERN_INFO "Product: %s\n", buf);
+#endif
+ } else {
+ buf [0] = 0;
+ prod = -1;
+ }
+ here = strchr (here, 0);
+ if (mfgr && usb_string (dev, mfgr, buf, 256) > 0) {
+ *here++ = ' ';
+ *here++ = '(';
+ strncpy (here, buf, end - here - 1);
+ here = strchr (here, 0);
+ *here++ = ')';
+#ifdef DEBUG
+ printk (KERN_INFO "Manufacturer: %s\n", buf);
+#endif
+ } else {
+ if (prod != -1)
+ snprintf (here, end - here - 1,
+ " (USB device %04x:%04x)",
+ dev->descriptor.idVendor,
+ dev->descriptor.idProduct);
+ /* both strings unavailable, keep the default */
+ }
+ kfree(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
@@ -1193,11 +1307,9 @@
dbg("new device strings: Mfr=%d, Product=%d, SerialNumber=%d",
dev->descriptor.iManufacturer, dev->descriptor.iProduct,
dev->descriptor.iSerialNumber);
+ set_device_description (dev);
+
#ifdef DEBUG
- if (dev->descriptor.iManufacturer)
- usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
- if (dev->descriptor.iProduct)
- usb_show_string(dev, "Product", dev->descriptor.iProduct);
if (dev->descriptor.iSerialNumber)
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
#endif
@@ -1206,6 +1318,7 @@
err = device_register (&dev->dev);
if (err)
return err;
+ device_create_file (&dev->dev, &usb_config_entry);
/* now that the basic setup is over, add a /proc/bus/usb entry */
usbfs_add_device(dev);
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
We have stuff for geeks like you.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel