summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/udc/core.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2022-05-10 11:51:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-05-11 18:59:25 +0200
commitf9d76d15072caf1ec5558fa7cc6d93c7b9d33488 (patch)
treeed7dfff99994add27e32f3b32c4b49bac3271d89 /drivers/usb/gadget/udc/core.c
parenta2673d570bd648851e00ac531bdf695f4ebb4f78 (diff)
USB: gadget: Add ID numbers to gadget names
Putting USB gadgets on a new bus of their own encounters a problem when multiple gadgets are present: They all have the same name! The driver core fails with a "sys: cannot create duplicate filename" error when creating any of the /sys/bus/gadget/devices/<gadget-name> symbolic links after the first. This patch fixes the problem by adding a ".N" suffix to each gadget's name when the gadget is registered (where N is a unique ID number), thus making the names distinct. Reported-and-tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Fixes: fc274c1e9973 ("USB: gadget: Add a new bus for gadgets") Link: https://lore.kernel.org/r/YnqKAXKyp9Vq/pbn@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/udc/core.c')
-rw-r--r--drivers/usb/gadget/udc/core.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 3281d8a3dae7..7886497253cc 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/list.h>
+#include <linux/idr.h>
#include <linux/err.h>
#include <linux/dma-mapping.h>
#include <linux/sched/task_stack.h>
@@ -23,6 +24,8 @@
#include "trace.h"
+static DEFINE_IDA(gadget_id_numbers);
+
static struct bus_type gadget_bus_type;
/**
@@ -1248,7 +1251,6 @@ static void usb_udc_nop_release(struct device *dev)
void usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
{
- dev_set_name(&gadget->dev, "gadget");
INIT_WORK(&gadget->work, usb_gadget_state_work);
gadget->dev.parent = parent;
@@ -1304,12 +1306,21 @@ int usb_add_gadget(struct usb_gadget *gadget)
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
+ ret = ida_alloc(&gadget_id_numbers, GFP_KERNEL);
+ if (ret < 0)
+ goto err_del_udc;
+ gadget->id_number = ret;
+ dev_set_name(&gadget->dev, "gadget.%d", ret);
+
ret = device_add(&gadget->dev);
if (ret)
- goto err_del_udc;
+ goto err_free_id;
return 0;
+ err_free_id:
+ ida_free(&gadget_id_numbers, gadget->id_number);
+
err_del_udc:
flush_work(&gadget->work);
device_del(&udc->dev);
@@ -1417,6 +1428,7 @@ void usb_del_gadget(struct usb_gadget *gadget)
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
flush_work(&gadget->work);
device_del(&gadget->dev);
+ ida_free(&gadget_id_numbers, gadget->id_number);
device_unregister(&udc->dev);
}
EXPORT_SYMBOL_GPL(usb_del_gadget);