Converting mass storage to the new function interface requires converting the USB mass storage's function code and its users. This patch converts the f_mass_storage.c to the new function interface. The file is now compiled into a separate usb_f_mass_storage.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/usb/gadget/Kconfig | 3 + drivers/usb/gadget/Makefile | 2 + drivers/usb/gadget/acm_ms.c | 1 + drivers/usb/gadget/f_mass_storage.c | 223 +++++++++++++++++++++++++++++++--- drivers/usb/gadget/f_mass_storage.h | 9 ++ drivers/usb/gadget/mass_storage.c | 1 + drivers/usb/gadget/multi.c | 1 + 7 files changed, 220 insertions(+), 20 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 98220dc..40adaf0 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -528,6 +528,9 @@ config USB_F_RNDIS config USB_U_MS tristate +config USB_F_MASS_STORAGE + tristate + choice tristate "USB Gadget Drivers" default USB_ETH diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index d90a0b0..4a86b0c 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -62,6 +62,8 @@ usb_f_rndis-y := f_rndis.o obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o u_ms-y := storage_common.o obj-$(CONFIG_USB_U_MS) += u_ms.o +usb_f_mass_storage-y := f_mass_storage.o +obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o # # USB gadget drivers diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 992ffb0..31aae8f 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -40,6 +40,7 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ +#define USB_FMS_INCLUDED #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 3b2fef8..185ff66 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -213,6 +213,7 @@ #include <linux/spinlock.h> #include <linux/string.h> #include <linux/freezer.h> +#include <linux/module.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -2627,11 +2628,17 @@ void fsg_common_get(struct fsg_common *common) { kref_get(&common->ref); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_get); +#endif void fsg_common_put(struct fsg_common *common) { kref_put(&common->ref, fsg_common_release); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_put); +#endif /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) @@ -2669,6 +2676,9 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs) { common->sysfs = sysfs; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_sysfs); +#endif static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n) { @@ -2720,6 +2730,9 @@ error_release: return -ENOMEM; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_num_buffers); +#endif static inline void fsg_common_remove_sysfs(struct fsg_lun *lun) { @@ -2740,6 +2753,9 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs) kfree(lun->name); kfree(lun); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_remove_lun); +#endif void _fsg_common_remove_luns(struct fsg_common *common, int n) { @@ -2751,6 +2767,9 @@ void _fsg_common_remove_luns(struct fsg_common *common, int n) common->luns[i] = NULL; } } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_remove_luns); +#endif void fsg_common_remove_luns(struct fsg_common *common) { @@ -2763,6 +2782,9 @@ void fsg_common_free_luns(struct fsg_common *common) kfree(common->luns); common->luns = NULL; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_free_luns); +#endif int fsg_common_set_nluns(struct fsg_common *common, int nluns) { @@ -2788,17 +2810,35 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) return 0; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_nluns); +#endif + +void fsg_common_free_buffers(struct fsg_common *common) +{ + _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); + common->buffhds = NULL; +} +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_free_buffers); +#endif void fsg_common_set_ops(struct fsg_common *common, const struct fsg_operations *ops) { common->ops = ops; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_ops); +#endif void fsg_common_set_private_data(struct fsg_common *common, void *priv) { common->private_data = priv; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_private_data); +#endif int fsg_common_set_cdev(struct fsg_common *common, struct usb_composite_dev *cdev, bool can_stall) @@ -2828,6 +2868,9 @@ int fsg_common_set_cdev(struct fsg_common *common, return 0; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_cdev); +#endif static inline int fsg_common_add_sysfs(struct fsg_common *common, struct fsg_lun *lun) @@ -2968,6 +3011,9 @@ error_name: kfree(lun); return rc; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_create_lun); +#endif int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg) { @@ -2989,6 +3035,9 @@ fail: _fsg_common_remove_luns(common, i); return rc; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_create_luns); +#endif void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, const char *pn) @@ -3005,6 +3054,9 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, : "File-Stor Gadget"), i); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_inquiry_string); +#endif int fsg_common_run_thread(struct fsg_common *common) { @@ -3023,6 +3075,9 @@ int fsg_common_run_thread(struct fsg_common *common) return 0; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_run_thread); +#endif struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev, @@ -3077,6 +3132,9 @@ error_release: fsg_common_release(&common->ref); return ERR_PTR(rc); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_init); +#endif static void fsg_common_release(struct kref *ref) { @@ -3119,24 +3177,6 @@ static void fsg_common_release(struct kref *ref) /*-------------------------------------------------------------------------*/ -static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct fsg_dev *fsg = fsg_from_func(f); - struct fsg_common *common = fsg->common; - - DBG(fsg, "unbind\n"); - if (fsg->common->fsg == fsg) { - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - /* FIXME: make interruptible or killable somehow? */ - wait_event(common->fsg_wait, common->fsg != fsg); - } - - fsg_common_put(common); - usb_free_all_descriptors(&fsg->function); - kfree(fsg); -} - static int fsg_bind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); @@ -3146,6 +3186,21 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) unsigned max_burst; int ret; +#ifndef USB_FMS_INCLUDED + struct fsg_opts *opts; + opts = container_of(f->fi, struct fsg_opts, func_inst); + if (!opts->no_configfs) { + ret = fsg_common_set_cdev(fsg->common, c->cdev, + fsg->common->can_stall); + if (ret) + return ret; + fsg_common_set_inquiry_string(fsg->common, 0, 0); + ret = fsg_common_run_thread(fsg->common); + if (ret) + return ret; + } +#endif + fsg->gadget = gadget; /* New interface */ @@ -3197,7 +3252,27 @@ autoconf_fail: return -ENOTSUPP; } -/****************************** ADD FUNCTION ******************************/ +/****************************** ALLOCATE FUNCTION *************************/ + +#ifdef USB_FMS_INCLUDED + +static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct fsg_dev *fsg = fsg_from_func(f); + struct fsg_common *common = fsg->common; + + DBG(fsg, "unbind\n"); + if (fsg->common->fsg == fsg) { + fsg->common->new_fsg = NULL; + raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); + /* FIXME: make interruptible or killable somehow? */ + wait_event(common->fsg_wait, common->fsg != fsg); + } + + fsg_common_put(common); + usb_free_all_descriptors(&fsg->function); + kfree(fsg); +} static int fsg_bind_config(struct usb_composite_dev *cdev, struct usb_configuration *c, @@ -3212,7 +3287,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, fsg->function.name = FSG_DRIVER_DESC; fsg->function.bind = fsg_bind; - fsg->function.unbind = fsg_unbind; + fsg->function.unbind = old_fsg_unbind; fsg->function.setup = fsg_setup; fsg->function.set_alt = fsg_set_alt; fsg->function.disable = fsg_disable; @@ -3234,6 +3309,111 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, return rc; } +#else + +static void fsg_free_inst(struct usb_function_instance *fi) +{ + struct fsg_opts *opts; + + opts = container_of(fi, struct fsg_opts, func_inst); + fsg_common_put(opts->common); + kfree(opts); +} + +static struct usb_function_instance *fsg_alloc_inst(void) +{ + struct fsg_opts *opts; + int ret; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + opts->func_inst.free_func_inst = fsg_free_inst; + opts->common = fsg_common_setup(opts->common, false); + if (IS_ERR(opts->common)) { + ret = PTR_ERR(opts->common); + goto release_opts; + } + ret = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS); + if (ret) + goto release_opts; + + ret = fsg_common_set_num_buffers(opts->common, + CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS); + if (ret) + goto release_luns; + + pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); + + return &opts->func_inst; + +release_luns: + kfree(opts->common->luns); +release_opts: + kfree(opts); + return ERR_PTR(ret); +} + +static void fsg_free(struct usb_function *f) +{ + struct fsg_dev *fsg; + + fsg = container_of(f, struct fsg_dev, function); + + kfree(fsg); +} + +static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct fsg_dev *fsg = fsg_from_func(f); + struct fsg_common *common = fsg->common; + + DBG(fsg, "unbind\n"); + if (fsg->common->fsg == fsg) { + fsg->common->new_fsg = NULL; + raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); + /* FIXME: make interruptible or killable somehow? */ + wait_event(common->fsg_wait, common->fsg != fsg); + } + + usb_free_all_descriptors(&fsg->function); +} + +static struct usb_function *fsg_alloc(struct usb_function_instance *fi) +{ + struct fsg_opts *opts = container_of(fi, struct fsg_opts, func_inst); + struct fsg_common *common = opts->common; + struct fsg_dev *fsg; + + fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); + if (unlikely(!fsg)) + return ERR_PTR(-ENOMEM); + + fsg->function.name = FSG_DRIVER_DESC; + fsg->function.bind = fsg_bind; + fsg->function.unbind = fsg_unbind; + fsg->function.setup = fsg_setup; + fsg->function.set_alt = fsg_set_alt; + fsg->function.disable = fsg_disable; + fsg->function.free_func = fsg_free; + + fsg->common = common; + /* + * Our caller holds a reference to common structure so we + * don't have to be worry about it being freed until we return + * from this function. So instead of incrementing counter now + * and decrement in error recovery we increment it only when + * call to usb_add_function() was successful. + */ + + return &fsg->function; +} + +DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michal Nazarewicz"); + +#endif /************************* Module parameters *************************/ @@ -3270,4 +3450,7 @@ void fsg_config_from_params(struct fsg_config *cfg, cfg->can_stall = params->stall; cfg->fsg_num_buffers = fsg_num_buffers; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_config_from_params); +#endif diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h index 1ae8d20..efd2077 100644 --- a/drivers/usb/gadget/f_mass_storage.h +++ b/drivers/usb/gadget/f_mass_storage.h @@ -1,6 +1,7 @@ #ifndef USB_F_MASS_STORAGE_H #define USB_F_MASS_STORAGE_H +#include <linux/usb/composite.h> #include "storage_common.h" struct fsg_module_parameters { @@ -70,6 +71,12 @@ struct fsg_operations { int (*thread_exits)(struct fsg_common *common); }; +struct fsg_opts { + struct fsg_common *common; + struct usb_function_instance func_inst; + bool no_configfs; /* for legacy gadgets */ +}; + struct fsg_lun_config { const char *filename; char ro; @@ -106,6 +113,8 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs); int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n); +void fsg_common_free_buffers(struct fsg_common *common); + void fsg_common_set_ops(struct fsg_common *common, const struct fsg_operations *ops); diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 4723d1b..f670251 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -55,6 +55,7 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ +#define USB_FMS_INCLUDED #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 6867d9d..42a5bed 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -41,6 +41,7 @@ MODULE_LICENSE("GPL"); * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ +#define USB_FMS_INCLUDED #include "f_mass_storage.c" #define USBF_ECM_INCLUDED -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html