Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d096e0b3 authored by Manu Gautam's avatar Manu Gautam
Browse files

USB: ci13xxx: Fail EP HALT operation in suspend state



USB function drivers typically don't issue set_halt in
suspend state, but some function drivers e.g. f_fs/adb
allow userspace to do this using ioctl. Hence, there is
a possibility of userspace issuing set_halt (e.g. after
ep_queue failed in bus_suspend with remote-wakeup disabled.
While at it also update ep_dequeue to not rely on in_lpm
flag but also check for suspended state to protect when
clocks are off but in_lpm is not set yet.

Change-Id: I6050a77908e3af317cd1942b1d772959b5a292cd
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 9f7af2ec
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3234,6 +3234,13 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
				__func__);
		return -EAGAIN;
	}

	if (udc->suspended) {
		dev_err(udc->transceiver->dev,
			"%s: Unable to dequeue while suspended\n", __func__);
		return -EAGAIN;
	}

	spin_lock_irqsave(mEp->lock, flags);
	/*
	 * Only ep0 IN is exposed to composite.  When a req is dequeued
@@ -3300,6 +3307,7 @@ static int is_sps_req(struct ci13xxx_req *mReq)
static int ep_set_halt(struct usb_ep *ep, int value)
{
	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
	struct ci13xxx *udc = _udc;
	int direction, retval = 0;
	unsigned long flags;

@@ -3308,6 +3316,12 @@ static int ep_set_halt(struct usb_ep *ep, int value)
	if (ep == NULL || mEp->desc == NULL)
		return -EINVAL;

	if (udc->suspended) {
		dev_err(udc->transceiver->dev,
			"%s: Unable to halt EP while suspended\n", __func__);
		return -EINVAL;
	}

	spin_lock_irqsave(mEp->lock, flags);

#ifndef STALL_IN