diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-11-06 16:10:44 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-11-06 16:10:44 +0100 |
commit | b97ac6bd41ba8336b4c3c6aa296f8bccde4697a3 (patch) | |
tree | 279ff1030722e98eacdd8632a3efb6e5c64507d3 /drivers | |
parent | 6aed170ef1ce8004972dc28e98204cd148d28631 (diff) | |
parent | e65090ecc629d0aa3061987ae315a392702c6758 (diff) | |
download | barebox-b97ac6bd41ba8336b4c3c6aa296f8bccde4697a3.tar.gz barebox-b97ac6bd41ba8336b4c3c6aa296f8bccde4697a3.tar.xz |
Merge branch 'for-next/usb'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/usb_kbd.c | 7 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 40 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 52 |
3 files changed, 54 insertions, 45 deletions
diff --git a/drivers/input/usb_kbd.c b/drivers/input/usb_kbd.c index 8c08aba799..655d0c7b25 100644 --- a/drivers/input/usb_kbd.c +++ b/drivers/input/usb_kbd.c @@ -274,7 +274,7 @@ static void usb_kbd_poll(struct poller_struct *poller) struct usb_kbd_pdata *data = container_of(poller, struct usb_kbd_pdata, poller); struct usb_device *usbdev = data->usbdev; - int diff, tout; + int diff, tout, ret; if (data->lock) return; @@ -284,7 +284,10 @@ static void usb_kbd_poll(struct poller_struct *poller) goto exit; data->last_poll = get_time_ns(); - if (0 > data->do_poll(data)) { + ret = data->do_poll(data); + if (ret == -EAGAIN) + goto exit; + if (ret < 0) { /* exit and lock forever */ dev_err(&usbdev->dev, "usb_submit_int_msg() failed. Keyboard disconnect?\n"); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index a3fb1e8808..ce229f2fcc 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -84,10 +84,25 @@ static void print_usb_device(struct usb_device *dev) static int host_busnum = 1; +static inline int usb_host_acquire(struct usb_host *host) +{ + if (host->sem) + return -EAGAIN; + host->sem++; + return 0; +} + +static inline void usb_host_release(struct usb_host *host) +{ + if (host->sem > 0) + host->sem--; +} + int usb_register_host(struct usb_host *host) { list_add_tail(&host->list, &host_list); host->busnum = host_busnum++; + host->sem = 0; asynch_allowed = 1; return 0; } @@ -563,8 +578,17 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval) { struct usb_host *host = dev->host; + int ret; + + ret = usb_host_acquire(host); + if (ret) + return ret; + + ret = host->submit_int_msg(dev, pipe, buffer, transfer_len, interval); - return host->submit_int_msg(dev, pipe, buffer, transfer_len, interval); + usb_host_release(host); + + return ret; } /* @@ -590,6 +614,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, return -1; } + ret = usb_host_acquire(host); + if (ret) + return ret; + /* set setup command */ setup_packet->requesttype = requesttype; setup_packet->request = request; @@ -603,6 +631,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, ret = host->submit_control_msg(dev, pipe, data, size, setup_packet, timeout); + + usb_host_release(host); + if (ret) return ret; @@ -623,8 +654,15 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, if (len < 0) return -1; + ret = usb_host_acquire(host); + if (ret) + return ret; + dev->status = USB_ST_NOT_PROC; /* not yet processed */ ret = host->submit_bulk_msg(dev, pipe, data, len, timeout); + + usb_host_release(host); + if (ret) return ret; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b43b6c7f51..91c6d73c30 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -51,8 +51,6 @@ struct ehci_priv { int periodic_schedules; struct QH *periodic_queue; uint32_t *periodic_list; - int sem; - struct device_d *usedby; }; struct int_queue { @@ -138,20 +136,6 @@ static struct descriptor { #define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT) -static void inline ehci_reentrance_detect(struct ehci_priv *ehci, - struct usb_device *dev, - const char *fname) -{ - if (ehci->sem) - dev_err(&dev->dev, "%s: re-entrance %d (%s:%s)\n", - fname, - ehci->sem, - ehci->usedby->driver->name, - ehci->usedby->name); - ehci->sem++; - ehci->usedby = &dev->dev; -} - static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; @@ -688,7 +672,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, * root */ ehci_powerup_fixup(ehci); - mdelay_non_interruptible(50); + mdelay(50); ehci->portreset |= 1 << port; /* terminate the reset */ ehci_writel(status_reg, reg & ~EHCI_PS_PR); @@ -751,7 +735,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, goto unknown; } - mdelay_non_interruptible(1); + mdelay(1); len = min3(srclen, (int)le16_to_cpu(req->length), length); if (srcptr != NULL && len > 0) memcpy(buffer, srcptr, len); @@ -888,7 +872,7 @@ static int ehci_init(struct usb_host *host) ehci_writel(&ehci->hcor->or_configflag, cmd); /* unblock posted write */ cmd = ehci_readl(&ehci->hcor->or_usbcmd); - mdelay_non_interruptible(5); + mdelay(5); ehci->rootdev = 0; @@ -904,18 +888,12 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, { struct usb_host *host = dev->host; struct ehci_priv *ehci = to_ehci(host); - int ret; - - ehci_reentrance_detect(ehci, dev, __func__); if (usb_pipetype(pipe) != PIPE_BULK) { dev_dbg(ehci->dev, "non-bulk pipe (type=%lu)", usb_pipetype(pipe)); - ehci->sem--; return -1; } - ret = ehci_submit_async(dev, pipe, buffer, length, NULL); - ehci->sem--; - return ret; + return ehci_submit_async(dev, pipe, buffer, length, NULL); } static int @@ -924,9 +902,6 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, { struct usb_host *host = dev->host; struct ehci_priv *ehci = to_ehci(host); - int ret; - - ehci_reentrance_detect(ehci, dev, __func__); if (usb_pipetype(pipe) != PIPE_CONTROL) { dev_dbg(ehci->dev, "non-control pipe (type=%lu)", usb_pipetype(pipe)); @@ -936,13 +911,9 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, if (usb_pipedevice(pipe) == ehci->rootdev) { if (ehci->rootdev == 0) dev->speed = USB_SPEED_HIGH; - ret = ehci_submit_root(dev, pipe, buffer, length, setup); - ehci->sem--; - return ret; + return ehci_submit_root(dev, pipe, buffer, length, setup); } - ret = ehci_submit_async(dev, pipe, buffer, length, setup); - ehci->sem--; - return ret; + return ehci_submit_async(dev, pipe, buffer, length, setup); } static int @@ -983,7 +954,9 @@ enable_periodic(struct ehci_priv *ehci) printf("EHCI failed: timeout when enabling periodic list\n"); return -ETIMEDOUT; } - mdelay_non_interruptible(1); + + mdelay(1); + return 0; } @@ -1265,8 +1238,6 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, void *backbuffer; int result = 0, ret; - ehci_reentrance_detect(ehci, dev, __func__); - dev_dbg(ehci->dev, "dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); @@ -1274,10 +1245,8 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, DMA_BIDIRECTIONAL); queue = ehci_create_int_queue(dev, pipe, 1, length, buffer, interval); - if (!queue) { - ehci->sem--; + if (!queue) return -EINVAL; - } start = get_time_ns(); while ((backbuffer = ehci_poll_int_queue(dev, queue)) == NULL) @@ -1303,7 +1272,6 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, ret = ehci_destroy_int_queue(dev, queue); if (!result) result = ret; - ehci->sem--; return result; } |