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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget)
	 * disconnect callbacks?
	 */
	spin_lock_irqsave(&cdev->lock, flags);
	cdev->suspended = 0;
	if (cdev->config)
		reset_config(cdev);
	if (cdev->driver->disconnect)
+18 −10
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ struct fsg_common;
struct fsg_common {
	struct usb_gadget	*gadget;
	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	fsg_wait;

@@ -290,6 +290,7 @@ struct fsg_common {
	unsigned int		bulk_out_maxpacket;
	enum fsg_state		state;		/* For exception handling */
	unsigned int		exception_req_tag;
	void			*exception_arg;

	enum data_direction	data_dir;
	u32			data_size;
@@ -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 */

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;

@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
	if (common->state <= new_state) {
		common->exception_req_tag = common->ep0_req_tag;
		common->state = new_state;
		common->exception_arg = arg;
		if (common->thread_task)
			send_sig_info(SIGUSR1, SEND_SIG_PRIV,
				      common->thread_task);
@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
	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 @@ reset:
static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{
	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;
}

static void fsg_disable(struct usb_function *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)
	enum fsg_state		old_state;
	struct fsg_lun		*curlun;
	unsigned int		exception_req_tag;
	struct fsg_dev		*new_fsg;

	/*
	 * Clear the existing signals.  Anything but SIGUSR1 is converted
@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common)
	common->next_buffhd_to_fill = &common->buffhds[0];
	common->next_buffhd_to_drain = &common->buffhds[0];
	exception_req_tag = common->exception_req_tag;
	new_fsg = common->exception_arg;
	old_state = common->state;
	common->state = FSG_STATE_NORMAL;

@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common)
		break;

	case FSG_STATE_CONFIG_CHANGE:
		do_set_interface(common, common->new_fsg);
		if (common->new_fsg)
		do_set_interface(common, new_fsg);
		if (new_fsg)
			usb_composite_setup_continue(common->cdev);
		break;

@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)

	DBG(fsg, "unbind\n");
	if (fsg->common->fsg == fsg) {
		fsg->common->new_fsg = NULL;
		raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
		__raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
		/* FIXME: make interruptible or killable somehow? */
		wait_event(common->fsg_wait, common->fsg != fsg);
	}
+3 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/pm_runtime.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sys_soc.h>
#include <linux/uaccess.h>
#include <linux/usb/ch9.h>
@@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
	if (usb3->forced_b_device)
		return -EBUSY;

	if (!strncmp(buf, "host", strlen("host")))
	if (sysfs_streq(buf, "host"))
		new_mode_is_host = true;
	else if (!strncmp(buf, "peripheral", strlen("peripheral")))
	else if (sysfs_streq(buf, "peripheral"))
		new_mode_is_host = false;
	else
		return -EINVAL;