aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_mass_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_mass_storage.c')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a37640eba434..f4911c09022e 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -368,7 +368,7 @@ struct fsg_common {
368 struct task_struct *thread_task; 368 struct task_struct *thread_task;
369 369
370 /* Callback function to call when thread exits. */ 370 /* Callback function to call when thread exits. */
371 void (*thread_exits)(struct fsg_common *common); 371 int (*thread_exits)(struct fsg_common *common);
372 /* Gadget's private data. */ 372 /* Gadget's private data. */
373 void *private_data; 373 void *private_data;
374 374
@@ -392,8 +392,12 @@ struct fsg_config {
392 const char *lun_name_format; 392 const char *lun_name_format;
393 const char *thread_name; 393 const char *thread_name;
394 394
395 /* Callback function to call when thread exits. */ 395 /* Callback function to call when thread exits. If no
396 void (*thread_exits)(struct fsg_common *common); 396 * callback is set or it returns value lower then zero MSF
397 * will force eject all LUNs it operates on (including those
398 * marked as non-removable or with prevent_medium_removal flag
399 * set). */
400 int (*thread_exits)(struct fsg_common *common);
397 /* Gadget's private data. */ 401 /* Gadget's private data. */
398 void *private_data; 402 void *private_data;
399 403
@@ -614,7 +618,12 @@ static int fsg_setup(struct usb_function *f,
614 return -EDOM; 618 return -EDOM;
615 VDBG(fsg, "get max LUN\n"); 619 VDBG(fsg, "get max LUN\n");
616 *(u8 *) req->buf = fsg->common->nluns - 1; 620 *(u8 *) req->buf = fsg->common->nluns - 1;
617 return 1; 621
622 /* Respond with data/status */
623 req->length = min((u16)1, w_length);
624 fsg->common->ep0req_name =
625 ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out";
626 return ep0_queue(fsg->common);
618 } 627 }
619 628
620 VDBG(fsg, 629 VDBG(fsg,
@@ -1041,7 +1050,7 @@ static void invalidate_sub(struct fsg_lun *curlun)
1041 unsigned long rc; 1050 unsigned long rc;
1042 1051
1043 rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); 1052 rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
1044 VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc); 1053 VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
1045} 1054}
1046 1055
1047static int do_verify(struct fsg_common *common) 1056static int do_verify(struct fsg_common *common)
@@ -2524,14 +2533,6 @@ static void handle_exception(struct fsg_common *common)
2524 2533
2525 case FSG_STATE_CONFIG_CHANGE: 2534 case FSG_STATE_CONFIG_CHANGE:
2526 rc = do_set_config(common, new_config); 2535 rc = do_set_config(common, new_config);
2527 if (common->ep0_req_tag != exception_req_tag)
2528 break;
2529 if (rc != 0) { /* STALL on errors */
2530 DBG(common, "ep0 set halt\n");
2531 usb_ep_set_halt(common->ep0);
2532 } else { /* Complete the status stage */
2533 ep0_queue(common);
2534 }
2535 break; 2536 break;
2536 2537
2537 case FSG_STATE_EXIT: 2538 case FSG_STATE_EXIT:
@@ -2615,8 +2616,20 @@ static int fsg_main_thread(void *common_)
2615 common->thread_task = NULL; 2616 common->thread_task = NULL;
2616 spin_unlock_irq(&common->lock); 2617 spin_unlock_irq(&common->lock);
2617 2618
2618 if (common->thread_exits) 2619 if (!common->thread_exits || common->thread_exits(common) < 0) {
2619 common->thread_exits(common); 2620 struct fsg_lun *curlun = common->luns;
2621 unsigned i = common->nluns;
2622
2623 down_write(&common->filesem);
2624 for (; i--; ++curlun) {
2625 if (!fsg_lun_is_open(curlun))
2626 continue;
2627
2628 fsg_lun_close(curlun);
2629 curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
2630 }
2631 up_write(&common->filesem);
2632 }
2620 2633
2621 /* Let the unbind and cleanup routines know the thread has exited */ 2634 /* Let the unbind and cleanup routines know the thread has exited */
2622 complete_and_exit(&common->thread_notifier, 0); 2635 complete_and_exit(&common->thread_notifier, 0);
@@ -2763,10 +2776,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2763 if (cfg->release != 0xffff) { 2776 if (cfg->release != 0xffff) {
2764 i = cfg->release; 2777 i = cfg->release;
2765 } else { 2778 } else {
2766 /* The sa1100 controller is not supported */ 2779 i = usb_gadget_controller_number(gadget);
2767 i = gadget_is_sa1100(gadget)
2768 ? -1
2769 : usb_gadget_controller_number(gadget);
2770 if (i >= 0) { 2780 if (i >= 0) {
2771 i = 0x0300 + i; 2781 i = 0x0300 + i;
2772 } else { 2782 } else {
@@ -2791,8 +2801,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2791 * disable stalls. 2801 * disable stalls.
2792 */ 2802 */
2793 common->can_stall = cfg->can_stall && 2803 common->can_stall = cfg->can_stall &&
2794 !(gadget_is_sh(common->gadget) || 2804 !(gadget_is_at91(common->gadget));
2795 gadget_is_at91(common->gadget));
2796 2805
2797 2806
2798 spin_lock_init(&common->lock); 2807 spin_lock_init(&common->lock);
@@ -2852,7 +2861,6 @@ error_release:
2852 /* Call fsg_common_release() directly, ref might be not 2861 /* Call fsg_common_release() directly, ref might be not
2853 * initialised */ 2862 * initialised */
2854 fsg_common_release(&common->ref); 2863 fsg_common_release(&common->ref);
2855 complete(&common->thread_notifier);
2856 return ERR_PTR(rc); 2864 return ERR_PTR(rc);
2857} 2865}
2858 2866
@@ -2902,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
2902} 2910}
2903 2911
2904 2912
2905static int fsg_bind(struct usb_configuration *c, struct usb_function *f) 2913static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
2906{ 2914{
2907 struct fsg_dev *fsg = fsg_from_func(f); 2915 struct fsg_dev *fsg = fsg_from_func(f);
2908 struct usb_gadget *gadget = c->cdev->gadget; 2916 struct usb_gadget *gadget = c->cdev->gadget;
@@ -2946,7 +2954,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
2946autoconf_fail: 2954autoconf_fail:
2947 ERROR(fsg, "unable to autoconfigure all endpoints\n"); 2955 ERROR(fsg, "unable to autoconfigure all endpoints\n");
2948 rc = -ENOTSUPP; 2956 rc = -ENOTSUPP;
2949 fsg_unbind(c, f);
2950 return rc; 2957 return rc;
2951} 2958}
2952 2959