Skip to content

Commit

Permalink
usb: gadget: provide interface for legacy gadgets to get UDC name
Browse files Browse the repository at this point in the history
Since commit 855ed04 ("usb: gadget:
udc-core: independent registration of gadgets and gadget drivers") gadget
drivers can not assume that UDC drivers are already available on their
initialization. This broke the HACK, which was used in gadgetfs driver,
to get UDC controller name. This patch removes this hack and replaces it
by additional function in the UDC core (which is usefully only for legacy
drivers, please don't use it in the new code).

Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
  • Loading branch information
Marek Szyprowski authored and Felipe Balbi committed Mar 4, 2016
1 parent 4111d49 commit 175f712
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 25 deletions.
28 changes: 3 additions & 25 deletions drivers/usb/gadget/legacy/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1699,28 +1699,6 @@ static struct usb_gadget_driver gadgetfs_driver = {
};

/*----------------------------------------------------------------------*/

static void gadgetfs_nop(struct usb_gadget *arg) { }

static int gadgetfs_probe(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
{
CHIP = gadget->name;
return -EISNAM;
}

static struct usb_gadget_driver probe_driver = {
.max_speed = USB_SPEED_HIGH,
.bind = gadgetfs_probe,
.unbind = gadgetfs_nop,
.setup = (void *)gadgetfs_nop,
.disconnect = gadgetfs_nop,
.driver = {
.name = "nop",
},
};


/* DEVICE INITIALIZATION
*
* fd = open ("/dev/gadget/$CHIP", O_RDWR)
Expand Down Expand Up @@ -1971,9 +1949,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
if (the_device)
return -ESRCH;

/* fake probe to determine $CHIP */
CHIP = NULL;
usb_gadget_probe_driver(&probe_driver);
CHIP = usb_get_gadget_udc_name();
if (!CHIP)
return -ENODEV;

Expand Down Expand Up @@ -2034,6 +2010,8 @@ gadgetfs_kill_sb (struct super_block *sb)
put_dev (the_device);
the_device = NULL;
}
kfree(CHIP);
CHIP = NULL;
}

/*----------------------------------------------------------------------*/
Expand Down
30 changes: 30 additions & 0 deletions drivers/usb/gadget/udc/udc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,36 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
}
EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release);

/**
* usb_get_gadget_udc_name - get the name of the first UDC controller
* This functions returns the name of the first UDC controller in the system.
* Please note that this interface is usefull only for legacy drivers which
* assume that there is only one UDC controller in the system and they need to
* get its name before initialization. There is no guarantee that the UDC
* of the returned name will be still available, when gadget driver registers
* itself.
*
* Returns pointer to string with UDC controller name on success, NULL
* otherwise. Caller should kfree() returned string.
*/
char *usb_get_gadget_udc_name(void)
{
struct usb_udc *udc;
char *name = NULL;

/* For now we take the first available UDC */
mutex_lock(&udc_lock);
list_for_each_entry(udc, &udc_list, list) {
if (!udc->driver) {
name = kstrdup(udc->gadget->name, GFP_KERNEL);
break;
}
}
mutex_unlock(&udc_lock);
return name;
}
EXPORT_SYMBOL_GPL(usb_get_gadget_udc_name);

/**
* usb_add_gadget_udc - adds a new gadget to the udc class driver list
* @parent: the parent device to this udc. Usually the controller
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/gadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,7 @@ extern int usb_add_gadget_udc_release(struct device *parent,
struct usb_gadget *gadget, void (*release)(struct device *dev));
extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget);
extern void usb_del_gadget_udc(struct usb_gadget *gadget);
extern char *usb_get_gadget_udc_name(void);

/*-------------------------------------------------------------------------*/

Expand Down

0 comments on commit 175f712

Please sign in to comment.