USB: gadget: added a saner gadget downloader registration API
authorMateusz Zalega <m.zalega@samsung.com>
Mon, 28 Apr 2014 19:13:28 +0000 (21:13 +0200)
committerLukasz Majewski <l.majewski@samsung.com>
Mon, 5 May 2014 06:21:47 +0000 (08:21 +0200)
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>
common/cmd_dfu.c
common/cmd_thordown.c
common/cmd_usb_mass_storage.c
drivers/usb/gadget/f_dfu.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_thor.c
drivers/usb/gadget/g_dnl.c
include/dfu.h
include/g_dnl.h
include/thor.h
include/usb_mass_storage.h

index 5547678208adf8753800bf76f68b4f7ad34869b8..a03538dabb370c320815aa12637fae31e5eccd3c 100644 (file)
@@ -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())
                        /*
index c4b35114587d09d8badcbb8703480d12d823b9f4..2dd750928e41ad39c2a924b38140c898f5c114e7 100644 (file)
@@ -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) {
index 14a5b6ae5ea1fcc9e855746a8f20a55f59e2a1b8..d8d9efd4f62b348b6ad553fbb95c1d50d3b824a4 100644 (file)
@@ -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;
index de75ff13390c44bdc961136ad02ad83452c580a0..1b1e1793d920f49076b5ccac37d25075a9e07060 100644 (file)
@@ -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);
index 4fae5cd3b1ad561674994b8e5c8265c4d5b69664..6374bb953a94478bbf469b09b52756e18796fac4 100644 (file)
 #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);
index ba479450073736e0fc6200fc97018d53e9ce5358..feef9e4619c482c31d7ce5a45bbab55a772c6146 100644 (file)
@@ -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);
index 973d7378b52a05bf79d47f45286e90624e82c697..743bae535ac8607ed02ad41f726e44b8022ffe00 100644 (file)
@@ -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;
 }
 
index dcd3215d06be866746c3af8e6c9d595362bcf2c8..240916854a12a7ce8745b0ef843f6c0e4d03a325 100644 (file)
@@ -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_ */
index f4e8d1089e639b8d3157221e0dff60294063fb37..1b1b35e0e1c5e0813994fa84a77a0462a6b8c053 100644 (file)
 
 #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);
index afeade45646bff851519cdbf58364d9ee944fc08..5051be714bdf0c98b15a7d2ce709f9957477d701 100644 (file)
 
 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_ */
index 058dcf11740423569c13a4cd8e5957aa09afb0fd..ed460644c1fe9152243ad97ddd516aaa9ef6e87a 100644 (file)
@@ -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__ */