USB: gadget: added a saner gadget downloader registration API
Preprocessor definitions and hardcoded implementation selection in g_dnl core were replaced by a linker list made of (usb_function_name, bind_callback) pairs. Signed-off-by: Mateusz Zalega <m.zalega@samsung.com> Acked-by: Lukasz Majewski <l.majewski@samsung.com> Acked-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
fad8edf0f7
commit
c4d0e85604
|
@ -22,7 +22,6 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
char *interface = argv[2];
|
||||
char *devstring = argv[3];
|
||||
|
||||
char *s = "dfu";
|
||||
int ret, i = 0;
|
||||
|
||||
ret = dfu_init_env_entities(interface, simple_strtoul(devstring,
|
||||
|
@ -38,7 +37,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
int controller_index = simple_strtoul(usb_controller, NULL, 0);
|
||||
board_usb_init(controller_index, USB_INIT_DEVICE);
|
||||
|
||||
g_dnl_register(s);
|
||||
g_dnl_register("usb_dnl_dfu");
|
||||
while (1) {
|
||||
if (dfu_reset())
|
||||
/*
|
||||
|
|
|
@ -22,7 +22,6 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
char *interface = argv[2];
|
||||
char *devstring = argv[3];
|
||||
|
||||
const char *s = "thor";
|
||||
int ret;
|
||||
|
||||
puts("TIZEN \"THOR\" Downloader\n");
|
||||
|
@ -40,7 +39,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
goto exit;
|
||||
}
|
||||
|
||||
g_dnl_register(s);
|
||||
g_dnl_register("usb_dnl_thor");
|
||||
|
||||
ret = thor_init();
|
||||
if (ret) {
|
||||
|
|
|
@ -40,7 +40,7 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
|
|||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
g_dnl_register("ums");
|
||||
g_dnl_register("usb_dnl_ums");
|
||||
|
||||
/* Timeout unit: seconds */
|
||||
int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/usb/composite.h>
|
||||
|
||||
#include <dfu.h>
|
||||
#include <g_dnl.h>
|
||||
#include "f_dfu.h"
|
||||
|
||||
struct f_dfu {
|
||||
|
@ -817,3 +818,5 @@ int dfu_add(struct usb_configuration *c)
|
|||
|
||||
return dfu_bind_config(c);
|
||||
}
|
||||
|
||||
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_dfu, dfu_add);
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
#include <linux/usb/gadget.h>
|
||||
#include <linux/usb/composite.h>
|
||||
#include <usb/lin_gadget_compat.h>
|
||||
#include <g_dnl.h>
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -2778,3 +2779,5 @@ int fsg_init(struct ums *ums_dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_ums, fsg_add);
|
||||
|
|
|
@ -1004,3 +1004,5 @@ int thor_add(struct usb_configuration *c)
|
|||
debug("%s:\n", __func__);
|
||||
return thor_func_init(c);
|
||||
}
|
||||
|
||||
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_thor, thor_add);
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#define DRIVER_VERSION "usb_dnl 2.0"
|
||||
|
||||
static const char shortname[] = "usb_dnl_";
|
||||
static const char product[] = "USB download gadget";
|
||||
static char g_dnl_serial[MAX_STRING_SERIAL];
|
||||
static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER;
|
||||
|
@ -96,29 +95,36 @@ static int g_dnl_unbind(struct usb_composite_dev *cdev)
|
|||
free(cdev->config);
|
||||
cdev->config = NULL;
|
||||
debug("%s: calling usb_gadget_disconnect for "
|
||||
"controller '%s'\n", shortname, gadget->name);
|
||||
"controller '%s'\n", __func__, gadget->name);
|
||||
usb_gadget_disconnect(gadget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct g_dnl_bind_callback *g_dnl_bind_callback_first(void)
|
||||
{
|
||||
return ll_entry_start(struct g_dnl_bind_callback,
|
||||
g_dnl_bind_callbacks);
|
||||
}
|
||||
|
||||
static inline struct g_dnl_bind_callback *g_dnl_bind_callback_end(void)
|
||||
{
|
||||
return ll_entry_end(struct g_dnl_bind_callback,
|
||||
g_dnl_bind_callbacks);
|
||||
}
|
||||
|
||||
static int g_dnl_do_config(struct usb_configuration *c)
|
||||
{
|
||||
const char *s = c->cdev->driver->name;
|
||||
int ret = -1;
|
||||
struct g_dnl_bind_callback *callback = g_dnl_bind_callback_first();
|
||||
|
||||
debug("%s: configuration: 0x%p composite dev: 0x%p\n",
|
||||
__func__, c, c->cdev);
|
||||
|
||||
printf("GADGET DRIVER: %s\n", s);
|
||||
if (!strcmp(s, "usb_dnl_dfu"))
|
||||
ret = dfu_add(c);
|
||||
else if (!strcmp(s, "usb_dnl_ums"))
|
||||
ret = fsg_add(c);
|
||||
else if (!strcmp(s, "usb_dnl_thor"))
|
||||
ret = thor_add(c);
|
||||
|
||||
return ret;
|
||||
for (; callback != g_dnl_bind_callback_end(); callback++)
|
||||
if (!strcmp(s, callback->usb_function_name))
|
||||
return callback->fptr(c);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int g_dnl_config_register(struct usb_composite_dev *cdev)
|
||||
|
@ -208,12 +214,12 @@ static int g_dnl_bind(struct usb_composite_dev *cdev)
|
|||
device_desc.bcdDevice = cpu_to_le16(gcnum);
|
||||
else {
|
||||
debug("%s: controller '%s' not recognized\n",
|
||||
shortname, gadget->name);
|
||||
__func__, gadget->name);
|
||||
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
|
||||
}
|
||||
|
||||
debug("%s: calling usb_gadget_connect for "
|
||||
"controller '%s'\n", shortname, gadget->name);
|
||||
"controller '%s'\n", __func__, gadget->name);
|
||||
usb_gadget_connect(gadget);
|
||||
|
||||
return 0;
|
||||
|
@ -232,36 +238,22 @@ static struct usb_composite_driver g_dnl_driver = {
|
|||
.unbind = g_dnl_unbind,
|
||||
};
|
||||
|
||||
int g_dnl_register(const char *type)
|
||||
/*
|
||||
* NOTICE:
|
||||
* Registering via USB function name won't be necessary after rewriting
|
||||
* g_dnl to support multiple USB functions.
|
||||
*/
|
||||
int g_dnl_register(const char *name)
|
||||
{
|
||||
/* The largest function name is 4 */
|
||||
static char name[sizeof(shortname) + 4];
|
||||
int ret;
|
||||
|
||||
if (!strcmp(type, "dfu")) {
|
||||
strcpy(name, shortname);
|
||||
strcat(name, type);
|
||||
} else if (!strcmp(type, "ums")) {
|
||||
strcpy(name, shortname);
|
||||
strcat(name, type);
|
||||
} else if (!strcmp(type, "thor")) {
|
||||
strcpy(name, shortname);
|
||||
strcat(name, type);
|
||||
} else {
|
||||
printf("%s: unknown command: %s\n", __func__, type);
|
||||
return -EINVAL;
|
||||
}
|
||||
int ret = usb_composite_register(&g_dnl_driver);
|
||||
|
||||
debug("%s: g_dnl_driver.name = %s\n", __func__, name);
|
||||
g_dnl_driver.name = name;
|
||||
|
||||
debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name);
|
||||
ret = usb_composite_register(&g_dnl_driver);
|
||||
|
||||
if (ret) {
|
||||
printf("%s: failed!, error: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,12 +168,5 @@ static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DFU_FUNCTION
|
||||
int dfu_add(struct usb_configuration *c);
|
||||
#else
|
||||
int dfu_add(struct usb_configuration *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* __DFU_ENTITY_H_ */
|
||||
|
|
|
@ -10,6 +10,29 @@
|
|||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/usb/composite.h>
|
||||
#include <linker_lists.h>
|
||||
|
||||
/*
|
||||
* @usb_fname: unescaped USB function name
|
||||
* @callback_ptr: bind callback, one per function name
|
||||
*/
|
||||
#define DECLARE_GADGET_BIND_CALLBACK(usb_fname, callback_ptr) \
|
||||
ll_entry_declare(struct g_dnl_bind_callback, \
|
||||
__usb_function_name_##usb_fname, \
|
||||
g_dnl_bind_callbacks) = { \
|
||||
.usb_function_name = #usb_fname, \
|
||||
.fptr = callback_ptr \
|
||||
}
|
||||
|
||||
typedef int (*g_dnl_bind_callback_f)(struct usb_configuration *);
|
||||
|
||||
/* used in Gadget downloader callback linker list */
|
||||
struct g_dnl_bind_callback {
|
||||
const char *usb_function_name;
|
||||
g_dnl_bind_callback_f fptr;
|
||||
};
|
||||
|
||||
int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *);
|
||||
int g_dnl_board_usb_cable_connected(void);
|
||||
int g_dnl_register(const char *s);
|
||||
|
|
|
@ -15,13 +15,5 @@
|
|||
|
||||
int thor_handle(void);
|
||||
int thor_init(void);
|
||||
|
||||
#ifdef CONFIG_THOR_FUNCTION
|
||||
int thor_add(struct usb_configuration *c);
|
||||
#else
|
||||
int thor_add(struct usb_configuration *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* __THOR_H_ */
|
||||
|
|
|
@ -40,13 +40,5 @@ int fsg_init(struct ums *);
|
|||
void fsg_cleanup(void);
|
||||
struct ums *ums_init(unsigned int);
|
||||
int fsg_main_thread(void *);
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_MASS_STORAGE
|
||||
int fsg_add(struct usb_configuration *c);
|
||||
#else
|
||||
int fsg_add(struct usb_configuration *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* __USB_MASS_STORAGE_H__ */
|
||||
|
|
Loading…
Reference in New Issue