aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_mass_storage.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-10-22 16:15:06 -0400
committerFelipe Balbi <balbi@ti.com>2012-10-31 09:09:44 -0400
commit10287baec761d33f0a82d84b46e37a44030350d8 (patch)
treeb769a6dddfd4ccf81a986386bf5771182d1b0c55 /drivers/usb/gadget/f_mass_storage.c
parent0f9df939385527049c8062a099fbfa1479fe7ce0 (diff)
usb: gadget: always update HS/SS descriptors and create a copy of them
HS and SS descriptors are staticaly created. They are updated during the bind process with the endpoint address, string id or interface numbers. After that, the descriptor chain is linked to struct usb_function which is used by composite in order to serve the GET_DESCRIPTOR requests, number of available configs and so on. There is no need to assign the HS descriptor only if the UDC supports HS speed because composite won't report those to the host if HS support has not been reached. The same reasoning is valid for SS. This patch makes sure each function updates HS/SS descriptors unconditionally and uses the newly introduced helper function to create a copy the descriptors for the speed which is supported by the UDC. While at that, also rename f->descriptors to f->fs_descriptors in order to make it more explicit what that means. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/f_mass_storage.c')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c59
1 files changed, 20 insertions, 39 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 3a7668bde3ef..3433e432a4ae 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2904,9 +2904,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
2904 } 2904 }
2905 2905
2906 fsg_common_put(common); 2906 fsg_common_put(common);
2907 usb_free_descriptors(fsg->function.descriptors); 2907 usb_free_all_descriptors(&fsg->function);
2908 usb_free_descriptors(fsg->function.hs_descriptors);
2909 usb_free_descriptors(fsg->function.ss_descriptors);
2910 kfree(fsg); 2908 kfree(fsg);
2911} 2909}
2912 2910
@@ -2916,6 +2914,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
2916 struct usb_gadget *gadget = c->cdev->gadget; 2914 struct usb_gadget *gadget = c->cdev->gadget;
2917 int i; 2915 int i;
2918 struct usb_ep *ep; 2916 struct usb_ep *ep;
2917 unsigned max_burst;
2918 int ret;
2919 2919
2920 fsg->gadget = gadget; 2920 fsg->gadget = gadget;
2921 2921
@@ -2939,45 +2939,27 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
2939 ep->driver_data = fsg->common; /* claim the endpoint */ 2939 ep->driver_data = fsg->common; /* claim the endpoint */
2940 fsg->bulk_out = ep; 2940 fsg->bulk_out = ep;
2941 2941
2942 /* Copy descriptors */ 2942 /* Assume endpoint addresses are the same for both speeds */
2943 f->descriptors = usb_copy_descriptors(fsg_fs_function); 2943 fsg_hs_bulk_in_desc.bEndpointAddress =
2944 if (unlikely(!f->descriptors)) 2944 fsg_fs_bulk_in_desc.bEndpointAddress;
2945 return -ENOMEM; 2945 fsg_hs_bulk_out_desc.bEndpointAddress =
2946 2946 fsg_fs_bulk_out_desc.bEndpointAddress;
2947 if (gadget_is_dualspeed(gadget)) {
2948 /* Assume endpoint addresses are the same for both speeds */
2949 fsg_hs_bulk_in_desc.bEndpointAddress =
2950 fsg_fs_bulk_in_desc.bEndpointAddress;
2951 fsg_hs_bulk_out_desc.bEndpointAddress =
2952 fsg_fs_bulk_out_desc.bEndpointAddress;
2953 f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
2954 if (unlikely(!f->hs_descriptors)) {
2955 usb_free_descriptors(f->descriptors);
2956 return -ENOMEM;
2957 }
2958 }
2959
2960 if (gadget_is_superspeed(gadget)) {
2961 unsigned max_burst;
2962 2947
2963 /* Calculate bMaxBurst, we know packet size is 1024 */ 2948 /* Calculate bMaxBurst, we know packet size is 1024 */
2964 max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); 2949 max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
2965 2950
2966 fsg_ss_bulk_in_desc.bEndpointAddress = 2951 fsg_ss_bulk_in_desc.bEndpointAddress =
2967 fsg_fs_bulk_in_desc.bEndpointAddress; 2952 fsg_fs_bulk_in_desc.bEndpointAddress;
2968 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; 2953 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
2969 2954
2970 fsg_ss_bulk_out_desc.bEndpointAddress = 2955 fsg_ss_bulk_out_desc.bEndpointAddress =
2971 fsg_fs_bulk_out_desc.bEndpointAddress; 2956 fsg_fs_bulk_out_desc.bEndpointAddress;
2972 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; 2957 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
2973 2958
2974 f->ss_descriptors = usb_copy_descriptors(fsg_ss_function); 2959 ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
2975 if (unlikely(!f->ss_descriptors)) { 2960 fsg_ss_function);
2976 usb_free_descriptors(f->hs_descriptors); 2961 if (ret)
2977 usb_free_descriptors(f->descriptors); 2962 goto autoconf_fail;
2978 return -ENOMEM;
2979 }
2980 }
2981 2963
2982 return 0; 2964 return 0;
2983 2965
@@ -2986,7 +2968,6 @@ autoconf_fail:
2986 return -ENOTSUPP; 2968 return -ENOTSUPP;
2987} 2969}
2988 2970
2989
2990/****************************** ADD FUNCTION ******************************/ 2971/****************************** ADD FUNCTION ******************************/
2991 2972
2992static struct usb_gadget_strings *fsg_strings_array[] = { 2973static struct usb_gadget_strings *fsg_strings_array[] = {