From 5a68e9b57b1c1984dae8a9625bbf1a505d166035 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 Aug 2013 09:43:28 +0200 Subject: usb: gadget: configfs: keep a function if it is not successfully added If usb_add_function() fails then the currently processed function is already not in the list in struct config_usb_cfg, and neither is it in the list in struct usb_configuration. At the err_purge_funcs label the purge_config_funcs() is called, which iterates over all configurations, and in each configuration it iterates over all _successfully_ added functions, and moves them back from the list in struct usb_configuration to the list in struct config_usb_cfg. BUT the function which has just failed adding and caused the unwind process is not taken care of and is effectively lost. This patch modifies the configfs_composite_bind() function so that if the usb_add_function() fails, then the currently processed function is returned to the list in struct config_usb_cfg. It would be tempting to delay the list_del() in question after usb_add_function() invocation, but a struct list_head (&f->list) cannot be stored in more than one list at the same time, so the list_del() must be called before usb_add_function(). Hence, the solution is to list_add() after usb_add_function() in case of error. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 80e7f75a56c7..8f0d6141e5e6 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -859,8 +859,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget, list_for_each_entry_safe(f, tmp, &cfg->func_list, list) { list_del(&f->list); ret = usb_add_function(c, f); - if (ret) + if (ret) { + list_add(&f->list, &cfg->func_list); goto err_purge_funcs; + } } usb_ep_autoconfig_reset(cdev->gadget); } -- cgit v1.2.3 From b2fb945d607ec33cbaf47ac1173fbd03511b4fb4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 18 Aug 2013 22:20:41 +0200 Subject: usb: gadget: USB_FUSB300 should depend on HAS_DMA If NO_DMA=y: drivers/built-in.o: In function `fusb300_set_idma': drivers/usb/gadget/fusb300_udc.c:946: undefined reference to `usb_gadget_map_request' drivers/usb/gadget/fusb300_udc.c:958: undefined reference to `usb_gadget_unmap_request' Signed-off-by: Geert Uytterhoeven Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bddd7ede5455..af19b562b6d9 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -187,7 +187,7 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" - depends on !PHYS_ADDR_T_64BIT + depends on !PHYS_ADDR_T_64BIT && HAS_DMA help Faraday usb device controller FUSB300 driver -- cgit v1.2.3 From 4ee4f23bb04ef6602910a0adbb0824094ffb4a7d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 18 Aug 2013 22:20:42 +0200 Subject: usb: gadget: USB_R8A66597 should depend on HAS_DMA If NO_DMA=y: drivers/built-in.o: In function `sudmac_free_channel': drivers/usb/gadget/r8a66597-udc.c:676: undefined reference to `usb_gadget_unmap_request' drivers/built-in.o: In function `sudmac_alloc_channel': drivers/usb/gadget/r8a66597-udc.c:666: undefined reference to `usb_gadget_map_request' Signed-off-by: Geert Uytterhoeven Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index af19b562b6d9..e1b64c47d1f7 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -244,6 +244,7 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" + depends on HAS_DMA help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers. -- cgit v1.2.3 From 272b05a9885bfe8575beac0e4fa1a1bc121f17ec Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 18 Aug 2013 22:20:43 +0200 Subject: usb: gadget: USB_NET2272_DMA should depend on HAS_DMA If NO_DMA=y: drivers/built-in.o: In function `net2272_done': drivers/usb/gadget/net2272.c:386: undefined reference to `usb_gadget_unmap_request' drivers/built-in.o: In function `net2272_queue': drivers/usb/gadget/net2272.c:848: undefined reference to `usb_gadget_map_request' Signed-off-by: Geert Uytterhoeven Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e1b64c47d1f7..30e2dd8a1f2c 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -386,7 +386,7 @@ config USB_NET2272 config USB_NET2272_DMA boolean "Support external DMA controller" - depends on USB_NET2272 + depends on USB_NET2272 && HAS_DMA help The NET2272 part can optionally support an external DMA controller, but your board has to have support in the -- cgit v1.2.3 From 1826e9b1bd9139850954acb9c2e0fb230ba94e0d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Aug 2013 11:14:49 +0300 Subject: usb: gadget: gadgetfs: use after free in dev_release() The call to put_dev() releases "dev". Hopefully, we don't need to set the state to STATE_DEV_DISABLED anyway so I have removed those lines. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/inode.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 570c005062ab..465ef8e2cc91 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1270,10 +1270,6 @@ dev_release (struct inode *inode, struct file *fd) dev->buf = NULL; put_dev (dev); - /* other endpoints were all decoupled from this device */ - spin_lock_irq(&dev->lock); - dev->state = STATE_DEV_DISABLED; - spin_unlock_irq(&dev->lock); return 0; } -- cgit v1.2.3 From df4989954abc5ae160865bec79b0f099086decce Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Aug 2013 11:16:15 +0300 Subject: usb: gadget: gadgetfs: potential use after free in unbind() ffs_data_put() can sometimes free "ffs" so I have moved the call down a line below the dereference. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index f394f295d63d..1a66c5baa0d1 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1417,8 +1417,8 @@ static void functionfs_unbind(struct ffs_data *ffs) usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req); ffs->ep0req = NULL; ffs->gadget = NULL; - ffs_data_put(ffs); clear_bit(FFS_FL_BOUND, &ffs->flags); + ffs_data_put(ffs); } } -- cgit v1.2.3 From ffb62a14c7b6109ca4ee9bb360ad867b294acddc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 21 Aug 2013 11:42:24 +0300 Subject: usb: gadget: double unlocks on error in atmel_usba_start() The "goto out" statements were wrong. We aren't holding any locks at that point so we should return directly. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/usb/gadget') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 40d23384b716..2cb52e0438df 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1772,7 +1772,7 @@ out: static int atmel_usba_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { - int ret = 0; + int ret; struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); unsigned long flags; @@ -1784,11 +1784,11 @@ static int atmel_usba_start(struct usb_gadget *gadget, ret = clk_prepare_enable(udc->pclk); if (ret) - goto out; + return ret; ret = clk_prepare_enable(udc->hclk); if (ret) { clk_disable_unprepare(udc->pclk); - goto out; + return ret; } DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); @@ -1804,11 +1804,9 @@ static int atmel_usba_start(struct usb_gadget *gadget, usba_writel(udc, CTRL, USBA_ENABLE_MASK); usba_writel(udc, INT_ENB, USBA_END_OF_RESET); } - -out: spin_unlock_irqrestore(&udc->lock, flags); - return ret; + return 0; } static int atmel_usba_stop(struct usb_gadget *gadget, -- cgit v1.2.3