Commit 0cf25bc5 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'fixes-for-v5.3-rc4' of...

Merge tag 'fixes-for-v5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

USB: fixes for v5.3-rc4

Just a three fixes this time around.

A race condition on mass storage gadget between disable() and
set_alt()

Clear a flag that was left set upon reset or disconnect

A fix for renesas_usb3 UDC's sysfs interface

* tag 'fixes-for-v5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb:
  usb: gadget: mass_storage: Fix races between fsg_disable and fsg_set_alt
  usb: gadget: composite: Clear "suspended" on reset/disconnect
  usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role"
parents d45331b0 4a56a478
...@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget) ...@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget)
* disconnect callbacks? * disconnect callbacks?
*/ */
spin_lock_irqsave(&cdev->lock, flags); spin_lock_irqsave(&cdev->lock, flags);
cdev->suspended = 0;
if (cdev->config) if (cdev->config)
reset_config(cdev); reset_config(cdev);
if (cdev->driver->disconnect) if (cdev->driver->disconnect)
......
...@@ -261,7 +261,7 @@ struct fsg_common; ...@@ -261,7 +261,7 @@ struct fsg_common;
struct fsg_common { struct fsg_common {
struct usb_gadget *gadget; struct usb_gadget *gadget;
struct usb_composite_dev *cdev; struct usb_composite_dev *cdev;
struct fsg_dev *fsg, *new_fsg; struct fsg_dev *fsg;
wait_queue_head_t io_wait; wait_queue_head_t io_wait;
wait_queue_head_t fsg_wait; wait_queue_head_t fsg_wait;
...@@ -290,6 +290,7 @@ struct fsg_common { ...@@ -290,6 +290,7 @@ struct fsg_common {
unsigned int bulk_out_maxpacket; unsigned int bulk_out_maxpacket;
enum fsg_state state; /* For exception handling */ enum fsg_state state; /* For exception handling */
unsigned int exception_req_tag; unsigned int exception_req_tag;
void *exception_arg;
enum data_direction data_dir; enum data_direction data_dir;
u32 data_size; u32 data_size;
...@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) ...@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
/* These routines may be called in process context or in_irq */ /* These routines may be called in process context or in_irq */
static void raise_exception(struct fsg_common *common, enum fsg_state new_state) static void __raise_exception(struct fsg_common *common, enum fsg_state new_state,
void *arg)
{ {
unsigned long flags; unsigned long flags;
...@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ...@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
if (common->state <= new_state) { if (common->state <= new_state) {
common->exception_req_tag = common->ep0_req_tag; common->exception_req_tag = common->ep0_req_tag;
common->state = new_state; common->state = new_state;
common->exception_arg = arg;
if (common->thread_task) if (common->thread_task)
send_sig_info(SIGUSR1, SEND_SIG_PRIV, send_sig_info(SIGUSR1, SEND_SIG_PRIV,
common->thread_task); common->thread_task);
...@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ...@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
spin_unlock_irqrestore(&common->lock, flags); spin_unlock_irqrestore(&common->lock, flags);
} }
static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
{
__raise_exception(common, new_state, NULL);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -2285,16 +2292,16 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) ...@@ -2285,16 +2292,16 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
fsg->common->new_fsg = fsg;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg);
return USB_GADGET_DELAYED_STATUS; return USB_GADGET_DELAYED_STATUS;
} }
static void fsg_disable(struct usb_function *f) static void fsg_disable(struct usb_function *f)
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
fsg->common->new_fsg = NULL;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
} }
...@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common)
enum fsg_state old_state; enum fsg_state old_state;
struct fsg_lun *curlun; struct fsg_lun *curlun;
unsigned int exception_req_tag; unsigned int exception_req_tag;
struct fsg_dev *new_fsg;
/* /*
* Clear the existing signals. Anything but SIGUSR1 is converted * Clear the existing signals. Anything but SIGUSR1 is converted
...@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common)
common->next_buffhd_to_fill = &common->buffhds[0]; common->next_buffhd_to_fill = &common->buffhds[0];
common->next_buffhd_to_drain = &common->buffhds[0]; common->next_buffhd_to_drain = &common->buffhds[0];
exception_req_tag = common->exception_req_tag; exception_req_tag = common->exception_req_tag;
new_fsg = common->exception_arg;
old_state = common->state; old_state = common->state;
common->state = FSG_STATE_NORMAL; common->state = FSG_STATE_NORMAL;
...@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common) ...@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common)
break; break;
case FSG_STATE_CONFIG_CHANGE: case FSG_STATE_CONFIG_CHANGE:
do_set_interface(common, common->new_fsg); do_set_interface(common, new_fsg);
if (common->new_fsg) if (new_fsg)
usb_composite_setup_continue(common->cdev); usb_composite_setup_continue(common->cdev);
break; break;
...@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) ...@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(fsg, "unbind\n"); DBG(fsg, "unbind\n");
if (fsg->common->fsg == fsg) { if (fsg->common->fsg == fsg) {
fsg->common->new_fsg = NULL; __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
/* FIXME: make interruptible or killable somehow? */ /* FIXME: make interruptible or killable somehow? */
wait_event(common->fsg_wait, common->fsg != fsg); wait_event(common->fsg_wait, common->fsg != fsg);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
...@@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, ...@@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
if (usb3->forced_b_device) if (usb3->forced_b_device)
return -EBUSY; return -EBUSY;
if (!strncmp(buf, "host", strlen("host"))) if (sysfs_streq(buf, "host"))
new_mode_is_host = true; new_mode_is_host = true;
else if (!strncmp(buf, "peripheral", strlen("peripheral"))) else if (sysfs_streq(buf, "peripheral"))
new_mode_is_host = false; new_mode_is_host = false;
else else
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment