aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichal Nazarewicz <m.nazarewicz@samsung.com>2009-10-28 11:57:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:19 -0500
commit9c610213370ad2e58a892f890a11a90615edf020 (patch)
treec4dc1b738aa33e42916cf26ba5595fac14cbc052 /drivers
parent606206c271722d613b99c737ce150f58f4485f41 (diff)
USB: g_mass_storage: fsg_common_init() created
Moved code initialising fsg_common structure to fsg_common_init() function which is called from fsg_bind(). Moreover, changed reference counting mechanism: fsg_common has a reference counter which counts how many fsg_dev structures uses it. When this reaches zero fsg_common_release() is run which unregisters LUN devices and frees memory. fsg_common_init() takes pointer to fsg_common structure as an argument. If it is NULL function allocates storage otherwise uses pointed to memory (handy if fsg_common is a field of another structure or a static variable). fsg_common_release() will free storage only if free_storage_on_release is set -- it is initialised by fsg_common_init(): set if allocation was done, unset otherwise (one may overwrite it of course). Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c361
1 files changed, 199 insertions, 162 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index b4ec76a3e37..5a0f5708c09 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -323,6 +323,8 @@ MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
323 323
324/* Data shared by all the FSG instances. */ 324/* Data shared by all the FSG instances. */
325struct fsg_common { 325struct fsg_common {
326 struct usb_gadget *gadget;
327
326 /* filesem protects: backing files in use */ 328 /* filesem protects: backing files in use */
327 struct rw_semaphore filesem; 329 struct rw_semaphore filesem;
328 330
@@ -337,6 +339,10 @@ struct fsg_common {
337 unsigned int lun; 339 unsigned int lun;
338 struct fsg_lun *luns; 340 struct fsg_lun *luns;
339 struct fsg_lun *curlun; 341 struct fsg_lun *curlun;
342
343 unsigned int free_storage_on_release:1;
344
345 struct kref ref;
340}; 346};
341 347
342 348
@@ -347,9 +353,6 @@ struct fsg_dev {
347 spinlock_t lock; 353 spinlock_t lock;
348 struct usb_gadget *gadget; 354 struct usb_gadget *gadget;
349 355
350 /* reference counting: wait until all LUNs are released */
351 struct kref ref;
352
353 struct usb_ep *ep0; // Handy copy of gadget->ep0 356 struct usb_ep *ep0; // Handy copy of gadget->ep0
354 struct usb_request *ep0req; // For control responses 357 struct usb_request *ep0req; // For control responses
355 unsigned int ep0_req_tag; 358 unsigned int ep0_req_tag;
@@ -2757,7 +2760,7 @@ static int fsg_main_thread(void *fsg_)
2757} 2760}
2758 2761
2759 2762
2760/*-------------------------------------------------------------------------*/ 2763/*************************** DEVICE ATTRIBUTES ***************************/
2761 2764
2762 2765
2763/* The write permissions and store_xxx pointers are set in fsg_bind() */ 2766/* The write permissions and store_xxx pointers are set in fsg_bind() */
@@ -2765,40 +2768,190 @@ static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
2765static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); 2768static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
2766 2769
2767 2770
2768/*-------------------------------------------------------------------------*/ 2771/****************************** FSG COMMON ******************************/
2772
2773static void fsg_common_release(struct kref *ref);
2769 2774
2770static void fsg_release(struct fsg_dev *fsg) 2775static void fsg_lun_release(struct device *dev)
2771{ 2776{
2772 kfree(fsg->common->luns); 2777 /* Nothing needs to be done */
2773 kfree(fsg);
2774} 2778}
2775 2779
2776static void lun_release(struct device *dev) 2780static inline void fsg_common_get(struct fsg_common *common)
2777{ 2781{
2782 kref_get(&common->ref);
2778} 2783}
2779 2784
2785static inline void fsg_common_put(struct fsg_common *common)
2786{
2787 kref_put(&common->ref, fsg_common_release);
2788}
2789
2790
2791static struct fsg_common *fsg_common_init(struct fsg_common *common,
2792 struct usb_gadget *gadget)
2793{
2794 struct fsg_buffhd *bh;
2795 struct fsg_lun *curlun;
2796 int nluns, i, rc;
2797
2798 /* Find out how many LUNs there should be */
2799 nluns = mod_data.nluns;
2800 if (nluns == 0)
2801 nluns = max(mod_data.num_filenames, 1u);
2802 if (nluns < 1 || nluns > FSG_MAX_LUNS) {
2803 dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
2804 return ERR_PTR(-EINVAL);
2805 }
2806
2807 /* Allocate? */
2808 if (!common) {
2809 common = kzalloc(sizeof *common, GFP_KERNEL);
2810 if (!common)
2811 return ERR_PTR(-ENOMEM);
2812 common->free_storage_on_release = 1;
2813 } else {
2814 memset(common, 0, sizeof common);
2815 common->free_storage_on_release = 0;
2816 }
2817 common->gadget = gadget;
2818
2819 /* Create the LUNs, open their backing files, and register the
2820 * LUN devices in sysfs. */
2821 curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL);
2822 if (!curlun) {
2823 kfree(common);
2824 return ERR_PTR(-ENOMEM);
2825 }
2826 common->luns = curlun;
2827
2828 init_rwsem(&common->filesem);
2829
2830 for (i = 0; i < nluns; ++i, ++curlun) {
2831 curlun->cdrom = !!mod_data.cdrom;
2832 curlun->ro = mod_data.cdrom || mod_data.ro[i];
2833 curlun->removable = mod_data.removable;
2834 curlun->dev.release = fsg_lun_release;
2835 curlun->dev.parent = &gadget->dev;
2836 curlun->dev.driver = &fsg_driver.driver;
2837 dev_set_drvdata(&curlun->dev, &common->filesem);
2838 dev_set_name(&curlun->dev,"%s-lun%d",
2839 dev_name(&gadget->dev), i);
2840
2841 rc = device_register(&curlun->dev);
2842 if (rc) {
2843 INFO(common, "failed to register LUN%d: %d\n", i, rc);
2844 common->nluns = i;
2845 goto error_release;
2846 }
2847
2848 rc = device_create_file(&curlun->dev, &dev_attr_ro);
2849 if (rc)
2850 goto error_luns;
2851 rc = device_create_file(&curlun->dev, &dev_attr_file);
2852 if (rc)
2853 goto error_luns;
2854
2855 if (mod_data.file[i] && *mod_data.file[i]) {
2856 rc = fsg_lun_open(curlun, mod_data.file[i]);
2857 if (rc)
2858 goto error_luns;
2859 } else if (!mod_data.removable) {
2860 ERROR(common, "no file given for LUN%d\n", i);
2861 rc = -EINVAL;
2862 goto error_luns;
2863 }
2864 }
2865 common->nluns = nluns;
2866
2867
2868 /* Data buffers cyclic list */
2869 /* Buffers in buffhds are static -- no need for additional
2870 * allocation. */
2871 bh = common->buffhds;
2872 i = FSG_NUM_BUFFERS - 1;
2873 do {
2874 bh->next = bh + 1;
2875 } while (++bh, --i);
2876 bh->next = common->buffhds;
2877
2878
2879 /* Release */
2880 if (mod_data.release == 0xffff) { // Parameter wasn't set
2881 int gcnum;
2882
2883 /* The sa1100 controller is not supported */
2884 if (gadget_is_sa1100(gadget))
2885 gcnum = -1;
2886 else
2887 gcnum = usb_gadget_controller_number(gadget);
2888 if (gcnum >= 0)
2889 mod_data.release = 0x0300 + gcnum;
2890 else {
2891 WARNING(common, "controller '%s' not recognized\n",
2892 gadget->name);
2893 WARNING(common, "controller '%s' not recognized\n",
2894 gadget->name);
2895 mod_data.release = 0x0399;
2896 }
2897 }
2898
2899
2900 /* Some peripheral controllers are known not to be able to
2901 * halt bulk endpoints correctly. If one of them is present,
2902 * disable stalls.
2903 */
2904 if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
2905 mod_data.can_stall = 0;
2906
2907
2908 kref_init(&common->ref);
2909 return common;
2910
2911
2912error_luns:
2913 common->nluns = i + 1;
2914error_release:
2915 /* Call fsg_common_release() directly, ref is not initialised */
2916 fsg_common_release(&common->ref);
2917 return ERR_PTR(rc);
2918}
2919
2920
2921static void fsg_common_release(struct kref *ref)
2922{
2923 struct fsg_common *common =
2924 container_of(ref, struct fsg_common, ref);
2925 unsigned i = common->nluns;
2926 struct fsg_lun *lun = common->luns;
2927
2928 /* Beware tempting for -> do-while optimization: when in error
2929 * recovery nluns may be zero. */
2930
2931 for (; i; --i, ++lun) {
2932 device_remove_file(&lun->dev, &dev_attr_ro);
2933 device_remove_file(&lun->dev, &dev_attr_file);
2934 fsg_lun_close(lun);
2935 device_unregister(&lun->dev);
2936 }
2937
2938 kfree(common->luns);
2939 if (common->free_storage_on_release)
2940 kfree(common);
2941}
2942
2943
2944/*-------------------------------------------------------------------------*/
2945
2946
2780static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) 2947static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
2781{ 2948{
2782 struct fsg_dev *fsg = get_gadget_data(gadget); 2949 struct fsg_dev *fsg = get_gadget_data(gadget);
2783 int i;
2784 struct fsg_lun *curlun;
2785 struct usb_request *req = fsg->ep0req; 2950 struct usb_request *req = fsg->ep0req;
2786 2951
2787 DBG(fsg, "unbind\n"); 2952 DBG(fsg, "unbind\n");
2788 clear_bit(REGISTERED, &fsg->atomic_bitflags); 2953 clear_bit(REGISTERED, &fsg->atomic_bitflags);
2789 2954
2790 /* Unregister the sysfs attribute files and the LUNs */
2791 for (i = 0; i < fsg->common->nluns; ++i) {
2792 curlun = &fsg->common->luns[i];
2793 if (curlun->registered) {
2794 device_remove_file(&curlun->dev, &dev_attr_ro);
2795 device_remove_file(&curlun->dev, &dev_attr_file);
2796 fsg_lun_close(curlun);
2797 device_unregister(&curlun->dev);
2798 curlun->registered = 0;
2799 }
2800 }
2801
2802 /* If the thread isn't already dead, tell it to exit now */ 2955 /* If the thread isn't already dead, tell it to exit now */
2803 if (fsg->state != FSG_STATE_TERMINATED) { 2956 if (fsg->state != FSG_STATE_TERMINATED) {
2804 raise_exception(fsg, FSG_STATE_EXIT); 2957 raise_exception(fsg, FSG_STATE_EXIT);
@@ -2814,43 +2967,15 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
2814 usb_ep_free_request(fsg->ep0, req); 2967 usb_ep_free_request(fsg->ep0, req);
2815 } 2968 }
2816 2969
2970 fsg_common_put(fsg->common);
2971 kfree(fsg);
2817 set_gadget_data(gadget, NULL); 2972 set_gadget_data(gadget, NULL);
2818} 2973}
2819 2974
2820 2975
2821static int __init check_parameters(struct fsg_dev *fsg)
2822{
2823 int gcnum;
2824
2825 /* Some peripheral controllers are known not to be able to
2826 * halt bulk endpoints correctly. If one of them is present,
2827 * disable stalls.
2828 */
2829 if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
2830 mod_data.can_stall = 0;
2831
2832 if (mod_data.release == 0xffff) { // Parameter wasn't set
2833 /* The sa1100 controller is not supported */
2834 if (gadget_is_sa1100(fsg->gadget))
2835 gcnum = -1;
2836 else
2837 gcnum = usb_gadget_controller_number(fsg->gadget);
2838 if (gcnum >= 0)
2839 mod_data.release = 0x0300 + gcnum;
2840 else {
2841 WARNING(fsg, "controller '%s' not recognized\n",
2842 fsg->gadget->name);
2843 mod_data.release = 0x0399;
2844 }
2845 }
2846
2847 return 0;
2848}
2849
2850
2851static int __init fsg_bind(struct usb_gadget *gadget) 2976static int __init fsg_bind(struct usb_gadget *gadget)
2852{ 2977{
2853 struct fsg_dev *fsg = the_fsg; 2978 struct fsg_dev *fsg;
2854 int rc; 2979 int rc;
2855 int i; 2980 int i;
2856 struct fsg_lun *curlun; 2981 struct fsg_lun *curlun;
@@ -2858,15 +2983,27 @@ static int __init fsg_bind(struct usb_gadget *gadget)
2858 struct usb_request *req; 2983 struct usb_request *req;
2859 char *pathbuf, *p; 2984 char *pathbuf, *p;
2860 2985
2986 /* Allocate */
2987 fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
2988 if (!fsg)
2989 return -ENOMEM;
2990
2991 /* Initialise common */
2992 fsg->common = fsg_common_init(0, gadget);
2993 if (IS_ERR(fsg->common))
2994 return PTR_ERR(fsg->common);
2995
2996 /* Basic parameters */
2861 fsg->gadget = gadget; 2997 fsg->gadget = gadget;
2862 set_gadget_data(gadget, fsg); 2998 set_gadget_data(gadget, fsg);
2863 fsg->ep0 = gadget->ep0; 2999 fsg->ep0 = gadget->ep0;
2864 fsg->ep0->driver_data = fsg; 3000 fsg->ep0->driver_data = fsg;
2865 3001
2866 if ((rc = check_parameters(fsg)) != 0) 3002 spin_lock_init(&fsg->lock);
2867 goto out; 3003 init_completion(&fsg->thread_notifier);
2868 3004
2869 if (mod_data.removable) { // Enable the store_xxx attributes 3005 /* Enable the store_xxx attributes */
3006 if (mod_data.removable) {
2870 dev_attr_file.attr.mode = 0644; 3007 dev_attr_file.attr.mode = 0644;
2871 dev_attr_file.store = fsg_store_file; 3008 dev_attr_file.store = fsg_store_file;
2872 if (!mod_data.cdrom) { 3009 if (!mod_data.cdrom) {
@@ -2875,62 +3012,6 @@ static int __init fsg_bind(struct usb_gadget *gadget)
2875 } 3012 }
2876 } 3013 }
2877 3014
2878 /* Find out how many LUNs there should be */
2879 i = mod_data.nluns;
2880 if (i == 0)
2881 i = max(mod_data.num_filenames, 1u);
2882 if (i > FSG_MAX_LUNS) {
2883 ERROR(fsg, "invalid number of LUNs: %d\n", i);
2884 rc = -EINVAL;
2885 goto out;
2886 }
2887
2888 /* Create the LUNs, open their backing files, and register the
2889 * LUN devices in sysfs. */
2890 fsg->common->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
2891 if (!fsg->common->luns) {
2892 rc = -ENOMEM;
2893 goto out;
2894 }
2895 fsg->common->nluns = i;
2896
2897 for (i = 0; i < fsg->common->nluns; ++i) {
2898 curlun = &fsg->common->luns[i];
2899 curlun->cdrom = !!mod_data.cdrom;
2900 curlun->ro = mod_data.cdrom || mod_data.ro[i];
2901 curlun->initially_ro = curlun->ro;
2902 curlun->removable = mod_data.removable;
2903 curlun->dev.release = lun_release;
2904 curlun->dev.parent = &gadget->dev;
2905 curlun->dev.driver = &fsg_driver.driver;
2906 dev_set_drvdata(&curlun->dev, &fsg->common->filesem);
2907 dev_set_name(&curlun->dev,"%s-lun%d",
2908 dev_name(&gadget->dev), i);
2909
2910 if ((rc = device_register(&curlun->dev)) != 0) {
2911 INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
2912 goto out;
2913 }
2914 if ((rc = device_create_file(&curlun->dev,
2915 &dev_attr_ro)) != 0 ||
2916 (rc = device_create_file(&curlun->dev,
2917 &dev_attr_file)) != 0) {
2918 device_unregister(&curlun->dev);
2919 goto out;
2920 }
2921 curlun->registered = 1;
2922
2923 if (mod_data.file[i] && *mod_data.file[i]) {
2924 if ((rc = fsg_lun_open(curlun,
2925 mod_data.file[i])) != 0)
2926 goto out;
2927 } else if (!mod_data.removable) {
2928 ERROR(fsg, "no file given for LUN%d\n", i);
2929 rc = -EINVAL;
2930 goto out;
2931 }
2932 }
2933
2934 /* Find all the endpoints we will use */ 3015 /* Find all the endpoints we will use */
2935 usb_ep_autoconfig_reset(gadget); 3016 usb_ep_autoconfig_reset(gadget);
2936 ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); 3017 ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
@@ -3028,6 +3109,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3028 3109
3029 /* Tell the thread to start working */ 3110 /* Tell the thread to start working */
3030 wake_up_process(fsg->thread_task); 3111 wake_up_process(fsg->thread_task);
3112
3113 the_fsg = fsg;
3031 return 0; 3114 return 0;
3032 3115
3033autoconf_fail: 3116autoconf_fail:
@@ -3066,64 +3149,18 @@ static struct usb_gadget_driver fsg_driver = {
3066}; 3149};
3067 3150
3068 3151
3069static int __init fsg_alloc(void)
3070{
3071 struct fsg_dev *fsg;
3072 struct fsg_buffhd *bh;
3073 unsigned i;
3074
3075 fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
3076 if (!fsg)
3077 return -ENOMEM;
3078
3079 fsg->common = kzalloc(sizeof *fsg->common, GFP_KERNEL);
3080 if (!fsg->common) {
3081 kfree(fsg);
3082 return -ENOMEM;
3083 }
3084
3085 bh = fsg->common->buffhds;
3086 i = FSG_NUM_BUFFERS - 1;
3087 do {
3088 bh->next = bh + 1;
3089 } while (++bh, --i);
3090 bh->next = fsg->common->buffhds;
3091
3092 spin_lock_init(&fsg->lock);
3093 init_rwsem(&fsg->common->filesem);
3094 init_completion(&fsg->thread_notifier);
3095
3096 the_fsg = fsg;
3097 return 0;
3098}
3099
3100
3101static int __init fsg_init(void) 3152static int __init fsg_init(void)
3102{ 3153{
3103 int rc; 3154 return usb_gadget_register_driver(&fsg_driver);
3104 struct fsg_dev *fsg;
3105
3106 if ((rc = fsg_alloc()) != 0)
3107 return rc;
3108 fsg = the_fsg;
3109 if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
3110 fsg_release(fsg);
3111 return rc;
3112} 3155}
3113module_init(fsg_init); 3156module_init(fsg_init);
3114 3157
3115 3158
3116static void __exit fsg_cleanup(void) 3159static void __exit fsg_cleanup(void)
3117{ 3160{
3118 struct fsg_dev *fsg = the_fsg;
3119
3120 /* Unregister the driver iff the thread hasn't already done so */ 3161 /* Unregister the driver iff the thread hasn't already done so */
3121 if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) 3162 if (the_fsg &&
3163 test_and_clear_bit(REGISTERED, &the_fsg->atomic_bitflags))
3122 usb_gadget_unregister_driver(&fsg_driver); 3164 usb_gadget_unregister_driver(&fsg_driver);
3123
3124 /* Wait for the thread to finish up */
3125 wait_for_completion(&fsg->thread_notifier);
3126
3127 fsg_release(fsg);
3128} 3165}
3129module_exit(fsg_cleanup); 3166module_exit(fsg_cleanup);