usb: gadget: storage-common: Set FSG_MAX_LUNS to 16
[firefly-linux-kernel-4.4.55.git] / drivers / usb / gadget / function / f_mass_storage.c
index d2259c6639960c55c76239401148bbcc2ec1f449..9e88e2b18d95e7919c85cada4c5fa831a3ed9741 100644 (file)
@@ -54,7 +54,7 @@
  * following fields:
  *
  *     nluns           Number of LUNs function have (anywhere from 1
- *                             to FSG_MAX_LUNS which is 8).
+ *                             to FSG_MAX_LUNS).
  *     luns            An array of LUN configuration values.  This
  *                             should be filled for each LUN that
  *                             function will include (ie. for "nluns"
@@ -2761,12 +2761,12 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
                        common->luns[i] = NULL;
                }
 }
-EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
 
 void fsg_common_remove_luns(struct fsg_common *common)
 {
        _fsg_common_remove_luns(common, common->nluns);
 }
+EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
 
 void fsg_common_free_luns(struct fsg_common *common)
 {
@@ -2786,7 +2786,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
                return -EINVAL;
        }
 
-       curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
+       curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
        if (unlikely(!curlun))
                return -ENOMEM;
 
@@ -2796,8 +2796,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
        common->luns = curlun;
        common->nluns = nluns;
 
-       pr_info("Number of LUNs=%d\n", common->nluns);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
@@ -3526,6 +3524,9 @@ static struct usb_function_instance *fsg_alloc_inst(void)
        config.removable = true;
        rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
                        (const char **)&opts->func_inst.group.cg_item.ci_name);
+       if (rc)
+               goto release_buffers;
+
        opts->lun0.lun = opts->common->luns[0];
        opts->lun0.lun_id = 0;
        config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
@@ -3536,6 +3537,8 @@ static struct usb_function_instance *fsg_alloc_inst(void)
 
        return &opts->func_inst;
 
+release_buffers:
+       fsg_common_free_buffers(opts->common);
 release_luns:
        kfree(opts->common->luns);
 release_opts:
@@ -3563,14 +3566,26 @@ 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);
+
        fsg->function.name      = FSG_DRIVER_DESC;
        fsg->function.bind      = fsg_bind;
        fsg->function.unbind    = fsg_unbind;