Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: MAINTAINERS: add myself as maintainer of USB/IP usb: r8a66597-hcd: fix cannot detect low/full speed device USB: ehci-ath79: fix a NULL pointer dereference USB: Add new FT232H chip to drivers/usb/serial/ftdi_sio.c usb/isp1760: Fix bug preventing the unlinking of control urbs USB: Fix up URB error codes to reflect implementation. xhci: Always set urb->status to zero for isoc endpoints. xhci: Add reset on resume quirk for asrock p67 host xHCI 1.0: Incompatible Device Error USB: don't let errors prevent system sleep USB: don't let the hub driver prevent system sleep USB: change maintainership of ohci-hcd and ehci-hcd xHCI 1.0: Force Stopped Event(FSE) xhci: Don't warn about zeroed bMaxBurst descriptor field. USB: Free bandwidth when usb_disable_device is called. xhci: Reject double add of active endpoints. USB: TI 3410/5052 USB Serial Driver: Fix mem leak when firmware is too big. usb: musb: gadget: clear TXPKTRDY flag when set FLUSHFIFO usb: musb: host: compare status for negative error values
This commit is contained in:
Коммит
2e34b429a4
|
@ -76,6 +76,13 @@ A transfer's actual_length may be positive even when an error has been
|
||||||
reported. That's because transfers often involve several packets, so that
|
reported. That's because transfers often involve several packets, so that
|
||||||
one or more packets could finish before an error stops further endpoint I/O.
|
one or more packets could finish before an error stops further endpoint I/O.
|
||||||
|
|
||||||
|
For isochronous URBs, the urb status value is non-zero only if the URB is
|
||||||
|
unlinked, the device is removed, the host controller is disabled, or the total
|
||||||
|
transferred length is less than the requested length and the URB_SHORT_NOT_OK
|
||||||
|
flag is set. Completion handlers for isochronous URBs should only see
|
||||||
|
urb->status set to zero, -ENOENT, -ECONNRESET, -ESHUTDOWN, or -EREMOTEIO.
|
||||||
|
Individual frame descriptor status fields may report more status codes.
|
||||||
|
|
||||||
|
|
||||||
0 Transfer completed successfully
|
0 Transfer completed successfully
|
||||||
|
|
||||||
|
@ -132,7 +139,7 @@ one or more packets could finish before an error stops further endpoint I/O.
|
||||||
device removal events immediately.
|
device removal events immediately.
|
||||||
|
|
||||||
-EXDEV ISO transfer only partially completed
|
-EXDEV ISO transfer only partially completed
|
||||||
look at individual frame status for details
|
(only set in iso_frame_desc[n].status, not urb->status)
|
||||||
|
|
||||||
-EINVAL ISO madness, if this happens: Log off and go home
|
-EINVAL ISO madness, if this happens: Log off and go home
|
||||||
|
|
||||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -6434,8 +6434,9 @@ S: Maintained
|
||||||
F: drivers/usb/misc/rio500*
|
F: drivers/usb/misc/rio500*
|
||||||
|
|
||||||
USB EHCI DRIVER
|
USB EHCI DRIVER
|
||||||
|
M: Alan Stern <stern@rowland.harvard.edu>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
S: Orphan
|
S: Maintained
|
||||||
F: Documentation/usb/ehci.txt
|
F: Documentation/usb/ehci.txt
|
||||||
F: drivers/usb/host/ehci*
|
F: drivers/usb/host/ehci*
|
||||||
|
|
||||||
|
@ -6465,6 +6466,12 @@ S: Maintained
|
||||||
F: Documentation/hid/hiddev.txt
|
F: Documentation/hid/hiddev.txt
|
||||||
F: drivers/hid/usbhid/
|
F: drivers/hid/usbhid/
|
||||||
|
|
||||||
|
USB/IP DRIVERS
|
||||||
|
M: Matt Mooney <mfm@muteddisk.com>
|
||||||
|
L: linux-usb@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/staging/usbip/
|
||||||
|
|
||||||
USB ISP116X DRIVER
|
USB ISP116X DRIVER
|
||||||
M: Olav Kongas <ok@artecdesign.ee>
|
M: Olav Kongas <ok@artecdesign.ee>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
|
@ -6494,8 +6501,9 @@ S: Maintained
|
||||||
F: sound/usb/midi.*
|
F: sound/usb/midi.*
|
||||||
|
|
||||||
USB OHCI DRIVER
|
USB OHCI DRIVER
|
||||||
|
M: Alan Stern <stern@rowland.harvard.edu>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
S: Orphan
|
S: Maintained
|
||||||
F: Documentation/usb/ohci.txt
|
F: Documentation/usb/ohci.txt
|
||||||
F: drivers/usb/host/ohci*
|
F: drivers/usb/host/ohci*
|
||||||
|
|
||||||
|
|
|
@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
||||||
for (i = n - 1; i >= 0; --i) {
|
for (i = n - 1; i >= 0; --i) {
|
||||||
intf = udev->actconfig->interface[i];
|
intf = udev->actconfig->interface[i];
|
||||||
status = usb_suspend_interface(udev, intf, msg);
|
status = usb_suspend_interface(udev, intf, msg);
|
||||||
|
|
||||||
|
/* Ignore errors during system sleep transitions */
|
||||||
|
if (!(msg.event & PM_EVENT_AUTO))
|
||||||
|
status = 0;
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status == 0)
|
if (status == 0) {
|
||||||
status = usb_suspend_device(udev, msg);
|
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 the suspend failed, resume interfaces that did get suspended */
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
|
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
|
||||||
|
|
|
@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev)
|
||||||
{
|
{
|
||||||
struct usb_device *udev = *pdev;
|
struct usb_device *udev = *pdev;
|
||||||
int i;
|
int i;
|
||||||
|
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
|
||||||
|
|
||||||
if (!udev) {
|
if (!udev) {
|
||||||
pr_debug ("%s nodev\n", __func__);
|
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.
|
* so that the hardware is now fully quiesced.
|
||||||
*/
|
*/
|
||||||
dev_dbg (&udev->dev, "unregistering device\n");
|
dev_dbg (&udev->dev, "unregistering device\n");
|
||||||
|
mutex_lock(hcd->bandwidth_mutex);
|
||||||
usb_disable_device(udev, 0);
|
usb_disable_device(udev, 0);
|
||||||
|
mutex_unlock(hcd->bandwidth_mutex);
|
||||||
usb_hcd_synchronize_unlinks(udev);
|
usb_hcd_synchronize_unlinks(udev);
|
||||||
|
|
||||||
usb_remove_ep_devs(&udev->ep0);
|
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,
|
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
USB_CTRL_SET_TIMEOUT);
|
USB_CTRL_SET_TIMEOUT);
|
||||||
|
|
||||||
|
/* System sleep transitions should never fail */
|
||||||
|
if (!(msg.event & PM_EVENT_AUTO))
|
||||||
|
status = 0;
|
||||||
} else {
|
} else {
|
||||||
/* device has up to 10 msec to fully suspend */
|
/* device has up to 10 msec to fully suspend */
|
||||||
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
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;
|
struct usb_device *hdev = hub->hdev;
|
||||||
unsigned port1;
|
unsigned port1;
|
||||||
|
|
||||||
/* fail if children aren't already suspended */
|
/* Warn if children aren't already suspended */
|
||||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||||
struct usb_device *udev;
|
struct usb_device *udev;
|
||||||
|
|
||||||
udev = hdev->children [port1-1];
|
udev = hdev->children [port1-1];
|
||||||
if (udev && udev->can_submit) {
|
if (udev && udev->can_submit) {
|
||||||
if (!(msg.event & PM_EVENT_AUTO))
|
dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
|
||||||
dev_dbg(&intf->dev, "port %d nyet suspended\n",
|
if (msg.event & PM_EVENT_AUTO)
|
||||||
port1);
|
return -EBUSY;
|
||||||
return -EBUSY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
|
||||||
* Deallocates hcd/hardware state for the endpoints (nuking all or most
|
* Deallocates hcd/hardware state for the endpoints (nuking all or most
|
||||||
* pending urbs) and usbcore state for the interfaces, so that usbcore
|
* pending urbs) and usbcore state for the interfaces, so that usbcore
|
||||||
* must usb_set_configuration() before any interfaces could be used.
|
* 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)
|
void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct usb_hcd *hcd = bus_to_hcd(dev->bus);
|
||||||
|
|
||||||
/* getting rid of interfaces will disconnect
|
/* getting rid of interfaces will disconnect
|
||||||
* any drivers bound to them (a key side effect)
|
* any drivers bound to them (a key side effect)
|
||||||
|
@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
||||||
|
|
||||||
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
|
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
|
||||||
skip_ep0 ? "non-ep0" : "all");
|
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) {
|
for (i = skip_ep0; i < 16; ++i) {
|
||||||
usb_disable_endpoint(dev, i, true);
|
usb_disable_endpoint(dev, i, true);
|
||||||
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
|
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
|
||||||
|
@ -1727,6 +1740,7 @@ free_interfaces:
|
||||||
/* if it's already configured, clear out old state first.
|
/* if it's already configured, clear out old state first.
|
||||||
* getting rid of old interfaces means unbinding their drivers.
|
* getting rid of old interfaces means unbinding their drivers.
|
||||||
*/
|
*/
|
||||||
|
mutex_lock(hcd->bandwidth_mutex);
|
||||||
if (dev->state != USB_STATE_ADDRESS)
|
if (dev->state != USB_STATE_ADDRESS)
|
||||||
usb_disable_device(dev, 1); /* Skip ep0 */
|
usb_disable_device(dev, 1); /* Skip ep0 */
|
||||||
|
|
||||||
|
@ -1739,7 +1753,6 @@ free_interfaces:
|
||||||
* host controller will not allow submissions to dropped endpoints. If
|
* host controller will not allow submissions to dropped endpoints. If
|
||||||
* this call fails, the device state is unchanged.
|
* this call fails, the device state is unchanged.
|
||||||
*/
|
*/
|
||||||
mutex_lock(hcd->bandwidth_mutex);
|
|
||||||
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
|
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mutex_unlock(hcd->bandwidth_mutex);
|
mutex_unlock(hcd->bandwidth_mutex);
|
||||||
|
|
|
@ -44,7 +44,6 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
|
||||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||||
struct platform_device *pdev = to_platform_device(hcd->self.controller);
|
struct platform_device *pdev = to_platform_device(hcd->self.controller);
|
||||||
const struct platform_device_id *id;
|
const struct platform_device_id *id;
|
||||||
int hclength;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
id = platform_get_device_id(pdev);
|
id = platform_get_device_id(pdev);
|
||||||
|
@ -53,20 +52,23 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hclength = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
|
|
||||||
switch (id->driver_data) {
|
switch (id->driver_data) {
|
||||||
case EHCI_ATH79_IP_V1:
|
case EHCI_ATH79_IP_V1:
|
||||||
ehci->has_synopsys_hc_bug = 1;
|
ehci->has_synopsys_hc_bug = 1;
|
||||||
|
|
||||||
ehci->caps = hcd->regs;
|
ehci->caps = hcd->regs;
|
||||||
ehci->regs = hcd->regs + hclength;
|
ehci->regs = hcd->regs +
|
||||||
|
HC_LENGTH(ehci,
|
||||||
|
ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EHCI_ATH79_IP_V2:
|
case EHCI_ATH79_IP_V2:
|
||||||
hcd->has_tt = 1;
|
hcd->has_tt = 1;
|
||||||
|
|
||||||
ehci->caps = hcd->regs + 0x100;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -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
|
* Copyright (c) 2000-2004 by David Brownell
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
|
|
@ -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
|
/* We need to forcefully reclaim the slot since some transfers never
|
||||||
return, e.g. interrupt transfers and NAKed bulk transfers. */
|
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 = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
|
||||||
skip_map |= (1 << qh->slot);
|
skip_map |= (1 << qh->slot);
|
||||||
reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
|
reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
|
||||||
|
|
|
@ -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 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||||
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
|
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
|
||||||
|
|
|
@ -2517,6 +2517,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
|
||||||
INIT_LIST_HEAD(&r8a66597->child_device);
|
INIT_LIST_HEAD(&r8a66597->child_device);
|
||||||
|
|
||||||
hcd->rsrc_start = res->start;
|
hcd->rsrc_start = res->start;
|
||||||
|
hcd->has_tt = 1;
|
||||||
|
|
||||||
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
|
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
|
|
@ -1215,8 +1215,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||||
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
|
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
|
||||||
/* dig out max burst from ep companion desc */
|
/* dig out max burst from ep companion desc */
|
||||||
max_packet = ep->ss_ep_comp.bMaxBurst;
|
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));
|
ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
|
||||||
break;
|
break;
|
||||||
case USB_SPEED_HIGH:
|
case USB_SPEED_HIGH:
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
|
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
|
||||||
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
|
#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";
|
static const char hcd_name[] = "xhci_hcd";
|
||||||
|
|
||||||
/* called after powerup, by probe or system-pm "wakeup" */
|
/* 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->quirks |= XHCI_EP_LIMIT_QUIRK;
|
||||||
xhci->limit_active_eps = 64;
|
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. */
|
/* Make sure the HC is halted. */
|
||||||
retval = xhci_halt(xhci);
|
retval = xhci_halt(xhci);
|
||||||
|
|
|
@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||||
frame->status = -EOVERFLOW;
|
frame->status = -EOVERFLOW;
|
||||||
skip_td = true;
|
skip_td = true;
|
||||||
break;
|
break;
|
||||||
|
case COMP_DEV_ERR:
|
||||||
case COMP_STALL:
|
case COMP_STALL:
|
||||||
frame->status = -EPROTO;
|
frame->status = -EPROTO;
|
||||||
skip_td = true;
|
skip_td = true;
|
||||||
|
@ -1767,9 +1768,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);
|
return finish_td(xhci, td, event_trb, event, ep, status, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1787,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||||
idx = urb_priv->td_cnt;
|
idx = urb_priv->td_cnt;
|
||||||
frame = &td->urb->iso_frame_desc[idx];
|
frame = &td->urb->iso_frame_desc[idx];
|
||||||
|
|
||||||
/* The transfer is partly done */
|
/* The transfer is partly done. */
|
||||||
*status = -EXDEV;
|
|
||||||
frame->status = -EXDEV;
|
frame->status = -EXDEV;
|
||||||
|
|
||||||
/* calc actual length */
|
/* calc actual length */
|
||||||
|
@ -2016,6 +2013,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
||||||
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
|
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
|
||||||
ep_index);
|
ep_index);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
case COMP_DEV_ERR:
|
||||||
|
xhci_warn(xhci, "WARN: detect an incompatible device");
|
||||||
|
status = -EPROTO;
|
||||||
|
break;
|
||||||
case COMP_MISSED_INT:
|
case COMP_MISSED_INT:
|
||||||
/*
|
/*
|
||||||
* When encounter missed service error, one or more isoc tds
|
* When encounter missed service error, one or more isoc tds
|
||||||
|
@ -2063,6 +2064,20 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
||||||
/* Is this a TRB in the currently executing TD? */
|
/* Is this a TRB in the currently executing TD? */
|
||||||
event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
|
event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
|
||||||
td->last_trb, event_dma);
|
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 (!event_seg) {
|
||||||
if (!ep->skip ||
|
if (!ep->skip ||
|
||||||
!usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
|
!usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
|
||||||
|
@ -2158,6 +2173,11 @@ cleanup:
|
||||||
urb->transfer_buffer_length,
|
urb->transfer_buffer_length,
|
||||||
status);
|
status);
|
||||||
spin_unlock(&xhci->lock);
|
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);
|
usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status);
|
||||||
spin_lock(&xhci->lock);
|
spin_lock(&xhci->lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
|
||||||
spin_lock_irq(&xhci->lock);
|
spin_lock_irq(&xhci->lock);
|
||||||
|
if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
||||||
|
hibernated = true;
|
||||||
|
|
||||||
if (!hibernated) {
|
if (!hibernated) {
|
||||||
/* step 1: restore register */
|
/* step 1: restore register */
|
||||||
|
@ -1401,6 +1403,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||||
u32 added_ctxs;
|
u32 added_ctxs;
|
||||||
unsigned int last_ctx;
|
unsigned int last_ctx;
|
||||||
u32 new_add_flags, new_drop_flags, new_slot_info;
|
u32 new_add_flags, new_drop_flags, new_slot_info;
|
||||||
|
struct xhci_virt_device *virt_dev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_ctx = xhci->devs[udev->slot_id]->in_ctx;
|
virt_dev = xhci->devs[udev->slot_id];
|
||||||
out_ctx = xhci->devs[udev->slot_id]->out_ctx;
|
in_ctx = virt_dev->in_ctx;
|
||||||
|
out_ctx = virt_dev->out_ctx;
|
||||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||||
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
|
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,
|
/* If the HCD has already noted the endpoint is enabled,
|
||||||
* ignore this request.
|
* 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
|
* process context, not interrupt context (or so documenation
|
||||||
* for usb_set_interface() and usb_set_configuration() claim).
|
* for usb_set_interface() and usb_set_configuration() claim).
|
||||||
*/
|
*/
|
||||||
if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
|
if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
|
||||||
udev, ep, GFP_NOIO) < 0) {
|
|
||||||
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
|
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
|
||||||
__func__, ep->desc.bEndpointAddress);
|
__func__, ep->desc.bEndpointAddress);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1537,6 +1553,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
|
||||||
"and endpoint is not disabled.\n");
|
"and endpoint is not disabled.\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
case COMP_DEV_ERR:
|
||||||
|
dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint "
|
||||||
|
"configure command.\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
break;
|
||||||
case COMP_SUCCESS:
|
case COMP_SUCCESS:
|
||||||
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
|
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
|
||||||
ret = 0;
|
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);
|
xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
case COMP_DEV_ERR:
|
||||||
|
dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate "
|
||||||
|
"context command.\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
break;
|
||||||
case COMP_MEL_ERR:
|
case COMP_MEL_ERR:
|
||||||
/* Max Exit Latency too large error */
|
/* Max Exit Latency too large error */
|
||||||
dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n");
|
dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n");
|
||||||
|
@ -2853,6 +2879,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||||
dev_warn(&udev->dev, "Device not responding to set address.\n");
|
dev_warn(&udev->dev, "Device not responding to set address.\n");
|
||||||
ret = -EPROTO;
|
ret = -EPROTO;
|
||||||
break;
|
break;
|
||||||
|
case COMP_DEV_ERR:
|
||||||
|
dev_warn(&udev->dev, "ERROR: Incompatible device for address "
|
||||||
|
"device command.\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
break;
|
||||||
case COMP_SUCCESS:
|
case COMP_SUCCESS:
|
||||||
xhci_dbg(xhci, "Successful Address Device command\n");
|
xhci_dbg(xhci, "Successful Address Device command\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -874,6 +874,8 @@ struct xhci_transfer_event {
|
||||||
#define COMP_PING_ERR 20
|
#define COMP_PING_ERR 20
|
||||||
/* Event Ring is full */
|
/* Event Ring is full */
|
||||||
#define COMP_ER_FULL 21
|
#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 */
|
/* Missed Service Error - HC couldn't service an isoc ep within interval */
|
||||||
#define COMP_MISSED_INT 23
|
#define COMP_MISSED_INT 23
|
||||||
/* Successfully stopped command ring */
|
/* Successfully stopped command ring */
|
||||||
|
@ -1308,6 +1310,7 @@ struct xhci_hcd {
|
||||||
*/
|
*/
|
||||||
#define XHCI_EP_LIMIT_QUIRK (1 << 5)
|
#define XHCI_EP_LIMIT_QUIRK (1 << 5)
|
||||||
#define XHCI_BROKEN_MSI (1 << 6)
|
#define XHCI_BROKEN_MSI (1 << 6)
|
||||||
|
#define XHCI_RESET_ON_RESUME (1 << 7)
|
||||||
unsigned int num_active_eps;
|
unsigned int num_active_eps;
|
||||||
unsigned int limit_active_eps;
|
unsigned int limit_active_eps;
|
||||||
/* There are two roothubs to keep track of bus suspend info for */
|
/* There are two roothubs to keep track of bus suspend info for */
|
||||||
|
|
|
@ -1524,6 +1524,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
|
||||||
csr = musb_readw(epio, MUSB_TXCSR);
|
csr = musb_readw(epio, MUSB_TXCSR);
|
||||||
if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
|
if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
|
||||||
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
|
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);
|
musb_writew(epio, MUSB_TXCSR, csr);
|
||||||
/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
|
/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
|
||||||
musb_writew(epio, MUSB_TXCSR, csr);
|
musb_writew(epio, MUSB_TXCSR, csr);
|
||||||
|
|
|
@ -1575,7 +1575,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
||||||
/* even if there was an error, we did the dma
|
/* even if there was an error, we did the dma
|
||||||
* for iso_frame_desc->length
|
* for iso_frame_desc->length
|
||||||
*/
|
*/
|
||||||
if (d->status != EILSEQ && d->status != -EOVERFLOW)
|
if (d->status != -EILSEQ && d->status != -EOVERFLOW)
|
||||||
d->status = 0;
|
d->status = 0;
|
||||||
|
|
||||||
if (++qh->iso_idx >= urb->number_of_packets)
|
if (++qh->iso_idx >= urb->number_of_packets)
|
||||||
|
|
|
@ -179,6 +179,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||||
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
|
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
|
||||||
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
|
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
|
||||||
{ USB_DEVICE(FTDI_VID, FTDI_4232H_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_MICRO_CHAMELEON_PID) },
|
||||||
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
|
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
|
||||||
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
|
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
|
||||||
|
@ -848,7 +849,8 @@ static const char *ftdi_chip_name[] = {
|
||||||
[FT2232C] = "FT2232C",
|
[FT2232C] = "FT2232C",
|
||||||
[FT232RL] = "FT232RL",
|
[FT232RL] = "FT232RL",
|
||||||
[FT2232H] = "FT2232H",
|
[FT2232H] = "FT2232H",
|
||||||
[FT4232H] = "FT4232H"
|
[FT4232H] = "FT4232H",
|
||||||
|
[FT232H] = "FT232H"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1168,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
|
||||||
break;
|
break;
|
||||||
case FT2232H: /* FT2232H chip */
|
case FT2232H: /* FT2232H chip */
|
||||||
case FT4232H: /* FT4232H chip */
|
case FT4232H: /* FT4232H chip */
|
||||||
|
case FT232H: /* FT232H chip */
|
||||||
if ((baud <= 12000000) & (baud >= 1200)) {
|
if ((baud <= 12000000) & (baud >= 1200)) {
|
||||||
div_value = ftdi_2232h_baud_to_divisor(baud);
|
div_value = ftdi_2232h_baud_to_divisor(baud);
|
||||||
} else if (baud < 1200) {
|
} else if (baud < 1200) {
|
||||||
|
@ -1429,9 +1432,12 @@ static void ftdi_determine_type(struct usb_serial_port *port)
|
||||||
} else if (version < 0x600) {
|
} else if (version < 0x600) {
|
||||||
/* Assume it's an FT232BM (or FT245BM) */
|
/* Assume it's an FT232BM (or FT245BM) */
|
||||||
priv->chip_type = FT232BM;
|
priv->chip_type = FT232BM;
|
||||||
} else {
|
} else if (version < 0x900) {
|
||||||
/* Assume it's an FT232R */
|
/* Assume it's an FT232RL */
|
||||||
priv->chip_type = 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]);
|
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 == FT2232C ||
|
||||||
priv->chip_type == FT232RL ||
|
priv->chip_type == FT232RL ||
|
||||||
priv->chip_type == FT2232H ||
|
priv->chip_type == FT2232H ||
|
||||||
priv->chip_type == FT4232H)) {
|
priv->chip_type == FT4232H ||
|
||||||
|
priv->chip_type == FT232H)) {
|
||||||
retval = device_create_file(&port->dev,
|
retval = device_create_file(&port->dev,
|
||||||
&dev_attr_latency_timer);
|
&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 == FT2232C ||
|
||||||
priv->chip_type == FT232RL ||
|
priv->chip_type == FT232RL ||
|
||||||
priv->chip_type == FT2232H ||
|
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);
|
device_remove_file(&port->dev, &dev_attr_latency_timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2212,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
|
||||||
case FT232RL:
|
case FT232RL:
|
||||||
case FT2232H:
|
case FT2232H:
|
||||||
case FT4232H:
|
case FT4232H:
|
||||||
|
case FT232H:
|
||||||
len = 2;
|
len = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -156,7 +156,8 @@ enum ftdi_chip_type {
|
||||||
FT2232C = 4,
|
FT2232C = 4,
|
||||||
FT232RL = 5,
|
FT232RL = 5,
|
||||||
FT2232H = 6,
|
FT2232H = 6,
|
||||||
FT4232H = 7
|
FT4232H = 7,
|
||||||
|
FT232H = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ftdi_sio_baudrate {
|
enum ftdi_sio_baudrate {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
|
#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
|
||||||
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
|
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
|
||||||
#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed 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_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
|
||||||
#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
|
#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
|
||||||
|
|
||||||
|
|
|
@ -1745,6 +1745,7 @@ static int ti_download_firmware(struct ti_device *tdev)
|
||||||
}
|
}
|
||||||
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
|
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
|
||||||
dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
|
dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
|
||||||
|
release_firmware(fw_p);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче