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

Commit f720af91 authored by David Vrabel's avatar David Vrabel Committed by Greg Kroah-Hartman
Browse files

USB: whci-hcd: check return value of usb_hcd_link_urb_to_ep()



Check the return value of usb_hcd_link_urb_to_ep() and do not add the
urb to the ASL/PZL if it returns an error.

Omitting the check results in urbs that appear to be submitted
successfully but then cannot be unliked (because
usb_hcd_check_unlink_urb() returns an error).  This can cause khubd (for
example) to block forever in usb_kill_urb().

Signed-off-by: default avatarDavid Vrabel <david.vrabel@csr.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7f0406db
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -255,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)

	spin_lock_irqsave(&whc->lock, flags);

	err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
	if (err < 0) {
		spin_unlock_irqrestore(&whc->lock, flags);
		return err;
	}

	qset = get_qset(whc, urb, GFP_ATOMIC);
	if (qset == NULL)
		err = -ENOMEM;
	else
		err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
	if (!err) {
		usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
		if (!qset->in_sw_list)
			asl_qset_insert_begin(whc, qset);
	}
	} else
		usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);

	spin_unlock_irqrestore(&whc->lock, flags);

	if (!err)
		queue_work(whc->workqueue, &whc->async_work);

	return 0;
	return err;
}

/**
+9 −3
Original line number Diff line number Diff line
@@ -283,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)

	spin_lock_irqsave(&whc->lock, flags);

	err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
	if (err < 0) {
		spin_unlock_irqrestore(&whc->lock, flags);
		return err;
	}

	qset = get_qset(whc, urb, GFP_ATOMIC);
	if (qset == NULL)
		err = -ENOMEM;
	else
		err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
	if (!err) {
		usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
		if (!qset->in_sw_list)
			qset_insert_in_sw_list(whc, qset);
	}
	} else
		usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);

	spin_unlock_irqrestore(&whc->lock, flags);

	if (!err)
		queue_work(whc->workqueue, &whc->periodic_work);

	return 0;
	return err;
}

/**