diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2013-10-09 04:05:55 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-10 11:21:48 -0400 |
commit | 6313caace5f5b4fd2c23b9bc40ea26f252a28bf9 (patch) | |
tree | 9049255d6fc9513af94e4a54f206117437171b2b /drivers/usb | |
parent | b24650df9521f1845571568684621cefb0ba4e3b (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.c | 72 | ||||
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.h | 2 |
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 | ||
2684 | int 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; | ||
2704 | buffhds_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 | |||
2717 | error_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 | |||
2684 | static inline void fsg_common_remove_sysfs(struct fsg_lun *lun) | 2727 | static 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; | ||
2843 | buffhds_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 | ||
105 | void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs); | 105 | void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs); |
106 | 106 | ||
107 | int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n); | ||
108 | |||
107 | void fsg_config_from_params(struct fsg_config *cfg, | 109 | void 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); |