diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-14 07:09:59 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-14 07:09:59 +0200 |
commit | bf7c1d95af67254957d1820ac112397001e1a9a9 (patch) | |
tree | 3adbfbc15812cd4aad20c1ce708fe33b639e0392 /drivers/usb/renesas_usbhs/mod_gadget.c | |
parent | 1141a7522e3961e8d4b20db7495d4dfb1e07d7ae (diff) | |
parent | 4f5cafb5cb8471e54afdc9054d973535614f7675 (diff) | |
download | linux-bf7c1d95af67254957d1820ac112397001e1a9a9.tar.bz2 |
Merge 5.4-rc3 into usb-next
we want the USB fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 1235f3c1f62a..b47e70ffeda6 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -728,8 +728,7 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct device *dev = usbhsg_gpriv_to_dev(gpriv); unsigned long flags; - - usbhsg_pipe_disable(uep); + int ret = 0; dev_dbg(dev, "set halt %d (pipe %d)\n", halt, usbhs_pipe_number(pipe)); @@ -737,6 +736,18 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) /******************** spin lock ********************/ usbhs_lock(priv, flags); + /* + * According to usb_ep_set_halt()'s description, this function should + * return -EAGAIN if the IN endpoint has any queue or data. Note + * that the usbhs_pipe_is_dir_in() returns false if the pipe is an + * IN endpoint in the gadget mode. + */ + if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) || + usbhs_pipe_contains_transmittable_data(pipe))) { + ret = -EAGAIN; + goto out; + } + if (halt) usbhs_pipe_stall(pipe); else @@ -747,10 +758,11 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) else usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); +out: usbhs_unlock(priv, flags); /******************** spin unlock ******************/ - return 0; + return ret; } static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) |