summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_mass_storage.c
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz2013-09-26 14:38:16 +0200
committerFelipe Balbi2013-10-01 16:50:57 +0200
commit6fdc5dd25e0cd5afc114fe65427150c65f0eb67b (patch)
tree36d30eff7d42a7ddb4ca76d6387888bb892803be /drivers/usb/gadget/f_mass_storage.c
parentusb: gadget: configfs: add a method to unregister the gadget (diff)
downloadkernel-qcow2-linux-6fdc5dd25e0cd5afc114fe65427150c65f0eb67b.tar.gz
kernel-qcow2-linux-6fdc5dd25e0cd5afc114fe65427150c65f0eb67b.tar.xz
kernel-qcow2-linux-6fdc5dd25e0cd5afc114fe65427150c65f0eb67b.zip
usb: gadget: create a utility module for mass_storage
Converting to configfs requires making the f_mass_storage.c a module. But first we need to get rid of "#include "storage_common.c". This patch makes storage_common.c a separately compiled file, which is built as a utility module named u_ms.ko. After all mass storage users are converted to the new function interface this module can be eliminated by merging it with the mass storage function's module. USB descriptors are exported so that they can be accessed from f_mass_storage. FSG_VENDOR_ID and FSG_PRODUCT_ID are moved to their only user. Handling of CONFIG_USB_GADGET_DEBUG_FILES is moved to f_mass_storage.c. The fsg_num_buffers static is moved to FSG_MODULE_PARAMETER users, so instead of using a global variable the f_mass_storage introduces fsg_num_buffers member in fsg_common (and fsg_config). fsg_strings and fsg_stringtab are moved to f_mass_storage.c. 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/f_mass_storage.c')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c106
1 files changed, 91 insertions, 15 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a01d7d38c016..def3426108b4 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -228,8 +228,18 @@
static const char fsg_string_interface[] = "Mass Storage";
-#include "storage_common.c"
+#include "storage_common.h"
+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+static struct usb_string fsg_strings[] = {
+ {FSG_STRING_INTERFACE, fsg_string_interface},
+ {}
+};
+
+static struct usb_gadget_strings fsg_stringtab = {
+ .language = 0x0409, /* en-us */
+ .strings = fsg_strings,
+};
/*-------------------------------------------------------------------------*/
@@ -268,6 +278,7 @@ struct fsg_common {
struct fsg_buffhd *next_buffhd_to_fill;
struct fsg_buffhd *next_buffhd_to_drain;
struct fsg_buffhd *buffhds;
+ unsigned int fsg_num_buffers;
int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE];
@@ -332,6 +343,7 @@ struct fsg_config {
const char *product_name; /* 16 characters or less */
char can_stall;
+ unsigned int fsg_num_buffers;
};
struct fsg_dev {
@@ -2244,7 +2256,7 @@ reset:
if (common->fsg) {
fsg = common->fsg;
- for (i = 0; i < fsg_num_buffers; ++i) {
+ for (i = 0; i < common->fsg_num_buffers; ++i) {
struct fsg_buffhd *bh = &common->buffhds[i];
if (bh->inreq) {
@@ -2303,7 +2315,7 @@ reset:
clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
/* Allocate the requests */
- for (i = 0; i < fsg_num_buffers; ++i) {
+ for (i = 0; i < common->fsg_num_buffers; ++i) {
struct fsg_buffhd *bh = &common->buffhds[i];
rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
@@ -2372,7 +2384,7 @@ static void handle_exception(struct fsg_common *common)
/* Cancel all the pending transfers */
if (likely(common->fsg)) {
- for (i = 0; i < fsg_num_buffers; ++i) {
+ for (i = 0; i < common->fsg_num_buffers; ++i) {
bh = &common->buffhds[i];
if (bh->inreq_busy)
usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
@@ -2384,7 +2396,7 @@ static void handle_exception(struct fsg_common *common)
/* Wait until everything is idle */
for (;;) {
int num_active = 0;
- for (i = 0; i < fsg_num_buffers; ++i) {
+ for (i = 0; i < common->fsg_num_buffers; ++i) {
bh = &common->buffhds[i];
num_active += bh->inreq_busy + bh->outreq_busy;
}
@@ -2407,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
*/
spin_lock_irq(&common->lock);
- for (i = 0; i < fsg_num_buffers; ++i) {
+ for (i = 0; i < common->fsg_num_buffers; ++i) {
bh = &common->buffhds[i];
bh->state = BUF_STATE_EMPTY;
}
@@ -2580,6 +2592,41 @@ static int fsg_main_thread(void *common_)
/*************************** DEVICE ATTRIBUTES ***************************/
+static ssize_t ro_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return fsg_show_ro(dev, attr, buf);
+}
+
+static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return fsg_show_nofua(dev, attr, buf);
+}
+
+static ssize_t file_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return fsg_show_file(dev, attr, buf);
+}
+
+static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return fsg_store_ro(dev, attr, buf, count);
+}
+
+static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return fsg_store_nofua(dev, attr, buf, count);
+}
+
+static ssize_t file_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return fsg_store_file(dev, attr, buf, count);
+}
+
static DEVICE_ATTR_RW(ro);
static DEVICE_ATTR_RW(nofua);
static DEVICE_ATTR_RW(file);
@@ -2607,6 +2654,16 @@ static inline void fsg_common_put(struct fsg_common *common)
kref_put(&common->ref, fsg_common_release);
}
+/* check if fsg_num_buffers is within a valid range */
+static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+{
+ if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+ return 0;
+ pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
+ fsg_num_buffers, 2, 4);
+ return -EINVAL;
+}
+
static struct fsg_common *fsg_common_init(struct fsg_common *common,
struct usb_composite_dev *cdev,
struct fsg_config *cfg)
@@ -2618,7 +2675,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
int nluns, i, rc;
char *pathbuf;
- rc = fsg_num_buffers_validate();
+ rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
if (rc != 0)
return ERR_PTR(rc);
@@ -2640,7 +2697,8 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
common->free_storage_on_release = 0;
}
- common->buffhds = kcalloc(fsg_num_buffers,
+ common->fsg_num_buffers = cfg->fsg_num_buffers;
+ common->buffhds = kcalloc(common->fsg_num_buffers,
sizeof *(common->buffhds), GFP_KERNEL);
if (!common->buffhds) {
if (common->free_storage_on_release)
@@ -2727,7 +2785,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
/* Data buffers cyclic list */
bh = common->buffhds;
- i = fsg_num_buffers;
+ i = common->fsg_num_buffers;
goto buffhds_first_it;
do {
bh->next = bh + 1;
@@ -2847,7 +2905,7 @@ static void fsg_common_release(struct kref *ref)
{
struct fsg_buffhd *bh = common->buffhds;
- unsigned i = fsg_num_buffers;
+ unsigned i = common->fsg_num_buffers;
do {
kfree(bh->buf);
} while (++bh, --i);
@@ -3009,7 +3067,7 @@ struct fsg_module_parameters {
S_IRUGO); \
MODULE_PARM_DESC(prefix ## name, desc)
-#define FSG_MODULE_PARAMETERS(prefix, params) \
+#define __FSG_MODULE_PARAMETERS(prefix, params) \
_FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \
"names of backing files or devices"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \
@@ -3025,9 +3083,24 @@ struct fsg_module_parameters {
_FSG_MODULE_PARAM(prefix, params, stall, bool, \
"false to prevent bulk stalls")
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+#define FSG_MODULE_PARAMETERS(prefix, params) \
+ __FSG_MODULE_PARAMETERS(prefix, params); \
+ module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+ MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+#else
+
+#define FSG_MODULE_PARAMETERS(prefix, params) \
+ __FSG_MODULE_PARAMETERS(prefix, params)
+
+#endif
+
+
static void
fsg_config_from_params(struct fsg_config *cfg,
- const struct fsg_module_parameters *params)
+ const struct fsg_module_parameters *params,
+ unsigned int fsg_num_buffers)
{
struct fsg_lun_config *lun;
unsigned i;
@@ -3055,19 +3128,22 @@ fsg_config_from_params(struct fsg_config *cfg,
/* Finalise */
cfg->can_stall = params->stall;
+ cfg->fsg_num_buffers = fsg_num_buffers;
}
static inline struct fsg_common *
fsg_common_from_params(struct fsg_common *common,
struct usb_composite_dev *cdev,
- const struct fsg_module_parameters *params)
+ const struct fsg_module_parameters *params,
+ unsigned int fsg_num_buffers)
__attribute__((unused));
static inline struct fsg_common *
fsg_common_from_params(struct fsg_common *common,
struct usb_composite_dev *cdev,
- const struct fsg_module_parameters *params)
+ const struct fsg_module_parameters *params,
+ unsigned int fsg_num_buffers)
{
struct fsg_config cfg;
- fsg_config_from_params(&cfg, params);
+ fsg_config_from_params(&cfg, params, fsg_num_buffers);
return fsg_common_init(common, cdev, &cfg);
}