aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2013-10-09 04:05:55 -0400
committerFelipe Balbi <balbi@ti.com>2013-10-10 11:21:48 -0400
commit6313caace5f5b4fd2c23b9bc40ea26f252a28bf9 (patch)
tree9049255d6fc9513af94e4a54f206117437171b2b /drivers/usb
parentb24650df9521f1845571568684621cefb0ba4e3b (diff)
usb: gadget: f_mass_storage: create fsg_common_set_num_buffers for use in fsg_common_init
fsg_common_init is a lengthy function. Factor a portion of it out. 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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c72
-rw-r--r--drivers/usb/gadget/f_mass_storage.h2
2 files changed, 48 insertions, 26 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index da87ffe34514..79d989979360 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2681,6 +2681,49 @@ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
2681 } 2681 }
2682} 2682}
2683 2683
2684int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
2685{
2686 struct fsg_buffhd *bh, *buffhds;
2687 int i, rc;
2688
2689 rc = fsg_num_buffers_validate(n);
2690 if (rc != 0)
2691 return rc;
2692
2693 buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL);
2694 if (!buffhds)
2695 return -ENOMEM;
2696
2697 /* Data buffers cyclic list */
2698 bh = buffhds;
2699 i = n;
2700 goto buffhds_first_it;
2701 do {
2702 bh->next = bh + 1;
2703 ++bh;
2704buffhds_first_it:
2705 bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
2706 if (unlikely(!bh->buf))
2707 goto error_release;
2708 } while (--i);
2709 bh->next = buffhds;
2710
2711 _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
2712 common->fsg_num_buffers = n;
2713 common->buffhds = buffhds;
2714
2715 return 0;
2716
2717error_release:
2718 /*
2719 * "buf"s pointed to by heads after n - i are NULL
2720 * so releasing them won't hurt
2721 */
2722 _fsg_common_free_buffers(buffhds, n);
2723
2724 return -ENOMEM;
2725}
2726
2684static inline void fsg_common_remove_sysfs(struct fsg_lun *lun) 2727static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
2685{ 2728{
2686 device_remove_file(&lun->dev, &dev_attr_nofua); 2729 device_remove_file(&lun->dev, &dev_attr_nofua);
@@ -2714,17 +2757,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
2714 struct fsg_config *cfg) 2757 struct fsg_config *cfg)
2715{ 2758{
2716 struct usb_gadget *gadget = cdev->gadget; 2759 struct usb_gadget *gadget = cdev->gadget;
2717 struct fsg_buffhd *bh;
2718 struct fsg_lun **curlun_it; 2760 struct fsg_lun **curlun_it;
2719 struct fsg_lun_config *lcfg; 2761 struct fsg_lun_config *lcfg;
2720 struct usb_string *us; 2762 struct usb_string *us;
2721 int nluns, i, rc; 2763 int nluns, i, rc;
2722 char *pathbuf; 2764 char *pathbuf;
2723 2765
2724 rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
2725 if (rc != 0)
2726 return ERR_PTR(rc);
2727
2728 /* Find out how many LUNs there should be */ 2766 /* Find out how many LUNs there should be */
2729 nluns = cfg->nluns; 2767 nluns = cfg->nluns;
2730 if (nluns < 1 || nluns > FSG_MAX_LUNS) { 2768 if (nluns < 1 || nluns > FSG_MAX_LUNS) {
@@ -2738,15 +2776,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
2738 fsg_common_set_sysfs(common, true); 2776 fsg_common_set_sysfs(common, true);
2739 common->state = FSG_STATE_IDLE; 2777 common->state = FSG_STATE_IDLE;
2740 2778
2741 common->fsg_num_buffers = cfg->fsg_num_buffers; 2779 rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
2742 common->buffhds = kcalloc(common->fsg_num_buffers, 2780 if (rc) {
2743 sizeof *(common->buffhds), GFP_KERNEL);
2744 if (!common->buffhds) {
2745 if (common->free_storage_on_release) 2781 if (common->free_storage_on_release)
2746 kfree(common); 2782 kfree(common);
2747 return ERR_PTR(-ENOMEM); 2783 return ERR_PTR(rc);
2748 } 2784 }
2749
2750 common->ops = cfg->ops; 2785 common->ops = cfg->ops;
2751 common->private_data = cfg->private_data; 2786 common->private_data = cfg->private_data;
2752 2787
@@ -2833,21 +2868,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
2833 } 2868 }
2834 common->nluns = nluns; 2869 common->nluns = nluns;
2835 2870
2836 /* Data buffers cyclic list */
2837 bh = common->buffhds;
2838 i = common->fsg_num_buffers;
2839 goto buffhds_first_it;
2840 do {
2841 bh->next = bh + 1;
2842 ++bh;
2843buffhds_first_it:
2844 bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
2845 if (unlikely(!bh->buf)) {
2846 rc = -ENOMEM;
2847 goto error_release;
2848 }
2849 } while (--i);
2850 bh->next = common->buffhds;
2851 2871
2852 /* Prepare inquiryString */ 2872 /* Prepare inquiryString */
2853 i = get_default_bcdDevice(); 2873 i = get_default_bcdDevice();
diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
index 1b88eae75283..a00f51a1d94b 100644
--- a/drivers/usb/gadget/f_mass_storage.h
+++ b/drivers/usb/gadget/f_mass_storage.h
@@ -104,6 +104,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
104 104
105void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs); 105void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
106 106
107int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
108
107void fsg_config_from_params(struct fsg_config *cfg, 109void fsg_config_from_params(struct fsg_config *cfg,
108 const struct fsg_module_parameters *params, 110 const struct fsg_module_parameters *params,
109 unsigned int fsg_num_buffers); 111 unsigned int fsg_num_buffers);