summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Opasiak <k.opasiak@samsung.com>2015-07-31 11:46:07 (GMT)
committerFelipe Balbi <balbi@ti.com>2015-07-31 14:01:19 (GMT)
commitdd02ea5a33059e4a753ae8bb877b698c54ee2907 (patch)
treeda31ce46795d007f422546cc930ffe5f4a136d23
parent5542f58c95aef67bc9016855f7c0bd6117b43100 (diff)
downloadlinux-dd02ea5a33059e4a753ae8bb877b698c54ee2907.tar.xz
usb: gadget: mass_storage: Use static array for luns
This patch replace dynamicly allocated luns array with static one. This simplifies the code of mass storage function and modules. Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com> Acked-by: Michal Nazarewicz <mina86@mina86.com>
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c127
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.h4
-rw-r--r--drivers/usb/gadget/legacy/acm_ms.c6
-rw-r--r--drivers/usb/gadget/legacy/mass_storage.c6
-rw-r--r--drivers/usb/gadget/legacy/multi.c6
-rw-r--r--drivers/usb/gadget/legacy/nokia.c14
6 files changed, 50 insertions, 113 deletions
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 9870913..04c3bb6 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -279,9 +279,8 @@ struct fsg_common {
int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE];
- unsigned int nluns;
unsigned int lun;
- struct fsg_lun **luns;
+ struct fsg_lun *luns[FSG_MAX_LUNS];
struct fsg_lun *curlun;
unsigned int bulk_out_maxpacket;
@@ -490,6 +489,16 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
spin_unlock(&common->lock);
}
+static int _fsg_common_get_max_lun(struct fsg_common *common)
+{
+ int i = ARRAY_SIZE(common->luns) - 1;
+
+ while (i >= 0 && !common->luns[i])
+ --i;
+
+ return i;
+}
+
static int fsg_setup(struct usb_function *f,
const struct usb_ctrlrequest *ctrl)
{
@@ -533,7 +542,7 @@ static int fsg_setup(struct usb_function *f,
w_length != 1)
return -EDOM;
VDBG(fsg, "get max LUN\n");
- *(u8 *)req->buf = fsg->common->nluns - 1;
+ *(u8 *)req->buf = _fsg_common_get_max_lun(fsg->common);
/* Respond with data/status */
req->length = min((u16)1, w_length);
@@ -2131,8 +2140,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
}
/* Is the CBW meaningful? */
- if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
- cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
+ if (cbw->Lun >= ARRAY_SIZE(common->luns) ||
+ cbw->Flags & ~US_BULK_FLAG_IN || cbw->Length <= 0 ||
+ cbw->Length > MAX_COMMAND_SIZE) {
DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
"cmdlen %u\n",
cbw->Lun, cbw->Flags, cbw->Length);
@@ -2159,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
if (common->data_size == 0)
common->data_dir = DATA_DIR_NONE;
common->lun = cbw->Lun;
- if (common->lun < common->nluns)
+ if (common->lun < ARRAY_SIZE(common->luns))
common->curlun = common->luns[common->lun];
else
common->curlun = NULL;
@@ -2307,7 +2317,7 @@ reset:
}
common->running = 1;
- for (i = 0; i < common->nluns; ++i)
+ for (i = 0; i < ARRAY_SIZE(common->luns); ++i)
if (common->luns[i])
common->luns[i]->unit_attention_data =
SS_RESET_OCCURRED;
@@ -2409,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
if (old_state == FSG_STATE_ABORT_BULK_OUT)
common->state = FSG_STATE_STATUS_PHASE;
else {
- for (i = 0; i < common->nluns; ++i) {
+ for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
curlun = common->luns[i];
if (!curlun)
continue;
@@ -2453,7 +2463,7 @@ static void handle_exception(struct fsg_common *common)
* a waste of time. Ditto for the INTERFACE_CHANGE and
* CONFIG_CHANGE cases.
*/
- /* for (i = 0; i < common->nluns; ++i) */
+ /* for (i = 0; i < common->ARRAY_SIZE(common->luns); ++i) */
/* if (common->luns[i]) */
/* common->luns[i]->unit_attention_data = */
/* SS_RESET_OCCURRED; */
@@ -2552,12 +2562,11 @@ static int fsg_main_thread(void *common_)
if (!common->ops || !common->ops->thread_exits
|| common->ops->thread_exits(common) < 0) {
- struct fsg_lun **curlun_it = common->luns;
- unsigned i = common->nluns;
+ int i;
down_write(&common->filesem);
- for (; i--; ++curlun_it) {
- struct fsg_lun *curlun = *curlun_it;
+ for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
+ struct fsg_lun *curlun = common->luns[i];
if (!curlun || !fsg_lun_is_open(curlun))
continue;
@@ -2676,6 +2685,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
init_completion(&common->thread_notifier);
init_waitqueue_head(&common->fsg_wait);
common->state = FSG_STATE_TERMINATED;
+ memset(common->luns, 0, sizeof(common->luns));
return common;
}
@@ -2764,42 +2774,10 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
void fsg_common_remove_luns(struct fsg_common *common)
{
- _fsg_common_remove_luns(common, common->nluns);
+ _fsg_common_remove_luns(common, ARRAY_SIZE(common->luns));
}
EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
-void fsg_common_free_luns(struct fsg_common *common)
-{
- fsg_common_remove_luns(common);
- kfree(common->luns);
- common->luns = NULL;
-}
-EXPORT_SYMBOL_GPL(fsg_common_free_luns);
-
-int fsg_common_set_nluns(struct fsg_common *common, int nluns)
-{
- struct fsg_lun **curlun;
-
- /* Find out how many LUNs there should be */
- if (nluns < 1 || nluns > FSG_MAX_LUNS) {
- pr_err("invalid number of LUNs: %u\n", nluns);
- return -EINVAL;
- }
-
- curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
- if (unlikely(!curlun))
- return -ENOMEM;
-
- if (common->luns)
- fsg_common_free_luns(common);
-
- common->luns = curlun;
- common->nluns = nluns;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
-
void fsg_common_set_ops(struct fsg_common *common,
const struct fsg_operations *ops)
{
@@ -2881,7 +2859,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
char *pathbuf, *p;
int rc = -ENOMEM;
- if (!common->nluns || !common->luns)
+ if (id >= ARRAY_SIZE(common->luns))
return -ENODEV;
if (common->luns[id])
@@ -2965,14 +2943,16 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
char buf[8]; /* enough for 100000000 different numbers, decimal */
int i, rc;
- for (i = 0; i < common->nluns; ++i) {
+ fsg_common_remove_luns(common);
+
+ for (i = 0; i < cfg->nluns; ++i) {
snprintf(buf, sizeof(buf), "lun%d", i);
rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
if (rc)
goto fail;
}
- pr_info("Number of LUNs=%d\n", common->nluns);
+ pr_info("Number of LUNs=%d\n", cfg->nluns);
return 0;
@@ -3021,6 +3001,7 @@ EXPORT_SYMBOL_GPL(fsg_common_run_thread);
static void fsg_common_release(struct kref *ref)
{
struct fsg_common *common = container_of(ref, struct fsg_common, ref);
+ int i;
/* If the thread isn't already dead, tell it to exit now */
if (common->state != FSG_STATE_TERMINATED) {
@@ -3028,22 +3009,14 @@ static void fsg_common_release(struct kref *ref)
wait_for_completion(&common->thread_notifier);
}
- if (likely(common->luns)) {
- struct fsg_lun **lun_it = common->luns;
- unsigned i = common->nluns;
-
- /* In error recovery common->nluns may be zero. */
- for (; i; --i, ++lun_it) {
- struct fsg_lun *lun = *lun_it;
- if (!lun)
- continue;
- fsg_lun_close(lun);
+ for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
+ struct fsg_lun *lun = common->luns[i];
+ if (!lun)
+ continue;
+ fsg_lun_close(lun);
if (device_is_registered(&lun->dev))
- device_unregister(&lun->dev);
- kfree(lun);
- }
-
- kfree(common->luns);
+ device_unregister(&lun->dev);
+ kfree(lun);
}
_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
@@ -3057,6 +3030,7 @@ static void fsg_common_release(struct kref *ref)
static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_common *common = fsg->common;
struct usb_gadget *gadget = c->cdev->gadget;
int i;
struct usb_ep *ep;
@@ -3064,6 +3038,13 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
int ret;
struct fsg_opts *opts;
+ /* Don't allow to bind if we don't have at least one LUN */
+ ret = _fsg_common_get_max_lun(common);
+ if (ret < 0) {
+ pr_err("There should be at least one LUN.\n");
+ return -EINVAL;
+ }
+
opts = fsg_opts_from_func_inst(f->fi);
if (!opts->no_configfs) {
ret = fsg_common_set_cdev(fsg->common, c->cdev,
@@ -3517,14 +3498,11 @@ static struct usb_function_instance *fsg_alloc_inst(void)
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;
+ goto release_opts;
pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
@@ -3547,8 +3525,6 @@ static struct usb_function_instance *fsg_alloc_inst(void)
release_buffers:
fsg_common_free_buffers(opts->common);
-release_luns:
- kfree(opts->common->luns);
release_opts:
kfree(opts);
return ERR_PTR(rc);
@@ -3574,23 +3550,12 @@ 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;
- unsigned nluns, i;
fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
if (unlikely(!fsg))
return ERR_PTR(-ENOMEM);
mutex_lock(&opts->lock);
- if (!opts->refcnt) {
- for (nluns = i = 0; i < FSG_MAX_LUNS; ++i)
- if (common->luns[i])
- nluns = i + 1;
- if (!nluns)
- pr_warn("No LUNS defined, continuing anyway\n");
- else
- common->nluns = nluns;
- pr_info("Number of LUNs=%u\n", common->nluns);
- }
opts->refcnt++;
mutex_unlock(&opts->lock);
diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h
index 37bc94c..445df67 100644
--- a/drivers/usb/gadget/function/f_mass_storage.h
+++ b/drivers/usb/gadget/function/f_mass_storage.h
@@ -141,10 +141,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun);
void fsg_common_remove_luns(struct fsg_common *common);
-void fsg_common_free_luns(struct fsg_common *common);
-
-int fsg_common_set_nluns(struct fsg_common *common, int nluns);
-
void fsg_common_set_ops(struct fsg_common *common,
const struct fsg_operations *ops);
diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c
index 4d8adb4..4b158e2 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -186,10 +186,6 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
if (status)
goto fail;
- status = fsg_common_set_nluns(opts->common, config.nluns);
- if (status)
- goto fail_set_nluns;
-
status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
if (status)
goto fail_set_cdev;
@@ -239,8 +235,6 @@ fail_otg_desc:
fail_string_ids:
fsg_common_remove_luns(opts->common);
fail_set_cdev:
- fsg_common_free_luns(opts->common);
-fail_set_nluns:
fsg_common_free_buffers(opts->common);
fail:
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c
index ab1a42c..bda3c51 100644
--- a/drivers/usb/gadget/legacy/mass_storage.c
+++ b/drivers/usb/gadget/legacy/mass_storage.c
@@ -177,10 +177,6 @@ static int msg_bind(struct usb_composite_dev *cdev)
if (status)
goto fail;
- status = fsg_common_set_nluns(opts->common, config.nluns);
- if (status)
- goto fail_set_nluns;
-
fsg_common_set_ops(opts->common, &ops);
status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
@@ -227,8 +223,6 @@ fail_otg_desc:
fail_string_ids:
fsg_common_remove_luns(opts->common);
fail_set_cdev:
- fsg_common_free_luns(opts->common);
-fail_set_nluns:
fsg_common_free_buffers(opts->common);
fail:
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c
index c38ead1..4fe794d 100644
--- a/drivers/usb/gadget/legacy/multi.c
+++ b/drivers/usb/gadget/legacy/multi.c
@@ -393,10 +393,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
if (status)
goto fail2;
- status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
- if (status)
- goto fail_set_nluns;
-
status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
if (status)
goto fail_set_cdev;
@@ -448,8 +444,6 @@ fail_otg_desc:
fail_string_ids:
fsg_common_remove_luns(fsg_opts->common);
fail_set_cdev:
- fsg_common_free_luns(fsg_opts->common);
-fail_set_nluns:
fsg_common_free_buffers(fsg_opts->common);
fail2:
usb_put_function_instance(fi_msg);
diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c
index 264c97e..c20f3b5 100644
--- a/drivers/usb/gadget/legacy/nokia.c
+++ b/drivers/usb/gadget/legacy/nokia.c
@@ -339,19 +339,15 @@ static int nokia_bind(struct usb_composite_dev *cdev)
if (status)
goto err_msg_inst;
- status = fsg_common_set_nluns(fsg_opts->common, fsg_config.nluns);
- if (status)
- goto err_msg_buf;
-
status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall);
if (status)
- goto err_msg_set_nluns;
+ goto err_msg_buf;
fsg_common_set_sysfs(fsg_opts->common, true);
status = fsg_common_create_luns(fsg_opts->common, &fsg_config);
if (status)
- goto err_msg_set_nluns;
+ goto err_msg_buf;
fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name,
fsg_config.product_name);
@@ -360,7 +356,7 @@ static int nokia_bind(struct usb_composite_dev *cdev)
status = usb_add_config(cdev, &nokia_config_500ma_driver,
nokia_bind_config);
if (status < 0)
- goto err_msg_set_cdev;
+ goto err_msg_luns;
status = usb_add_config(cdev, &nokia_config_100ma_driver,
nokia_bind_config);
@@ -381,10 +377,8 @@ err_put_cfg1:
if (!IS_ERR_OR_NULL(f_phonet_cfg1))
usb_put_function(f_phonet_cfg1);
usb_put_function(f_ecm_cfg1);
-err_msg_set_cdev:
+err_msg_luns:
fsg_common_remove_luns(fsg_opts->common);
-err_msg_set_nluns:
- fsg_common_free_luns(fsg_opts->common);
err_msg_buf:
fsg_common_free_buffers(fsg_opts->common);
err_msg_inst: