diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-02-06 12:46:35 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-09 03:10:57 -0500 |
commit | 609ca228073ae06c5513474d2cdf0af7ee5766ec (patch) | |
tree | c6d1fe216bade3bb47a5b8d54d9f478ea507dda0 /drivers/usb/gadget/epautoconf.c | |
parent | 637b78eb31e0b167ed913f1750bb645dfeda38f0 (diff) |
usb: gadget: clean the ep in autoconf before returning it.
Since commit 72c973dd aka ("usb: gadget: add usb_endpoint_descriptor to
struct usb_ep) the descriptor is part of the ep. Most gadgets like
g_zero or masstorage call config_ep_by_speed() to grab an available
endpoint which may be used for FS/HS/SS bulk/iso/intr and in a second
they assign the proper descriptor by calling config_ep_by_speed(). This
is good so far. A few of them like ncm call config_ep_by_speed() only if
ep->desc not assigned earlier. That means ep->desc is never assigned if
the endpoint was used by another gadget before it was removed.
Some of those gadgets also assign ep->driver_data to NULL on reset or
ep_disable part _but_ keep a reference to this endpoint. At ep_enable
time they assign driver_data to their private data. This probably needs
a clean up of its own.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/epautoconf.c')
-rw-r--r-- | drivers/usb/gadget/epautoconf.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 753aa0683ac1..f59f7e367b5a 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -275,24 +275,24 @@ struct usb_ep *usb_ep_autoconfig_ss( | |||
275 | /* ep-e, ep-f are PIO with only 64 byte fifos */ | 275 | /* ep-e, ep-f are PIO with only 64 byte fifos */ |
276 | ep = find_ep (gadget, "ep-e"); | 276 | ep = find_ep (gadget, "ep-e"); |
277 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 277 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
278 | return ep; | 278 | goto found_ep; |
279 | ep = find_ep (gadget, "ep-f"); | 279 | ep = find_ep (gadget, "ep-f"); |
280 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 280 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
281 | return ep; | 281 | goto found_ep; |
282 | 282 | ||
283 | } else if (gadget_is_goku (gadget)) { | 283 | } else if (gadget_is_goku (gadget)) { |
284 | if (USB_ENDPOINT_XFER_INT == type) { | 284 | if (USB_ENDPOINT_XFER_INT == type) { |
285 | /* single buffering is enough */ | 285 | /* single buffering is enough */ |
286 | ep = find_ep(gadget, "ep3-bulk"); | 286 | ep = find_ep(gadget, "ep3-bulk"); |
287 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 287 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
288 | return ep; | 288 | goto found_ep; |
289 | } else if (USB_ENDPOINT_XFER_BULK == type | 289 | } else if (USB_ENDPOINT_XFER_BULK == type |
290 | && (USB_DIR_IN & desc->bEndpointAddress)) { | 290 | && (USB_DIR_IN & desc->bEndpointAddress)) { |
291 | /* DMA may be available */ | 291 | /* DMA may be available */ |
292 | ep = find_ep(gadget, "ep2-bulk"); | 292 | ep = find_ep(gadget, "ep2-bulk"); |
293 | if (ep && ep_matches(gadget, ep, desc, | 293 | if (ep && ep_matches(gadget, ep, desc, |
294 | ep_comp)) | 294 | ep_comp)) |
295 | return ep; | 295 | goto found_ep; |
296 | } | 296 | } |
297 | 297 | ||
298 | #ifdef CONFIG_BLACKFIN | 298 | #ifdef CONFIG_BLACKFIN |
@@ -311,18 +311,22 @@ struct usb_ep *usb_ep_autoconfig_ss( | |||
311 | } else | 311 | } else |
312 | ep = NULL; | 312 | ep = NULL; |
313 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 313 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
314 | return ep; | 314 | goto found_ep; |
315 | #endif | 315 | #endif |
316 | } | 316 | } |
317 | 317 | ||
318 | /* Second, look at endpoints until an unclaimed one looks usable */ | 318 | /* Second, look at endpoints until an unclaimed one looks usable */ |
319 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { | 319 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { |
320 | if (ep_matches(gadget, ep, desc, ep_comp)) | 320 | if (ep_matches(gadget, ep, desc, ep_comp)) |
321 | return ep; | 321 | goto found_ep; |
322 | } | 322 | } |
323 | 323 | ||
324 | /* Fail */ | 324 | /* Fail */ |
325 | return NULL; | 325 | return NULL; |
326 | found_ep: | ||
327 | ep->desc = NULL; | ||
328 | ep->comp_desc = NULL; | ||
329 | return ep; | ||
326 | } | 330 | } |
327 | 331 | ||
328 | /** | 332 | /** |