diff options
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r-- | drivers/usb/gadget/composite.c | 68 |
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 | */ | ||
149 | int 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 | */ | ||
175 | int 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; |
372 | done: | 436 | done: |
373 | usb_gadget_vbus_draw(gadget, power); | 437 | usb_gadget_vbus_draw(gadget, power); |
374 | return result; | 438 | return result; |