usb: gadget: mass_storage: Use static array for luns
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Fri, 31 Jul 2015 11:46:07 +0000 (13:46 +0200)
committerFelipe Balbi <balbi@ti.com>
Fri, 31 Jul 2015 14:01:19 +0000 (09:01 -0500)
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>
drivers/usb/gadget/function/f_mass_storage.c
drivers/usb/gadget/function/f_mass_storage.h
drivers/usb/gadget/legacy/acm_ms.c
drivers/usb/gadget/legacy/mass_storage.c
drivers/usb/gadget/legacy/multi.c
drivers/usb/gadget/legacy/nokia.c

index 9870913e34bfc1ece822f1ee0f8d97256fea3d90..04c3bb6e9dcd132399f2fa13700ab28a78ebebbb 100644 (file)
@@ -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);
 
index 37bc94cbb7f321a4d289a4eb36dc7d564eb449e4..445df67756091678336dd3e9490de1c6ec595096 100644 (file)
@@ -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);
 
index 4d8adb48b8a75f5e0858636ca059ca8f250be418..4b158e2d1e57b829b19c8eb30c3cf8cadb6d32c4 100644 (file)
@@ -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);
index ab1a42ce75d2dc61614e1953db4c29dab94cf671..bda3c519110fe266dec569c4e85159499fa062d1 100644 (file)
@@ -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);
index c38ead1d67a45af8665006c1fe9f4c5adf494066..4fe794ddcd49ced2c4206c730b251be8a008352f 100644 (file)
@@ -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);
index 264c97e15478b27e99b53cc0062145a339fed74f..c20f3b58f12636616d065ee264eb90a91ea57acb 100644 (file)
@@ -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: