Commit f9d76d15 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

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: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Fixes: fc274c1e ("USB: gadget: Add a new bus for gadgets")
Link: https://lore.kernel.org/r/YnqKAXKyp9Vq/pbn@rowland.harvard.eduSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a2673d57
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/idr.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
...@@ -23,6 +24,8 @@ ...@@ -23,6 +24,8 @@
#include "trace.h" #include "trace.h"
static DEFINE_IDA(gadget_id_numbers);
static struct bus_type gadget_bus_type; static struct bus_type gadget_bus_type;
/** /**
...@@ -1248,7 +1251,6 @@ static void usb_udc_nop_release(struct device *dev) ...@@ -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 usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev)) void (*release)(struct device *dev))
{ {
dev_set_name(&gadget->dev, "gadget");
INIT_WORK(&gadget->work, usb_gadget_state_work); INIT_WORK(&gadget->work, usb_gadget_state_work);
gadget->dev.parent = parent; gadget->dev.parent = parent;
...@@ -1304,12 +1306,21 @@ int usb_add_gadget(struct usb_gadget *gadget) ...@@ -1304,12 +1306,21 @@ int usb_add_gadget(struct usb_gadget *gadget)
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true; 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); ret = device_add(&gadget->dev);
if (ret) if (ret)
goto err_del_udc; goto err_free_id;
return 0; return 0;
err_free_id:
ida_free(&gadget_id_numbers, gadget->id_number);
err_del_udc: err_del_udc:
flush_work(&gadget->work); flush_work(&gadget->work);
device_del(&udc->dev); device_del(&udc->dev);
...@@ -1417,6 +1428,7 @@ void usb_del_gadget(struct usb_gadget *gadget) ...@@ -1417,6 +1428,7 @@ void usb_del_gadget(struct usb_gadget *gadget)
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
flush_work(&gadget->work); flush_work(&gadget->work);
device_del(&gadget->dev); device_del(&gadget->dev);
ida_free(&gadget_id_numbers, gadget->id_number);
device_unregister(&udc->dev); device_unregister(&udc->dev);
} }
EXPORT_SYMBOL_GPL(usb_del_gadget); EXPORT_SYMBOL_GPL(usb_del_gadget);
......
...@@ -386,6 +386,7 @@ struct usb_gadget_ops { ...@@ -386,6 +386,7 @@ struct usb_gadget_ops {
* @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag * @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag
* indicates that it supports LPM as per the LPM ECN & errata. * indicates that it supports LPM as per the LPM ECN & errata.
* @irq: the interrupt number for device controller. * @irq: the interrupt number for device controller.
* @id_number: a unique ID number for ensuring that gadget names are distinct
* *
* Gadgets have a mostly-portable "gadget driver" implementing device * Gadgets have a mostly-portable "gadget driver" implementing device
* functions, handling all usb configurations and interfaces. Gadget * functions, handling all usb configurations and interfaces. Gadget
...@@ -446,6 +447,7 @@ struct usb_gadget { ...@@ -446,6 +447,7 @@ struct usb_gadget {
unsigned connected:1; unsigned connected:1;
unsigned lpm_capable:1; unsigned lpm_capable:1;
int irq; int irq;
int id_number;
}; };
#define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) #define work_to_gadget(w) (container_of((w), struct usb_gadget, work))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment