aboutsummaryrefslogtreecommitdiffstats
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.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 85c876c1f150..f2da0269e1b1 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -128,6 +128,70 @@ done:
128} 128}
129 129
130/** 130/**
131 * usb_function_deactivate - prevent function and gadget enumeration
132 * @function: the function that isn't yet ready to respond
133 *
134 * Blocks response of the gadget driver to host enumeration by
135 * preventing the data line pullup from being activated. This is
136 * normally called during @bind() processing to change from the
137 * initial "ready to respond" state, or when a required resource
138 * becomes available.
139 *
140 * For example, drivers that serve as a passthrough to a userspace
141 * daemon can block enumeration unless that daemon (such as an OBEX,
142 * MTP, or print server) is ready to handle host requests.
143 *
144 * Not all systems support software control of their USB peripheral
145 * data pullups.
146 *
147 * Returns zero on success, else negative errno.
148 */
149int usb_function_deactivate(struct usb_function *function)
150{
151 struct usb_composite_dev *cdev = function->config->cdev;
152 int status = 0;
153
154 spin_lock(&cdev->lock);
155
156 if (cdev->deactivations == 0)
157 status = usb_gadget_disconnect(cdev->gadget);
158 if (status == 0)
159 cdev->deactivations++;
160
161 spin_unlock(&cdev->lock);
162 return status;
163}
164
165/**
166 * usb_function_activate - allow function and gadget enumeration
167 * @function: function on which usb_function_activate() was called
168 *
169 * Reverses effect of usb_function_deactivate(). If no more functions
170 * are delaying their activation, the gadget driver will respond to
171 * host enumeration procedures.
172 *
173 * Returns zero on success, else negative errno.
174 */
175int usb_function_activate(struct usb_function *function)
176{
177 struct usb_composite_dev *cdev = function->config->cdev;
178 int status = 0;
179
180 spin_lock(&cdev->lock);
181
182 if (WARN_ON(cdev->deactivations == 0))
183 status = -EINVAL;
184 else {
185 cdev->deactivations--;
186 if (cdev->deactivations == 0)
187 status = usb_gadget_connect(cdev->gadget);
188 }
189
190 spin_unlock(&cdev->lock);
191 return status;
192}
193
194/**
131 * usb_interface_id() - allocate an unused interface ID 195 * usb_interface_id() - allocate an unused interface ID
132 * @config: configuration associated with the interface 196 * @config: configuration associated with the interface
133 * @function: function handling the interface 197 * @function: function handling the interface
@@ -181,7 +245,7 @@ static int config_buf(struct usb_configuration *config,
181 c->bConfigurationValue = config->bConfigurationValue; 245 c->bConfigurationValue = config->bConfigurationValue;
182 c->iConfiguration = config->iConfiguration; 246 c->iConfiguration = config->iConfiguration;
183 c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; 247 c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
184 c->bMaxPower = config->bMaxPower; 248 c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2);
185 249
186 /* There may be e.g. OTG descriptors */ 250 /* There may be e.g. OTG descriptors */
187 if (config->descriptors) { 251 if (config->descriptors) {
@@ -368,7 +432,7 @@ static int set_config(struct usb_composite_dev *cdev,
368 } 432 }
369 433
370 /* when we return, be sure our power usage is valid */ 434 /* when we return, be sure our power usage is valid */
371 power = 2 * c->bMaxPower; 435 power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
372done: 436done:
373 usb_gadget_vbus_draw(gadget, power); 437 usb_gadget_vbus_draw(gadget, power);
374 return result; 438 return result;