As the configuration is not complete at the time of thread
creation, defering the file-storage thread wakeup till the end.
Also stop the thread in case of failure during configuration.

Signed-off-by: Sanjay Singh Rawat <snjs...@gmail.com>
---
 drivers/usb/gadget/function/f_mass_storage.c | 75 ++--------------------------
 drivers/usb/gadget/function/f_mass_storage.h | 68 ++++++++++++++++++++++++-
 drivers/usb/gadget/legacy/acm_ms.c           |  5 ++
 drivers/usb/gadget/legacy/mass_storage.c     |  4 ++
 drivers/usb/gadget/legacy/multi.c            |  4 ++
 5 files changed, 83 insertions(+), 73 deletions(-)

diff --git a/drivers/usb/gadget/function/f_mass_storage.c 
b/drivers/usb/gadget/function/f_mass_storage.c
index 0e90e38..560e73d 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -251,76 +251,6 @@ static struct usb_gadget_strings *fsg_strings_array[] = {
 
 /*-------------------------------------------------------------------------*/
 
-struct fsg_dev;
-struct fsg_common;
-
-/* Data shared by all the FSG instances. */
-struct fsg_common {
-       struct usb_gadget       *gadget;
-       struct usb_composite_dev *cdev;
-       struct fsg_dev          *fsg, *new_fsg;
-       wait_queue_head_t       fsg_wait;
-
-       /* filesem protects: backing files in use */
-       struct rw_semaphore     filesem;
-
-       /* lock protects: state, all the req_busy's */
-       spinlock_t              lock;
-
-       struct usb_ep           *ep0;           /* Copy of gadget->ep0 */
-       struct usb_request      *ep0req;        /* Copy of cdev->req */
-       unsigned int            ep0_req_tag;
-
-       struct fsg_buffhd       *next_buffhd_to_fill;
-       struct fsg_buffhd       *next_buffhd_to_drain;
-       struct fsg_buffhd       *buffhds;
-       unsigned int            fsg_num_buffers;
-
-       int                     cmnd_size;
-       u8                      cmnd[MAX_COMMAND_SIZE];
-
-       unsigned int            nluns;
-       unsigned int            lun;
-       struct fsg_lun          **luns;
-       struct fsg_lun          *curlun;
-
-       unsigned int            bulk_out_maxpacket;
-       enum fsg_state          state;          /* For exception handling */
-       unsigned int            exception_req_tag;
-
-       enum data_direction     data_dir;
-       u32                     data_size;
-       u32                     data_size_from_cmnd;
-       u32                     tag;
-       u32                     residue;
-       u32                     usb_amount_left;
-
-       unsigned int            can_stall:1;
-       unsigned int            free_storage_on_release:1;
-       unsigned int            phase_error:1;
-       unsigned int            short_packet_received:1;
-       unsigned int            bad_lun_okay:1;
-       unsigned int            running:1;
-       unsigned int            sysfs:1;
-
-       int                     thread_wakeup_needed;
-       struct completion       thread_notifier;
-       struct task_struct      *thread_task;
-
-       /* Callback functions. */
-       const struct fsg_operations     *ops;
-       /* Gadget's private data. */
-       void                    *private_data;
-
-       /*
-        * Vendor (8 chars), product (16 chars), release (4
-        * hexadecimal digits) and NUL byte
-        */
-       char inquiry_string[8 + 16 + 4 + 1];
-
-       struct kref             ref;
-};
-
 struct fsg_dev {
        struct usb_function     function;
        struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
@@ -3013,8 +2943,6 @@ int fsg_common_run_thread(struct fsg_common *common)
 
        DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
 
-       wake_up_process(common->thread_task);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(fsg_common_run_thread);
@@ -3121,6 +3049,9 @@ static int fsg_bind(struct usb_configuration *c, struct 
usb_function *f)
        if (ret)
                goto autoconf_fail;
 
+       /* wakeup the thread */
+       wake_up_process(fsg->common->thread_task);
+
        return 0;
 
 autoconf_fail:
diff --git a/drivers/usb/gadget/function/f_mass_storage.h 
b/drivers/usb/gadget/function/f_mass_storage.h
index b4866fc..c05fe16 100644
--- a/drivers/usb/gadget/function/f_mass_storage.h
+++ b/drivers/usb/gadget/function/f_mass_storage.h
@@ -57,7 +57,73 @@ struct fsg_module_parameters {
 
 #endif
 
-struct fsg_common;
+/* Data shared by all the FSG instances. */
+struct fsg_common {
+       struct usb_gadget       *gadget;
+       struct usb_composite_dev *cdev;
+       struct fsg_dev          *fsg, *new_fsg;
+       wait_queue_head_t       fsg_wait;
+
+       /* filesem protects: backing files in use */
+       struct rw_semaphore     filesem;
+
+       /* lock protects: state, all the req_busy's */
+       spinlock_t              lock;
+
+       struct usb_ep           *ep0;           /* Copy of gadget->ep0 */
+       struct usb_request      *ep0req;        /* Copy of cdev->req */
+       unsigned int            ep0_req_tag;
+
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       *buffhds;
+       unsigned int            fsg_num_buffers;
+
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+
+       unsigned int            nluns;
+       unsigned int            lun;
+       struct fsg_lun          **luns;
+       struct fsg_lun          *curlun;
+
+       unsigned int            bulk_out_maxpacket;
+       enum fsg_state          state;          /* For exception handling */
+       unsigned int            exception_req_tag;
+
+       enum data_direction     data_dir;
+
+       u32                     data_size;
+       u32                     data_size_from_cmnd;
+       u32                     tag;
+       u32                     residue;
+       u32                     usb_amount_left;
+
+       unsigned int            can_stall:1;
+       unsigned int            free_storage_on_release:1;
+       unsigned int            phase_error:1;
+       unsigned int            short_packet_received:1;
+       unsigned int            bad_lun_okay:1;
+       unsigned int            running:1;
+       unsigned int            sysfs:1;
+
+       int                     thread_wakeup_needed;
+       struct completion       thread_notifier;
+       struct task_struct      *thread_task;
+
+       /* Callback functions. */
+       const struct fsg_operations     *ops;
+       /* Gadget's private data. */
+       void                    *private_data;
+
+       /*
+       * Vendor (8 chars), product (16 chars), release (4
+       * hexadecimal digits) and NUL byte
+       */
+       char inquiry_string[8 + 16 + 4 + 1];
+
+       struct kref             ref;
+};
 
 /* FSF callback functions */
 struct fsg_operations {
diff --git a/drivers/usb/gadget/legacy/acm_ms.c 
b/drivers/usb/gadget/legacy/acm_ms.c
index 1194b09..bbdb867 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -15,6 +15,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 
 #include "u_serial.h"
@@ -155,8 +156,12 @@ static int acm_ms_do_config(struct usb_configuration *c)
        if (status)
                goto remove_acm;
 
+       /* wakeup the thread */
+       wake_up_process(opts->common->thread_task);
+
        return 0;
 remove_acm:
+       kthread_stop(opts->common->thread_task);
        usb_remove_function(c, f_acm);
 put_msg:
        usb_put_function(f_msg);
diff --git a/drivers/usb/gadget/legacy/mass_storage.c 
b/drivers/usb/gadget/legacy/mass_storage.c
index e7bfb08..ee1f61f 100644
--- a/drivers/usb/gadget/legacy/mass_storage.c
+++ b/drivers/usb/gadget/legacy/mass_storage.c
@@ -154,9 +154,13 @@ static int msg_do_config(struct usb_configuration *c)
        if (ret)
                goto put_func;
 
+       /* wakeup the thread */
+       wake_up_process(opts->common->thread_task);
+
        return 0;
 
 put_func:
+       kthread_stop(opts->common->thread_task);
        usb_put_function(f_msg);
        return ret;
 }
diff --git a/drivers/usb/gadget/legacy/multi.c 
b/drivers/usb/gadget/legacy/multi.c
index b21b51f..f9d8d13 100644
--- a/drivers/usb/gadget/legacy/multi.c
+++ b/drivers/usb/gadget/legacy/multi.c
@@ -14,6 +14,7 @@
 
 
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 
@@ -192,8 +193,11 @@ static int rndis_do_config(struct usb_configuration *c)
        if (ret)
                goto err_run;
 
+       /* wakeup the thread */
+       wake_up_process(fsg_opts->common->thread_task);
        return 0;
 err_run:
+       kthread_stop(fsg_opts->common->thread_task);
        usb_put_function(f_msg_rndis);
 err_fsg:
        usb_remove_function(c, f_acm_rndis);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to