aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@intel.com>2007-10-03 17:56:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:30 -0400
commit4d59d8a11383ebf0e0260ee481a4e766959fd7d9 (patch)
tree240cf81cc56896a69c1467b7c8bc4f3f4022c3fd
parent437f375f262417b484f28007c3e8d21bd01d0e01 (diff)
USB: Export URB statistics for powertop
powertop currently tracks interrupts generated by uhci, ehci, and ohci, but it has no way of telling which USB device to blame USB bus activity on. This patch exports the number of URBs that are submitted for a given device. Cat the file 'urbnum' in /sys/bus/usb/devices/.../ Signed-off-by: Sarah Sharp <sarah.a.sharp@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/sysfs.c11
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--include/linux/usb.h1
4 files changed, 15 insertions, 0 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2c79aa6ca2b4..3dd997df8505 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1176,6 +1176,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
1176 */ 1176 */
1177 usb_get_urb(urb); 1177 usb_get_urb(urb);
1178 atomic_inc(&urb->use_count); 1178 atomic_inc(&urb->use_count);
1179 atomic_inc(&urb->dev->urbnum);
1179 usbmon_urb_submit(&hcd->self, urb); 1180 usbmon_urb_submit(&hcd->self, urb);
1180 1181
1181 /* NOTE requirements on root-hub callers (usbfs and the hub 1182 /* NOTE requirements on root-hub callers (usbfs and the hub
@@ -1197,6 +1198,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
1197 urb->hcpriv = NULL; 1198 urb->hcpriv = NULL;
1198 INIT_LIST_HEAD(&urb->urb_list); 1199 INIT_LIST_HEAD(&urb->urb_list);
1199 atomic_dec(&urb->use_count); 1200 atomic_dec(&urb->use_count);
1201 atomic_dec(&urb->dev->urbnum);
1200 if (urb->reject) 1202 if (urb->reject)
1201 wake_up(&usb_kill_urb_queue); 1203 wake_up(&usb_kill_urb_queue);
1202 usb_put_urb(urb); 1204 usb_put_urb(urb);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index e02590297d31..b04afd06e502 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -169,6 +169,16 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
169} 169}
170static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); 170static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
171 171
172static ssize_t
173show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
174{
175 struct usb_device *udev;
176
177 udev = to_usb_device(dev);
178 return sprintf(buf, "%d\n", atomic_read(&udev->urbnum));
179}
180static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL);
181
172 182
173#if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) 183#if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND)
174static const char power_group[] = "power"; 184static const char power_group[] = "power";
@@ -458,6 +468,7 @@ static struct attribute *dev_attrs[] = {
458 &dev_attr_bConfigurationValue.attr, 468 &dev_attr_bConfigurationValue.attr,
459 &dev_attr_bmAttributes.attr, 469 &dev_attr_bmAttributes.attr,
460 &dev_attr_bMaxPower.attr, 470 &dev_attr_bMaxPower.attr,
471 &dev_attr_urbnum.attr,
461 /* device attributes */ 472 /* device attributes */
462 &dev_attr_idVendor.attr, 473 &dev_attr_idVendor.attr,
463 &dev_attr_idProduct.attr, 474 &dev_attr_idProduct.attr,
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 8121edbd1494..c99938d5f78e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -266,6 +266,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
266 dev->dev.dma_mask = bus->controller->dma_mask; 266 dev->dev.dma_mask = bus->controller->dma_mask;
267 set_dev_node(&dev->dev, dev_to_node(bus->controller)); 267 set_dev_node(&dev->dev, dev_to_node(bus->controller));
268 dev->state = USB_STATE_ATTACHED; 268 dev->state = USB_STATE_ATTACHED;
269 atomic_set(&dev->urbnum, 0);
269 270
270 INIT_LIST_HEAD(&dev->ep0.urb_list); 271 INIT_LIST_HEAD(&dev->ep0.urb_list);
271 dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; 272 dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e5b35e0dca23..c10935fdc03a 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -415,6 +415,7 @@ struct usb_device {
415 415
416 int pm_usage_cnt; /* usage counter for autosuspend */ 416 int pm_usage_cnt; /* usage counter for autosuspend */
417 u32 quirks; /* quirks of the whole device */ 417 u32 quirks; /* quirks of the whole device */
418 atomic_t urbnum; /* number of URBs submitted for the whole device */
418 419
419#ifdef CONFIG_PM 420#ifdef CONFIG_PM
420 struct delayed_work autosuspend; /* for delayed autosuspends */ 421 struct delayed_work autosuspend; /* for delayed autosuspends */