Merge 4.16-rc3 into usb-next
We want the USB fixes in here. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
@@ -633,14 +633,6 @@ config USB_UHCI_ASPEED
|
||||
bool
|
||||
default y if ARCH_ASPEED
|
||||
|
||||
config USB_UHCI_BIG_ENDIAN_MMIO
|
||||
bool
|
||||
default y if SPARC_LEON
|
||||
|
||||
config USB_UHCI_BIG_ENDIAN_DESC
|
||||
bool
|
||||
default y if SPARC_LEON
|
||||
|
||||
config USB_FHCI_HCD
|
||||
tristate "Freescale QE USB Host Controller support"
|
||||
depends on OF_GPIO && QE_GPIO && QUICC_ENGINE
|
||||
|
@@ -774,12 +774,12 @@ static struct urb *request_single_step_set_feature_urb(
|
||||
atomic_inc(&urb->use_count);
|
||||
atomic_inc(&urb->dev->urbnum);
|
||||
urb->setup_dma = dma_map_single(
|
||||
hcd->self.controller,
|
||||
hcd->self.sysdev,
|
||||
urb->setup_packet,
|
||||
sizeof(struct usb_ctrlrequest),
|
||||
DMA_TO_DEVICE);
|
||||
urb->transfer_dma = dma_map_single(
|
||||
hcd->self.controller,
|
||||
hcd->self.sysdev,
|
||||
urb->transfer_buffer,
|
||||
urb->transfer_buffer_length,
|
||||
DMA_FROM_DEVICE);
|
||||
|
@@ -1188,10 +1188,10 @@ static int submit_single_step_set_feature(
|
||||
* 15 secs after the setup
|
||||
*/
|
||||
if (is_setup) {
|
||||
/* SETUP pid */
|
||||
/* SETUP pid, and interrupt after SETUP completion */
|
||||
qtd_fill(ehci, qtd, urb->setup_dma,
|
||||
sizeof(struct usb_ctrlrequest),
|
||||
token | (2 /* "setup" */ << 8), 8);
|
||||
QTD_IOC | token | (2 /* "setup" */ << 8), 8);
|
||||
|
||||
submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
|
||||
return 0; /*Return now; we shall come back after 15 seconds*/
|
||||
@@ -1228,12 +1228,8 @@ static int submit_single_step_set_feature(
|
||||
qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
|
||||
list_add_tail(&qtd->qtd_list, head);
|
||||
|
||||
/* dont fill any data in such packets */
|
||||
qtd_fill(ehci, qtd, 0, 0, token, 0);
|
||||
|
||||
/* by default, enable interrupt on urb completion */
|
||||
if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
|
||||
qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
|
||||
/* Interrupt after STATUS completion */
|
||||
qtd_fill(ehci, qtd, 0, 0, token | QTD_IOC, 0);
|
||||
|
||||
submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
|
||||
|
||||
|
@@ -74,6 +74,7 @@ static const char hcd_name [] = "ohci_hcd";
|
||||
|
||||
#define STATECHANGE_DELAY msecs_to_jiffies(300)
|
||||
#define IO_WATCHDOG_DELAY msecs_to_jiffies(275)
|
||||
#define IO_WATCHDOG_OFF 0xffffff00
|
||||
|
||||
#include "ohci.h"
|
||||
#include "pci-quirks.h"
|
||||
@@ -231,7 +232,7 @@ static int ohci_urb_enqueue (
|
||||
}
|
||||
|
||||
/* Start up the I/O watchdog timer, if it's not running */
|
||||
if (!timer_pending(&ohci->io_watchdog) &&
|
||||
if (ohci->prev_frame_no == IO_WATCHDOG_OFF &&
|
||||
list_empty(&ohci->eds_in_use) &&
|
||||
!(ohci->flags & OHCI_QUIRK_QEMU)) {
|
||||
ohci->prev_frame_no = ohci_frame_no(ohci);
|
||||
@@ -501,6 +502,7 @@ static int ohci_init (struct ohci_hcd *ohci)
|
||||
return 0;
|
||||
|
||||
timer_setup(&ohci->io_watchdog, io_watchdog_func, 0);
|
||||
ohci->prev_frame_no = IO_WATCHDOG_OFF;
|
||||
|
||||
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
|
||||
sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL);
|
||||
@@ -730,7 +732,7 @@ static void io_watchdog_func(struct timer_list *t)
|
||||
u32 head;
|
||||
struct ed *ed;
|
||||
struct td *td, *td_start, *td_next;
|
||||
unsigned frame_no;
|
||||
unsigned frame_no, prev_frame_no = IO_WATCHDOG_OFF;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ohci->lock, flags);
|
||||
@@ -835,7 +837,7 @@ static void io_watchdog_func(struct timer_list *t)
|
||||
}
|
||||
}
|
||||
if (!list_empty(&ohci->eds_in_use)) {
|
||||
ohci->prev_frame_no = frame_no;
|
||||
prev_frame_no = frame_no;
|
||||
ohci->prev_wdh_cnt = ohci->wdh_cnt;
|
||||
ohci->prev_donehead = ohci_readl(ohci,
|
||||
&ohci->regs->donehead);
|
||||
@@ -845,6 +847,7 @@ static void io_watchdog_func(struct timer_list *t)
|
||||
}
|
||||
|
||||
done:
|
||||
ohci->prev_frame_no = prev_frame_no;
|
||||
spin_unlock_irqrestore(&ohci->lock, flags);
|
||||
}
|
||||
|
||||
@@ -973,6 +976,7 @@ static void ohci_stop (struct usb_hcd *hcd)
|
||||
if (quirk_nec(ohci))
|
||||
flush_work(&ohci->nec_work);
|
||||
del_timer_sync(&ohci->io_watchdog);
|
||||
ohci->prev_frame_no = IO_WATCHDOG_OFF;
|
||||
|
||||
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
||||
ohci_usb_reset(ohci);
|
||||
|
@@ -311,8 +311,10 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
|
||||
rc = ohci_rh_suspend (ohci, 0);
|
||||
spin_unlock_irq (&ohci->lock);
|
||||
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
del_timer_sync(&ohci->io_watchdog);
|
||||
ohci->prev_frame_no = IO_WATCHDOG_OFF;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@@ -1019,6 +1019,8 @@ skip_ed:
|
||||
* have modified this list. normally it's just prepending
|
||||
* entries (which we'd ignore), but paranoia won't hurt.
|
||||
*/
|
||||
*last = ed->ed_next;
|
||||
ed->ed_next = NULL;
|
||||
modified = 0;
|
||||
|
||||
/* unlink urbs as requested, but rescan the list after
|
||||
@@ -1077,21 +1079,22 @@ rescan_this:
|
||||
goto rescan_this;
|
||||
|
||||
/*
|
||||
* If no TDs are queued, take ED off the ed_rm_list.
|
||||
* If no TDs are queued, ED is now idle.
|
||||
* Otherwise, if the HC is running, reschedule.
|
||||
* If not, leave it on the list for further dequeues.
|
||||
* If the HC isn't running, add ED back to the
|
||||
* start of the list for later processing.
|
||||
*/
|
||||
if (list_empty(&ed->td_list)) {
|
||||
*last = ed->ed_next;
|
||||
ed->ed_next = NULL;
|
||||
ed->state = ED_IDLE;
|
||||
list_del(&ed->in_use_list);
|
||||
} else if (ohci->rh_state == OHCI_RH_RUNNING) {
|
||||
*last = ed->ed_next;
|
||||
ed->ed_next = NULL;
|
||||
ed_schedule(ohci, ed);
|
||||
} else {
|
||||
last = &ed->ed_next;
|
||||
ed->ed_next = ohci->ed_rm_list;
|
||||
ohci->ed_rm_list = ed;
|
||||
/* Don't loop on the same ED */
|
||||
if (last == &ohci->ed_rm_list)
|
||||
last = &ed->ed_next;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
|
@@ -66,6 +66,23 @@
|
||||
#define AX_INDXC 0x30
|
||||
#define AX_DATAC 0x34
|
||||
|
||||
#define PT_ADDR_INDX 0xE8
|
||||
#define PT_READ_INDX 0xE4
|
||||
#define PT_SIG_1_ADDR 0xA520
|
||||
#define PT_SIG_2_ADDR 0xA521
|
||||
#define PT_SIG_3_ADDR 0xA522
|
||||
#define PT_SIG_4_ADDR 0xA523
|
||||
#define PT_SIG_1_DATA 0x78
|
||||
#define PT_SIG_2_DATA 0x56
|
||||
#define PT_SIG_3_DATA 0x34
|
||||
#define PT_SIG_4_DATA 0x12
|
||||
#define PT4_P1_REG 0xB521
|
||||
#define PT4_P2_REG 0xB522
|
||||
#define PT2_P1_REG 0xD520
|
||||
#define PT2_P2_REG 0xD521
|
||||
#define PT1_P1_REG 0xD522
|
||||
#define PT1_P2_REG 0xD523
|
||||
|
||||
#define NB_PCIE_INDX_ADDR 0xe0
|
||||
#define NB_PCIE_INDX_DATA 0xe4
|
||||
#define PCIE_P_CNTL 0x10040
|
||||
@@ -512,6 +529,98 @@ void usb_amd_dev_put(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_amd_dev_put);
|
||||
|
||||
/*
|
||||
* Check if port is disabled in BIOS on AMD Promontory host.
|
||||
* BIOS Disabled ports may wake on connect/disconnect and need
|
||||
* driver workaround to keep them disabled.
|
||||
* Returns true if port is marked disabled.
|
||||
*/
|
||||
bool usb_amd_pt_check_port(struct device *device, int port)
|
||||
{
|
||||
unsigned char value, port_shift;
|
||||
struct pci_dev *pdev;
|
||||
u16 reg;
|
||||
|
||||
pdev = to_pci_dev(device);
|
||||
pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_1_ADDR);
|
||||
|
||||
pci_read_config_byte(pdev, PT_READ_INDX, &value);
|
||||
if (value != PT_SIG_1_DATA)
|
||||
return false;
|
||||
|
||||
pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_2_ADDR);
|
||||
|
||||
pci_read_config_byte(pdev, PT_READ_INDX, &value);
|
||||
if (value != PT_SIG_2_DATA)
|
||||
return false;
|
||||
|
||||
pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_3_ADDR);
|
||||
|
||||
pci_read_config_byte(pdev, PT_READ_INDX, &value);
|
||||
if (value != PT_SIG_3_DATA)
|
||||
return false;
|
||||
|
||||
pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_4_ADDR);
|
||||
|
||||
pci_read_config_byte(pdev, PT_READ_INDX, &value);
|
||||
if (value != PT_SIG_4_DATA)
|
||||
return false;
|
||||
|
||||
/* Check disabled port setting, if bit is set port is enabled */
|
||||
switch (pdev->device) {
|
||||
case 0x43b9:
|
||||
case 0x43ba:
|
||||
/*
|
||||
* device is AMD_PROMONTORYA_4(0x43b9) or PROMONTORYA_3(0x43ba)
|
||||
* PT4_P1_REG bits[7..1] represents USB2.0 ports 6 to 0
|
||||
* PT4_P2_REG bits[6..0] represents ports 13 to 7
|
||||
*/
|
||||
if (port > 6) {
|
||||
reg = PT4_P2_REG;
|
||||
port_shift = port - 7;
|
||||
} else {
|
||||
reg = PT4_P1_REG;
|
||||
port_shift = port + 1;
|
||||
}
|
||||
break;
|
||||
case 0x43bb:
|
||||
/*
|
||||
* device is AMD_PROMONTORYA_2(0x43bb)
|
||||
* PT2_P1_REG bits[7..5] represents USB2.0 ports 2 to 0
|
||||
* PT2_P2_REG bits[5..0] represents ports 9 to 3
|
||||
*/
|
||||
if (port > 2) {
|
||||
reg = PT2_P2_REG;
|
||||
port_shift = port - 3;
|
||||
} else {
|
||||
reg = PT2_P1_REG;
|
||||
port_shift = port + 5;
|
||||
}
|
||||
break;
|
||||
case 0x43bc:
|
||||
/*
|
||||
* device is AMD_PROMONTORYA_1(0x43bc)
|
||||
* PT1_P1_REG[7..4] represents USB2.0 ports 3 to 0
|
||||
* PT1_P2_REG[5..0] represents ports 9 to 4
|
||||
*/
|
||||
if (port > 3) {
|
||||
reg = PT1_P2_REG;
|
||||
port_shift = port - 4;
|
||||
} else {
|
||||
reg = PT1_P1_REG;
|
||||
port_shift = port + 4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
pci_write_config_word(pdev, PT_ADDR_INDX, reg);
|
||||
pci_read_config_byte(pdev, PT_READ_INDX, &value);
|
||||
|
||||
return !(value & BIT(port_shift));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
|
||||
|
||||
/*
|
||||
* Make sure the controller is completely inactive, unable to
|
||||
* generate interrupts or do DMA.
|
||||
|
@@ -17,6 +17,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
|
||||
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
|
||||
void sb800_prefetch(struct device *dev, int on);
|
||||
bool usb_xhci_needs_pci_reset(struct pci_dev *pdev);
|
||||
bool usb_amd_pt_check_port(struct device *device, int port);
|
||||
#else
|
||||
struct pci_dev;
|
||||
static inline void usb_amd_quirk_pll_disable(void) {}
|
||||
@@ -25,6 +26,10 @@ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
|
||||
static inline void usb_amd_dev_put(void) {}
|
||||
static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
|
||||
static inline void sb800_prefetch(struct device *dev, int on) {}
|
||||
static inline bool usb_amd_pt_check_port(struct device *device, int port)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_USB_PCI */
|
||||
|
||||
#endif /* __LINUX_USB_PCI_QUIRKS_H */
|
||||
|
@@ -211,7 +211,7 @@ static void xhci_ring_dump_segment(struct seq_file *s,
|
||||
static int xhci_ring_trb_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
int i;
|
||||
struct xhci_ring *ring = s->private;
|
||||
struct xhci_ring *ring = *(struct xhci_ring **)s->private;
|
||||
struct xhci_segment *seg = ring->first_seg;
|
||||
|
||||
for (i = 0; i < ring->num_segs; i++) {
|
||||
@@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
|
||||
|
||||
snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
|
||||
epriv->root = xhci_debugfs_create_ring_dir(xhci,
|
||||
&dev->eps[ep_index].new_ring,
|
||||
&dev->eps[ep_index].ring,
|
||||
epriv->name,
|
||||
spriv->root);
|
||||
spriv->eps[ep_index] = epriv;
|
||||
|
@@ -1224,17 +1224,17 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
temp = readl(port_array[wIndex]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Software should not attempt to set
|
||||
* port link state above '3' (U3) and the port
|
||||
* must be enabled.
|
||||
*/
|
||||
if ((temp & PORT_PE) == 0 ||
|
||||
(link_state > USB_SS_PORT_LS_U3)) {
|
||||
xhci_warn(xhci, "Cannot set link state.\n");
|
||||
/* Port must be enabled */
|
||||
if (!(temp & PORT_PE)) {
|
||||
retval = -ENODEV;
|
||||
break;
|
||||
}
|
||||
/* Can't set port link state above '3' (U3) */
|
||||
if (link_state > USB_SS_PORT_LS_U3) {
|
||||
xhci_warn(xhci, "Cannot set port %d link state %d\n",
|
||||
wIndex, link_state);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (link_state == USB_SS_PORT_LS_U3) {
|
||||
slot_id = xhci_find_slot_id_by_port(hcd, xhci,
|
||||
wIndex + 1);
|
||||
@@ -1522,6 +1522,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
|
||||
t2 |= PORT_WKOC_E | PORT_WKCONN_E;
|
||||
t2 &= ~PORT_WKDISC_E;
|
||||
}
|
||||
|
||||
if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
|
||||
(hcd->speed < HCD_USB3)) {
|
||||
if (usb_amd_pt_check_port(hcd->self.controller,
|
||||
port_index))
|
||||
t2 &= ~PORT_WAKE_BITS;
|
||||
}
|
||||
} else
|
||||
t2 &= ~PORT_WAKE_BITS;
|
||||
|
||||
|
@@ -42,6 +42,10 @@
|
||||
#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
|
||||
#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0
|
||||
|
||||
#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
|
||||
#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
|
||||
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
|
||||
#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
|
||||
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
|
||||
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
@@ -125,6 +129,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_AMD)
|
||||
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
|
||||
if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
|
||||
((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
|
||||
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
|
||||
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
|
||||
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
|
||||
xhci->quirks |= XHCI_U2_DISABLE_WAKE;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
xhci->quirks |= XHCI_LPM_SUPPORT;
|
||||
xhci->quirks |= XHCI_INTEL_HOST;
|
||||
|
@@ -646,8 +646,6 @@ static void xhci_stop(struct usb_hcd *hcd)
|
||||
return;
|
||||
}
|
||||
|
||||
xhci_debugfs_exit(xhci);
|
||||
|
||||
xhci_dbc_exit(xhci);
|
||||
|
||||
spin_lock_irq(&xhci->lock);
|
||||
@@ -680,6 +678,7 @@ static void xhci_stop(struct usb_hcd *hcd)
|
||||
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory");
|
||||
xhci_mem_cleanup(xhci);
|
||||
xhci_debugfs_exit(xhci);
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
||||
"xhci_stop completed - status = %x",
|
||||
readl(&xhci->op_regs->status));
|
||||
@@ -1014,6 +1013,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
|
||||
xhci_dbg(xhci, "cleaning up memory\n");
|
||||
xhci_mem_cleanup(xhci);
|
||||
xhci_debugfs_exit(xhci);
|
||||
xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
|
||||
readl(&xhci->op_regs->status));
|
||||
|
||||
@@ -3544,12 +3544,10 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING;
|
||||
del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
|
||||
}
|
||||
|
||||
xhci_debugfs_remove_slot(xhci, udev->slot_id);
|
||||
ret = xhci_disable_slot(xhci, udev->slot_id);
|
||||
if (ret) {
|
||||
xhci_debugfs_remove_slot(xhci, udev->slot_id);
|
||||
if (ret)
|
||||
xhci_free_virt_device(xhci, udev->slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
|
||||
|
@@ -1822,7 +1822,7 @@ struct xhci_hcd {
|
||||
/* For controller with a broken Port Disable implementation */
|
||||
#define XHCI_BROKEN_PORT_PED (1 << 25)
|
||||
#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
|
||||
/* Reserved. It was XHCI_U2_DISABLE_WAKE */
|
||||
#define XHCI_U2_DISABLE_WAKE (1 << 27)
|
||||
#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28)
|
||||
#define XHCI_HW_LPM_DISABLE (1 << 29)
|
||||
|
||||
|
Reference in New Issue
Block a user