Skip to content

Commit

Permalink
USB: gadget: f_mass_storage: per function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michal Nazarewicz authored and Greg Kroah-Hartman committed May 20, 2010
1 parent dd0543e commit 0fb2c2a
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions drivers/usb/gadget/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -2919,6 +2919,8 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)

DBG(fsg, "unbind\n");
fsg_common_put(fsg->common);
usb_free_descriptors(fsg->function.descriptors);
usb_free_descriptors(fsg->function.hs_descriptors);
kfree(fsg);
}

Expand Down Expand Up @@ -2959,7 +2961,9 @@ static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
fsg_fs_bulk_in_desc.bEndpointAddress;
fsg_hs_bulk_out_desc.bEndpointAddress =
fsg_fs_bulk_out_desc.bEndpointAddress;
f->hs_descriptors = fsg_hs_function;
f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
if (unlikely(!f->hs_descriptors))
return -ENOMEM;
}

return 0;
Expand Down Expand Up @@ -2991,7 +2995,11 @@ static int fsg_add(struct usb_composite_dev *cdev,

fsg->function.name = FSG_DRIVER_DESC;
fsg->function.strings = fsg_strings_array;
fsg->function.descriptors = fsg_fs_function;
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;
Expand All @@ -3006,11 +3014,19 @@ static int fsg_add(struct usb_composite_dev *cdev,
* call to usb_add_function() was successful. */

rc = usb_add_function(c, &fsg->function);
if (unlikely(rc))
goto error_free_all;

if (likely(rc == 0))
fsg_common_get(fsg->common);
else
kfree(fsg);
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);

return rc;
}
Expand Down

0 comments on commit 0fb2c2a

Please sign in to comment.