Commit c4d0e856047f2689278ffea63a562c4f22a35ee3
Committed by
Lukasz Majewski
1 parent
fad8edf0f7
Exists in
v2017.01-smarct4x
and in
40 other branches
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>
Showing 11 changed files with 62 additions and 64 deletions Side-by-side Diff
common/cmd_dfu.c
... | ... | @@ -22,7 +22,6 @@ |
22 | 22 | char *interface = argv[2]; |
23 | 23 | char *devstring = argv[3]; |
24 | 24 | |
25 | - char *s = "dfu"; | |
26 | 25 | int ret, i = 0; |
27 | 26 | |
28 | 27 | ret = dfu_init_env_entities(interface, simple_strtoul(devstring, |
... | ... | @@ -38,7 +37,7 @@ |
38 | 37 | int controller_index = simple_strtoul(usb_controller, NULL, 0); |
39 | 38 | board_usb_init(controller_index, USB_INIT_DEVICE); |
40 | 39 | |
41 | - g_dnl_register(s); | |
40 | + g_dnl_register("usb_dnl_dfu"); | |
42 | 41 | while (1) { |
43 | 42 | if (dfu_reset()) |
44 | 43 | /* |
common/cmd_thordown.c
... | ... | @@ -22,7 +22,6 @@ |
22 | 22 | char *interface = argv[2]; |
23 | 23 | char *devstring = argv[3]; |
24 | 24 | |
25 | - const char *s = "thor"; | |
26 | 25 | int ret; |
27 | 26 | |
28 | 27 | puts("TIZEN \"THOR\" Downloader\n"); |
... | ... | @@ -40,7 +39,7 @@ |
40 | 39 | goto exit; |
41 | 40 | } |
42 | 41 | |
43 | - g_dnl_register(s); | |
42 | + g_dnl_register("usb_dnl_thor"); | |
44 | 43 | |
45 | 44 | ret = thor_init(); |
46 | 45 | if (ret) { |
common/cmd_usb_mass_storage.c
drivers/usb/gadget/f_dfu.c
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | #include <linux/usb/composite.h> |
25 | 25 | |
26 | 26 | #include <dfu.h> |
27 | +#include <g_dnl.h> | |
27 | 28 | #include "f_dfu.h" |
28 | 29 | |
29 | 30 | struct f_dfu { |
... | ... | @@ -817,4 +818,6 @@ |
817 | 818 | |
818 | 819 | return dfu_bind_config(c); |
819 | 820 | } |
821 | + | |
822 | +DECLARE_GADGET_BIND_CALLBACK(usb_dnl_dfu, dfu_add); |
drivers/usb/gadget/f_mass_storage.c
... | ... | @@ -255,6 +255,7 @@ |
255 | 255 | #include <linux/usb/gadget.h> |
256 | 256 | #include <linux/usb/composite.h> |
257 | 257 | #include <usb/lin_gadget_compat.h> |
258 | +#include <g_dnl.h> | |
258 | 259 | |
259 | 260 | /*------------------------------------------------------------------------*/ |
260 | 261 | |
... | ... | @@ -2778,4 +2779,6 @@ |
2778 | 2779 | |
2779 | 2780 | return 0; |
2780 | 2781 | } |
2782 | + | |
2783 | +DECLARE_GADGET_BIND_CALLBACK(usb_dnl_ums, fsg_add); |
drivers/usb/gadget/f_thor.c
drivers/usb/gadget/g_dnl.c
... | ... | @@ -41,7 +41,6 @@ |
41 | 41 | |
42 | 42 | #define DRIVER_VERSION "usb_dnl 2.0" |
43 | 43 | |
44 | -static const char shortname[] = "usb_dnl_"; | |
45 | 44 | static const char product[] = "USB download gadget"; |
46 | 45 | static char g_dnl_serial[MAX_STRING_SERIAL]; |
47 | 46 | static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; |
48 | 47 | |
49 | 48 | |
50 | 49 | |
... | ... | @@ -96,29 +95,36 @@ |
96 | 95 | free(cdev->config); |
97 | 96 | cdev->config = NULL; |
98 | 97 | debug("%s: calling usb_gadget_disconnect for " |
99 | - "controller '%s'\n", shortname, gadget->name); | |
98 | + "controller '%s'\n", __func__, gadget->name); | |
100 | 99 | usb_gadget_disconnect(gadget); |
101 | 100 | |
102 | 101 | return 0; |
103 | 102 | } |
104 | 103 | |
104 | +static inline struct g_dnl_bind_callback *g_dnl_bind_callback_first(void) | |
105 | +{ | |
106 | + return ll_entry_start(struct g_dnl_bind_callback, | |
107 | + g_dnl_bind_callbacks); | |
108 | +} | |
109 | + | |
110 | +static inline struct g_dnl_bind_callback *g_dnl_bind_callback_end(void) | |
111 | +{ | |
112 | + return ll_entry_end(struct g_dnl_bind_callback, | |
113 | + g_dnl_bind_callbacks); | |
114 | +} | |
115 | + | |
105 | 116 | static int g_dnl_do_config(struct usb_configuration *c) |
106 | 117 | { |
107 | 118 | const char *s = c->cdev->driver->name; |
108 | - int ret = -1; | |
119 | + struct g_dnl_bind_callback *callback = g_dnl_bind_callback_first(); | |
109 | 120 | |
110 | 121 | debug("%s: configuration: 0x%p composite dev: 0x%p\n", |
111 | 122 | __func__, c, c->cdev); |
112 | 123 | |
113 | - printf("GADGET DRIVER: %s\n", s); | |
114 | - if (!strcmp(s, "usb_dnl_dfu")) | |
115 | - ret = dfu_add(c); | |
116 | - else if (!strcmp(s, "usb_dnl_ums")) | |
117 | - ret = fsg_add(c); | |
118 | - else if (!strcmp(s, "usb_dnl_thor")) | |
119 | - ret = thor_add(c); | |
120 | - | |
121 | - return ret; | |
124 | + for (; callback != g_dnl_bind_callback_end(); callback++) | |
125 | + if (!strcmp(s, callback->usb_function_name)) | |
126 | + return callback->fptr(c); | |
127 | + return -ENODEV; | |
122 | 128 | } |
123 | 129 | |
124 | 130 | static int g_dnl_config_register(struct usb_composite_dev *cdev) |
125 | 131 | |
... | ... | @@ -208,12 +214,12 @@ |
208 | 214 | device_desc.bcdDevice = cpu_to_le16(gcnum); |
209 | 215 | else { |
210 | 216 | debug("%s: controller '%s' not recognized\n", |
211 | - shortname, gadget->name); | |
217 | + __func__, gadget->name); | |
212 | 218 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); |
213 | 219 | } |
214 | 220 | |
215 | 221 | debug("%s: calling usb_gadget_connect for " |
216 | - "controller '%s'\n", shortname, gadget->name); | |
222 | + "controller '%s'\n", __func__, gadget->name); | |
217 | 223 | usb_gadget_connect(gadget); |
218 | 224 | |
219 | 225 | return 0; |
220 | 226 | |
221 | 227 | |
222 | 228 | |
223 | 229 | |
... | ... | @@ -232,36 +238,22 @@ |
232 | 238 | .unbind = g_dnl_unbind, |
233 | 239 | }; |
234 | 240 | |
235 | -int g_dnl_register(const char *type) | |
241 | +/* | |
242 | + * NOTICE: | |
243 | + * Registering via USB function name won't be necessary after rewriting | |
244 | + * g_dnl to support multiple USB functions. | |
245 | + */ | |
246 | +int g_dnl_register(const char *name) | |
236 | 247 | { |
237 | - /* The largest function name is 4 */ | |
238 | - static char name[sizeof(shortname) + 4]; | |
239 | - int ret; | |
248 | + int ret = usb_composite_register(&g_dnl_driver); | |
240 | 249 | |
241 | - if (!strcmp(type, "dfu")) { | |
242 | - strcpy(name, shortname); | |
243 | - strcat(name, type); | |
244 | - } else if (!strcmp(type, "ums")) { | |
245 | - strcpy(name, shortname); | |
246 | - strcat(name, type); | |
247 | - } else if (!strcmp(type, "thor")) { | |
248 | - strcpy(name, shortname); | |
249 | - strcat(name, type); | |
250 | - } else { | |
251 | - printf("%s: unknown command: %s\n", __func__, type); | |
252 | - return -EINVAL; | |
253 | - } | |
254 | - | |
250 | + debug("%s: g_dnl_driver.name = %s\n", __func__, name); | |
255 | 251 | g_dnl_driver.name = name; |
256 | 252 | |
257 | - debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name); | |
258 | - ret = usb_composite_register(&g_dnl_driver); | |
259 | - | |
260 | 253 | if (ret) { |
261 | 254 | printf("%s: failed!, error: %d\n", __func__, ret); |
262 | 255 | return ret; |
263 | 256 | } |
264 | - | |
265 | 257 | return 0; |
266 | 258 | } |
267 | 259 |
include/dfu.h
include/g_dnl.h
... | ... | @@ -10,6 +10,29 @@ |
10 | 10 | |
11 | 11 | #include <linux/usb/ch9.h> |
12 | 12 | #include <linux/usb/gadget.h> |
13 | +#include <linux/usb/composite.h> | |
14 | +#include <linker_lists.h> | |
15 | + | |
16 | +/* | |
17 | + * @usb_fname: unescaped USB function name | |
18 | + * @callback_ptr: bind callback, one per function name | |
19 | + */ | |
20 | +#define DECLARE_GADGET_BIND_CALLBACK(usb_fname, callback_ptr) \ | |
21 | + ll_entry_declare(struct g_dnl_bind_callback, \ | |
22 | + __usb_function_name_##usb_fname, \ | |
23 | + g_dnl_bind_callbacks) = { \ | |
24 | + .usb_function_name = #usb_fname, \ | |
25 | + .fptr = callback_ptr \ | |
26 | + } | |
27 | + | |
28 | +typedef int (*g_dnl_bind_callback_f)(struct usb_configuration *); | |
29 | + | |
30 | +/* used in Gadget downloader callback linker list */ | |
31 | +struct g_dnl_bind_callback { | |
32 | + const char *usb_function_name; | |
33 | + g_dnl_bind_callback_f fptr; | |
34 | +}; | |
35 | + | |
13 | 36 | int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *); |
14 | 37 | int g_dnl_board_usb_cable_connected(void); |
15 | 38 | int g_dnl_register(const char *s); |
include/thor.h
include/usb_mass_storage.h
... | ... | @@ -40,14 +40,6 @@ |
40 | 40 | void fsg_cleanup(void); |
41 | 41 | struct ums *ums_init(unsigned int); |
42 | 42 | int fsg_main_thread(void *); |
43 | - | |
44 | -#ifdef CONFIG_USB_GADGET_MASS_STORAGE | |
45 | 43 | int fsg_add(struct usb_configuration *c); |
46 | -#else | |
47 | -int fsg_add(struct usb_configuration *c) | |
48 | -{ | |
49 | - return 0; | |
50 | -} | |
51 | -#endif | |
52 | 44 | #endif /* __USB_MASS_STORAGE_H__ */ |