Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sebastian Andrzej Siewior and committed by
Felipe Balbi
609ca228 637b78eb

+10 -6
+10 -6
drivers/usb/gadget/epautoconf.c
··· 275 275 /* ep-e, ep-f are PIO with only 64 byte fifos */ 276 276 ep = find_ep (gadget, "ep-e"); 277 277 if (ep && ep_matches(gadget, ep, desc, ep_comp)) 278 - return ep; 278 + goto found_ep; 279 279 ep = find_ep (gadget, "ep-f"); 280 280 if (ep && ep_matches(gadget, ep, desc, ep_comp)) 281 - return ep; 281 + goto found_ep; 282 282 283 283 } else if (gadget_is_goku (gadget)) { 284 284 if (USB_ENDPOINT_XFER_INT == type) { 285 285 /* single buffering is enough */ 286 286 ep = find_ep(gadget, "ep3-bulk"); 287 287 if (ep && ep_matches(gadget, ep, desc, ep_comp)) 288 - return ep; 288 + goto found_ep; 289 289 } else if (USB_ENDPOINT_XFER_BULK == type 290 290 && (USB_DIR_IN & desc->bEndpointAddress)) { 291 291 /* DMA may be available */ 292 292 ep = find_ep(gadget, "ep2-bulk"); 293 293 if (ep && ep_matches(gadget, ep, desc, 294 294 ep_comp)) 295 - return ep; 295 + goto found_ep; 296 296 } 297 297 298 298 #ifdef CONFIG_BLACKFIN ··· 311 311 } else 312 312 ep = NULL; 313 313 if (ep && ep_matches(gadget, ep, desc, ep_comp)) 314 - return ep; 314 + goto found_ep; 315 315 #endif 316 316 } 317 317 318 318 /* Second, look at endpoints until an unclaimed one looks usable */ 319 319 list_for_each_entry (ep, &gadget->ep_list, ep_list) { 320 320 if (ep_matches(gadget, ep, desc, ep_comp)) 321 - return ep; 321 + goto found_ep; 322 322 } 323 323 324 324 /* Fail */ 325 325 return NULL; 326 + found_ep: 327 + ep->desc = NULL; 328 + ep->comp_desc = NULL; 329 + return ep; 326 330 } 327 331 328 332 /**