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) */ usb_get_urb(urb); atomic_inc(&urb->use_count); + atomic_inc(&urb->dev->urbnum); usbmon_urb_submit(&hcd->self, urb); /* 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) urb->hcpriv = NULL; INIT_LIST_HEAD(&urb->urb_list); atomic_dec(&urb->use_count); + atomic_dec(&urb->dev->urbnum); if (urb->reject) wake_up(&usb_kill_urb_queue); 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) } static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); +static ssize_t +show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_device *udev; + + udev = to_usb_device(dev); + return sprintf(buf, "%d\n", atomic_read(&udev->urbnum)); +} +static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); + #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) static const char power_group[] = "power"; @@ -458,6 +468,7 @@ static struct attribute *dev_attrs[] = { &dev_attr_bConfigurationValue.attr, &dev_attr_bmAttributes.attr, &dev_attr_bMaxPower.attr, + &dev_attr_urbnum.attr, /* device attributes */ &dev_attr_idVendor.attr, &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) dev->dev.dma_mask = bus->controller->dma_mask; set_dev_node(&dev->dev, dev_to_node(bus->controller)); dev->state = USB_STATE_ATTACHED; + atomic_set(&dev->urbnum, 0); INIT_LIST_HEAD(&dev->ep0.urb_list); 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 { int pm_usage_cnt; /* usage counter for autosuspend */ u32 quirks; /* quirks of the whole device */ + atomic_t urbnum; /* number of URBs submitted for the whole device */ #ifdef CONFIG_PM struct delayed_work autosuspend; /* for delayed autosuspends */