diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2013-10-09 04:08:27 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-10 11:24:49 -0400 |
commit | 1bcce939478f894b46a592aed28ccc9caaf1a52a (patch) | |
tree | 2777ce5541160d388abd5f878cd90efd804dbe8c /drivers/usb/gadget | |
parent | 4d1a8f68b42d2a726e36bfe2f891496b4c6bdbbb (diff) |
usb: gadget: multi: convert to new interface of f_mass_storage
Convert the legacy multi gadget to the new interface of f_mass_storage,
so that later the compatibility layer in f_mass_storage can be removed.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/multi.c | 112 |
2 files changed, 83 insertions, 30 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bbcc313f0317..4b0c456f9d63 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -1038,6 +1038,7 @@ config USB_G_MULTI | |||
1038 | select USB_U_ETHER | 1038 | select USB_U_ETHER |
1039 | select USB_F_ACM | 1039 | select USB_F_ACM |
1040 | select USB_U_MS | 1040 | select USB_U_MS |
1041 | select USB_F_MASS_STORAGE | ||
1041 | help | 1042 | help |
1042 | The Multifunction Composite Gadget provides Ethernet (RNDIS | 1043 | The Multifunction Composite Gadget provides Ethernet (RNDIS |
1043 | and/or CDC Ethernet), mass storage and ACM serial link | 1044 | and/or CDC Ethernet), mass storage and ACM serial link |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index fceef0fc0860..4fdaa54a2a2a 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -33,17 +33,7 @@ MODULE_AUTHOR("Michal Nazarewicz"); | |||
33 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
34 | 34 | ||
35 | 35 | ||
36 | /***************************** All the files... *****************************/ | 36 | #include "f_mass_storage.h" |
37 | |||
38 | /* | ||
39 | * kbuild is not very cooperative with respect to linking separately | ||
40 | * compiled library objects into one module. So for now we won't use | ||
41 | * separate compilation ... ensuring init/exit sections work to shrink | ||
42 | * the runtime footprint, and giving us at least some parts of what | ||
43 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
44 | */ | ||
45 | #define USB_FMS_INCLUDED | ||
46 | #include "f_mass_storage.c" | ||
47 | 37 | ||
48 | #include "u_ecm.h" | 38 | #include "u_ecm.h" |
49 | #ifdef USB_ETH_RNDIS | 39 | #ifdef USB_ETH_RNDIS |
@@ -148,9 +138,8 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; | |||
148 | 138 | ||
149 | FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); | 139 | FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); |
150 | 140 | ||
151 | static struct fsg_common fsg_common; | ||
152 | |||
153 | static struct usb_function_instance *fi_acm; | 141 | static struct usb_function_instance *fi_acm; |
142 | static struct usb_function_instance *fi_msg; | ||
154 | 143 | ||
155 | /********** RNDIS **********/ | 144 | /********** RNDIS **********/ |
156 | 145 | ||
@@ -158,9 +147,11 @@ static struct usb_function_instance *fi_acm; | |||
158 | static struct usb_function_instance *fi_rndis; | 147 | static struct usb_function_instance *fi_rndis; |
159 | static struct usb_function *f_acm_rndis; | 148 | static struct usb_function *f_acm_rndis; |
160 | static struct usb_function *f_rndis; | 149 | static struct usb_function *f_rndis; |
150 | static struct usb_function *f_msg_rndis; | ||
161 | 151 | ||
162 | static __init int rndis_do_config(struct usb_configuration *c) | 152 | static __init int rndis_do_config(struct usb_configuration *c) |
163 | { | 153 | { |
154 | struct fsg_opts *fsg_opts; | ||
164 | int ret; | 155 | int ret; |
165 | 156 | ||
166 | if (gadget_is_otg(c->cdev->gadget)) { | 157 | if (gadget_is_otg(c->cdev->gadget)) { |
@@ -186,11 +177,24 @@ static __init int rndis_do_config(struct usb_configuration *c) | |||
186 | if (ret) | 177 | if (ret) |
187 | goto err_conf; | 178 | goto err_conf; |
188 | 179 | ||
189 | ret = fsg_bind_config(c->cdev, c, &fsg_common); | 180 | f_msg_rndis = usb_get_function(fi_msg); |
190 | if (ret < 0) | 181 | if (IS_ERR(f_msg_rndis)) { |
182 | ret = PTR_ERR(f_msg_rndis); | ||
191 | goto err_fsg; | 183 | goto err_fsg; |
184 | } | ||
185 | |||
186 | fsg_opts = fsg_opts_from_func_inst(fi_msg); | ||
187 | ret = fsg_common_run_thread(fsg_opts->common); | ||
188 | if (ret) | ||
189 | goto err_run; | ||
190 | |||
191 | ret = usb_add_function(c, f_msg_rndis); | ||
192 | if (ret) | ||
193 | goto err_run; | ||
192 | 194 | ||
193 | return 0; | 195 | return 0; |
196 | err_run: | ||
197 | usb_put_function(f_msg_rndis); | ||
194 | err_fsg: | 198 | err_fsg: |
195 | usb_remove_function(c, f_acm_rndis); | 199 | usb_remove_function(c, f_acm_rndis); |
196 | err_conf: | 200 | err_conf: |
@@ -231,9 +235,11 @@ static __ref int rndis_config_register(struct usb_composite_dev *cdev) | |||
231 | static struct usb_function_instance *fi_ecm; | 235 | static struct usb_function_instance *fi_ecm; |
232 | static struct usb_function *f_acm_multi; | 236 | static struct usb_function *f_acm_multi; |
233 | static struct usb_function *f_ecm; | 237 | static struct usb_function *f_ecm; |
238 | static struct usb_function *f_msg_multi; | ||
234 | 239 | ||
235 | static __init int cdc_do_config(struct usb_configuration *c) | 240 | static __init int cdc_do_config(struct usb_configuration *c) |
236 | { | 241 | { |
242 | struct fsg_opts *fsg_opts; | ||
237 | int ret; | 243 | int ret; |
238 | 244 | ||
239 | if (gadget_is_otg(c->cdev->gadget)) { | 245 | if (gadget_is_otg(c->cdev->gadget)) { |
@@ -260,11 +266,24 @@ static __init int cdc_do_config(struct usb_configuration *c) | |||
260 | if (ret) | 266 | if (ret) |
261 | goto err_conf; | 267 | goto err_conf; |
262 | 268 | ||
263 | ret = fsg_bind_config(c->cdev, c, &fsg_common); | 269 | f_msg_multi = usb_get_function(fi_msg); |
264 | if (ret < 0) | 270 | if (IS_ERR(f_msg_multi)) { |
271 | ret = PTR_ERR(f_msg_multi); | ||
265 | goto err_fsg; | 272 | goto err_fsg; |
273 | } | ||
274 | |||
275 | fsg_opts = fsg_opts_from_func_inst(fi_msg); | ||
276 | ret = fsg_common_run_thread(fsg_opts->common); | ||
277 | if (ret) | ||
278 | goto err_run; | ||
279 | |||
280 | ret = usb_add_function(c, f_msg_multi); | ||
281 | if (ret) | ||
282 | goto err_run; | ||
266 | 283 | ||
267 | return 0; | 284 | return 0; |
285 | err_run: | ||
286 | usb_put_function(f_msg_multi); | ||
268 | err_fsg: | 287 | err_fsg: |
269 | usb_remove_function(c, f_acm_multi); | 288 | usb_remove_function(c, f_acm_multi); |
270 | err_conf: | 289 | err_conf: |
@@ -311,6 +330,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) | |||
311 | #ifdef USB_ETH_RNDIS | 330 | #ifdef USB_ETH_RNDIS |
312 | struct f_rndis_opts *rndis_opts; | 331 | struct f_rndis_opts *rndis_opts; |
313 | #endif | 332 | #endif |
333 | struct fsg_opts *fsg_opts; | ||
334 | struct fsg_config config; | ||
314 | int status; | 335 | int status; |
315 | 336 | ||
316 | if (!can_support_ecm(cdev->gadget)) { | 337 | if (!can_support_ecm(cdev->gadget)) { |
@@ -373,41 +394,65 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) | |||
373 | } | 394 | } |
374 | 395 | ||
375 | /* set up mass storage function */ | 396 | /* set up mass storage function */ |
376 | { | 397 | fi_msg = usb_get_function_instance("mass_storage"); |
377 | void *retp; | 398 | if (IS_ERR(fi_msg)) { |
378 | retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data, | 399 | status = PTR_ERR(fi_msg); |
379 | fsg_num_buffers); | 400 | goto fail1; |
380 | if (IS_ERR(retp)) { | ||
381 | status = PTR_ERR(retp); | ||
382 | goto fail1; | ||
383 | } | ||
384 | } | 401 | } |
402 | fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers); | ||
403 | fsg_opts = fsg_opts_from_func_inst(fi_msg); | ||
404 | |||
405 | fsg_opts->no_configfs = true; | ||
406 | status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers); | ||
407 | if (status) | ||
408 | goto fail2; | ||
409 | |||
410 | status = fsg_common_set_nluns(fsg_opts->common, config.nluns); | ||
411 | if (status) | ||
412 | goto fail_set_nluns; | ||
413 | |||
414 | status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall); | ||
415 | if (status) | ||
416 | goto fail_set_cdev; | ||
417 | |||
418 | fsg_common_set_sysfs(fsg_opts->common, true); | ||
419 | status = fsg_common_create_luns(fsg_opts->common, &config); | ||
420 | if (status) | ||
421 | goto fail_set_cdev; | ||
422 | |||
423 | fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name, | ||
424 | config.product_name); | ||
385 | 425 | ||
386 | /* allocate string IDs */ | 426 | /* allocate string IDs */ |
387 | status = usb_string_ids_tab(cdev, strings_dev); | 427 | status = usb_string_ids_tab(cdev, strings_dev); |
388 | if (unlikely(status < 0)) | 428 | if (unlikely(status < 0)) |
389 | goto fail2; | 429 | goto fail_string_ids; |
390 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; | 430 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; |
391 | 431 | ||
392 | /* register configurations */ | 432 | /* register configurations */ |
393 | status = rndis_config_register(cdev); | 433 | status = rndis_config_register(cdev); |
394 | if (unlikely(status < 0)) | 434 | if (unlikely(status < 0)) |
395 | goto fail2; | 435 | goto fail_string_ids; |
396 | 436 | ||
397 | status = cdc_config_register(cdev); | 437 | status = cdc_config_register(cdev); |
398 | if (unlikely(status < 0)) | 438 | if (unlikely(status < 0)) |
399 | goto fail2; | 439 | goto fail_string_ids; |
400 | usb_composite_overwrite_options(cdev, &coverwrite); | 440 | usb_composite_overwrite_options(cdev, &coverwrite); |
401 | 441 | ||
402 | /* we're done */ | 442 | /* we're done */ |
403 | dev_info(&gadget->dev, DRIVER_DESC "\n"); | 443 | dev_info(&gadget->dev, DRIVER_DESC "\n"); |
404 | fsg_common_put(&fsg_common); | ||
405 | return 0; | 444 | return 0; |
406 | 445 | ||
407 | 446 | ||
408 | /* error recovery */ | 447 | /* error recovery */ |
448 | fail_string_ids: | ||
449 | fsg_common_remove_luns(fsg_opts->common); | ||
450 | fail_set_cdev: | ||
451 | fsg_common_free_luns(fsg_opts->common); | ||
452 | fail_set_nluns: | ||
453 | fsg_common_free_buffers(fsg_opts->common); | ||
409 | fail2: | 454 | fail2: |
410 | fsg_common_put(&fsg_common); | 455 | usb_put_function_instance(fi_msg); |
411 | fail1: | 456 | fail1: |
412 | usb_put_function_instance(fi_acm); | 457 | usb_put_function_instance(fi_acm); |
413 | fail0: | 458 | fail0: |
@@ -424,6 +469,13 @@ fail: | |||
424 | static int __exit multi_unbind(struct usb_composite_dev *cdev) | 469 | static int __exit multi_unbind(struct usb_composite_dev *cdev) |
425 | { | 470 | { |
426 | #ifdef CONFIG_USB_G_MULTI_CDC | 471 | #ifdef CONFIG_USB_G_MULTI_CDC |
472 | usb_put_function(f_msg_multi); | ||
473 | #endif | ||
474 | #ifdef USB_ETH_RNDIS | ||
475 | usb_put_function(f_msg_rndis); | ||
476 | #endif | ||
477 | usb_put_function_instance(fi_msg); | ||
478 | #ifdef CONFIG_USB_G_MULTI_CDC | ||
427 | usb_put_function(f_acm_multi); | 479 | usb_put_function(f_acm_multi); |
428 | #endif | 480 | #endif |
429 | #ifdef USB_ETH_RNDIS | 481 | #ifdef USB_ETH_RNDIS |