mirror of https://gitee.com/openkylin/linux.git
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:
commit
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
|
||||
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
|
||||
|
||||
|
@ -132,7 +139,7 @@ one or more packets could finish before an error stops further endpoint I/O.
|
|||
device removal events immediately.
|
||||
|
||||
-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
|
||||
|
||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -6434,8 +6434,9 @@ S: Maintained
|
|||
F: drivers/usb/misc/rio500*
|
||||
|
||||
USB EHCI DRIVER
|
||||
M: Alan Stern <stern@rowland.harvard.edu>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
F: Documentation/usb/ehci.txt
|
||||
F: drivers/usb/host/ehci*
|
||||
|
||||
|
@ -6465,6 +6466,12 @@ S: Maintained
|
|||
F: Documentation/hid/hiddev.txt
|
||||
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
|
||||
M: Olav Kongas <ok@artecdesign.ee>
|
||||
L: linux-usb@vger.kernel.org
|
||||
|
@ -6494,8 +6501,9 @@ S: Maintained
|
|||
F: sound/usb/midi.*
|
||||
|
||||
USB OHCI DRIVER
|
||||
M: Alan Stern <stern@rowland.harvard.edu>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
F: Documentation/usb/ohci.txt
|
||||
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) {
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* 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)
|
||||
|
@ -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__,
|
||||
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);
|
||||
|
@ -1727,6 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
|||
/* 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 +1753,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
|||
* 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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1733,6 +1733,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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1787,8 +1785,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 */
|
||||
|
@ -2016,6 +2013,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
|
||||
|
@ -2063,6 +2064,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)) {
|
||||
|
@ -2158,6 +2173,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
@ -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");
|
||||
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;
|
||||
|
|
|
@ -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 */
|
||||
|
@ -1308,6 +1310,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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -156,7 +156,8 @@ enum ftdi_chip_type {
|
|||
FT2232C = 4,
|
||||
FT232RL = 5,
|
||||
FT2232H = 6,
|
||||
FT4232H = 7
|
||||
FT4232H = 7,
|
||||
FT232H = 8
|
||||
};
|
||||
|
||||
enum ftdi_sio_baudrate {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue