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

Commit 4a00027d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: Eliminate urb->status usage!



This patch (as979) removes the last vestiges of urb->status from the
host controller drivers and the root-hub emulator.  Now the field
doesn't get set until just before the URB's completion routine is
called.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
CC: Olav Kongas <ok@artecdesign.ee>
CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
CC: Tony Olech <tony.olech@elandigitalsystems.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9347d51c
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -532,7 +532,6 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)

	/* any errors get returned through the urb completion */
	spin_lock_irq(&hcd_root_hub_lock);
	urb->status = status;
	usb_hcd_unlink_urb_from_ep(hcd, urb);

	/* This peculiar use of spinlocks echoes what real HC drivers do.
@@ -540,7 +539,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
	 * RT-friendly.
	 */
	spin_unlock(&hcd_root_hub_lock);
	usb_hcd_giveback_urb(hcd, urb);
	usb_hcd_giveback_urb(hcd, urb, status);
	spin_lock(&hcd_root_hub_lock);

	spin_unlock_irq(&hcd_root_hub_lock);
@@ -578,13 +577,12 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
		if (urb) {
			hcd->poll_pending = 0;
			hcd->status_urb = NULL;
			urb->status = 0;
			urb->actual_length = length;
			memcpy(urb->transfer_buffer, buffer, length);

			usb_hcd_unlink_urb_from_ep(hcd, urb);
			spin_unlock(&hcd_root_hub_lock);
			usb_hcd_giveback_urb(hcd, urb);
			usb_hcd_giveback_urb(hcd, urb, 0);
			spin_lock(&hcd_root_hub_lock);
		} else {
			length = 0;
@@ -677,7 +675,7 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
			usb_hcd_unlink_urb_from_ep(hcd, urb);

			spin_unlock(&hcd_root_hub_lock);
			usb_hcd_giveback_urb(hcd, urb);
			usb_hcd_giveback_urb(hcd, urb, status);
			spin_lock(&hcd_root_hub_lock);
		}
	}
@@ -1252,6 +1250,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
 * usb_hcd_giveback_urb - return URB from HCD to device driver
 * @hcd: host controller returning the URB
 * @urb: urb being returned to the USB device driver.
 * @status: completion status code for the URB.
 * Context: in_interrupt()
 *
 * This hands the URB from HCD to its USB device driver, using its
@@ -1260,25 +1259,26 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
 * the device driver won't cause problems if it frees, modifies,
 * or resubmits this URB.
 *
 * If @urb was unlinked, the value of @urb->status will be overridden by
 * If @urb was unlinked, the value of @status will be overridden by
 * @urb->unlinked.  Erroneous short transfers are detected in case
 * the HCD hasn't checked for them.
 */
void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
{
	urb->hcpriv = NULL;
	if (unlikely(urb->unlinked))
		urb->status = urb->unlinked;
		status = urb->unlinked;
	else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
			urb->actual_length < urb->transfer_buffer_length &&
			!urb->status))
		urb->status = -EREMOTEIO;
			!status))
		status = -EREMOTEIO;

	unmap_urb_for_dma(hcd, urb);
	usbmon_urb_complete(&hcd->self, urb, urb->status);
	usbmon_urb_complete(&hcd->self, urb, status);
	usb_unanchor_urb(urb);

	/* pass ownership to the completion handler */
	urb->status = status;
	urb->complete (urb);
	atomic_dec (&urb->use_count);
	if (unlikely (urb->reject))
+2 −1
Original line number Diff line number Diff line
@@ -217,7 +217,8 @@ extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);

extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags);
extern int usb_hcd_unlink_urb (struct urb *urb, int status);
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
		int status);
extern void usb_hcd_endpoint_disable (struct usb_device *udev,
		struct usb_host_endpoint *ep);
extern int usb_hcd_get_frame_number (struct usb_device *udev);
+1 −2
Original line number Diff line number Diff line
@@ -1511,8 +1511,7 @@ static void dummy_timer (unsigned long _dum)

		usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb);
		spin_unlock (&dum->lock);
		urb->status = status;
		usb_hcd_giveback_urb (dummy_to_hcd(dum), urb);
		usb_hcd_giveback_urb(dummy_to_hcd(dum), urb, status);
		spin_lock (&dum->lock);

		goto restart;
+1 −2
Original line number Diff line number Diff line
@@ -256,8 +256,7 @@ __acquires(ehci->lock)
	/* complete() can reenter this HCD */
	usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
	spin_unlock (&ehci->lock);
	urb->status = status;
	usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb);
	usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status);
	spin_lock (&ehci->lock);
}

+5 −10
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ static void preproc_atl_queue(struct isp116x *isp116x)
  processed urbs.
*/
static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
			   struct urb *urb)
			   struct urb *urb, int status)
__releases(isp116x->lock) __acquires(isp116x->lock)
{
	unsigned i;
@@ -291,7 +291,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock)

	usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
	spin_unlock(&isp116x->lock);
	usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
	usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status);
	spin_lock(&isp116x->lock);

	/* take idle endpoints out of the schedule */
@@ -453,13 +453,8 @@ static void postproc_atl_queue(struct isp116x *isp116x)
		}

 done:
		if (status != -EINPROGRESS) {
			spin_lock(&urb->lock);
			urb->status = status;
			spin_unlock(&urb->lock);
		}
		if (urb->status != -EINPROGRESS || urb->unlinked)
			finish_request(isp116x, ep, urb);
		if (status != -EINPROGRESS || urb->unlinked)
			finish_request(isp116x, ep, urb, status);
	}
}

@@ -853,7 +848,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
			}

	if (urb)
		finish_request(isp116x, ep, urb);
		finish_request(isp116x, ep, urb, status);
 done:
	spin_unlock_irqrestore(&isp116x->lock, flags);
	return rc;
Loading