summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r--drivers/usb/gadget/composite.c60
1 files changed, 23 insertions, 37 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index bdda8c74602d..5b3866909b75 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1011,7 +1011,7 @@ static int set_config(struct usb_composite_dev *cdev,
ep = (struct usb_endpoint_descriptor *)*descriptors;
addr = ((ep->bEndpointAddress & 0x80) >> 3)
- | (ep->bEndpointAddress & 0x0f);
+ | usb_endpoint_num(ep);
set_bit(addr, f->endpoints);
}
@@ -1050,10 +1050,11 @@ static int set_config(struct usb_composite_dev *cdev,
else
usb_gadget_set_remote_wakeup(gadget, 0);
done:
- if (power <= USB_SELF_POWER_VBUS_MAX_DRAW)
- usb_gadget_set_selfpowered(gadget);
- else
+ if (power > USB_SELF_POWER_VBUS_MAX_DRAW ||
+ (c && !(c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)))
usb_gadget_clear_selfpowered(gadget);
+ else
+ usb_gadget_set_selfpowered(gadget);
usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status)
@@ -1193,30 +1194,6 @@ static void remove_config(struct usb_composite_dev *cdev,
}
}
-/**
- * usb_remove_config() - remove a configuration from a device.
- * @cdev: wraps the USB gadget
- * @config: the configuration
- *
- * Drivers must call usb_gadget_disconnect before calling this function
- * to disconnect the device from the host and make sure the host will not
- * try to enumerate the device while we are changing the config list.
- */
-void usb_remove_config(struct usb_composite_dev *cdev,
- struct usb_configuration *config)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cdev->lock, flags);
-
- if (cdev->config == config)
- reset_config(cdev);
-
- spin_unlock_irqrestore(&cdev->lock, flags);
-
- remove_config(cdev, config);
-}
-
/*-------------------------------------------------------------------------*/
/* We support strings in multiple languages ... string descriptor zero
@@ -2010,15 +1987,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
if (f->get_status) {
status = f->get_status(f);
+
if (status < 0)
break;
- } else {
- /* Set D0 and D1 bits based on func wakeup capability */
- if (f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP) {
- status |= USB_INTRF_STAT_FUNC_RW_CAP;
- if (f->func_wakeup_armed)
- status |= USB_INTRF_STAT_FUNC_RW;
- }
+
+ /* if D5 is not set, then device is not wakeup capable */
+ if (!(f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP))
+ status &= ~(USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW);
}
put_unaligned_le16(status & 0x0000ffff, req->buf);
@@ -2490,6 +2465,11 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
if (!cdev->os_desc_req->buf) {
ret = -ENOMEM;
usb_ep_free_request(ep0, cdev->os_desc_req);
+ /*
+ * Set os_desc_req to NULL so that composite_dev_cleanup()
+ * will not try to free it again.
+ */
+ cdev->os_desc_req = NULL;
goto end;
}
cdev->os_desc_req->context = cdev;
@@ -2615,7 +2595,10 @@ void composite_suspend(struct usb_gadget *gadget)
cdev->suspended = 1;
- usb_gadget_set_selfpowered(gadget);
+ if (cdev->config &&
+ cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER)
+ usb_gadget_set_selfpowered(gadget);
+
usb_gadget_vbus_draw(gadget, 2);
}
@@ -2649,8 +2632,11 @@ void composite_resume(struct usb_gadget *gadget)
else
maxpower = min(maxpower, 900U);
- if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW)
+ if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW ||
+ !(cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER))
usb_gadget_clear_selfpowered(gadget);
+ else
+ usb_gadget_set_selfpowered(gadget);
usb_gadget_vbus_draw(gadget, maxpower);
} else {