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

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

Merge 9408f5a4 ("USB: HCD: Fix URB giveback issue in tasklet function") into android-mainline



Steps on the way to 4.19.256

Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
Change-Id: I84d2aef74fb2297d4a3db0842fd4e2bfbb191ad9
parents 88a4eb86 9408f5a4
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -1805,7 +1805,6 @@ static void usb_giveback_urb_bh(unsigned long param)

	spin_lock_irq(&bh->lock);
	bh->running = true;
 restart:
	list_replace_init(&bh->head, &local_list);
	spin_unlock_irq(&bh->lock);

@@ -1819,10 +1818,17 @@ static void usb_giveback_urb_bh(unsigned long param)
		bh->completing_ep = NULL;
	}

	/* check if there are new URBs to giveback */
	/*
	 * giveback new URBs next time to prevent this function
	 * from not exiting for a long time.
	 */
	spin_lock_irq(&bh->lock);
	if (!list_empty(&bh->head))
		goto restart;
	if (!list_empty(&bh->head)) {
		if (bh->high_prio)
			tasklet_hi_schedule(&bh->bh);
		else
			tasklet_schedule(&bh->bh);
	}
	bh->running = false;
	spin_unlock_irq(&bh->lock);
}
@@ -1847,7 +1853,7 @@ static void usb_giveback_urb_bh(unsigned long param)
void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
{
	struct giveback_urb_bh *bh;
	bool running, high_prio_bh;
	bool running;

	/* pass status to tasklet via unlinked */
	if (likely(!urb->unlinked))
@@ -1858,13 +1864,10 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
		return;
	}

	if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) {
	if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe))
		bh = &hcd->high_prio_bh;
		high_prio_bh = true;
	} else {
	else
		bh = &hcd->low_prio_bh;
		high_prio_bh = false;
	}

	spin_lock(&bh->lock);
	list_add_tail(&urb->urb_list, &bh->head);
@@ -1873,7 +1876,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)

	if (running)
		;
	else if (high_prio_bh)
	else if (bh->high_prio)
		tasklet_hi_schedule(&bh->bh);
	else
		tasklet_schedule(&bh->bh);
@@ -2946,6 +2949,7 @@ int usb_add_hcd(struct usb_hcd *hcd,

	/* initialize tasklets */
	init_giveback_urb_bh(&hcd->high_prio_bh);
	hcd->high_prio_bh.high_prio = true;
	init_giveback_urb_bh(&hcd->low_prio_bh);

	/* enable irqs just before we start the controller,
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@

struct giveback_urb_bh {
	bool running;
	bool high_prio;
	spinlock_t lock;
	struct list_head  head;
	struct tasklet_struct bh;