aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Nazarewicz <m.nazarewicz@samsung.com>2010-03-29 08:01:32 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:36 -0400
commit0fb2c2a1692b8f77be25d38f8802b0142cb6e6bc (patch)
treea9fee9add6aef38f6ddc2d70e1c94750366d7864
parentdd0543ecc638947d67bdd3a8a41b95ed3c7b885e (diff)
USB: gadget: f_mass_storage: per function
Mass Storage Function (MSF) used the same descriptors for each usb_function instance (meaning usb_function::descriptors of different functions pointed to the same static area (the same was true for usb_function::hs_descriptors)). This would leads to problems if MSF were used in several USB configurations with different interface and/or endpoint numbers. Descriptors for all configurations would have interface/endpoint numbers overwritten by the values valid for the last configuration. This patch adds code that copies the descriptors each time MSF is added to USB configuration (that is for each usb_function). Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> Cc: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/usb/gadget/f_mass_storage.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 218f51db9721..9dbe86dec332 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2919,6 +2919,8 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
2919 2919
2920 DBG(fsg, "unbind\n"); 2920 DBG(fsg, "unbind\n");
2921 fsg_common_put(fsg->common); 2921 fsg_common_put(fsg->common);
2922 usb_free_descriptors(fsg->function.descriptors);
2923 usb_free_descriptors(fsg->function.hs_descriptors);
2922 kfree(fsg); 2924 kfree(fsg);
2923} 2925}
2924 2926
@@ -2959,7 +2961,9 @@ static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
2959 fsg_fs_bulk_in_desc.bEndpointAddress; 2961 fsg_fs_bulk_in_desc.bEndpointAddress;
2960 fsg_hs_bulk_out_desc.bEndpointAddress = 2962 fsg_hs_bulk_out_desc.bEndpointAddress =
2961 fsg_fs_bulk_out_desc.bEndpointAddress; 2963 fsg_fs_bulk_out_desc.bEndpointAddress;
2962 f->hs_descriptors = fsg_hs_function; 2964 f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
2965 if (unlikely(!f->hs_descriptors))
2966 return -ENOMEM;
2963 } 2967 }
2964 2968
2965 return 0; 2969 return 0;
@@ -2991,7 +2995,11 @@ static int fsg_add(struct usb_composite_dev *cdev,
2991 2995
2992 fsg->function.name = FSG_DRIVER_DESC; 2996 fsg->function.name = FSG_DRIVER_DESC;
2993 fsg->function.strings = fsg_strings_array; 2997 fsg->function.strings = fsg_strings_array;
2994 fsg->function.descriptors = fsg_fs_function; 2998 fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function);
2999 if (unlikely(!fsg->function.descriptors)) {
3000 rc = -ENOMEM;
3001 goto error_free_fsg;
3002 }
2995 fsg->function.bind = fsg_bind; 3003 fsg->function.bind = fsg_bind;
2996 fsg->function.unbind = fsg_unbind; 3004 fsg->function.unbind = fsg_unbind;
2997 fsg->function.setup = fsg_setup; 3005 fsg->function.setup = fsg_setup;
@@ -3006,11 +3014,19 @@ static int fsg_add(struct usb_composite_dev *cdev,
3006 * call to usb_add_function() was successful. */ 3014 * call to usb_add_function() was successful. */
3007 3015
3008 rc = usb_add_function(c, &fsg->function); 3016 rc = usb_add_function(c, &fsg->function);
3017 if (unlikely(rc))
3018 goto error_free_all;
3009 3019
3010 if (likely(rc == 0)) 3020 fsg_common_get(fsg->common);
3011 fsg_common_get(fsg->common); 3021 return 0;
3012 else 3022
3013 kfree(fsg); 3023error_free_all:
3024 usb_free_descriptors(fsg->function.descriptors);
3025 /* fsg_bind() might have copied those; or maybe not? who cares
3026 * -- free it just in case. */
3027 usb_free_descriptors(fsg->function.hs_descriptors);
3028error_free_fsg:
3029 kfree(fsg);
3014 3030
3015 return rc; 3031 return rc;
3016} 3032}