[PATCH 02/13] usb: renesas_usbhs: cleanup complicated ureq alloc/free

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

 



DCP data/status stage needs ureq to usbhs_pkt_push(),
but sometimes, there is no data stage.
In that case, allocated ureq was not freed,
Current ureq alloc/free pair were difficult to understand.
This patch removed unnecessary/un-understandable ureq alloc
from usbhsh_urb_enqueue(), and create simpler alloc/free pair.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx>
---
 drivers/usb/renesas_usbhs/mod_host.c |  107 ++++++++++++++++++----------------
 1 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 1c4f793..435b2ae 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -503,11 +503,12 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)
 
 static int usbhsh_queue_push(struct usb_hcd *hcd,
 			     struct usbhs_pipe *pipe,
-			     struct urb *urb)
+			     struct urb *urb,
+			     gfp_t mem_flags)
 {
-	struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb);
-	struct usbhs_pkt *pkt = &ureq->pkt;
+	struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
 	struct device *dev = usbhsh_hcd_to_dev(hcd);
+	struct usbhsh_request *ureq;
 	void *buf;
 	int len;
 
@@ -516,6 +517,14 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
 		return -EIO;
 	}
 
+	/* this ureq will be freed on usbhsh_queue_done() */
+	ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
+	if (unlikely(!ureq)) {
+		dev_err(dev, "ureq alloc fail\n");
+		return -ENOMEM;
+	}
+	usbhsh_urb_to_ureq(urb) = ureq;
+
 	if (usb_pipein(urb->pipe))
 		pipe->handler = &usbhs_fifo_pio_pop_handler;
 	else
@@ -525,7 +534,7 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
 	len = urb->transfer_buffer_length - urb->actual_length;
 
 	dev_dbg(dev, "%s\n", __func__);
-	usbhs_pkt_push(pipe, pkt, usbhsh_queue_done,
+	usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done,
 		       buf, len, (urb->transfer_flags & URB_ZERO_PACKET));
 	usbhs_pkt_start(pipe);
 
@@ -605,72 +614,72 @@ static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv,
 	usbhsh_urb_to_ureq(urb) = NULL;
 }
 
-static void usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
-					  struct urb *urb,
-					  struct usbhs_pipe *pipe)
+static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
+					 struct urb *urb,
+					 struct usbhs_pipe *pipe,
+					 gfp_t mem_flags)
+
 {
 	struct usbhsh_request *ureq;
-	struct usbhs_pkt *pkt;
 
-	/*
-	 * FIXME
-	 *
-	 * data stage uses ureq which is connected to urb
-	 * see usbhsh_urb_enqueue() :: alloc new request.
-	 * it will be freed in usbhsh_data_stage_packet_done()
-	 */
-	ureq	= usbhsh_urb_to_ureq(urb);
-	pkt	= &ureq->pkt;
+	/* this ureq will be freed on usbhsh_data_stage_packet_done() */
+	ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
+	if (unlikely(!ureq))
+		return -ENOMEM;
+	usbhsh_urb_to_ureq(urb) = ureq;
 
 	if (usb_pipein(urb->pipe))
 		pipe->handler = &usbhs_dcp_data_stage_in_handler;
 	else
 		pipe->handler = &usbhs_dcp_data_stage_out_handler;
 
-	usbhs_pkt_push(pipe, pkt,
+	usbhs_pkt_push(pipe, &ureq->pkt,
 		       usbhsh_data_stage_packet_done,
 		       urb->transfer_buffer,
 		       urb->transfer_buffer_length,
 		       (urb->transfer_flags & URB_ZERO_PACKET));
+
+	return 0;
 }
 
 /*
  *		DCP status stage
  */
-static void usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv,
+static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv,
 					    struct urb *urb,
-					    struct usbhs_pipe *pipe)
+					    struct usbhs_pipe *pipe,
+					    gfp_t mem_flags)
 {
 	struct usbhsh_request *ureq;
-	struct usbhs_pkt *pkt;
 
-	/*
-	 * FIXME
-	 *
-	 * status stage uses allocated ureq.
-	 * it will be freed on usbhsh_queue_done()
-	 */
-	ureq	= usbhsh_ureq_alloc(hpriv, urb, GFP_KERNEL);
-	pkt	= &ureq->pkt;
+	/* This ureq will be freed on usbhsh_queue_done() */
+	ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
+	if (unlikely(!ureq))
+		return -ENOMEM;
+	usbhsh_urb_to_ureq(urb) = ureq;
 
 	if (usb_pipein(urb->pipe))
 		pipe->handler = &usbhs_dcp_status_stage_in_handler;
 	else
 		pipe->handler = &usbhs_dcp_status_stage_out_handler;
 
-	usbhs_pkt_push(pipe, pkt,
+	usbhs_pkt_push(pipe, &ureq->pkt,
 		       usbhsh_queue_done,
 		       NULL,
 		       urb->transfer_buffer_length,
 		       0);
+
+	return 0;
 }
 
 static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
-				 struct usbhsh_hpriv *hpriv,
 				 struct usbhs_pipe *pipe,
-				 struct urb *urb)
+				 struct urb *urb,
+				 gfp_t mflags)
 {
+	struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
 	struct device *dev = usbhsh_hcd_to_dev(hcd);
+	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
 
@@ -686,13 +695,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
 	 *
 	 * It is pushed only when urb has buffer.
 	 */
-	if (urb->transfer_buffer_length)
-		usbhsh_data_stage_packet_push(hpriv, urb, pipe);
+	if (urb->transfer_buffer_length) {
+		ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags);
+		if (ret < 0) {
+			dev_err(dev, "data stage failed\n");
+			return ret;
+		}
+	}
 
 	/*
 	 * status stage
 	 */
-	usbhsh_status_stage_packet_push(hpriv, urb, pipe);
+	ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags);
+	if (ret < 0) {
+		dev_err(dev, "status stage failed\n");
+		return ret;
+	}
 
 	/*
 	 * start pushed packets
@@ -731,7 +749,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
 	struct device *dev = usbhs_priv_to_dev(priv);
 	struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
 	struct usb_host_endpoint *ep = urb->ep;
-	struct usbhsh_request *ureq;
 	struct usbhsh_device *udev, *new_udev = NULL;
 	struct usbhs_pipe *pipe;
 	struct usbhsh_ep *uep;
@@ -770,27 +787,15 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
 	pipe = usbhsh_uep_to_pipe(uep);
 
 	/*
-	 * alloc new request
-	 */
-	ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
-	if (unlikely(!ureq)) {
-		ret = -ENOMEM;
-		goto usbhsh_urb_enqueue_error_free_endpoint;
-	}
-	usbhsh_urb_to_ureq(urb) = ureq;
-
-	/*
 	 * push packet
 	 */
 	if (usb_pipecontrol(urb->pipe))
-		usbhsh_dcp_queue_push(hcd, hpriv, pipe, urb);
+		ret = usbhsh_dcp_queue_push(hcd, pipe, urb, mem_flags);
 	else
-		usbhsh_queue_push(hcd, pipe, urb);
+		ret = usbhsh_queue_push(hcd, pipe, urb, mem_flags);
 
-	return 0;
+	return ret;
 
-usbhsh_urb_enqueue_error_free_endpoint:
-	usbhsh_endpoint_free(hpriv, ep);
 usbhsh_urb_enqueue_error_free_device:
 	if (new_udev)
 		usbhsh_device_free(hpriv, new_udev);
-- 
1.7.5.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