usb: gadget: f_mass_storage: convert to new function interface with backward compatibility

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@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Andrzej Pietrasiewicz 2013-10-09 10:06:01 +02:00 committed by Felipe Balbi
parent 5de862d73b
commit e5eaa0dc48
7 changed files with 179 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

@ -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"
/*-------------------------------------------------------------------------*/

View File

@ -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>
@ -226,6 +227,13 @@
#define FSG_DRIVER_DESC "Mass Storage Function"
#define FSG_DRIVER_VERSION "2009/09/11"
/* to avoid a lot of #ifndef-#endif in the temporary compatibility layer */
#ifndef USB_FMS_INCLUDED
#define EXPORT_SYMBOL_GPL_IF_MODULE(m) EXPORT_SYMBOL_GPL(m);
#else
#define EXPORT_SYMBOL_GPL_IF_MODULE(m)
#endif
static const char fsg_string_interface[] = "Mass Storage";
#include "storage_common.h"
@ -2627,11 +2635,13 @@ void fsg_common_get(struct fsg_common *common)
{
kref_get(&common->ref);
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_get);
void fsg_common_put(struct fsg_common *common)
{
kref_put(&common->ref, fsg_common_release);
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_put);
/* check if fsg_num_buffers is within a valid range */
static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
@ -2643,7 +2653,7 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
return -EINVAL;
}
static struct fsg_common *fsg_common_setup(struct fsg_common *common)
static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
{
if (!common) {
common = kzalloc(sizeof(*common), GFP_KERNEL);
@ -2651,7 +2661,8 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
return ERR_PTR(-ENOMEM);
common->free_storage_on_release = 1;
} else {
memset(common, 0, sizeof(*common));
if (zero)
memset(common, 0, sizeof(*common));
common->free_storage_on_release = 0;
}
init_rwsem(&common->filesem);
@ -2668,6 +2679,7 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
{
common->sysfs = sysfs;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_sysfs);
static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
{
@ -2723,6 +2735,7 @@ error_release:
return -ENOMEM;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_num_buffers);
static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
{
@ -2761,6 +2774,7 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
fsg_lun_close(lun);
kfree(lun);
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_lun);
static void _fsg_common_remove_luns(struct fsg_common *common, int n)
{
@ -2772,6 +2786,7 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
common->luns[i] = NULL;
}
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_luns);
void fsg_common_remove_luns(struct fsg_common *common)
{
@ -2784,6 +2799,7 @@ void fsg_common_free_luns(struct fsg_common *common)
kfree(common->luns);
common->luns = NULL;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_luns);
int fsg_common_set_nluns(struct fsg_common *common, int nluns)
{
@ -2809,6 +2825,14 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
return 0;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_nluns);
void fsg_common_free_buffers(struct fsg_common *common)
{
_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
common->buffhds = NULL;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_buffers);
int fsg_common_set_cdev(struct fsg_common *common,
struct usb_composite_dev *cdev, bool can_stall)
@ -2836,6 +2860,7 @@ int fsg_common_set_cdev(struct fsg_common *common,
return 0;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_cdev);
static inline int fsg_common_add_sysfs(struct fsg_common *common,
struct fsg_lun *lun)
@ -2958,6 +2983,7 @@ error_sysfs:
kfree(lun);
return rc;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_lun);
int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
{
@ -2979,6 +3005,7 @@ fail:
_fsg_common_remove_luns(common, i);
return rc;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_luns);
void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
const char *pn)
@ -2995,6 +3022,7 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
: "File-Stor Gadget"),
i);
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_inquiry_string);
int fsg_common_run_thread(struct fsg_common *common)
{
@ -3013,6 +3041,7 @@ int fsg_common_run_thread(struct fsg_common *common)
return 0;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_run_thread);
struct fsg_common *fsg_common_init(struct fsg_common *common,
struct usb_composite_dev *cdev,
@ -3020,7 +3049,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
{
int rc;
common = fsg_common_setup(common);
common = fsg_common_setup(common, !!common);
if (IS_ERR(common))
return common;
fsg_common_set_sysfs(common, true);
@ -3066,6 +3095,7 @@ error_release:
fsg_common_release(&common->ref);
return ERR_PTR(rc);
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_init);
static void fsg_common_release(struct kref *ref)
{
@ -3105,24 +3135,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);
@ -3132,6 +3144,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 = fsg_opts_from_func_inst(f->fi);
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 */
@ -3183,7 +3210,31 @@ autoconf_fail:
return -ENOTSUPP;
}
/****************************** ADD FUNCTION ******************************/
/****************************** ALLOCATE FUNCTION *************************/
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);
}
#ifdef USB_FMS_INCLUDED
fsg_common_put(common);
#endif
usb_free_all_descriptors(&fsg->function);
#ifdef USB_FMS_INCLUDED
kfree(fsg);
#endif
}
#ifdef USB_FMS_INCLUDED
static int fsg_bind_config(struct usb_composite_dev *cdev,
struct usb_configuration *c,
@ -3220,6 +3271,88 @@ 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 = fsg_opts_from_func_inst(fi);
fsg_common_put(opts->common);
kfree(opts);
}
static struct usb_function_instance *fsg_alloc_inst(void)
{
struct fsg_opts *opts;
int rc;
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)) {
rc = PTR_ERR(opts->common);
goto release_opts;
}
rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
if (rc)
goto release_opts;
rc = fsg_common_set_num_buffers(opts->common,
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
if (rc)
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(rc);
}
static void fsg_free(struct usb_function *f)
{
struct fsg_dev *fsg;
fsg = container_of(f, struct fsg_dev, function);
kfree(fsg);
}
static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
{
struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
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;
return &fsg->function;
}
DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michal Nazarewicz");
#endif
/************************* Module parameters *************************/
@ -3256,4 +3389,5 @@ void fsg_config_from_params(struct fsg_config *cfg,
cfg->can_stall = params->stall;
cfg->fsg_num_buffers = fsg_num_buffers;
}
EXPORT_SYMBOL_GPL_IF_MODULE(fsg_config_from_params);

View File

@ -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;
@ -94,6 +101,12 @@ struct fsg_config {
unsigned int fsg_num_buffers;
};
static inline struct fsg_opts *
fsg_opts_from_func_inst(const struct usb_function_instance *fi)
{
return container_of(fi, struct fsg_opts, func_inst);
}
void fsg_common_get(struct fsg_common *common);
void fsg_common_put(struct fsg_common *common);
@ -106,6 +119,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);
int fsg_common_set_cdev(struct fsg_common *common,
struct usb_composite_dev *cdev, bool can_stall);

View File

@ -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"
/*-------------------------------------------------------------------------*/

View File

@ -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