diff options
| author | Michal Nazarewicz <m.nazarewicz@samsung.com> | 2010-06-25 10:29:26 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-30 11:16:07 -0400 |
| commit | e5fd39d9b80aaa0b8a16dd570fa55009905d6af4 (patch) | |
| tree | e74ed16e930d8c8a78c1733a7ae4138b29c09e33 | |
| parent | c0f1f8e38fda8e345cad9269c559b4f036378120 (diff) | |
USB: gadget: f_mass_storage: fixed fs descriptors not being updated
The full speed descriptors were copied to the usb_function structure
in the fsg_bind_config function before call to the usb_ep_autoconfig.
The usb_ep_autoconfig was called in fsg_bind using the original
descriptors. In effect copied descriptors were not updated.
This patch changes the copy full speed descriptors after the call to
usb_op_autoconfig is performed. This way, copied full speed
descriptors have updated values.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Reported-by: Dries Van Puymbroeck <Dries.VanPuymbroeck@dekimo.com>
Tested-by: Dries Van Puymbroeck <Dries.VanPuymbroeck@dekimo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 34 |
1 files changed, 12 insertions, 22 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7d05a0be5c60..f866b7e72a28 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
| @@ -2970,7 +2970,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 2970 | { | 2970 | { |
| 2971 | struct fsg_dev *fsg = fsg_from_func(f); | 2971 | struct fsg_dev *fsg = fsg_from_func(f); |
| 2972 | struct usb_gadget *gadget = c->cdev->gadget; | 2972 | struct usb_gadget *gadget = c->cdev->gadget; |
| 2973 | int rc; | ||
| 2974 | int i; | 2973 | int i; |
| 2975 | struct usb_ep *ep; | 2974 | struct usb_ep *ep; |
| 2976 | 2975 | ||
| @@ -2996,6 +2995,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 2996 | ep->driver_data = fsg->common; /* claim the endpoint */ | 2995 | ep->driver_data = fsg->common; /* claim the endpoint */ |
| 2997 | fsg->bulk_out = ep; | 2996 | fsg->bulk_out = ep; |
| 2998 | 2997 | ||
| 2998 | /* Copy descriptors */ | ||
| 2999 | f->descriptors = usb_copy_descriptors(fsg_fs_function); | ||
| 3000 | if (unlikely(!f->descriptors)) | ||
| 3001 | return -ENOMEM; | ||
| 3002 | |||
| 2999 | if (gadget_is_dualspeed(gadget)) { | 3003 | if (gadget_is_dualspeed(gadget)) { |
| 3000 | /* Assume endpoint addresses are the same for both speeds */ | 3004 | /* Assume endpoint addresses are the same for both speeds */ |
| 3001 | fsg_hs_bulk_in_desc.bEndpointAddress = | 3005 | fsg_hs_bulk_in_desc.bEndpointAddress = |
| @@ -3003,16 +3007,17 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 3003 | fsg_hs_bulk_out_desc.bEndpointAddress = | 3007 | fsg_hs_bulk_out_desc.bEndpointAddress = |
| 3004 | fsg_fs_bulk_out_desc.bEndpointAddress; | 3008 | fsg_fs_bulk_out_desc.bEndpointAddress; |
| 3005 | f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); | 3009 | f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); |
| 3006 | if (unlikely(!f->hs_descriptors)) | 3010 | if (unlikely(!f->hs_descriptors)) { |
| 3011 | usb_free_descriptors(f->descriptors); | ||
| 3007 | return -ENOMEM; | 3012 | return -ENOMEM; |
| 3013 | } | ||
| 3008 | } | 3014 | } |
| 3009 | 3015 | ||
| 3010 | return 0; | 3016 | return 0; |
| 3011 | 3017 | ||
| 3012 | autoconf_fail: | 3018 | autoconf_fail: |
| 3013 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); | 3019 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); |
| 3014 | rc = -ENOTSUPP; | 3020 | return -ENOTSUPP; |
| 3015 | return rc; | ||
| 3016 | } | 3021 | } |
| 3017 | 3022 | ||
| 3018 | 3023 | ||
| @@ -3036,11 +3041,6 @@ static int fsg_add(struct usb_composite_dev *cdev, | |||
| 3036 | 3041 | ||
| 3037 | fsg->function.name = FSG_DRIVER_DESC; | 3042 | fsg->function.name = FSG_DRIVER_DESC; |
| 3038 | fsg->function.strings = fsg_strings_array; | 3043 | fsg->function.strings = fsg_strings_array; |
| 3039 | fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function); | ||
| 3040 | if (unlikely(!fsg->function.descriptors)) { | ||
| 3041 | rc = -ENOMEM; | ||
| 3042 | goto error_free_fsg; | ||
| 3043 | } | ||
| 3044 | fsg->function.bind = fsg_bind; | 3044 | fsg->function.bind = fsg_bind; |
| 3045 | fsg->function.unbind = fsg_unbind; | 3045 | fsg->function.unbind = fsg_unbind; |
| 3046 | fsg->function.setup = fsg_setup; | 3046 | fsg->function.setup = fsg_setup; |
| @@ -3056,19 +3056,9 @@ static int fsg_add(struct usb_composite_dev *cdev, | |||
| 3056 | 3056 | ||
| 3057 | rc = usb_add_function(c, &fsg->function); | 3057 | rc = usb_add_function(c, &fsg->function); |
| 3058 | if (unlikely(rc)) | 3058 | if (unlikely(rc)) |
| 3059 | goto error_free_all; | 3059 | kfree(fsg); |
| 3060 | 3060 | else | |
| 3061 | fsg_common_get(fsg->common); | 3061 | fsg_common_get(fsg->common); |
| 3062 | return 0; | ||
| 3063 | |||
| 3064 | error_free_all: | ||
| 3065 | usb_free_descriptors(fsg->function.descriptors); | ||
| 3066 | /* fsg_bind() might have copied those; or maybe not? who cares | ||
| 3067 | * -- free it just in case. */ | ||
| 3068 | usb_free_descriptors(fsg->function.hs_descriptors); | ||
| 3069 | error_free_fsg: | ||
| 3070 | kfree(fsg); | ||
| 3071 | |||
| 3072 | return rc; | 3062 | return rc; |
| 3073 | } | 3063 | } |
| 3074 | 3064 | ||
