[RFC 1/3] usb/dummy_hcd: move code that handles an URB into a separate function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The code here is moved out of the list for each into a separate
function. There should be no functional change.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/gadget/dummy_hcd.c |  314 +++++++++++++++++++++-------------------
 1 file changed, 162 insertions(+), 152 deletions(-)

diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 0f7541b..ea702c6 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1659,6 +1659,164 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,
 	return ret_val;
 }
 
+static int handle_one_urb(struct urbp *urbp, struct dummy_hcd *dum_hcd, int *total)
+{
+	struct dummy		*dum = dum_hcd->dum;
+	struct urb		*urb;
+	struct dummy_request	*req;
+	u8			address;
+	struct dummy_ep		*ep = NULL;
+	int			type;
+	int			status = -EINPROGRESS;
+	int			limit;
+
+	urb = urbp->urb;
+	if (urb->unlinked)
+		goto return_urb;
+	else if (dum_hcd->rh_state != DUMMY_RH_RUNNING)
+		return 0;
+	type = usb_pipetype(urb->pipe);
+
+	/* used up this frame's non-periodic bandwidth?
+	 * FIXME there's infinite bandwidth for control and
+	 * periodic transfers ... unrealistic.
+	 */
+	if (*total <= 0 && type == PIPE_BULK)
+		return 0;
+
+	/* find the gadget's ep for this request (if configured) */
+	address = usb_pipeendpoint (urb->pipe);
+	if (usb_pipein(urb->pipe))
+		address |= USB_DIR_IN;
+	ep = find_endpoint(dum, address);
+	if (!ep) {
+		/* set_configuration() disagreement */
+		dev_dbg(dummy_dev(dum_hcd),
+				"no ep configured for urb %p\n",
+				urb);
+		status = -EPROTO;
+		goto return_urb;
+	}
+
+	if (ep->already_seen)
+		return 0;
+	ep->already_seen = 1;
+	if (ep == &dum->ep[0] && urb->error_count) {
+		ep->setup_stage = 1;	/* a new urb */
+		urb->error_count = 0;
+	}
+	if (ep->halted && !ep->setup_stage) {
+		/* NOTE: must not be iso! */
+		dev_dbg(dummy_dev(dum_hcd), "ep %s halted, urb %p\n",
+				ep->ep.name, urb);
+		status = -EPIPE;
+		goto return_urb;
+	}
+	/* FIXME make sure both ends agree on maxpacket */
+
+	/* handle control requests */
+	if (ep == &dum->ep[0] && ep->setup_stage) {
+		struct usb_ctrlrequest		setup;
+		int				value = 1;
+
+		setup = *(struct usb_ctrlrequest *) urb->setup_packet;
+		/* paranoia, in case of stale queued data */
+		list_for_each_entry(req, &ep->queue, queue) {
+			list_del_init(&req->queue);
+			req->req.status = -EOVERFLOW;
+			dev_dbg(udc_dev(dum), "stale req = %p\n",
+					req);
+
+			spin_unlock(&dum->lock);
+			req->req.complete(&ep->ep, &req->req);
+			spin_lock(&dum->lock);
+			ep->already_seen = 0;
+			return 1;
+		}
+
+		/* gadget driver never sees set_address or operations
+		 * on standard feature flags.  some hardware doesn't
+		 * even expose them.
+		 */
+		ep->last_io = jiffies;
+		ep->setup_stage = 0;
+		ep->halted = 0;
+
+		value = handle_control_request(dum_hcd, urb, &setup,
+				&status);
+
+		/* gadget driver handles all other requests.  block
+		 * until setup() returns; no reentrancy issues etc.
+		 */
+		if (value > 0) {
+			spin_unlock(&dum->lock);
+			value = dum->driver->setup(&dum->gadget,
+					&setup);
+			spin_lock(&dum->lock);
+
+			if (value >= 0) {
+				/* no delays (max 64KB data stage) */
+				limit = 64*1024;
+				goto treat_control_like_bulk;
+			}
+			/* error, see below */
+		}
+
+		if (value < 0) {
+			if (value != -EOPNOTSUPP)
+				dev_dbg(udc_dev(dum),
+						"setup --> %d\n",
+						value);
+			status = -EPIPE;
+			urb->actual_length = 0;
+		}
+
+		goto return_urb;
+	}
+
+	/* non-control requests */
+	limit = *total;
+	switch (usb_pipetype(urb->pipe)) {
+		case PIPE_ISOCHRONOUS:
+			/* FIXME is it urb->interval since the last xfer?
+			 * use urb->iso_frame_desc[i].
+			 * complete whether or not ep has requests queued.
+			 * report random errors, to debug drivers.
+			 */
+			limit = max(limit, periodic_bytes(dum, ep));
+			status = -ENOSYS;
+			break;
+
+		case PIPE_INTERRUPT:
+			/* FIXME is it urb->interval since the last xfer?
+			 * this almost certainly polls too fast.
+			 */
+			limit = max(limit, periodic_bytes(dum, ep));
+			/* FALLTHROUGH */
+
+		default:
+treat_control_like_bulk:
+			ep->last_io = jiffies;
+			*total = transfer(dum_hcd, urb, ep, limit, &status);
+			break;
+	}
+
+	/* incomplete transfer? */
+	if (status == -EINPROGRESS)
+		return 0;
+return_urb:
+	list_del(&urbp->urbp_list);
+	kfree(urbp);
+	if (ep)
+		ep->already_seen = ep->setup_stage = 0;
+
+	usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb);
+	spin_unlock(&dum->lock);
+	usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status);
+	spin_lock(&dum->lock);
+	return 1;
+}
+
 /* drive both sides of the transfers; looks like irq handlers to
  * both drivers except the callbacks aren't in_irq().
  */
@@ -1668,7 +1826,7 @@ static void dummy_timer(unsigned long _dum_hcd)
 	struct dummy		*dum = dum_hcd->dum;
 	struct urbp		*urbp, *tmp;
 	unsigned long		flags;
-	int			limit, total;
+	int			total;
 	int			i;
 
 	/* simplistic model for one frame's bandwidth */
@@ -1711,159 +1869,11 @@ static void dummy_timer(unsigned long _dum_hcd)
 
 restart:
 	list_for_each_entry_safe(urbp, tmp, &dum_hcd->urbp_list, urbp_list) {
-		struct urb		*urb;
-		struct dummy_request	*req;
-		u8			address;
-		struct dummy_ep		*ep = NULL;
-		int			type;
-		int			status = -EINPROGRESS;
-
-		urb = urbp->urb;
-		if (urb->unlinked)
-			goto return_urb;
-		else if (dum_hcd->rh_state != DUMMY_RH_RUNNING)
-			continue;
-		type = usb_pipetype(urb->pipe);
-
-		/* used up this frame's non-periodic bandwidth?
-		 * FIXME there's infinite bandwidth for control and
-		 * periodic transfers ... unrealistic.
-		 */
-		if (total <= 0 && type == PIPE_BULK)
-			continue;
-
-		/* find the gadget's ep for this request (if configured) */
-		address = usb_pipeendpoint (urb->pipe);
-		if (usb_pipein(urb->pipe))
-			address |= USB_DIR_IN;
-		ep = find_endpoint(dum, address);
-		if (!ep) {
-			/* set_configuration() disagreement */
-			dev_dbg(dummy_dev(dum_hcd),
-				"no ep configured for urb %p\n",
-				urb);
-			status = -EPROTO;
-			goto return_urb;
-		}
+		int ret;
 
-		if (ep->already_seen)
+		ret = handle_one_urb(urbp, dum_hcd, &total);
+		if (!ret)
 			continue;
-		ep->already_seen = 1;
-		if (ep == &dum->ep[0] && urb->error_count) {
-			ep->setup_stage = 1;	/* a new urb */
-			urb->error_count = 0;
-		}
-		if (ep->halted && !ep->setup_stage) {
-			/* NOTE: must not be iso! */
-			dev_dbg(dummy_dev(dum_hcd), "ep %s halted, urb %p\n",
-					ep->ep.name, urb);
-			status = -EPIPE;
-			goto return_urb;
-		}
-		/* FIXME make sure both ends agree on maxpacket */
-
-		/* handle control requests */
-		if (ep == &dum->ep[0] && ep->setup_stage) {
-			struct usb_ctrlrequest		setup;
-			int				value = 1;
-
-			setup = *(struct usb_ctrlrequest *) urb->setup_packet;
-			/* paranoia, in case of stale queued data */
-			list_for_each_entry(req, &ep->queue, queue) {
-				list_del_init(&req->queue);
-				req->req.status = -EOVERFLOW;
-				dev_dbg(udc_dev(dum), "stale req = %p\n",
-						req);
-
-				spin_unlock(&dum->lock);
-				req->req.complete(&ep->ep, &req->req);
-				spin_lock(&dum->lock);
-				ep->already_seen = 0;
-				goto restart;
-			}
-
-			/* gadget driver never sees set_address or operations
-			 * on standard feature flags.  some hardware doesn't
-			 * even expose them.
-			 */
-			ep->last_io = jiffies;
-			ep->setup_stage = 0;
-			ep->halted = 0;
-
-			value = handle_control_request(dum_hcd, urb, &setup,
-						       &status);
-
-			/* gadget driver handles all other requests.  block
-			 * until setup() returns; no reentrancy issues etc.
-			 */
-			if (value > 0) {
-				spin_unlock(&dum->lock);
-				value = dum->driver->setup(&dum->gadget,
-						&setup);
-				spin_lock(&dum->lock);
-
-				if (value >= 0) {
-					/* no delays (max 64KB data stage) */
-					limit = 64*1024;
-					goto treat_control_like_bulk;
-				}
-				/* error, see below */
-			}
-
-			if (value < 0) {
-				if (value != -EOPNOTSUPP)
-					dev_dbg(udc_dev(dum),
-						"setup --> %d\n",
-						value);
-				status = -EPIPE;
-				urb->actual_length = 0;
-			}
-
-			goto return_urb;
-		}
-
-		/* non-control requests */
-		limit = total;
-		switch (usb_pipetype(urb->pipe)) {
-		case PIPE_ISOCHRONOUS:
-			/* FIXME is it urb->interval since the last xfer?
-			 * use urb->iso_frame_desc[i].
-			 * complete whether or not ep has requests queued.
-			 * report random errors, to debug drivers.
-			 */
-			limit = max(limit, periodic_bytes(dum, ep));
-			status = -ENOSYS;
-			break;
-
-		case PIPE_INTERRUPT:
-			/* FIXME is it urb->interval since the last xfer?
-			 * this almost certainly polls too fast.
-			 */
-			limit = max(limit, periodic_bytes(dum, ep));
-			/* FALLTHROUGH */
-
-		default:
-treat_control_like_bulk:
-			ep->last_io = jiffies;
-			total = transfer(dum_hcd, urb, ep, limit, &status);
-			break;
-		}
-
-		/* incomplete transfer? */
-		if (status == -EINPROGRESS)
-			continue;
-
-return_urb:
-		list_del(&urbp->urbp_list);
-		kfree(urbp);
-		if (ep)
-			ep->already_seen = ep->setup_stage = 0;
-
-		usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb);
-		spin_unlock(&dum->lock);
-		usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status);
-		spin_lock(&dum->lock);
-
 		goto restart;
 	}
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux