summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/driver.c17
-rw-r--r--drivers/usb/core/hub.c16
-rw-r--r--drivers/usb/core/message.c26
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c2
-rw-r--r--drivers/usb/gadget/f_phonet.c1
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c42
-rw-r--r--drivers/usb/gadget/printer.c5
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h4
-rw-r--r--drivers/usb/host/ehci-ath79.c12
-rw-r--r--drivers/usb/host/ehci-cns3xxx.c2
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/host/ehci-grlib.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c2
-rw-r--r--drivers/usb/host/ehci-octeon.c2
-rw-r--r--drivers/usb/host/ehci-pmcmsp.c10
-rw-r--r--drivers/usb/host/ehci-ppc-of.c2
-rw-r--r--drivers/usb/host/ehci-w90x900.c2
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c2
-rw-r--r--drivers/usb/host/fhci-hcd.c2
-rw-r--r--drivers/usb/host/isp1760-hcd.c2
-rw-r--r--drivers/usb/host/ohci-ath79.c4
-rw-r--r--drivers/usb/host/ohci-cns3xxx.c2
-rw-r--r--drivers/usb/host/ohci-da8xx.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c4
-rw-r--r--drivers/usb/host/ohci-octeon.c2
-rw-r--r--drivers/usb/host/ohci-ppc-of.c2
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c2
-rw-r--r--drivers/usb/host/ohci-sa1111.c2
-rw-r--r--drivers/usb/host/ohci-sm501.c11
-rw-r--r--drivers/usb/host/ohci-ssb.c2
-rw-r--r--drivers/usb/host/ohci-tmio.c6
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c1
-rw-r--r--drivers/usb/host/uhci-grlib.c2
-rw-r--r--drivers/usb/host/whci/init.c2
-rw-r--r--drivers/usb/host/xhci-mem.c2
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci-ring.c30
-rw-r--r--drivers/usb/host/xhci.c39
-rw-r--r--drivers/usb/host/xhci.h3
-rw-r--r--drivers/usb/misc/ftdi-elan.c28
-rw-r--r--drivers/usb/musb/musb_core.c2
-rw-r--r--drivers/usb/musb/musb_gadget.c6
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/otg/isp1301_omap.c4
-rw-r--r--drivers/usb/otg/otg_fsm.c1
-rw-r--r--drivers/usb/otg/twl4030-usb.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c19
-rw-r--r--drivers/usb/serial/ftdi_sio.h3
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h1
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c1
52 files changed, 247 insertions, 109 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index e35a17687c0..34e3da5aa72 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev)
* Just re-enable it without affecting the endpoint toggles.
*/
usb_enable_interface(udev, intf, false);
- } else if (!error && !intf->dev.power.in_suspend) {
+ } else if (!error && !intf->dev.power.is_prepared) {
r = usb_set_interface(udev, intf->altsetting[0].
desc.bInterfaceNumber, 0);
if (r < 0)
@@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf)
}
/* Try to rebind the interface */
- if (!intf->dev.power.in_suspend) {
+ if (!intf->dev.power.is_prepared) {
intf->needs_binding = 0;
rc = device_attach(&intf->dev);
if (rc < 0)
@@ -1107,7 +1107,7 @@ static int usb_resume_interface(struct usb_device *udev,
if (intf->condition == USB_INTERFACE_UNBOUND) {
/* Carry out a deferred switch to altsetting 0 */
- if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) {
+ if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) {
usb_set_interface(udev, intf->altsetting[0].
desc.bInterfaceNumber, 0);
intf->needs_altsetting0 = 0;
@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
for (i = n - 1; i >= 0; --i) {
intf = udev->actconfig->interface[i];
status = usb_suspend_interface(udev, intf, msg);
+
+ /* Ignore errors during system sleep transitions */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
if (status != 0)
break;
}
}
- if (status == 0)
+ if (status == 0) {
status = usb_suspend_device(udev, msg);
+ /* Again, ignore errors during system sleep transitions */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
+ }
+
/* If the suspend failed, resume interfaces that did get suspended */
if (status != 0) {
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 90ae1753dda..a428aa080a3 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev)
{
struct usb_device *udev = *pdev;
int i;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
if (!udev) {
pr_debug ("%s nodev\n", __func__);
@@ -1661,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev)
* so that the hardware is now fully quiesced.
*/
dev_dbg (&udev->dev, "unregistering device\n");
+ mutex_lock(hcd->bandwidth_mutex);
usb_disable_device(udev, 0);
+ mutex_unlock(hcd->bandwidth_mutex);
usb_hcd_synchronize_unlinks(udev);
usb_remove_ep_devs(&udev->ep0);
@@ -2362,6 +2365,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
+
+ /* System sleep transitions should never fail */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
} else {
/* device has up to 10 msec to fully suspend */
dev_dbg(&udev->dev, "usb %ssuspend\n",
@@ -2611,16 +2618,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
struct usb_device *hdev = hub->hdev;
unsigned port1;
- /* fail if children aren't already suspended */
+ /* Warn if children aren't already suspended */
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
udev = hdev->children [port1-1];
if (udev && udev->can_submit) {
- if (!(msg.event & PM_EVENT_AUTO))
- dev_dbg(&intf->dev, "port %d nyet suspended\n",
- port1);
- return -EBUSY;
+ dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
+ if (msg.event & PM_EVENT_AUTO)
+ return -EBUSY;
}
}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 5701e857392..0b5ec234c78 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1135,15 +1135,26 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
* Deallocates hcd/hardware state for the endpoints (nuking all or most
* pending urbs) and usbcore state for the interfaces, so that usbcore
* must usb_set_configuration() before any interfaces could be used.
+ *
+ * Must be called with hcd->bandwidth_mutex held.
*/
void usb_disable_device(struct usb_device *dev, int skip_ep0)
{
int i;
+ struct usb_hcd *hcd = bus_to_hcd(dev->bus);
/* getting rid of interfaces will disconnect
* any drivers bound to them (a key side effect)
*/
if (dev->actconfig) {
+ /*
+ * FIXME: In order to avoid self-deadlock involving the
+ * bandwidth_mutex, we have to mark all the interfaces
+ * before unregistering any of them.
+ */
+ for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
+ dev->actconfig->interface[i]->unregistering = 1;
+
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *interface;
@@ -1153,7 +1164,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
continue;
dev_dbg(&dev->dev, "unregistering interface %s\n",
dev_name(&interface->dev));
- interface->unregistering = 1;
remove_intf_ep_devs(interface);
device_del(&interface->dev);
}
@@ -1172,6 +1182,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
skip_ep0 ? "non-ep0" : "all");
+ if (hcd->driver->check_bandwidth) {
+ /* First pass: Cancel URBs, leave endpoint pointers intact. */
+ for (i = skip_ep0; i < 16; ++i) {
+ usb_disable_endpoint(dev, i, false);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, false);
+ }
+ /* Remove endpoints from the host controller internal state */
+ usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+ /* Second pass: remove endpoint pointers */
+ }
for (i = skip_ep0; i < 16; ++i) {
usb_disable_endpoint(dev, i, true);
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
@@ -1273,6 +1293,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
interface);
return -EINVAL;
}
+ if (iface->unregistering)
+ return -ENODEV;
alt = usb_altnum_to_altsetting(iface, alternate);
if (!alt) {
@@ -1727,6 +1749,7 @@ free_interfaces:
/* if it's already configured, clear out old state first.
* getting rid of old interfaces means unbinding their drivers.
*/
+ mutex_lock(hcd->bandwidth_mutex);
if (dev->state != USB_STATE_ADDRESS)
usb_disable_device(dev, 1); /* Skip ep0 */
@@ -1739,7 +1762,6 @@ free_interfaces:
* host controller will not allow submissions to dropped endpoints. If
* this call fails, the device state is unchanged.
*/
- mutex_lock(hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
mutex_unlock(hcd->bandwidth_mutex);
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index e6b970a2a29..5b1665eb1be 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -272,7 +272,7 @@ static void usba_init_debugfs(struct usba_udc *udc)
regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM,
CTRL_IOMEM_ID);
- regs->d_inode->i_size = regs_resource->end - regs_resource->start + 1;
+ regs->d_inode->i_size = resource_size(regs_resource);
udc->debugfs_regs = regs;
usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0));
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index 0d6d26090da..8f8d3f6cd89 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -20,6 +20,7 @@
* 02110-1301 USA
*/
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 5e3dbed7d00..de24a4233c2 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -46,7 +46,6 @@
#include <asm/system.h>
#include <asm/unaligned.h>
#include <asm/dma.h>
-#include <asm/cacheflush.h>
#include "fsl_usb2_udc.h"
@@ -118,6 +117,17 @@ static void (*_fsl_writel)(u32 v, unsigned __iomem *p);
#define fsl_readl(p) (*_fsl_readl)((p))
#define fsl_writel(v, p) (*_fsl_writel)((v), (p))
+static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->big_endian_mmio) {
+ _fsl_readl = _fsl_readl_be;
+ _fsl_writel = _fsl_writel_be;
+ } else {
+ _fsl_readl = _fsl_readl_le;
+ _fsl_writel = _fsl_writel_le;
+ }
+}
+
static inline u32 cpu_to_hc32(const u32 x)
{
return udc_controller->pdata->big_endian_desc
@@ -132,6 +142,8 @@ static inline u32 hc32_to_cpu(const u32 x)
: le32_to_cpu((__force __le32)x);
}
#else /* !CONFIG_PPC32 */
+static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {}
+
#define fsl_readl(addr) readl(addr)
#define fsl_writel(val32, addr) writel(val32, addr)
#define cpu_to_hc32(x) cpu_to_le32(x)
@@ -1282,6 +1294,11 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
req->req.complete = NULL;
req->dtd_count = 0;
+ req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+ req->req.buf, req->req.length,
+ ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->mapped = 1;
+
if (fsl_req_to_dtd(req) == 0)
fsl_queue_td(ep, req);
else
@@ -1353,9 +1370,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
/* Fill in the reqest structure */
*((u16 *) req->req.buf) = cpu_to_le16(tmp);
- /* flush cache for the req buffer */
- flush_dcache_range((u32)req->req.buf, (u32)req->req.buf + 8);
-
req->ep = ep;
req->req.length = 2;
req->req.status = -EINPROGRESS;
@@ -1363,6 +1377,11 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
req->req.complete = NULL;
req->dtd_count = 0;
+ req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+ req->req.buf, req->req.length,
+ ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->mapped = 1;
+
/* prime the data phase */
if ((fsl_req_to_dtd(req) == 0))
fsl_queue_td(ep, req);
@@ -2357,7 +2376,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
struct fsl_req, req);
/* allocate a small amount of memory to get valid address */
udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
- udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf);
udc->resume_state = USB_STATE_NOTATTACHED;
udc->usb_state = USB_STATE_POWERED;
@@ -2448,7 +2466,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
}
if (pdata->operating_mode == FSL_USB2_DR_DEVICE) {
- if (!request_mem_region(res->start, res->end - res->start + 1,
+ if (!request_mem_region(res->start, resource_size(res),
driver_name)) {
ERR("request mem region for %s failed\n", pdev->name);
ret = -EBUSY;
@@ -2473,13 +2491,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
}
/* Set accessors only after pdata->init() ! */
- if (pdata->big_endian_mmio) {
- _fsl_readl = _fsl_readl_be;
- _fsl_writel = _fsl_writel_be;
- } else {
- _fsl_readl = _fsl_readl_le;
- _fsl_writel = _fsl_writel_le;
- }
+ fsl_set_accessors(pdata);
#ifndef CONFIG_ARCH_MXC
if (pdata->have_sysif_regs)
@@ -2603,7 +2615,7 @@ err_iounmap_noclk:
iounmap(dr_regs);
err_release_mem_region:
if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
err_kfree:
kfree(udc_controller);
udc_controller = NULL;
@@ -2640,7 +2652,7 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
free_irq(udc_controller->irq, udc_controller);
iounmap(dr_regs);
if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
device_unregister(&udc_controller->gadget.dev);
/* free udc --wait for the release() finished */
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index d5df8dd9d58..a341dde6f9c 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -794,12 +794,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
}
static int
-printer_fsync(struct file *fd, int datasync)
+printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
{
struct printer_dev *dev = fd->private_data;
+ struct inode *inode = fd->f_path.dentry->d_inode;
unsigned long flags;
int tx_list_empty;
+ mutex_lock(&inode->i_mutex);
spin_lock_irqsave(&dev->lock, flags);
tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
spin_unlock_irqrestore(&dev->lock, flags);
@@ -809,6 +811,7 @@ printer_fsync(struct file *fd, int datasync)
wait_event_interruptible(dev->tx_flush_wait,
(likely(list_empty(&dev->tx_reqs_active))));
}
+ mutex_unlock(&inode->i_mutex);
return 0;
}
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index cd16231d8c7..b01696eab06 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -88,9 +88,9 @@
#define UDCISR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL)
#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */
-#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt
+#define UDCOTGICR_IEXR (1 << 17) /* Extra Transceiver Interrupt
Rising Edge Interrupt Enable */
-#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt
+#define UDCOTGICR_IEXF (1 << 16) /* Extra Transceiver Interrupt
Falling Edge Interrupt Enable */
#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge
Interrupt Enable */
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
index 98cc8a13169..4d2e88d04da 100644
--- a/drivers/usb/host/ehci-ath79.c
+++ b/drivers/usb/host/ehci-ath79.c
@@ -44,7 +44,6 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct platform_device *pdev = to_platform_device(hcd->self.controller);
const struct platform_device_id *id;
- int hclength;
int ret;
id = platform_get_device_id(pdev);
@@ -53,20 +52,23 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
return -EINVAL;
}
- hclength = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
switch (id->driver_data) {
case EHCI_ATH79_IP_V1:
ehci->has_synopsys_hc_bug = 1;
ehci->caps = hcd->regs;
- ehci->regs = hcd->regs + hclength;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci,
+ ehci_readl(ehci, &ehci->caps->hc_capbase));
break;
case EHCI_ATH79_IP_V2:
hcd->has_tt = 1;
ehci->caps = hcd->regs + 0x100;
- ehci->regs = hcd->regs + 0x100 + hclength;
+ ehci->regs = hcd->regs + 0x100 +
+ HC_LENGTH(ehci,
+ ehci_readl(ehci, &ehci->caps->hc_capbase));
break;
default:
@@ -146,7 +148,7 @@ static int ehci_ath79_probe(struct platform_device *pdev)
return -ENOMEM;
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
dev_dbg(&pdev->dev, "controller already in use\n");
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c
index d41745c6f0c..6536abdea6e 100644
--- a/drivers/usb/host/ehci-cns3xxx.c
+++ b/drivers/usb/host/ehci-cns3xxx.c
@@ -107,7 +107,7 @@ static int cns3xxx_ehci_probe(struct platform_device *pdev)
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index f380bf97e5a..34a3140d1e5 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -100,7 +100,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
goto err2;
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c
index 93b230dc51a..fdfd8c5b639 100644
--- a/drivers/usb/host/ehci-grlib.c
+++ b/drivers/usb/host/ehci-grlib.c
@@ -130,7 +130,7 @@ static int __devinit ehci_hcd_grlib_probe(struct platform_device *op)
return -ENOMEM;
hcd->rsrc_start = res.start;
- hcd->rsrc_len = res.end - res.start + 1;
+ hcd->rsrc_len = resource_size(&res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2902199fa8f..f72ae0b6ee7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1,4 +1,8 @@
/*
+ * Enhanced Host Controller Interface (EHCI) driver for USB.
+ *
+ * Maintainer: Alan Stern <stern@rowland.harvard.edu>
+ *
* Copyright (c) 2000-2004 by David Brownell
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
index 50e600d26e2..c4460f3d009 100644
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ b/drivers/usb/host/ehci-ixp4xx.c
@@ -100,7 +100,7 @@ static int ixp4xx_ehci_probe(struct platform_device *pdev)
goto fail_request_resource;
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
index ff55757ba7d..c3ba3ed5f3a 100644
--- a/drivers/usb/host/ehci-octeon.c
+++ b/drivers/usb/host/ehci-octeon.c
@@ -124,7 +124,7 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)
return -ENOMEM;
hcd->rsrc_start = res_mem->start;
- hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+ hcd->rsrc_len = resource_size(res_mem);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
OCTEON_EHCI_HCD_NAME)) {
diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c
index cd69099cda1..e8d54de44ac 100644
--- a/drivers/usb/host/ehci-pmcmsp.c
+++ b/drivers/usb/host/ehci-pmcmsp.c
@@ -124,7 +124,7 @@ static int usb_hcd_msp_map_regs(struct mspusb_device *dev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res == NULL)
return -ENOMEM;
- res_len = res->end - res->start + 1;
+ res_len = resource_size(res);
if (!request_mem_region(res->start, res_len, "mab regs"))
return -EBUSY;
@@ -140,7 +140,7 @@ static int usb_hcd_msp_map_regs(struct mspusb_device *dev)
retval = -ENOMEM;
goto err2;
}
- res_len = res->end - res->start + 1;
+ res_len = resource_size(res);
if (!request_mem_region(res->start, res_len, "usbid regs")) {
retval = -EBUSY;
goto err2;
@@ -154,13 +154,13 @@ static int usb_hcd_msp_map_regs(struct mspusb_device *dev)
return 0;
err3:
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- res_len = res->end - res->start + 1;
+ res_len = resource_size(res);
release_mem_region(res->start, res_len);
err2:
iounmap(dev->mab_regs);
err1:
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- res_len = res->end - res->start + 1;
+ res_len = resource_size(res);
release_mem_region(res->start, res_len);
dev_err(&pdev->dev, "Failed to map non-EHCI regs.\n");
return retval;
@@ -194,7 +194,7 @@ int usb_hcd_msp_probe(const struct hc_driver *driver,
goto err1;
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) {
retval = -EBUSY;
goto err1;
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index 8552db6c29c..41d11fe1425 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -130,7 +130,7 @@ static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op)
return -ENOMEM;
hcd->rsrc_start = res.start;
- hcd->rsrc_len = res.end - res.start + 1;
+ hcd->rsrc_len = resource_size(&res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index 52a027aaa37..d661cf7de14 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -41,7 +41,7 @@ static int __devinit usb_w90x900_probe(const struct hc_driver *driver,
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
retval = -EBUSY;
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index a64d6d66d76..32793ce3d9e 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -174,7 +174,7 @@ static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op)
return -ENOMEM;
hcd->rsrc_start = res.start;
- hcd->rsrc_len = res.end - res.start + 1;
+ hcd->rsrc_len = resource_size(&res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 19223c7449e..572ea53b022 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -605,7 +605,7 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev)
goto err_regs;
}
- hcd->regs = ioremap(usb_regs.start, usb_regs.end - usb_regs.start + 1);
+ hcd->regs = ioremap(usb_regs.start, resource_size(&usb_regs));
if (!hcd->regs) {
dev_err(dev, "could not ioremap regs\n");
ret = -ENOMEM;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index c9e6e454c62..55d3d5859ac 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1555,7 +1555,7 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb,
/* We need to forcefully reclaim the slot since some transfers never
return, e.g. interrupt transfers and NAKed bulk transfers. */
- if (usb_pipebulk(urb->pipe)) {
+ if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) {
skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
skip_map |= (1 << qh->slot);
reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c
index ffea3e7cb0a..c620c50f677 100644
--- a/drivers/usb/host/ohci-ath79.c
+++ b/drivers/usb/host/ohci-ath79.c
@@ -93,8 +93,8 @@ static int ohci_ath79_probe(struct platform_device *pdev)
ret = -ENODEV;
goto err_put_hcd;
}
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
dev_dbg(&pdev->dev, "controller already in use\n");
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
index f05ef87e934..5a00a1e1c6c 100644
--- a/drivers/usb/host/ohci-cns3xxx.c
+++ b/drivers/usb/host/ohci-cns3xxx.c
@@ -100,7 +100,7 @@ static int cns3xxx_ohci_probe(struct platform_device *pdev)
goto err1;
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index d22fb4d577b..6aca2c4453f 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -322,7 +322,7 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
goto err2;
}
hcd->rsrc_start = mem->start;
- hcd->rsrc_len = mem->end - mem->start + 1;
+ hcd->rsrc_len = resource_size(mem);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
dev_dbg(&pdev->dev, "request_mem_region failed\n");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9aa10bdf391..f9cf3f04b74 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1,5 +1,7 @@
/*
- * OHCI HCD (Host Controller Driver) for USB.
+ * Open Host Controller Interface (OHCI) driver for USB.
+ *
+ * Maintainer: Alan Stern <stern@rowland.harvard.edu>
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
index e4ddfaf8870..d8b45647d1d 100644
--- a/drivers/usb/host/ohci-octeon.c
+++ b/drivers/usb/host/ohci-octeon.c
@@ -135,7 +135,7 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)
return -ENOMEM;
hcd->rsrc_start = res_mem->start;
- hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+ hcd->rsrc_len = resource_size(res_mem);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
OCTEON_OHCI_HCD_NAME)) {
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 1ca1821320f..0c12f4e14dc 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -110,7 +110,7 @@ static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op)
return -ENOMEM;
hcd->rsrc_start = res.start;
- hcd->rsrc_len = res.end - res.start + 1;
+ hcd->rsrc_len = resource_size(&res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 89e670e38c1..c0f595c4448 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -56,7 +56,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
if (!hcd)
return -ENOMEM;
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
pr_debug("%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index d8eb3bdafab..4204d9720d2 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -131,7 +131,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
if (!hcd)
return -ENOMEM;
hcd->rsrc_start = dev->res.start;
- hcd->rsrc_len = dev->res.end - dev->res.start + 1;
+ hcd->rsrc_len = resource_size(&dev->res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
dbg("request_mem_region failed");
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 041d30f30c1..78918ca0da2 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -103,8 +103,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
goto err0;
}
- if (!request_mem_region(mem->start, mem->end - mem->start + 1,
- pdev->name)) {
+ if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
dev_err(dev, "request_mem_region failed\n");
retval = -EBUSY;
goto err0;
@@ -126,7 +125,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
if (!dma_declare_coherent_memory(dev, mem->start,
mem->start - mem->parent->start,
- (mem->end - mem->start) + 1,
+ resource_size(mem),
DMA_MEMORY_MAP |
DMA_MEMORY_EXCLUSIVE)) {
dev_err(dev, "cannot declare coherent memory\n");
@@ -149,7 +148,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, pdev->name)) {
dev_err(dev, "request_mem_region failed\n");
@@ -185,7 +184,7 @@ err3:
err2:
dma_release_declared_memory(dev);
err1:
- release_mem_region(mem->start, mem->end - mem->start + 1);
+ release_mem_region(mem->start, resource_size(mem));
err0:
return retval;
}
@@ -201,7 +200,7 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev)
dma_release_declared_memory(&pdev->dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (mem)
- release_mem_region(mem->start, mem->end - mem->start + 1);
+ release_mem_region(mem->start, resource_size(mem));
/* mask interrupts and disable power */
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
index 48ee6943bf3..c4aea3b8315 100644
--- a/drivers/usb/host/ohci-ssb.c
+++ b/drivers/usb/host/ohci-ssb.c
@@ -2,7 +2,7 @@
* Sonics Silicon Backplane
* Broadcom USB-core OHCI driver
*
- * Copyright 2007 Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007 Michael Buesch <m@bues.ch>
*
* Derived from the OHCI-PCI driver
* Copyright 1999 Roman Weissgaerber
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 3558491dd87..57ad1271fc9 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -208,13 +208,13 @@ static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
}
hcd->rsrc_start = regs->start;
- hcd->rsrc_len = regs->end - regs->start + 1;
+ hcd->rsrc_len = resource_size(regs);
tmio = hcd_to_tmio(hcd);
spin_lock_init(&tmio->lock);
- tmio->ccr = ioremap(config->start, config->end - config->start + 1);
+ tmio->ccr = ioremap(config->start, resource_size(config));
if (!tmio->ccr) {
ret = -ENOMEM;
goto err_ioremap_ccr;
@@ -228,7 +228,7 @@ static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
if (!dma_declare_coherent_memory(&dev->dev, sram->start,
sram->start,
- sram->end - sram->start + 1,
+ resource_size(sram),
DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) {
ret = -EBUSY;
goto err_dma_declare;
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 5fbe997dc6d..dcd889803f0 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -3828,7 +3828,7 @@ static int oxu_drv_probe(struct platform_device *pdev)
return -ENODEV;
}
memstart = res->start;
- memlen = res->end - res->start + 1;
+ memlen = resource_size(res);
dev_dbg(&pdev->dev, "MEM resource %lx-%lx\n", memstart, memlen);
if (!request_mem_region(memstart, memlen,
oxu_hc_driver.description)) {
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index fd35901861c..40a0d8b03ad 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2517,6 +2517,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&r8a66597->child_device);
hcd->rsrc_start = res->start;
+ hcd->has_tt = 1;
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
if (ret != 0) {
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c
index d01c1e22768..f7a62138e3e 100644
--- a/drivers/usb/host/uhci-grlib.c
+++ b/drivers/usb/host/uhci-grlib.c
@@ -111,7 +111,7 @@ static int __devinit uhci_hcd_grlib_probe(struct platform_device *op)
return -ENOMEM;
hcd->rsrc_start = res.start;
- hcd->rsrc_len = res.end - res.start + 1;
+ hcd->rsrc_len = resource_size(&res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c
index f7582e8e216..d3e13b640d4 100644
--- a/drivers/usb/host/whci/init.c
+++ b/drivers/usb/host/whci/init.c
@@ -178,7 +178,7 @@ void whc_clean_up(struct whc *whc)
if (whc->qset_pool)
dma_pool_destroy(whc->qset_pool);
- len = whc->umc->resource.end - whc->umc->resource.start + 1;
+ len = resource_size(&whc->umc->resource);
if (whc->base)
iounmap(whc->base);
if (whc->base_phys)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1370db808fc..d446886b22b 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1215,8 +1215,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
/* dig out max burst from ep companion desc */
max_packet = ep->ss_ep_comp.bMaxBurst;
- if (!max_packet)
- xhci_warn(xhci, "WARN no SS endpoint bMaxBurst\n");
ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
break;
case USB_SPEED_HIGH:
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 17541d09eab..cb16de213f6 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -29,6 +29,9 @@
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
+#define PCI_VENDOR_ID_ETRON 0x1b6f
+#define PCI_DEVICE_ID_ASROCK_P67 0x7023
+
static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */
@@ -134,6 +137,11 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
xhci->limit_active_eps = 64;
}
+ if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+ pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
+ }
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e5530181baa..7113d16e2d3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1731,6 +1731,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
frame->status = -EOVERFLOW;
skip_td = true;
break;
+ case COMP_DEV_ERR:
case COMP_STALL:
frame->status = -EPROTO;
skip_td = true;
@@ -1763,9 +1764,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
}
}
- if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS)
- *status = 0;
-
return finish_td(xhci, td, event_trb, event, ep, status, false);
}
@@ -1783,8 +1781,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
idx = urb_priv->td_cnt;
frame = &td->urb->iso_frame_desc[idx];
- /* The transfer is partly done */
- *status = -EXDEV;
+ /* The transfer is partly done. */
frame->status = -EXDEV;
/* calc actual length */
@@ -2010,6 +2007,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index);
goto cleanup;
+ case COMP_DEV_ERR:
+ xhci_warn(xhci, "WARN: detect an incompatible device");
+ status = -EPROTO;
+ break;
case COMP_MISSED_INT:
/*
* When encounter missed service error, one or more isoc tds
@@ -2057,6 +2058,20 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* Is this a TRB in the currently executing TD? */
event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
td->last_trb, event_dma);
+
+ /*
+ * Skip the Force Stopped Event. The event_trb(event_dma) of FSE
+ * is not in the current TD pointed by ep_ring->dequeue because
+ * that the hardware dequeue pointer still at the previous TRB
+ * of the current TD. The previous TRB maybe a Link TD or the
+ * last TRB of the previous TD. The command completion handle
+ * will take care the rest.
+ */
+ if (!event_seg && trb_comp_code == COMP_STOP_INVAL) {
+ ret = 0;
+ goto cleanup;
+ }
+
if (!event_seg) {
if (!ep->skip ||
!usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
@@ -2150,6 +2165,11 @@ cleanup:
urb->transfer_buffer_length,
status);
spin_unlock(&xhci->lock);
+ /* EHCI, UHCI, and OHCI always unconditionally set the
+ * urb->status of an isochronous endpoint to 0.
+ */
+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
+ status = 0;
usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status);
spin_lock(&xhci->lock);
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d0a65401670..763f484bc09 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
msleep(100);
spin_lock_irq(&xhci->lock);
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+ hibernated = true;
if (!hibernated) {
/* step 1: restore register */
@@ -1401,6 +1403,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
u32 added_ctxs;
unsigned int last_ctx;
u32 new_add_flags, new_drop_flags, new_slot_info;
+ struct xhci_virt_device *virt_dev;
int ret = 0;
ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
@@ -1425,11 +1428,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
return 0;
}
- in_ctx = xhci->devs[udev->slot_id]->in_ctx;
- out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ virt_dev = xhci->devs[udev->slot_id];
+ in_ctx = virt_dev->in_ctx;
+ out_ctx = virt_dev->out_ctx;
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+
+ /* If this endpoint is already in use, and the upper layers are trying
+ * to add it again without dropping it, reject the addition.
+ */
+ if (virt_dev->eps[ep_index].ring &&
+ !(le32_to_cpu(ctrl_ctx->drop_flags) &
+ xhci_get_endpoint_flag(&ep->desc))) {
+ xhci_warn(xhci, "Trying to add endpoint 0x%x "
+ "without dropping it.\n",
+ (unsigned int) ep->desc.bEndpointAddress);
+ return -EINVAL;
+ }
+
/* If the HCD has already noted the endpoint is enabled,
* ignore this request.
*/
@@ -1445,8 +1462,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
* process context, not interrupt context (or so documenation
* for usb_set_interface() and usb_set_configuration() claim).
*/
- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
- udev, ep, GFP_NOIO) < 0) {
+ if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
__func__, ep->desc.bEndpointAddress);
return -ENOMEM;
@@ -1537,6 +1553,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
"and endpoint is not disabled.\n");
ret = -EINVAL;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint "
+ "configure command.\n");
+ ret = -ENODEV;
+ break;
case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
ret = 0;
@@ -1571,6 +1592,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
ret = -EINVAL;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate "
+ "context command.\n");
+ ret = -ENODEV;
+ break;
case COMP_MEL_ERR:
/* Max Exit Latency too large error */
dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n");
@@ -2851,6 +2877,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
dev_warn(&udev->dev, "Device not responding to set address.\n");
ret = -EPROTO;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for address "
+ "device command.\n");
+ ret = -ENODEV;
+ break;
case COMP_SUCCESS:
xhci_dbg(xhci, "Successful Address Device command\n");
break;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a2cc7674169..cae8e23308b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -874,6 +874,8 @@ struct xhci_transfer_event {
#define COMP_PING_ERR 20
/* Event Ring is full */
#define COMP_ER_FULL 21
+/* Incompatible Device Error */
+#define COMP_DEV_ERR 22
/* Missed Service Error - HC couldn't service an isoc ep within interval */
#define COMP_MISSED_INT 23
/* Successfully stopped command ring */
@@ -1315,6 +1317,7 @@ struct xhci_hcd {
*/
#define XHCI_EP_LIMIT_QUIRK (1 << 5)
#define XHCI_BROKEN_MSI (1 << 6)
+#define XHCI_RESET_ON_RESUME (1 << 7)
unsigned int num_active_eps;
unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index b16bd3ce391..2f41089cd85 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -187,7 +187,7 @@ struct usb_ftdi {
u32 controlreg;
u8 response[4 + 1024];
int expected;
- int recieved;
+ int received;
int ed_found;
};
#define kref_to_usb_ftdi(d) container_of(d, struct usb_ftdi, kref)
@@ -353,7 +353,7 @@ static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi)
mutex_lock(&ftdi->u132_lock);
}
}
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
mutex_unlock(&ftdi->u132_lock);
@@ -411,7 +411,7 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
}
}
}
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
mutex_unlock(&ftdi->u132_lock);
@@ -447,7 +447,7 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
}
}
}
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
mutex_unlock(&ftdi->u132_lock);
@@ -874,7 +874,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
return ftdi->response;
@@ -890,7 +890,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
return ftdi->response;
@@ -905,7 +905,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
return ftdi->response;
@@ -914,7 +914,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
return ftdi->response;
@@ -934,7 +934,7 @@ static char *have_ed_get_response(struct usb_ftdi *ftdi,
if (target->active)
ftdi_elan_do_callback(ftdi, target, NULL, 0);
target->abandoning = 0;
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
return ftdi->response;
@@ -951,7 +951,7 @@ static char *have_ed_get_response(struct usb_ftdi *ftdi,
*/
static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi)
{
- u8 *b = ftdi->response + ftdi->recieved;
+ u8 *b = ftdi->response + ftdi->received;
int bytes_read = 0;
int retry_on_empty = 1;
int retry_on_timeout = 3;
@@ -1043,11 +1043,11 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi)
u8 c = ftdi->bulk_in_buffer[++ftdi->bulk_in_last];
bytes_read += 1;
ftdi->bulk_in_left -= 1;
- if (ftdi->recieved == 0 && c == 0xFF) {
+ if (ftdi->received == 0 && c == 0xFF) {
goto have;
} else
*b++ = c;
- if (++ftdi->recieved < ftdi->expected) {
+ if (++ftdi->received < ftdi->expected) {
goto have;
} else if (ftdi->ed_found) {
int ed_number = (ftdi->response[0] >> 5) & 0x03;
@@ -1069,7 +1069,7 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi)
}
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
b = ftdi->response;
@@ -1089,7 +1089,7 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi)
*respond->value = data;
*respond->result = 0;
complete(&respond->wait_completion);
- ftdi->recieved = 0;
+ ftdi->received = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
b = ftdi->response;
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 4d39e08d456..20a28731c33 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1892,7 +1892,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
* - initializes musb->xceiv, usually by otg_get_transceiver()
* - stops powering VBUS
*
- * There are various transciever configurations. Blackfin,
+ * There are various transceiver configurations. Blackfin,
* DaVinci, TUSB60x0, and others integrate them. OMAP3 uses
* external/discrete ones in various flavors (twl4030 family,
* isp1504, non-OTG, etc) mostly hooking up through ULPI.
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 8b626548989..b67a062f556 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1524,6 +1524,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
csr = musb_readw(epio, MUSB_TXCSR);
if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
+ /*
+ * Setting both TXPKTRDY and FLUSHFIFO makes controller
+ * to interrupt current FIFO loading, but not flushing
+ * the already loaded ones.
+ */
+ csr &= ~MUSB_TXCSR_TXPKTRDY;
musb_writew(epio, MUSB_TXCSR, csr);
/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
musb_writew(epio, MUSB_TXCSR, csr);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 7295e316bdf..8b2473fa0f4 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1575,7 +1575,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* even if there was an error, we did the dma
* for iso_frame_desc->length
*/
- if (d->status != EILSEQ && d->status != -EOVERFLOW)
+ if (d->status != -EILSEQ && d->status != -EOVERFLOW)
d->status = 0;
if (++qh->iso_idx >= urb->number_of_packets)
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c
index 8c282258e1b..ca9b690a7e4 100644
--- a/drivers/usb/otg/isp1301_omap.c
+++ b/drivers/usb/otg/isp1301_omap.c
@@ -660,7 +660,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
int ret = IRQ_NONE;
struct isp1301 *isp = _isp;
- /* update ISP1301 transciever from OTG controller */
+ /* update ISP1301 transceiver from OTG controller */
if (otg_irq & OPRT_CHG) {
omap_writew(OPRT_CHG, OTG_IRQ_SRC);
isp1301_defer_work(isp, WORK_UPDATE_ISP);
@@ -755,7 +755,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
omap_writew(A_VBUS_ERR, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
- /* switch driver; the transciever code activates it,
+ /* switch driver; the transceiver code activates it,
* ungating the udc clock or resuming OHCI.
*/
} else if (otg_irq & DRIVER_SWITCH) {
diff --git a/drivers/usb/otg/otg_fsm.c b/drivers/usb/otg/otg_fsm.c
index b0cc422f2ff..09117387d2a 100644
--- a/drivers/usb/otg/otg_fsm.c
+++ b/drivers/usb/otg/otg_fsm.c
@@ -28,7 +28,6 @@
#include <linux/usb.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
-#include <linux/types.h>
#include "otg_fsm.h"
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index efeb4d1517f..14f66c35862 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -166,7 +166,7 @@ struct twl4030_usb {
};
/* internal define on top of container_of */
-#define xceiv_to_twl(x) container_of((x), struct twl4030_usb, otg);
+#define xceiv_to_twl(x) container_of((x), struct twl4030_usb, otg)
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 16272897755..2e06b90aa1f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -179,6 +179,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
@@ -848,7 +849,8 @@ static const char *ftdi_chip_name[] = {
[FT2232C] = "FT2232C",
[FT232RL] = "FT232RL",
[FT2232H] = "FT2232H",
- [FT4232H] = "FT4232H"
+ [FT4232H] = "FT4232H",
+ [FT232H] = "FT232H"
};
@@ -1168,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
break;
case FT2232H: /* FT2232H chip */
case FT4232H: /* FT4232H chip */
+ case FT232H: /* FT232H chip */
if ((baud <= 12000000) & (baud >= 1200)) {
div_value = ftdi_2232h_baud_to_divisor(baud);
} else if (baud < 1200) {
@@ -1429,9 +1432,12 @@ static void ftdi_determine_type(struct usb_serial_port *port)
} else if (version < 0x600) {
/* Assume it's an FT232BM (or FT245BM) */
priv->chip_type = FT232BM;
- } else {
- /* Assume it's an FT232R */
+ } else if (version < 0x900) {
+ /* Assume it's an FT232RL */
priv->chip_type = FT232RL;
+ } else {
+ /* Assume it's an FT232H */
+ priv->chip_type = FT232H;
}
dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]);
}
@@ -1559,7 +1565,8 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
priv->chip_type == FT2232C ||
priv->chip_type == FT232RL ||
priv->chip_type == FT2232H ||
- priv->chip_type == FT4232H)) {
+ priv->chip_type == FT4232H ||
+ priv->chip_type == FT232H)) {
retval = device_create_file(&port->dev,
&dev_attr_latency_timer);
}
@@ -1580,7 +1587,8 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
priv->chip_type == FT2232C ||
priv->chip_type == FT232RL ||
priv->chip_type == FT2232H ||
- priv->chip_type == FT4232H) {
+ priv->chip_type == FT4232H ||
+ priv->chip_type == FT232H) {
device_remove_file(&port->dev, &dev_attr_latency_timer);
}
}
@@ -2212,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
case FT232RL:
case FT2232H:
case FT4232H:
+ case FT232H:
len = 2;
break;
default:
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 213fe3d6128..19584faa86f 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -156,7 +156,8 @@ enum ftdi_chip_type {
FT2232C = 4,
FT232RL = 5,
FT2232H = 6,
- FT4232H = 7
+ FT4232H = 7,
+ FT232H = 8
};
enum ftdi_sio_baudrate {
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index ab1fcdf3c37..19156d1049f 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -22,6 +22,7 @@
#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
+#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */
#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index c6d92a53008..ea8445689c8 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1745,6 +1745,7 @@ static int ti_download_firmware(struct ti_device *tdev)
}
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
+ release_firmware(fw_p);
return -ENOENT;
}