usb: gadget: consider link speed for bMaxPower
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Mon, 3 Dec 2012 19:07:05 +0000 (20:07 +0100)
committerFelipe Balbi <balbi@ti.com>
Thu, 10 Jan 2013 10:38:52 +0000 (12:38 +0200)
The USB 2.0 specification says that bMaxPower is the maximum power
consumption expressed in 2 mA units and the USB 3.0 specification says
that it is expressed in 8 mA units.

This patch renames bMaxPower to MaxPower and the various /2 and *2 are
removed. Before reporting the config descriptor, the proper value is
computer based on the speed, all in-tree users are updated. MaxPower is
also increased to u16 so we can store the nokia gadget value which is
larger than the max value allowed for u8.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/composite.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/nokia.c
drivers/usb/gadget/webcam.c
include/linux/usb/composite.h

index 2a6bfe7..71475b6 100644 (file)
@@ -320,6 +320,25 @@ int usb_interface_id(struct usb_configuration *config,
 }
 EXPORT_SYMBOL_GPL(usb_interface_id);
 
+static u8 encode_bMaxPower(enum usb_device_speed speed,
+               struct usb_configuration *c)
+{
+       unsigned val;
+
+       if (c->MaxPower)
+               val = c->MaxPower;
+       else
+               val = CONFIG_USB_GADGET_VBUS_DRAW;
+       if (!val)
+               return 0;
+       switch (speed) {
+       case USB_SPEED_SUPER:
+               return DIV_ROUND_UP(val, 8);
+       default:
+               return DIV_ROUND_UP(val, 2);
+       };
+}
+
 static int config_buf(struct usb_configuration *config,
                enum usb_device_speed speed, void *buf, u8 type)
 {
@@ -339,7 +358,7 @@ static int config_buf(struct usb_configuration *config,
        c->bConfigurationValue = config->bConfigurationValue;
        c->iConfiguration = config->iConfiguration;
        c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
-       c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2);
+       c->bMaxPower = encode_bMaxPower(speed, config);
 
        /* There may be e.g. OTG descriptors */
        if (config->descriptors) {
@@ -656,7 +675,7 @@ static int set_config(struct usb_composite_dev *cdev,
        }
 
        /* when we return, be sure our power usage is valid */
-       power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
+       power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
 done:
        usb_gadget_vbus_draw(gadget, power);
        if (result >= 0 && cdev->delayed_status)
@@ -1518,10 +1537,10 @@ composite_resume(struct usb_gadget *gadget)
                                f->resume(f);
                }
 
-               maxpower = cdev->config->bMaxPower;
+               maxpower = cdev->config->MaxPower;
 
                usb_gadget_vbus_draw(gadget, maxpower ?
-                       (2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW);
+                       maxpower : CONFIG_USB_GADGET_VBUS_DRAW);
        }
 
        cdev->suspended = 0;
index 881aab8..e879e2c 100644 (file)
@@ -125,7 +125,7 @@ static struct usb_configuration midi_config = {
        .bConfigurationValue = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes   = USB_CONFIG_ATT_ONE,
-       .bMaxPower      = CONFIG_USB_GADGET_VBUS_DRAW / 2,
+       .MaxPower       = CONFIG_USB_GADGET_VBUS_DRAW,
 };
 
 static int __init midi_bind_config(struct usb_configuration *c)
index 661600a..1475d66 100644 (file)
@@ -133,7 +133,7 @@ static struct usb_configuration nokia_config_500ma_driver = {
        .bConfigurationValue = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes   = USB_CONFIG_ATT_ONE,
-       .bMaxPower      = 250, /* 500mA */
+       .MaxPower       = 500,
 };
 
 static struct usb_configuration nokia_config_100ma_driver = {
@@ -141,7 +141,7 @@ static struct usb_configuration nokia_config_100ma_driver = {
        .bConfigurationValue = 2,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes   = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower      = 50, /* 100 mA */
+       .MaxPower       = 100,
 };
 
 static int __init nokia_bind(struct usb_composite_dev *cdev)
index 69cf5c2..8cef1e6 100644 (file)
@@ -336,7 +336,7 @@ static struct usb_configuration webcam_config_driver = {
        .bConfigurationValue    = 1,
        .iConfiguration         = 0, /* dynamic */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower              = CONFIG_USB_GADGET_VBUS_DRAW / 2,
+       .MaxPower               = CONFIG_USB_GADGET_VBUS_DRAW,
 };
 
 static int /* __init_or_exit */
index b09c37e..dc512c9 100644 (file)
@@ -184,7 +184,8 @@ int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f,
  * @bConfigurationValue: Copied into configuration descriptor.
  * @iConfiguration: Copied into configuration descriptor.
  * @bmAttributes: Copied into configuration descriptor.
- * @bMaxPower: Copied into configuration descriptor.
+ * @MaxPower: Power consumtion in mA. Used to compute bMaxPower in the
+ *     configuration descriptor after considering the bus speed.
  * @cdev: assigned by @usb_add_config() before calling @bind(); this is
  *     the device associated with this configuration.
  *
@@ -230,7 +231,7 @@ struct usb_configuration {
        u8                      bConfigurationValue;
        u8                      iConfiguration;
        u8                      bmAttributes;
-       u8                      bMaxPower;
+       u16                     MaxPower;
 
        struct usb_composite_dev        *cdev;