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

Commit 7b332e5f authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Felipe Balbi
Browse files

usb: renesas_usbhs: host: add endpoint user counter



renesas_usbhs attaches pipe to endpoint when urb was queued, and it will be
detached when transfer was done.  Multi device controlling was enabled by this
behavior.

Now renesas_usbhs driver tried to wait until detaching if urb was queued to
endpoint which already has been attached to pipe, and it created strange driver
behavior.

But it can re-use this attached pipe if multi urb was queued.  This patch
implements it.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 24e4c1c3
Loading
Loading
Loading
Loading
+13 −11
Original line number Original line Diff line number Diff line
@@ -85,6 +85,7 @@ struct usbhsh_ep {
	struct usbhsh_device	*udev;   /* attached udev */
	struct usbhsh_device	*udev;   /* attached udev */
	struct usb_host_endpoint *ep;
	struct usb_host_endpoint *ep;
	struct list_head	ep_list; /* list to usbhsh_device */
	struct list_head	ep_list; /* list to usbhsh_device */
	unsigned int		counter; /* pipe attach counter */
};
};


#define USBHSH_DEVICE_MAX	10 /* see DEVADDn / DCPMAXP / PIPEMAXP */
#define USBHSH_DEVICE_MAX	10 /* see DEVADDn / DCPMAXP / PIPEMAXP */
@@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
	/********************  spin lock ********************/
	/********************  spin lock ********************/
	usbhs_lock(priv, flags);
	usbhs_lock(priv, flags);


	if (unlikely(usbhsh_uep_to_pipe(uep))) {
	/*
		dev_err(dev, "uep already has pipe\n");
	 * if uep has been attached to pipe,
	 * reuse it
	 */
	if (usbhsh_uep_to_pipe(uep)) {
		ret = 0;
		goto usbhsh_pipe_attach_done;
		goto usbhsh_pipe_attach_done;
	}
	}


@@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
	}
	}


usbhsh_pipe_attach_done:
usbhsh_pipe_attach_done:
	if (0 == ret)
		uep->counter++;

	usbhs_unlock(priv, flags);
	usbhs_unlock(priv, flags);
	/********************  spin unlock ******************/
	/********************  spin unlock ******************/


@@ -341,7 +349,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,


	if (unlikely(!pipe)) {
	if (unlikely(!pipe)) {
		dev_err(dev, "uep doens't have pipe\n");
		dev_err(dev, "uep doens't have pipe\n");
	} else {
	} else if (1 == uep->counter--) { /* last user */
		struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep);
		struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep);
		struct usbhsh_device *udev = usbhsh_uep_to_udev(uep);
		struct usbhsh_device *udev = usbhsh_uep_to_udev(uep);


@@ -386,6 +394,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
	/*
	/*
	 * init endpoint
	 * init endpoint
	 */
	 */
	uep->counter = 0;
	INIT_LIST_HEAD(&uep->ep_list);
	INIT_LIST_HEAD(&uep->ep_list);
	list_add_tail(&uep->ep_list, &udev->ep_list_head);
	list_add_tail(&uep->ep_list, &udev->ep_list_head);


@@ -954,7 +963,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
	struct usb_host_endpoint *ep = urb->ep;
	struct usb_host_endpoint *ep = urb->ep;
	struct usbhsh_device *new_udev = NULL;
	struct usbhsh_device *new_udev = NULL;
	int is_dir_in = usb_pipein(urb->pipe);
	int is_dir_in = usb_pipein(urb->pipe);
	int i;
	int ret;
	int ret;


	dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
	dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
@@ -1000,13 +1008,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
	 * attach pipe to endpoint
	 * attach pipe to endpoint
	 * see [image of mod_host]
	 * see [image of mod_host]
	 */
	 */
	for (i = 0; i < 1024; i++) {
	ret = usbhsh_pipe_attach(hpriv, urb);
	ret = usbhsh_pipe_attach(hpriv, urb);
		if (ret < 0)
			msleep(100);
		else
			break;
	}
	if (ret < 0) {
	if (ret < 0) {
		dev_err(dev, "pipe attach failed\n");
		dev_err(dev, "pipe attach failed\n");
		goto usbhsh_urb_enqueue_error_free_endpoint;
		goto usbhsh_urb_enqueue_error_free_endpoint;