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 <snjsrwt@xxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html