aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorRoger Quadros <roger.quadros@nokia.com>2011-05-09 06:08:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-10 17:14:58 -0400
commit95ed32366748e2034e82c9e738c312df8fb3d3a9 (patch)
tree9506a9ec54bc1245fac73f6bc850315511e56ca2 /drivers/usb
parent1b9ba000177ee47bcc5b44c7c34e48e735f5f9b1 (diff)
usb: gadget: f_mass_storage: Make us pass USBCV MSC Compliance tests
Defer the SET_CONFIG and SET_INTERFACE control transfer's data/status stages till we are ready to process new CBW from the host. This way we ensure that we don't loose any CBW during MSC compliance tests and cause lock up. Signed-off-by: Roger Quadros <roger.quadros@nokia.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 01ae27b60d4c..ad96be808b29 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -347,6 +347,7 @@ struct fsg_operations {
347/* Data shared by all the FSG instances. */ 347/* Data shared by all the FSG instances. */
348struct fsg_common { 348struct fsg_common {
349 struct usb_gadget *gadget; 349 struct usb_gadget *gadget;
350 struct usb_composite_dev *cdev;
350 struct fsg_dev *fsg, *new_fsg; 351 struct fsg_dev *fsg, *new_fsg;
351 wait_queue_head_t fsg_wait; 352 wait_queue_head_t fsg_wait;
352 353
@@ -2441,7 +2442,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
2441 struct fsg_dev *fsg = fsg_from_func(f); 2442 struct fsg_dev *fsg = fsg_from_func(f);
2442 fsg->common->new_fsg = fsg; 2443 fsg->common->new_fsg = fsg;
2443 raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); 2444 raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
2444 return 0; 2445 return USB_GADGET_DELAYED_STATUS;
2445} 2446}
2446 2447
2447static void fsg_disable(struct usb_function *f) 2448static void fsg_disable(struct usb_function *f)
@@ -2577,6 +2578,8 @@ static void handle_exception(struct fsg_common *common)
2577 2578
2578 case FSG_STATE_CONFIG_CHANGE: 2579 case FSG_STATE_CONFIG_CHANGE:
2579 do_set_interface(common, common->new_fsg); 2580 do_set_interface(common, common->new_fsg);
2581 if (common->new_fsg)
2582 usb_composite_setup_continue(common->cdev);
2580 break; 2583 break;
2581 2584
2582 case FSG_STATE_EXIT: 2585 case FSG_STATE_EXIT:
@@ -2747,6 +2750,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2747 common->gadget = gadget; 2750 common->gadget = gadget;
2748 common->ep0 = gadget->ep0; 2751 common->ep0 = gadget->ep0;
2749 common->ep0req = cdev->req; 2752 common->ep0req = cdev->req;
2753 common->cdev = cdev;
2750 2754
2751 /* Maybe allocate device-global string IDs, and patch descriptors */ 2755 /* Maybe allocate device-global string IDs, and patch descriptors */
2752 if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { 2756 if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {