[PATCH 24/48] usb: gadget: renesas_usbhs: bugfix: care pipe direction

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

 



From: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx>

renesas_usbhs is caring pipe type and its direction.
but current usbhs_endpoint_alloc() didn't check direction.
this patch modify it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx>
Signed-off-by: Felipe Balbi <balbi@xxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/renesas_usbhs/mod_host.c |   29 +++++++++++++++++++++--------
 1 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index b964f25..f8f612c 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,
 struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 					struct usbhsh_device *udev,
 					struct usb_host_endpoint *ep,
+					int dir_in_req,
 					gfp_t mem_flags)
 {
 	struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
@@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 	struct usbhs_pipe *pipe, *best_pipe;
 	struct device *dev = usbhsh_hcd_to_dev(hcd);
 	struct usb_endpoint_descriptor *desc = &ep->desc;
-	int type, i;
+	int type, i, dir_in;
 	unsigned int min_usr;
 
+	dir_in_req = !!dir_in_req;
+
 	uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
 	if (!uep) {
 		dev_err(dev, "usbhsh_ep alloc fail\n");
 		return NULL;
 	}
-	type = usb_endpoint_type(desc);
+
+	if (usb_endpoint_xfer_control(desc)) {
+		best_pipe = usbhsh_hpriv_to_dcp(hpriv);
+		goto usbhsh_endpoint_alloc_find_pipe;
+	}
 
 	/*
 	 * find best pipe for endpoint
 	 * see
 	 *	HARDWARE LIMITATION
 	 */
+	type = usb_endpoint_type(desc);
 	min_usr = ~0;
 	best_pipe = NULL;
-	usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
+	usbhs_for_each_pipe(pipe, priv, i) {
 		if (!usbhs_pipe_type_is(pipe, type))
 			continue;
 
+		dir_in = !!usbhs_pipe_is_dir_in(pipe);
+		if (0 != (dir_in - dir_in_req))
+			continue;
+
 		info = usbhsh_pipe_info(pipe);
 
 		if (min_usr > info->usr_cnt) {
@@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 		kfree(uep);
 		return NULL;
 	}
-
+usbhsh_endpoint_alloc_find_pipe:
 	/*
 	 * init uep
 	 */
@@ -430,7 +442,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 
 	dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
 		usbhsh_device_number(hpriv, udev),
-		usbhs_pipe_name(pipe), uep);
+		usbhs_pipe_name(uep->pipe), uep);
 
 	return uep;
 }
@@ -722,11 +734,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
 	struct usbhsh_device *udev, *new_udev = NULL;
 	struct usbhs_pipe *pipe;
 	struct usbhsh_ep *uep;
+	int is_dir_in = usb_pipein(urb->pipe);
 
 	int ret;
 
-	dev_dbg(dev, "%s (%s)\n",
-		__func__, usb_pipein(urb->pipe) ? "in" : "out");
+	dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
 
 	ret = usb_hcd_link_urb_to_ep(hcd, urb);
 	if (ret)
@@ -749,7 +761,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
 	 */
 	uep = usbhsh_ep_to_uep(ep);
 	if (!uep) {
-		uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags);
+		uep = usbhsh_endpoint_alloc(hpriv, udev, ep,
+					    is_dir_in, mem_flags);
 		if (!uep)
 			goto usbhsh_urb_enqueue_error_free_device;
 	}
-- 
1.7.7.3

--
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