From e5fd39d9b80aaa0b8a16dd570fa55009905d6af4 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 25 Jun 2010 16:29:26 +0200 Subject: [PATCH] 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 Cc: Kyungmin Park Reported-by: Dries Van Puymbroeck Tested-by: Dries Van Puymbroeck Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7d05a0b..f866b7e 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) { struct fsg_dev *fsg = fsg_from_func(f); struct usb_gadget *gadget = c->cdev->gadget; - int rc; int i; struct usb_ep *ep; @@ -2996,6 +2995,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; + /* Copy descriptors */ + f->descriptors = usb_copy_descriptors(fsg_fs_function); + if (unlikely(!f->descriptors)) + return -ENOMEM; + if (gadget_is_dualspeed(gadget)) { /* Assume endpoint addresses are the same for both speeds */ fsg_hs_bulk_in_desc.bEndpointAddress = @@ -3003,16 +3007,17 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) fsg_hs_bulk_out_desc.bEndpointAddress = fsg_fs_bulk_out_desc.bEndpointAddress; f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); - if (unlikely(!f->hs_descriptors)) + if (unlikely(!f->hs_descriptors)) { + usb_free_descriptors(f->descriptors); return -ENOMEM; + } } return 0; autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); - rc = -ENOTSUPP; - return rc; + return -ENOTSUPP; } @@ -3036,11 +3041,6 @@ static int fsg_add(struct usb_composite_dev *cdev, fsg->function.name = FSG_DRIVER_DESC; fsg->function.strings = fsg_strings_array; - fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function); - if (unlikely(!fsg->function.descriptors)) { - rc = -ENOMEM; - goto error_free_fsg; - } fsg->function.bind = fsg_bind; fsg->function.unbind = fsg_unbind; fsg->function.setup = fsg_setup; @@ -3056,19 +3056,9 @@ static int fsg_add(struct usb_composite_dev *cdev, rc = usb_add_function(c, &fsg->function); if (unlikely(rc)) - goto error_free_all; - - fsg_common_get(fsg->common); - return 0; - -error_free_all: - usb_free_descriptors(fsg->function.descriptors); - /* fsg_bind() might have copied those; or maybe not? who cares - * -- free it just in case. */ - usb_free_descriptors(fsg->function.hs_descriptors); -error_free_fsg: - kfree(fsg); - + kfree(fsg); + else + fsg_common_get(fsg->common); return rc; } -- 2.7.4