summaryrefslogtreecommitdiff
path: root/drivers/usb/renesas_usbhs/mod_host.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-11 17:31:53 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-11 17:31:53 -0800
commit7fd94beecaff19b346efbf6b77288ab4b0b42dbd (patch)
tree01c1354e59c8c338fd2fe65772c169022aa0ca81 /drivers/usb/renesas_usbhs/mod_host.c
parent0f89fc3fd861b8c50fc8c8db5b9a640959744ac7 (diff)
parentf72e3b78867142a19b77f1de0698ce8b03dc6cbd (diff)
Merge tag 'gadget-for-v3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB gadget patches from Felipe: "usb: gadget: patches for v3.8 renesas_usbhs implements ->pullup() method, switches over to devm_request_irq(), adds support for DMA Engine and got a few miscelaneous cleanups. The NCM gadget got an endianness fix and the Ethernet gadget a frame size fix. We're finally removing the g_file_storage gadget and sticking to g_mass_storage and the new tcm_usb_gadget gadgets since that was a huge duplicaton of effort anyway. While removing g_file_storage, we also had to fix a bunch of defconfigs which were still pointing to the old gadget. There's a big series getting us closer to being able to introduce our configfs interface. The series converts functions into loadable modules which will, eventually, be registered to the configfs interface. Other than that there's the usual typo fixes and miscelaneous cleanups all over the place."
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c45
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 069cd765400c..3d3cd6ca2689 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);
}