Commit 8ee7a330 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some fixes for 3.15-rc8 that resolve a number of tiny USB
  issues that have been reported, and there are some new device ids as
  well.

  All have been tested in linux-next"

* tag 'usb-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  xhci: delete endpoints from bandwidth list before freeing whole device
  usb: pci-quirks: Prevent Sony VAIO t-series from switching usb ports
  USB: cdc-wdm: properly include types.h
  usb: cdc-wdm: export cdc-wdm uapi header
  USB: serial: option: add support for Novatel E371 PCIe card
  USB: ftdi_sio: add NovaTech OrionLXm product ID
  USB: io_ti: fix firmware download on big-endian machines (part 2)
  USB: Avoid runtime suspend loops for HCDs that can't handle suspend/resume
parents da579dd6 5dc2808c
...@@ -1822,10 +1822,13 @@ int usb_runtime_suspend(struct device *dev) ...@@ -1822,10 +1822,13 @@ int usb_runtime_suspend(struct device *dev)
if (status == -EAGAIN || status == -EBUSY) if (status == -EAGAIN || status == -EBUSY)
usb_mark_last_busy(udev); usb_mark_last_busy(udev);
/* The PM core reacts badly unless the return code is 0, /*
* -EAGAIN, or -EBUSY, so always return -EBUSY on an error. * The PM core reacts badly unless the return code is 0,
* -EAGAIN, or -EBUSY, so always return -EBUSY on an error
* (except for root hubs, because they don't suspend through
* an upstream port like other USB devices).
*/ */
if (status != 0) if (status != 0 && udev->parent)
return -EBUSY; return -EBUSY;
return status; return status;
} }
......
...@@ -1691,8 +1691,19 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1691,8 +1691,19 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
*/ */
pm_runtime_set_autosuspend_delay(&hdev->dev, 0); pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
/* Hubs have proper suspend/resume support. */ /*
usb_enable_autosuspend(hdev); * Hubs have proper suspend/resume support, except for root hubs
* where the controller driver doesn't have bus_suspend and
* bus_resume methods.
*/
if (hdev->parent) { /* normal device */
usb_enable_autosuspend(hdev);
} else { /* root hub */
const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
if (drv->bus_suspend && drv->bus_resume)
usb_enable_autosuspend(hdev);
}
if (hdev->level == MAX_TOPO_LEVEL) { if (hdev->level == MAX_TOPO_LEVEL) {
dev_err(&intf->dev, dev_err(&intf->dev,
......
...@@ -847,6 +847,13 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) ...@@ -847,6 +847,13 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
bool ehci_found = false; bool ehci_found = false;
struct pci_dev *companion = NULL; struct pci_dev *companion = NULL;
/* Sony VAIO t-series with subsystem device ID 90a8 is not capable of
* switching ports from EHCI to xHCI
*/
if (xhci_pdev->subsystem_vendor == PCI_VENDOR_ID_SONY &&
xhci_pdev->subsystem_device == 0x90a8)
return;
/* make sure an intel EHCI controller exists */ /* make sure an intel EHCI controller exists */
for_each_pci_dev(companion) { for_each_pci_dev(companion) {
if (companion->class == PCI_CLASS_SERIAL_USB_EHCI && if (companion->class == PCI_CLASS_SERIAL_USB_EHCI &&
......
...@@ -1822,6 +1822,16 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) ...@@ -1822,6 +1822,16 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
kfree(cur_cd); kfree(cur_cd);
} }
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
for (i = 0; i < num_ports; i++) {
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
struct list_head *ep = &bwt->interval_bw[j].endpoints;
while (!list_empty(ep))
list_del_init(ep->next);
}
}
for (i = 1; i < MAX_HC_SLOTS; ++i) for (i = 1; i < MAX_HC_SLOTS; ++i)
xhci_free_virt_device(xhci, i); xhci_free_virt_device(xhci, i);
...@@ -1857,16 +1867,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) ...@@ -1857,16 +1867,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
if (!xhci->rh_bw) if (!xhci->rh_bw)
goto no_bw; goto no_bw;
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
for (i = 0; i < num_ports; i++) {
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
struct list_head *ep = &bwt->interval_bw[j].endpoints;
while (!list_empty(ep))
list_del_init(ep->next);
}
}
for (i = 0; i < num_ports; i++) { for (i = 0; i < num_ports; i++) {
struct xhci_tt_bw_info *tt, *n; struct xhci_tt_bw_info *tt, *n;
list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) {
......
...@@ -580,6 +580,8 @@ static const struct usb_device_id id_table_combined[] = { ...@@ -580,6 +580,8 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID), { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
/* /*
* ELV devices: * ELV devices:
*/ */
......
...@@ -538,6 +538,11 @@ ...@@ -538,6 +538,11 @@
*/ */
#define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */ #define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */
/*
* NovaTech product ids (FTDI_VID)
*/
#define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */
/********************************/ /********************************/
/** third-party VID/PID combos **/ /** third-party VID/PID combos **/
......
...@@ -821,7 +821,7 @@ static int build_i2c_fw_hdr(__u8 *header, struct device *dev) ...@@ -821,7 +821,7 @@ static int build_i2c_fw_hdr(__u8 *header, struct device *dev)
firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data; firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data;
i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK; i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK;
i2c_header->Size = (__u16)buffer_size; i2c_header->Size = cpu_to_le16(buffer_size);
i2c_header->CheckSum = cs; i2c_header->CheckSum = cs;
firmware_rec->Ver_Major = OperationalMajorVersion; firmware_rec->Ver_Major = OperationalMajorVersion;
firmware_rec->Ver_Minor = OperationalMinorVersion; firmware_rec->Ver_Minor = OperationalMinorVersion;
......
...@@ -594,7 +594,7 @@ struct edge_boot_descriptor { ...@@ -594,7 +594,7 @@ struct edge_boot_descriptor {
struct ti_i2c_desc { struct ti_i2c_desc {
__u8 Type; // Type of descriptor __u8 Type; // Type of descriptor
__u16 Size; // Size of data only not including header __le16 Size; // Size of data only not including header
__u8 CheckSum; // Checksum (8 bit sum of data only) __u8 CheckSum; // Checksum (8 bit sum of data only)
__u8 Data[0]; // Data starts here __u8 Data[0]; // Data starts here
} __attribute__((packed)); } __attribute__((packed));
......
...@@ -161,6 +161,7 @@ static void option_instat_callback(struct urb *urb); ...@@ -161,6 +161,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_E371 0x9011
#define NOVATELWIRELESS_PRODUCT_G2 0xA010 #define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 #define NOVATELWIRELESS_PRODUCT_MC551 0xB001
...@@ -1012,6 +1013,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -1012,6 +1013,7 @@ static const struct usb_device_id option_ids[] = {
/* Novatel Ovation MC551 a.k.a. Verizon USB551L */ /* Novatel Ovation MC551 a.k.a. Verizon USB551L */
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
......
# UAPI Header export list # UAPI Header export list
header-y += audio.h header-y += audio.h
header-y += cdc.h header-y += cdc.h
header-y += cdc-wdm.h
header-y += ch11.h header-y += ch11.h
header-y += ch9.h header-y += ch9.h
header-y += functionfs.h header-y += functionfs.h
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#ifndef _UAPI__LINUX_USB_CDC_WDM_H #ifndef _UAPI__LINUX_USB_CDC_WDM_H
#define _UAPI__LINUX_USB_CDC_WDM_H #define _UAPI__LINUX_USB_CDC_WDM_H
#include <linux/types.h>
/* /*
* This IOCTL is used to retrieve the wMaxCommand for the device, * This IOCTL is used to retrieve the wMaxCommand for the device,
* defining the message limit for both reading and writing. * defining the message limit for both reading and writing.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment