diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
| -rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 45 | 
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 069cd765400..3d3cd6ca268 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -85,6 +85,7 @@ struct usbhsh_ep {  	struct usbhsh_device	*udev;   /* attached udev */  	struct usb_host_endpoint *ep;  	struct list_head	ep_list; /* list to usbhsh_device */ +	unsigned int		counter; /* pipe attach counter */  };  #define USBHSH_DEVICE_MAX	10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ @@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,  	/********************  spin lock ********************/  	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;  	} @@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,  	}  usbhsh_pipe_attach_done: +	if (0 == ret) +		uep->counter++; +  	usbhs_unlock(priv, flags);  	/********************  spin unlock ******************/ @@ -346,7 +354,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,  	if (unlikely(!pipe)) {  		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 usbhsh_device *udev = usbhsh_uep_to_udev(uep); @@ -391,6 +399,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,  	/*  	 * init endpoint  	 */ +	uep->counter = 0;  	INIT_LIST_HEAD(&uep->ep_list);  	list_add_tail(&uep->ep_list, &udev->ep_list_head); @@ -686,9 +695,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,  	}  	if (usb_pipein(urb->pipe)) -		pipe->handler = &usbhs_fifo_pio_pop_handler; +		pipe->handler = &usbhs_fifo_dma_pop_handler;  	else -		pipe->handler = &usbhs_fifo_pio_push_handler; +		pipe->handler = &usbhs_fifo_dma_push_handler;  	buf = (void *)(urb->transfer_buffer + urb->actual_length);  	len = urb->transfer_buffer_length - urb->actual_length; @@ -921,6 +930,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,   */  static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map)  { +	if (map) { +		struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); +		struct urb *urb = ureq->urb; + +		/* it can not use scatter/gather */ +		if (urb->num_sgs) +			return -EINVAL; + +		pkt->dma = urb->transfer_dma; +		if (!pkt->dma) +			return -EINVAL; +	} +  	return 0;  } @@ -946,7 +968,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,  	struct usb_host_endpoint *ep = urb->ep;  	struct usbhsh_device *new_udev = NULL;  	int is_dir_in = usb_pipein(urb->pipe); -	int i;  	int ret;  	dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); @@ -992,13 +1013,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,  	 * attach pipe to endpoint  	 * see [image of mod_host]  	 */ -	for (i = 0; i < 1024; i++) { -		ret = usbhsh_pipe_attach(hpriv, urb); -		if (ret < 0) -			msleep(100); -		else -			break; -	} +	ret = usbhsh_pipe_attach(hpriv, urb);  	if (ret < 0) {  		dev_err(dev, "pipe attach failed\n");  		goto usbhsh_urb_enqueue_error_free_endpoint; @@ -1072,8 +1087,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd,  static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)  {  	struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); -	struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); -	struct device *dev = usbhs_priv_to_dev(priv);  	int roothub_id = 1; /* only 1 root hub */  	/* @@ -1085,8 +1098,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)  	else  		*buf = 0; -	dev_dbg(dev, "%s (%02x)\n", __func__, *buf); -  	return !!(*buf);  }  | 
