Merge branch 'origin' into for-linus

Conflicts:
	MAINTAINERS
This commit is contained in:
Russell King
2009-09-24 21:22:33 +01:00
bovenliggende ae19ffbadc 94e0fb086f
commit baea7b946f
3418 gewijzigde bestanden met toevoegingen van 295792 en 97045 verwijderingen

Bestand weergeven

@@ -113,6 +113,12 @@ config USB_EHCI_HCD_PPC_OF
Enables support for the USB controller present on the PowerPC
OpenFirmware platform bus.
config USB_W90X900_EHCI
bool "W90X900(W90P910) EHCI support"
depends on USB_EHCI_HCD && ARCH_W90X900
---help---
Enables support for the W90X900 USB controller
config USB_OXU210HP_HCD
tristate "OXU210HP HCD support"
depends on USB
@@ -153,6 +159,18 @@ config USB_ISP1760_HCD
To compile this driver as a module, choose M here: the
module will be called isp1760.
config USB_ISP1362_HCD
tristate "ISP1362 HCD support"
depends on USB
default N
---help---
Supports the Philips ISP1362 chip as a host controller
This driver does not support isochronous transfers.
To compile this driver as a module, choose M here: the
module will be called isp1362-hcd.
config USB_OHCI_HCD
tristate "OHCI HCD support"
depends on USB && USB_ARCH_HAS_OHCI
@@ -336,13 +354,6 @@ config USB_R8A66597_HCD
To compile this driver as a module, choose M here: the
module will be called r8a66597-hcd.
config SUPERH_ON_CHIP_R8A66597
boolean "Enable SuperH on-chip R8A66597 USB"
depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
help
This driver enables support for the on-chip R8A66597 in the
SH7366, SH7723 and SH7724 processors.
config USB_WHCI_HCD
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
depends on EXPERIMENTAL

Bestand weergeven

@@ -21,6 +21,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_FHCI_HCD) += fhci.o

Bestand weergeven

@@ -0,0 +1,230 @@
/*
* Driver for EHCI UHP on Atmel chips
*
* Copyright (C) 2009 Atmel Corporation,
* Nicolas Ferre <nicolas.ferre@atmel.com>
*
* Based on various ehci-*.c drivers
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/clk.h>
#include <linux/platform_device.h>
/* interface and function clocks */
static struct clk *iclk, *fclk;
static int clocked;
/*-------------------------------------------------------------------------*/
static void atmel_start_clock(void)
{
clk_enable(iclk);
clk_enable(fclk);
clocked = 1;
}
static void atmel_stop_clock(void)
{
clk_disable(fclk);
clk_disable(iclk);
clocked = 0;
}
static void atmel_start_ehci(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "start\n");
atmel_start_clock();
}
static void atmel_stop_ehci(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "stop\n");
atmel_stop_clock();
}
/*-------------------------------------------------------------------------*/
static int ehci_atmel_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval = 0;
/* registers start at offset 0x0 */
ehci->caps = hcd->regs;
ehci->regs = hcd->regs +
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
dbg_hcs_params(ehci, "reset");
dbg_hcc_params(ehci, "reset");
/* cache this readonly data; minimize chip reads */
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
retval = ehci_halt(ehci);
if (retval)
return retval;
/* data structure init */
retval = ehci_init(hcd);
if (retval)
return retval;
ehci->sbrn = 0x20;
ehci_reset(ehci);
ehci_port_power(ehci, 0);
return retval;
}
static const struct hc_driver ehci_atmel_hc_driver = {
.description = hcd_name,
.product_desc = "Atmel EHCI UHP HS",
.hcd_priv_size = sizeof(struct ehci_hcd),
/* generic hardware linkage */
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2,
/* basic lifecycle operations */
.reset = ehci_atmel_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
/* managing i/o requests and associated device resources */
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
/* scheduling support */
.get_frame_number = ehci_get_frame,
/* root hub support */
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
};
static int __init ehci_atmel_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
const struct hc_driver *driver = &ehci_atmel_hc_driver;
struct resource *res;
int irq;
int retval;
if (usb_disabled())
return -ENODEV;
pr_debug("Initializing Atmel-SoC USB Host Controller\n");
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(&pdev->dev,
"Found HC with no IRQ. Check %s setup!\n",
dev_name(&pdev->dev));
retval = -ENODEV;
goto fail_create_hcd;
}
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
retval = -ENOMEM;
goto fail_create_hcd;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev,
"Found HC with no register addr. Check %s setup!\n",
dev_name(&pdev->dev));
retval = -ENODEV;
goto fail_request_resource;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = res->end - res->start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
retval = -EBUSY;
goto fail_request_resource;
}
hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
dev_dbg(&pdev->dev, "error mapping memory\n");
retval = -EFAULT;
goto fail_ioremap;
}
iclk = clk_get(&pdev->dev, "ehci_clk");
if (IS_ERR(iclk)) {
dev_err(&pdev->dev, "Error getting interface clock\n");
retval = -ENOENT;
goto fail_get_iclk;
}
fclk = clk_get(&pdev->dev, "uhpck");
if (IS_ERR(fclk)) {
dev_err(&pdev->dev, "Error getting function clock\n");
retval = -ENOENT;
goto fail_get_fclk;
}
atmel_start_ehci(pdev);
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (retval)
goto fail_add_hcd;
return retval;
fail_add_hcd:
atmel_stop_ehci(pdev);
clk_put(fclk);
fail_get_fclk:
clk_put(iclk);
fail_get_iclk:
iounmap(hcd->regs);
fail_ioremap:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
fail_request_resource:
usb_put_hcd(hcd);
fail_create_hcd:
dev_err(&pdev->dev, "init %s fail, %d\n",
dev_name(&pdev->dev), retval);
return retval;
}
static int __exit ehci_atmel_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
ehci_shutdown(hcd);
usb_remove_hcd(hcd);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
atmel_stop_ehci(pdev);
clk_put(fclk);
clk_put(iclk);
fclk = iclk = NULL;
return 0;
}
static struct platform_driver ehci_atmel_driver = {
.probe = ehci_atmel_drv_probe,
.remove = __exit_p(ehci_atmel_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
.driver.name = "atmel-ehci",
};

Bestand weergeven

@@ -199,10 +199,9 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
static int ehci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
pm_message_t message)
static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned long flags;
int rc;
@@ -229,12 +228,6 @@ static int ehci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable);
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW) {
ehci_halt(ehci);
ehci_reset(ehci);
}
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
au1xxx_stop_ehc();
@@ -248,10 +241,9 @@ bail:
return rc;
}
static int ehci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
au1xxx_start_ehc();
@@ -305,20 +297,25 @@ static int ehci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
return 0;
}
static struct dev_pm_ops au1xxx_ehci_pmops = {
.suspend = ehci_hcd_au1xxx_drv_suspend,
.resume = ehci_hcd_au1xxx_drv_resume,
};
#define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops
#else
#define ehci_hcd_au1xxx_drv_suspend NULL
#define ehci_hcd_au1xxx_drv_resume NULL
#define AU1XXX_EHCI_PMOPS NULL
#endif
static struct platform_driver ehci_hcd_au1xxx_driver = {
.probe = ehci_hcd_au1xxx_drv_probe,
.remove = ehci_hcd_au1xxx_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ehci_hcd_au1xxx_drv_suspend,
.resume = ehci_hcd_au1xxx_drv_resume,
.driver = {
.name = "au1xxx-ehci",
.owner = THIS_MODULE,
.pm = AU1XXX_EHCI_PMOPS,
}
};

Bestand weergeven

@@ -134,10 +134,11 @@ dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
static void __maybe_unused
dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
{
struct ehci_qh_hw *hw = qh->hw;
ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
qh, qh->hw_next, qh->hw_info1, qh->hw_info2,
qh->hw_current);
dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
}
static void __maybe_unused
@@ -400,31 +401,32 @@ static void qh_lines (
char *next = *nextp;
char mark;
__le32 list_end = EHCI_LIST_END(ehci);
struct ehci_qh_hw *hw = qh->hw;
if (qh->hw_qtd_next == list_end) /* NEC does this */
if (hw->hw_qtd_next == list_end) /* NEC does this */
mark = '@';
else
mark = token_mark(ehci, qh->hw_token);
mark = token_mark(ehci, hw->hw_token);
if (mark == '/') { /* qh_alt_next controls qh advance? */
if ((qh->hw_alt_next & QTD_MASK(ehci))
== ehci->async->hw_alt_next)
if ((hw->hw_alt_next & QTD_MASK(ehci))
== ehci->async->hw->hw_alt_next)
mark = '#'; /* blocked */
else if (qh->hw_alt_next == list_end)
else if (hw->hw_alt_next == list_end)
mark = '.'; /* use hw_qtd_next */
/* else alt_next points to some other qtd */
}
scratch = hc32_to_cpup(ehci, &qh->hw_info1);
hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &qh->hw_current) : 0;
scratch = hc32_to_cpup(ehci, &hw->hw_info1);
hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
temp = scnprintf (next, size,
"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
qh, scratch & 0x007f,
speed_char (scratch),
(scratch >> 8) & 0x000f,
scratch, hc32_to_cpup(ehci, &qh->hw_info2),
hc32_to_cpup(ehci, &qh->hw_token), mark,
(cpu_to_hc32(ehci, QTD_TOGGLE) & qh->hw_token)
scratch, hc32_to_cpup(ehci, &hw->hw_info2),
hc32_to_cpup(ehci, &hw->hw_token), mark,
(cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token)
? "data1" : "data0",
(hc32_to_cpup(ehci, &qh->hw_alt_next) >> 1) & 0x0f);
(hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f);
size -= temp;
next += temp;
@@ -435,10 +437,10 @@ static void qh_lines (
mark = ' ';
if (hw_curr == td->qtd_dma)
mark = '*';
else if (qh->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma))
else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma))
mark = '+';
else if (QTD_LENGTH (scratch)) {
if (td->hw_alt_next == ehci->async->hw_alt_next)
if (td->hw_alt_next == ehci->async->hw->hw_alt_next)
mark = '#';
else if (td->hw_alt_next != list_end)
mark = '/';
@@ -550,12 +552,15 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
next += temp;
do {
struct ehci_qh_hw *hw;
switch (hc32_to_cpu(ehci, tag)) {
case Q_TYPE_QH:
hw = p.qh->hw;
temp = scnprintf (next, size, " qh%d-%04x/%p",
p.qh->period,
hc32_to_cpup(ehci,
&p.qh->hw_info2)
&hw->hw_info2)
/* uframe masks */
& (QH_CMASK | QH_SMASK),
p.qh);
@@ -576,7 +581,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
/* show more info the first time around */
if (temp == seen_count) {
u32 scratch = hc32_to_cpup(ehci,
&p.qh->hw_info1);
&hw->hw_info1);
struct ehci_qtd *qtd;
char *type = "";
@@ -609,7 +614,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
} else
temp = 0;
if (p.qh) {
tag = Q_NEXT_TYPE(ehci, p.qh->hw_next);
tag = Q_NEXT_TYPE(ehci, hw->hw_next);
p = p.qh->qh_next;
}
break;
@@ -879,8 +884,7 @@ static int debug_close(struct inode *inode, struct file *file)
struct debug_buffer *buf = file->private_data;
if (buf) {
if (buf->output_buf)
vfree(buf->output_buf);
vfree(buf->output_buf);
kfree(buf);
}

Bestand weergeven

@@ -30,7 +30,6 @@
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
@@ -127,6 +126,8 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
switch (action) {
case TIMER_IO_WATCHDOG:
if (!ehci->need_io_watchdog)
return;
t = EHCI_IO_JIFFIES;
break;
case TIMER_ASYNC_OFF:
@@ -239,6 +240,11 @@ static int ehci_reset (struct ehci_hcd *ehci)
int retval;
u32 command = ehci_readl(ehci, &ehci->regs->command);
/* If the EHCI debug controller is active, special care must be
* taken before and after a host controller reset */
if (ehci->debug && !dbgp_reset_prep())
ehci->debug = NULL;
command |= CMD_RESET;
dbg_cmd (ehci, "reset", command);
ehci_writel(ehci, command, &ehci->regs->command);
@@ -247,12 +253,21 @@ static int ehci_reset (struct ehci_hcd *ehci)
retval = handshake (ehci, &ehci->regs->command,
CMD_RESET, 0, 250 * 1000);
if (ehci->has_hostpc) {
ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS,
(u32 __iomem *)(((u8 *)ehci->regs) + USBMODE_EX));
ehci_writel(ehci, TXFIFO_DEFAULT,
(u32 __iomem *)(((u8 *)ehci->regs) + TXFILLTUNING));
}
if (retval)
return retval;
if (ehci_is_TDI(ehci))
tdi_reset (ehci);
if (ehci->debug)
dbgp_external_startup();
return retval;
}
@@ -505,9 +520,14 @@ static int ehci_init(struct usb_hcd *hcd)
u32 temp;
int retval;
u32 hcc_params;
struct ehci_qh_hw *hw;
spin_lock_init(&ehci->lock);
/*
* keep io watchdog by default, those good HCDs could turn off it later
*/
ehci->need_io_watchdog = 1;
init_timer(&ehci->watchdog);
ehci->watchdog.function = ehci_watchdog;
ehci->watchdog.data = (unsigned long) ehci;
@@ -544,12 +564,13 @@ static int ehci_init(struct usb_hcd *hcd)
* from automatically advancing to the next td after short reads.
*/
ehci->async->qh_next.qh = NULL;
ehci->async->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);
ehci->async->hw_info1 = cpu_to_hc32(ehci, QH_HEAD);
ehci->async->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
ehci->async->hw_qtd_next = EHCI_LIST_END(ehci);
hw = ehci->async->hw;
hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);
hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD);
hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
hw->hw_qtd_next = EHCI_LIST_END(ehci);
ehci->async->qh_state = QH_STATE_LINKED;
ehci->async->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
hw->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
/* clear interrupt enables, set irq latency */
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
@@ -850,12 +871,18 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim)
end_unlink_async(ehci);
/* if it's not linked then there's nothing to do */
if (qh->qh_state != QH_STATE_LINKED)
;
/* If the QH isn't linked then there's nothing we can do
* unless we were called during a giveback, in which case
* qh_completions() has to deal with it.
*/
if (qh->qh_state != QH_STATE_LINKED) {
if (qh->qh_state == QH_STATE_COMPLETING)
qh->needs_rescan = 1;
return;
}
/* defer till later if busy */
else if (ehci->reclaim) {
if (ehci->reclaim) {
struct ehci_qh *last;
for (last = ehci->reclaim;
@@ -915,8 +942,9 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
break;
switch (qh->qh_state) {
case QH_STATE_LINKED:
case QH_STATE_COMPLETING:
intr_deschedule (ehci, qh);
/* FALL THROUGH */
break;
case QH_STATE_IDLE:
qh_completions (ehci, qh);
break;
@@ -925,23 +953,6 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
qh, qh->qh_state);
goto done;
}
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
&& HC_IS_RUNNING (hcd->state)) {
rc = qh_schedule(ehci, qh);
/* An error here likely indicates handshake failure
* or no space left in the schedule. Neither fault
* should happen often ...
*
* FIXME kill the now-dysfunctional queued urbs
*/
if (rc != 0)
ehci_err(ehci,
"can't reschedule qh %p, err %d",
qh, rc);
}
break;
case PIPE_ISOCHRONOUS:
@@ -979,7 +990,7 @@ rescan:
/* endpoints can be iso streams. for now, we don't
* accelerate iso completions ... so spin a while.
*/
if (qh->hw_info1 == 0) {
if (qh->hw->hw_info1 == 0) {
ehci_vdbg (ehci, "iso delay\n");
goto idle_timeout;
}
@@ -988,6 +999,7 @@ rescan:
qh->qh_state = QH_STATE_IDLE;
switch (qh->qh_state) {
case QH_STATE_LINKED:
case QH_STATE_COMPLETING:
for (tmp = ehci->async->qh_next.qh;
tmp && tmp != qh;
tmp = tmp->qh_next.qh)
@@ -1052,18 +1064,17 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
usb_settoggle(qh->dev, epnum, is_out, 0);
if (!list_empty(&qh->qtd_list)) {
WARN_ONCE(1, "clear_halt for a busy endpoint\n");
} else if (qh->qh_state == QH_STATE_LINKED) {
} else if (qh->qh_state == QH_STATE_LINKED ||
qh->qh_state == QH_STATE_COMPLETING) {
/* The toggle value in the QH can't be updated
* while the QH is active. Unlink it now;
* re-linking will call qh_refresh().
*/
if (eptype == USB_ENDPOINT_XFER_BULK) {
if (eptype == USB_ENDPOINT_XFER_BULK)
unlink_async(ehci, qh);
} else {
else
intr_deschedule(ehci, qh);
(void) qh_schedule(ehci, qh);
}
}
}
spin_unlock_irqrestore(&ehci->lock, flags);
@@ -1117,6 +1128,16 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ixp4xx_ehci_driver
#endif
#ifdef CONFIG_USB_W90X900_EHCI
#include "ehci-w90x900.c"
#define PLATFORM_DRIVER ehci_hcd_w90x900_driver
#endif
#ifdef CONFIG_ARCH_AT91
#include "ehci-atmel.c"
#define PLATFORM_DRIVER ehci_atmel_driver
#endif
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"

Bestand weergeven

@@ -111,6 +111,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int port;
int mask;
u32 __iomem *hostpc_reg = NULL;
ehci_dbg(ehci, "suspend root hub\n");
@@ -142,6 +143,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
u32 t2 = t1;
if (ehci->has_hostpc)
hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
+ HOSTPC0 + 4 * (port & 0xff));
/* keep track of which ports we suspend */
if (t1 & PORT_OWNER)
set_bit(port, &ehci->owned_ports);
@@ -151,15 +155,37 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
}
/* enable remote wakeup on all ports */
if (hcd->self.root_hub->do_remote_wakeup)
t2 |= PORT_WAKE_BITS;
else
if (hcd->self.root_hub->do_remote_wakeup) {
/* only enable appropriate wake bits, otherwise the
* hardware can not go phy low power mode. If a race
* condition happens here(connection change during bits
* set), the port change detection will finally fix it.
*/
if (t1 & PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 &= ~PORT_WKCONN_E;
} else {
t2 |= PORT_WKOC_E | PORT_WKCONN_E;
t2 &= ~PORT_WKDISC_E;
}
} else
t2 &= ~PORT_WAKE_BITS;
if (t1 != t2) {
ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
port + 1, t1, t2);
ehci_writel(ehci, t2, reg);
if (hostpc_reg) {
u32 t3;
msleep(5);/* 5ms for HCD enter low pwr mode */
t3 = ehci_readl(ehci, hostpc_reg);
ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
t3 = ehci_readl(ehci, hostpc_reg);
ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
port, (t3 & HOSTPC_PHCD) ?
"succeeded" : "failed");
}
}
}
@@ -183,6 +209,11 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
spin_unlock_irq (&ehci->lock);
/* ehci_work() may have re-enabled the watchdog timer, which we do not
* want, and so we must delete any pending watchdog timer events.
*/
del_timer_sync(&ehci->watchdog);
return 0;
}
@@ -204,6 +235,13 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
return -ESHUTDOWN;
}
if (unlikely(ehci->debug)) {
if (ehci->debug && !dbgp_reset_prep())
ehci->debug = NULL;
else
dbgp_external_startup();
}
/* Ideally and we've got a real resume here, and no port's power
* was lost. (For PCI, that means Vaux was maintained.) But we
* could instead be restoring a swsusp snapshot -- so that BIOS was
@@ -563,7 +601,8 @@ static int ehci_hub_control (
int ports = HCS_N_PORTS (ehci->hcs_params);
u32 __iomem *status_reg = &ehci->regs->port_status[
(wIndex & 0xff) - 1];
u32 temp, status;
u32 __iomem *hostpc_reg = NULL;
u32 temp, temp1, status;
unsigned long flags;
int retval = 0;
unsigned selector;
@@ -575,6 +614,9 @@ static int ehci_hub_control (
* power, "this is the one", etc. EHCI spec supports this.
*/
if (ehci->has_hostpc)
hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
+ HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
spin_lock_irqsave (&ehci->lock, flags);
switch (typeReq) {
case ClearHubFeature:
@@ -773,7 +815,11 @@ static int ehci_hub_control (
if (temp & PORT_CONNECT) {
status |= 1 << USB_PORT_FEAT_CONNECTION;
// status may be from integrated TT
status |= ehci_port_speed(ehci, temp);
if (ehci->has_hostpc) {
temp1 = ehci_readl(ehci, hostpc_reg);
status |= ehci_port_speed(ehci, temp1);
} else
status |= ehci_port_speed(ehci, temp);
}
if (temp & PORT_PE)
status |= 1 << USB_PORT_FEAT_ENABLE;
@@ -816,6 +862,15 @@ static int ehci_hub_control (
case SetPortFeature:
selector = wIndex >> 8;
wIndex &= 0xff;
if (unlikely(ehci->debug)) {
/* If the debug port is active any port
* feature requests should get denied */
if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
(readl(&ehci->debug->control) & DBGP_ENABLED)) {
retval = -ENODEV;
goto error_exit;
}
}
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
@@ -832,6 +887,24 @@ static int ehci_hub_control (
|| (temp & PORT_RESET) != 0)
goto error;
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
/* After above check the port must be connected.
* Set appropriate bit thus could put phy into low power
* mode if we have hostpc feature
*/
if (hostpc_reg) {
temp &= ~PORT_WKCONN_E;
temp |= (PORT_WKDISC_E | PORT_WKOC_E);
ehci_writel(ehci, temp | PORT_SUSPEND,
status_reg);
msleep(5);/* 5ms for HCD enter low pwr mode */
temp1 = ehci_readl(ehci, hostpc_reg);
ehci_writel(ehci, temp1 | HOSTPC_PHCD,
hostpc_reg);
temp1 = ehci_readl(ehci, hostpc_reg);
ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
wIndex, (temp1 & HOSTPC_PHCD) ?
"succeeded" : "failed");
}
set_bit(wIndex, &ehci->suspended_ports);
break;
case USB_PORT_FEAT_POWER:
@@ -894,6 +967,7 @@ error:
/* "stall" on error */
retval = -EPIPE;
}
error_exit:
spin_unlock_irqrestore (&ehci->lock, flags);
return retval;
}

Bestand weergeven

@@ -75,7 +75,8 @@ static void qh_destroy(struct ehci_qh *qh)
}
if (qh->dummy)
ehci_qtd_free (ehci, qh->dummy);
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma);
kfree(qh);
}
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
@@ -83,12 +84,14 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
struct ehci_qh *qh;
dma_addr_t dma;
qh = (struct ehci_qh *)
dma_pool_alloc (ehci->qh_pool, flags, &dma);
qh = kzalloc(sizeof *qh, GFP_ATOMIC);
if (!qh)
return qh;
memset (qh, 0, sizeof *qh);
goto done;
qh->hw = (struct ehci_qh_hw *)
dma_pool_alloc(ehci->qh_pool, flags, &dma);
if (!qh->hw)
goto fail;
memset(qh->hw, 0, sizeof *qh->hw);
qh->refcount = 1;
qh->ehci = ehci;
qh->qh_dma = dma;
@@ -99,10 +102,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
qh->dummy = ehci_qtd_alloc (ehci, flags);
if (qh->dummy == NULL) {
ehci_dbg (ehci, "no dummy td\n");
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
qh = NULL;
goto fail1;
}
done:
return qh;
fail1:
dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma);
fail:
kfree(qh);
return NULL;
}
/* to share a qh (cpu threads, or hc) */
@@ -180,7 +188,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* QHs for control/bulk/intr transfers */
ehci->qh_pool = dma_pool_create ("ehci_qh",
ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_qh),
sizeof(struct ehci_qh_hw),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
if (!ehci->qh_pool) {

Bestand weergeven

@@ -27,28 +27,8 @@
/* called after powerup, by probe or system-pm "wakeup" */
static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
{
u32 temp;
int retval;
/* optional debug port, normally in the first BAR */
temp = pci_find_capability(pdev, 0x0a);
if (temp) {
pci_read_config_dword(pdev, temp, &temp);
temp >>= 16;
if ((temp & (3 << 13)) == (1 << 13)) {
temp &= 0x1fff;
ehci->debug = ehci_to_hcd(ehci)->regs + temp;
temp = ehci_readl(ehci, &ehci->debug->control);
ehci_info(ehci, "debug port %d%s\n",
HCS_DEBUG_PORT(ehci->hcs_params),
(temp & DBGP_ENABLED)
? " IN USE"
: "");
if (!(temp & DBGP_ENABLED))
ehci->debug = NULL;
}
}
/* we expect static quirk code to handle the "extended capabilities"
* (currently just BIOS handoff) allowed starting with EHCI 0.96
*/
@@ -129,6 +109,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
return retval;
switch (pdev->vendor) {
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
break;
case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
hcd->has_tt = 1;
@@ -192,6 +175,25 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
}
/* optional debug port, normally in the first BAR */
temp = pci_find_capability(pdev, 0x0a);
if (temp) {
pci_read_config_dword(pdev, temp, &temp);
temp >>= 16;
if ((temp & (3 << 13)) == (1 << 13)) {
temp &= 0x1fff;
ehci->debug = ehci_to_hcd(ehci)->regs + temp;
temp = ehci_readl(ehci, &ehci->debug->control);
ehci_info(ehci, "debug port %d%s\n",
HCS_DEBUG_PORT(ehci->hcs_params),
(temp & DBGP_ENABLED)
? " IN USE"
: "");
if (!(temp & DBGP_ENABLED))
ehci->debug = NULL;
}
}
ehci_reset(ehci);
/* at least the Genesys GL880S needs fixup here */
@@ -242,7 +244,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
* System suspend currently expects to be able to suspend the entire
* device tree, device-at-a-time. If we failed selective suspend
* reports, system suspend would fail; so the root hub code must claim
* success. That's lying to usbcore, and it matters for for runtime
* success. That's lying to usbcore, and it matters for runtime
* PM scenarios with selective suspend and remote wakeup...
*/
if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev))

Bestand weergeven

@@ -87,31 +87,33 @@ qtd_fill(struct ehci_hcd *ehci, struct ehci_qtd *qtd, dma_addr_t buf,
static inline void
qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
{
struct ehci_qh_hw *hw = qh->hw;
/* writes to an active overlay are unsafe */
BUG_ON(qh->qh_state != QH_STATE_IDLE);
qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
qh->hw_alt_next = EHCI_LIST_END(ehci);
hw->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
hw->hw_alt_next = EHCI_LIST_END(ehci);
/* Except for control endpoints, we make hardware maintain data
* toggle (like OHCI) ... here (re)initialize the toggle in the QH,
* and set the pseudo-toggle in udev. Only usb_clear_halt() will
* ever clear it.
*/
if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
unsigned is_out, epnum;
is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
usb_settoggle (qh->dev, epnum, is_out, 1);
}
}
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb ();
qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
hw->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
}
/* if it weren't for a common silicon quirk (writing the dummy into the qh
@@ -129,7 +131,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
qtd = list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list);
/* first qtd may already be partially processed */
if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current)
if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current)
qtd = NULL;
}
@@ -260,7 +262,7 @@ __acquires(ehci->lock)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */
if ((qh->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -297,7 +299,6 @@ __acquires(ehci->lock)
static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
/*
@@ -308,13 +309,14 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
struct ehci_qtd *last = NULL, *end = qh->dummy;
struct ehci_qtd *last, *end = qh->dummy;
struct list_head *entry, *tmp;
int last_status = -EINPROGRESS;
int last_status;
int stopped;
unsigned count = 0;
u8 state;
__le32 halt = HALT_BIT(ehci);
const __le32 halt = HALT_BIT(ehci);
struct ehci_qh_hw *hw = qh->hw;
if (unlikely (list_empty (&qh->qtd_list)))
return count;
@@ -324,11 +326,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
* they add urbs to this qh's queue or mark them for unlinking.
*
* NOTE: unlinking expects to be done in queue order.
*
* It's a bug for qh->qh_state to be anything other than
* QH_STATE_IDLE, unless our caller is scan_async() or
* scan_periodic().
*/
state = qh->qh_state;
qh->qh_state = QH_STATE_COMPLETING;
stopped = (state == QH_STATE_IDLE);
rescan:
last = NULL;
last_status = -EINPROGRESS;
qh->needs_rescan = 0;
/* remove de-activated QTDs from front of queue.
* after faults (including short reads), cleanup this urb
* then let the queue advance.
@@ -392,7 +403,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
qtd->hw_token = cpu_to_hc32(ehci,
token);
wmb();
qh->hw_token = cpu_to_hc32(ehci, token);
hw->hw_token = cpu_to_hc32(ehci,
token);
goto retry_xacterr;
}
stopped = 1;
@@ -435,8 +447,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* qh unlinked; token in overlay may be most current */
if (state == QH_STATE_IDLE
&& cpu_to_hc32(ehci, qtd->qtd_dma)
== qh->hw_current) {
token = hc32_to_cpu(ehci, qh->hw_token);
== hw->hw_current) {
token = hc32_to_cpu(ehci, hw->hw_token);
/* An unlink may leave an incomplete
* async transaction in the TT buffer.
@@ -449,9 +461,9 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
* patch the qh later and so that completions can't
* activate it while we "know" it's stopped.
*/
if ((halt & qh->hw_token) == 0) {
if ((halt & hw->hw_token) == 0) {
halt:
qh->hw_token |= halt;
hw->hw_token |= halt;
wmb ();
}
}
@@ -503,6 +515,21 @@ halt:
ehci_qtd_free (ehci, last);
}
/* Do we need to rescan for URBs dequeued during a giveback? */
if (unlikely(qh->needs_rescan)) {
/* If the QH is already unlinked, do the rescan now. */
if (state == QH_STATE_IDLE)
goto rescan;
/* Otherwise we have to wait until the QH is fully unlinked.
* Our caller will start an unlink if qh->needs_rescan is
* set. But if an unlink has already started, nothing needs
* to be done.
*/
if (state != QH_STATE_LINKED)
qh->needs_rescan = 0;
}
/* restore original state; caller must unlink or relink */
qh->qh_state = state;
@@ -510,7 +537,7 @@ halt:
* it after fault cleanup, or recovering from silicon wrongly
* overlaying the dummy qtd (which reduces DMA chatter).
*/
if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END(ehci)) {
if (stopped != 0 || hw->hw_qtd_next == EHCI_LIST_END(ehci)) {
switch (state) {
case QH_STATE_IDLE:
qh_refresh(ehci, qh);
@@ -527,12 +554,9 @@ halt:
* That should be rare for interrupt transfers,
* except maybe high bandwidth ...
*/
if ((cpu_to_hc32(ehci, QH_SMASK)
& qh->hw_info2) != 0) {
intr_deschedule (ehci, qh);
(void) qh_schedule (ehci, qh);
} else
unlink_async (ehci, qh);
/* Tell the caller to start an unlink */
qh->needs_rescan = 1;
break;
/* otherwise, unlink already started */
}
@@ -649,7 +673,7 @@ qh_urb_transaction (
* (this will usually be overridden later.)
*/
if (is_input)
qtd->hw_alt_next = ehci->async->hw_alt_next;
qtd->hw_alt_next = ehci->async->hw->hw_alt_next;
/* qh makes control packets use qtd toggle; maybe switch it */
if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
@@ -744,6 +768,7 @@ qh_make (
int is_input, type;
int maxp = 0;
struct usb_tt *tt = urb->dev->tt;
struct ehci_qh_hw *hw;
if (!qh)
return qh;
@@ -890,8 +915,9 @@ done:
/* init as live, toggle clear, advance to dummy */
qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_hc32(ehci, info1);
qh->hw_info2 = cpu_to_hc32(ehci, info2);
hw = qh->hw;
hw->hw_info1 = cpu_to_hc32(ehci, info1);
hw->hw_info2 = cpu_to_hc32(ehci, info2);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
qh_refresh (ehci, qh);
return qh;
@@ -910,6 +936,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (unlikely(qh->clearing_tt))
return;
WARN_ON(qh->qh_state != QH_STATE_IDLE);
/* (re)start the async schedule? */
head = ehci->async;
timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -928,16 +956,15 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
/* clear halt and/or toggle; and maybe recover from silicon quirk */
if (qh->qh_state == QH_STATE_IDLE)
qh_refresh (ehci, qh);
qh_refresh(ehci, qh);
/* splice right after start */
qh->qh_next = head->qh_next;
qh->hw_next = head->hw_next;
qh->hw->hw_next = head->hw->hw_next;
wmb ();
head->qh_next.qh = qh;
head->hw_next = dma;
head->hw->hw_next = dma;
qh_get(qh);
qh->xacterrs = 0;
@@ -984,7 +1011,7 @@ static struct ehci_qh *qh_append_tds (
/* usb_reset_device() briefly reverts to address 0 */
if (usb_pipedevice (urb->pipe) == 0)
qh->hw_info1 &= ~qh_addr_mask;
qh->hw->hw_info1 &= ~qh_addr_mask;
}
/* just one way to queue requests: swap with the dummy qtd.
@@ -1169,7 +1196,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
while (prev->qh_next.qh != qh)
prev = prev->qh_next.qh;
prev->hw_next = qh->hw_next;
prev->hw->hw_next = qh->hw->hw_next;
prev->qh_next = qh->qh_next;
wmb ();
@@ -1214,6 +1241,8 @@ rescan:
qh = qh_get (qh);
qh->stamp = ehci->stamp;
temp = qh_completions (ehci, qh);
if (qh->needs_rescan)
unlink_async(ehci, qh);
qh_put (qh);
if (temp != 0) {
goto rescan;

Bestand weergeven

@@ -60,6 +60,20 @@ periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
}
}
static __hc32 *
shadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic,
__hc32 tag)
{
switch (hc32_to_cpu(ehci, tag)) {
/* our ehci_shadow.qh is actually software part */
case Q_TYPE_QH:
return &periodic->qh->hw->hw_next;
/* others are hw parts */
default:
return periodic->hw_next;
}
}
/* caller must hold ehci->lock */
static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
{
@@ -71,7 +85,8 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
while (here.ptr && here.ptr != ptr) {
prev_p = periodic_next_shadow(ehci, prev_p,
Q_NEXT_TYPE(ehci, *hw_p));
hw_p = here.hw_next;
hw_p = shadow_next_periodic(ehci, &here,
Q_NEXT_TYPE(ehci, *hw_p));
here = *prev_p;
}
/* an interrupt entry (at list end) could have been shared */
@@ -83,7 +98,7 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
*/
*prev_p = *periodic_next_shadow(ehci, &here,
Q_NEXT_TYPE(ehci, *hw_p));
*hw_p = *here.hw_next;
*hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p));
}
/* how many of the uframe's 125 usecs are allocated? */
@@ -93,18 +108,20 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
__hc32 *hw_p = &ehci->periodic [frame];
union ehci_shadow *q = &ehci->pshadow [frame];
unsigned usecs = 0;
struct ehci_qh_hw *hw;
while (q->ptr) {
switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
case Q_TYPE_QH:
hw = q->qh->hw;
/* is it in the S-mask? */
if (q->qh->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
usecs += q->qh->usecs;
/* ... or C-mask? */
if (q->qh->hw_info2 & cpu_to_hc32(ehci,
if (hw->hw_info2 & cpu_to_hc32(ehci,
1 << (8 + uframe)))
usecs += q->qh->c_usecs;
hw_p = &q->qh->hw_next;
hw_p = &hw->hw_next;
q = &q->qh->qh_next;
break;
// case Q_TYPE_FSTN:
@@ -237,10 +254,10 @@ periodic_tt_usecs (
continue;
case Q_TYPE_QH:
if (same_tt(dev, q->qh->dev)) {
uf = tt_start_uframe(ehci, q->qh->hw_info2);
uf = tt_start_uframe(ehci, q->qh->hw->hw_info2);
tt_usecs[uf] += q->qh->tt_usecs;
}
hw_p = &q->qh->hw_next;
hw_p = &q->qh->hw->hw_next;
q = &q->qh->qh_next;
continue;
case Q_TYPE_SITD:
@@ -375,6 +392,7 @@ static int tt_no_collision (
for (; frame < ehci->periodic_size; frame += period) {
union ehci_shadow here;
__hc32 type;
struct ehci_qh_hw *hw;
here = ehci->pshadow [frame];
type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]);
@@ -385,17 +403,18 @@ static int tt_no_collision (
here = here.itd->itd_next;
continue;
case Q_TYPE_QH:
hw = here.qh->hw;
if (same_tt (dev, here.qh->dev)) {
u32 mask;
mask = hc32_to_cpu(ehci,
here.qh->hw_info2);
hw->hw_info2);
/* "knows" no gap is needed */
mask |= mask >> 8;
if (mask & uf_mask)
break;
}
type = Q_NEXT_TYPE(ehci, here.qh->hw_next);
type = Q_NEXT_TYPE(ehci, hw->hw_next);
here = here.qh->qh_next;
continue;
case Q_TYPE_SITD:
@@ -498,7 +517,8 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
dev_dbg (&qh->dev->dev,
"link qh%d-%04x/%p start %d [%d/%d us]\n",
period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
& (QH_CMASK | QH_SMASK),
qh, qh->start, qh->usecs, qh->c_usecs);
/* high bandwidth, or otherwise every microframe */
@@ -517,7 +537,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
break;
prev = periodic_next_shadow(ehci, prev, type);
hw_p = &here.qh->hw_next;
hw_p = shadow_next_periodic(ehci, &here, type);
here = *prev;
}
@@ -528,14 +548,14 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (qh->period > here.qh->period)
break;
prev = &here.qh->qh_next;
hw_p = &here.qh->hw_next;
hw_p = &here.qh->hw->hw_next;
here = *prev;
}
/* link in this qh, unless some earlier pass did that */
if (qh != here.qh) {
qh->qh_next = here;
if (here.qh)
qh->hw_next = *hw_p;
qh->hw->hw_next = *hw_p;
wmb ();
prev->qh = qh;
*hw_p = QH_NEXT (ehci, qh->qh_dma);
@@ -581,7 +601,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
dev_dbg (&qh->dev->dev,
"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
qh->period,
hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
qh, qh->start, qh->usecs, qh->c_usecs);
/* qh->qh_next still "live" to HC */
@@ -595,7 +615,19 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
unsigned wait;
unsigned wait;
struct ehci_qh_hw *hw = qh->hw;
int rc;
/* If the QH isn't linked then there's nothing we can do
* unless we were called during a giveback, in which case
* qh_completions() has to deal with it.
*/
if (qh->qh_state != QH_STATE_LINKED) {
if (qh->qh_state == QH_STATE_COMPLETING)
qh->needs_rescan = 1;
return;
}
qh_unlink_periodic (ehci, qh);
@@ -606,15 +638,33 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
*/
if (list_empty (&qh->qtd_list)
|| (cpu_to_hc32(ehci, QH_CMASK)
& qh->hw_info2) != 0)
& hw->hw_info2) != 0)
wait = 2;
else
wait = 55; /* worst case: 3 * 1024 */
udelay (wait);
qh->qh_state = QH_STATE_IDLE;
qh->hw_next = EHCI_LIST_END(ehci);
hw->hw_next = EHCI_LIST_END(ehci);
wmb ();
qh_completions(ehci, qh);
/* reschedule QH iff another request is queued */
if (!list_empty(&qh->qtd_list) &&
HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
rc = qh_schedule(ehci, qh);
/* An error here likely indicates handshake failure
* or no space left in the schedule. Neither fault
* should happen often ...
*
* FIXME kill the now-dysfunctional queued urbs
*/
if (rc != 0)
ehci_err(ehci, "can't reschedule qh %p, err %d\n",
qh, rc);
}
}
/*-------------------------------------------------------------------------*/
@@ -739,14 +789,15 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
unsigned uframe;
__hc32 c_mask;
unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
struct ehci_qh_hw *hw = qh->hw;
qh_refresh(ehci, qh);
qh->hw_next = EHCI_LIST_END(ehci);
hw->hw_next = EHCI_LIST_END(ehci);
frame = qh->start;
/* reuse the previous schedule slots, if we can */
if (frame < qh->period) {
uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK);
uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK);
status = check_intr_schedule (ehci, frame, --uframe,
qh, &c_mask);
} else {
@@ -784,11 +835,11 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
qh->hw_info2 |= qh->period
hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
hw->hw_info2 |= qh->period
? cpu_to_hc32(ehci, 1 << uframe)
: cpu_to_hc32(ehci, QH_SMASK);
qh->hw_info2 |= c_mask;
hw->hw_info2 |= c_mask;
} else
ehci_dbg (ehci, "reused qh %p schedule\n", qh);
@@ -2188,10 +2239,11 @@ restart:
case Q_TYPE_QH:
/* handle any completions */
temp.qh = qh_get (q.qh);
type = Q_NEXT_TYPE(ehci, q.qh->hw_next);
type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
q = q.qh->qh_next;
modified = qh_completions (ehci, temp.qh);
if (unlikely (list_empty (&temp.qh->qtd_list)))
if (unlikely(list_empty(&temp.qh->qtd_list) ||
temp.qh->needs_rescan))
intr_deschedule (ehci, temp.qh);
qh_put (temp.qh);
break;

Bestand weergeven

@@ -0,0 +1,181 @@
/*
* linux/driver/usb/host/ehci-w90x900.c
*
* Copyright (c) 2008 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation;version 2 of the License.
*
*/
#include <linux/platform_device.h>
/*ebable phy0 and phy1 for w90p910*/
#define ENPHY (0x01<<8)
#define PHY0_CTR (0xA4)
#define PHY1_CTR (0xA8)
static int __devinit usb_w90x900_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct ehci_hcd *ehci;
struct resource *res;
int retval = 0, irq;
unsigned long val;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENXIO;
goto err1;
}
hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI");
if (!hcd) {
retval = -ENOMEM;
goto err1;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = res->end - res->start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
retval = -EBUSY;
goto err2;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
retval = -EFAULT;
goto err3;
}
ehci = hcd_to_ehci(hcd);
ehci->caps = hcd->regs;
ehci->regs = hcd->regs +
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
/* enable PHY 0,1,the regs only apply to w90p910
* 0xA4,0xA8 were offsets of PHY0 and PHY1 controller of
* w90p910 IC relative to ehci->regs.
*/
val = __raw_readl(ehci->regs+PHY0_CTR);
val |= ENPHY;
__raw_writel(val, ehci->regs+PHY0_CTR);
val = __raw_readl(ehci->regs+PHY1_CTR);
val |= ENPHY;
__raw_writel(val, ehci->regs+PHY1_CTR);
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
ehci->sbrn = 0x20;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
goto err4;
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (retval != 0)
goto err4;
ehci_writel(ehci, 1, &ehci->regs->configured_flag);
return retval;
err4:
iounmap(hcd->regs);
err3:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
usb_put_hcd(hcd);
err1:
return retval;
}
static
void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev)
{
usb_remove_hcd(hcd);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
static const struct hc_driver ehci_w90x900_hc_driver = {
.description = hcd_name,
.product_desc = "Nuvoton w90x900 EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
/*
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_USB2|HCD_MEMORY,
/*
* basic lifecycle operations
*/
.reset = ehci_init,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
/*
* scheduling support
*/
.get_frame_number = ehci_get_frame,
/*
* root hub support
*/
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,
#ifdef CONFIG_PM
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
#endif
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
};
static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
{
if (usb_disabled())
return -ENODEV;
return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev);
}
static int __devexit ehci_w90x900_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_w90x900_remove(hcd, pdev);
return 0;
}
static struct platform_driver ehci_hcd_w90x900_driver = {
.probe = ehci_w90x900_probe,
.remove = __devexit_p(ehci_w90x900_remove),
.driver = {
.name = "w90x900-ehci",
.owner = THIS_MODULE,
},
};
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("w90p910 usb ehci driver!");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:w90p910-ehci");

Bestand weergeven

@@ -37,7 +37,7 @@ typedef __u16 __bitwise __hc16;
#define __hc16 __le16
#endif
/* statistics can be kept for for tuning/monitoring */
/* statistics can be kept for tuning/monitoring */
struct ehci_stats {
/* irq usage */
unsigned long normal;
@@ -126,6 +126,7 @@ struct ehci_hcd { /* one per controller */
unsigned big_endian_mmio:1;
unsigned big_endian_desc:1;
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
@@ -135,6 +136,7 @@ struct ehci_hcd { /* one per controller */
#define OHCI_HCCTRL_OFFSET 0x4
#define OHCI_HCCTRL_LEN 0x4
__hc32 *ohci_hcctrl_reg;
unsigned has_hostpc:1;
u8 sbrn; /* packed release number */
@@ -298,8 +300,8 @@ union ehci_shadow {
* These appear in both the async and (for interrupt) periodic schedules.
*/
struct ehci_qh {
/* first part defined by EHCI spec */
/* first part defined by EHCI spec */
struct ehci_qh_hw {
__hc32 hw_next; /* see EHCI 3.6.1 */
__hc32 hw_info1; /* see EHCI 3.6.2 */
#define QH_HEAD 0x00008000
@@ -317,7 +319,10 @@ struct ehci_qh {
__hc32 hw_token;
__hc32 hw_buf [5];
__hc32 hw_buf_hi [5];
} __attribute__ ((aligned(32)));
struct ehci_qh {
struct ehci_qh_hw *hw;
/* the rest is HCD-private */
dma_addr_t qh_dma; /* address of qh */
union ehci_shadow qh_next; /* ptr to qh; or periodic */
@@ -336,6 +341,7 @@ struct ehci_qh {
u32 refcount;
unsigned stamp;
u8 needs_rescan; /* Dequeue during giveback */
u8 qh_state;
#define QH_STATE_LINKED 1 /* HC sees this */
#define QH_STATE_UNLINK 2 /* HC may still see this */
@@ -357,7 +363,7 @@ struct ehci_qh {
struct usb_device *dev; /* access to TT */
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
} __attribute__ ((aligned (32)));
};
/*-------------------------------------------------------------------------*/
@@ -544,7 +550,7 @@ static inline unsigned int
ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
{
if (ehci_is_TDI(ehci)) {
switch ((portsc>>26)&3) {
switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) {
case 0:
return 0;
case 1:

Diff onderdrukt omdat het te groot bestand Laad Diff

1079
drivers/usb/host/isp1362.h Normal file

Diff onderdrukt omdat het te groot bestand Laad Diff

Bestand weergeven

@@ -386,6 +386,10 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
hwmode |= HW_DACK_POL_HIGH;
if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
hwmode |= HW_DREQ_POL_HIGH;
if (priv->devflags & ISP1760_FLAG_INTR_POL_HIGH)
hwmode |= HW_INTR_HIGH_ACT;
if (priv->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
hwmode |= HW_INTR_EDGE_TRIG;
/*
* We have to set this first in case we're in 16-bit mode.

Bestand weergeven

@@ -142,6 +142,8 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
#define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */
#define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */
#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */
#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */
/* chip memory management */
struct memory_chunk {

Bestand weergeven

@@ -3,6 +3,7 @@
* Currently there is support for
* - OpenFirmware
* - PCI
* - PDEV (generic platform device centralized driver model)
*
* (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
*
@@ -11,6 +12,7 @@
#include <linux/usb.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/usb/isp1760.h>
#include "../core/hcd.h"
#include "isp1760-hcd.h"
@@ -308,6 +310,8 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
struct resource *mem_res;
struct resource *irq_res;
resource_size_t mem_size;
struct isp1760_platform_data *priv = pdev->dev.platform_data;
unsigned int devflags = 0;
unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -330,8 +334,23 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
}
irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
if (priv) {
if (priv->is_isp1761)
devflags |= ISP1760_FLAG_ISP1761;
if (priv->bus_width_16)
devflags |= ISP1760_FLAG_BUS_WIDTH_16;
if (priv->port1_otg)
devflags |= ISP1760_FLAG_OTG_EN;
if (priv->analog_oc)
devflags |= ISP1760_FLAG_ANALOG_OC;
if (priv->dack_polarity_high)
devflags |= ISP1760_FLAG_DACK_POL_HIGH;
if (priv->dreq_polarity_high)
devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
}
hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
irqflags, &pdev->dev, dev_name(&pdev->dev), 0);
irqflags, &pdev->dev, dev_name(&pdev->dev), devflags);
if (IS_ERR(hcd)) {
pr_warning("isp1760: Failed to register the HCD device\n");
ret = -ENODEV;

Bestand weergeven

@@ -148,7 +148,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
at91_start_hc(pdev);
ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
if (retval == 0)
return retval;

Bestand weergeven

@@ -248,10 +248,9 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
pm_message_t message)
static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
unsigned long flags;
int rc;
@@ -274,10 +273,6 @@ static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
(void)ohci_readl(ohci, &ohci->regs->intrdisable);
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW)
ohci_usb_reset(ohci);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
au1xxx_stop_ohc();
@@ -287,9 +282,9 @@ bail:
return rc;
}
static int ohci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = dev_get_drvdata(dev);
au1xxx_start_ohc();
@@ -298,20 +293,26 @@ static int ohci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
return 0;
}
static struct dev_pm_ops au1xxx_ohci_pmops = {
.suspend = ohci_hcd_au1xxx_drv_suspend,
.resume = ohci_hcd_au1xxx_drv_resume,
};
#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops
#else
#define ohci_hcd_au1xxx_drv_suspend NULL
#define ohci_hcd_au1xxx_drv_resume NULL
#define AU1XXX_OHCI_PMOPS NULL
#endif
static struct platform_driver ohci_hcd_au1xxx_driver = {
.probe = ohci_hcd_au1xxx_drv_probe,
.remove = ohci_hcd_au1xxx_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_au1xxx_drv_suspend,
.resume = ohci_hcd_au1xxx_drv_resume,
.driver = {
.name = "au1xxx-ohci",
.owner = THIS_MODULE,
.pm = AU1XXX_OHCI_PMOPS,
},
};

Bestand weergeven

@@ -188,7 +188,6 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int status;
if (time_before(jiffies, ohci->next_statechange))
msleep(5);

Bestand weergeven

@@ -34,7 +34,6 @@
#include <linux/usb/otg.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/reboot.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>

Bestand weergeven

@@ -177,9 +177,13 @@ static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
if (inf->flags & NO_OC_PROTECTION)
uhcrhda |= UHCRHDA_NOCP;
else
uhcrhda &= ~UHCRHDA_NOCP;
if (inf->flags & OC_MODE_PERPORT)
uhcrhda |= UHCRHDA_OCPM;
else
uhcrhda &= ~UHCRHDA_OCPM;
if (inf->power_on_delay) {
uhcrhda &= ~UHCRHDA_POTPGT(0xff);

Bestand weergeven

@@ -418,7 +418,7 @@ static struct ed *ed_get (
is_out = !(ep->desc.bEndpointAddress & USB_DIR_IN);
/* FIXME usbcore changes dev->devnum before SET_ADDRESS
* suceeds ... otherwise we wouldn't need "pipe".
* succeeds ... otherwise we wouldn't need "pipe".
*/
info = usb_pipedevice (pipe);
ed->type = usb_pipetype(pipe);

Bestand weergeven

@@ -33,7 +33,6 @@
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>

Bestand weergeven

@@ -475,4 +475,4 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
quirk_usb_handoff_xhci(pdev);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);

Bestand weergeven

@@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
u16 tmp;
int i = 0;
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#if defined(CONFIG_HAVE_CLK)
clk_enable(r8a66597->clk);
if (r8a66597->pdata->on_chip) {
#ifdef CONFIG_HAVE_CLK
clk_enable(r8a66597->clk);
#endif
do {
r8a66597_write(r8a66597, SCKE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
r8a66597_write(r8a66597, 0x04, 0x02);
#else
do {
r8a66597_write(r8a66597, USBE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & USBE) != USBE);
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
SYSCFG0);
do {
r8a66597_write(r8a66597, SCKE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
printk(KERN_ERR "r8a66597: reg access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
r8a66597_write(r8a66597, 0x04, 0x02);
} else {
do {
r8a66597_write(r8a66597, USBE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
printk(KERN_ERR "r8a66597: reg access fail.\n");
return -ENXIO;
}
} while ((tmp & USBE) != USBE);
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
XTAL, SYSCFG0);
i = 0;
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
do {
msleep(1);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 500) {
printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
i = 0;
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
do {
msleep(1);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 500) {
printk(KERN_ERR "r8a66597: reg access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
}
return 0;
}
@@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
{
r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
udelay(1);
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#if defined(CONFIG_HAVE_CLK)
clk_disable(r8a66597->clk);
#endif
#else
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
if (r8a66597->pdata->on_chip) {
#ifdef CONFIG_HAVE_CLK
clk_disable(r8a66597->clk);
#endif
} else {
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
}
}
static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
@@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
for (port = 0; port < r8a66597->max_root_hub; port++)
r8a66597_enable_port(r8a66597, port);
return 0;
@@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597)
r8a66597_write(r8a66597, 0, INTENB0);
r8a66597_write(r8a66597, 0, INTSTS0);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
for (port = 0; port < r8a66597->max_root_hub; port++)
r8a66597_disable_port(r8a66597, port);
r8a66597_clock_disable(r8a66597);
@@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath)
return ((strlen(devpath) >= 4) ? 1 : 0);
}
static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
static void get_port_number(struct r8a66597 *r8a66597,
char *devpath, u16 *root_port, u16 *hub_port)
{
if (root_port) {
*root_port = (devpath[0] & 0x0F) - 1;
if (*root_port >= R8A66597_MAX_ROOT_HUB)
if (*root_port >= r8a66597->max_root_hub)
printk(KERN_ERR "r8a66597: Illegal root port number.\n");
}
if (hub_port)
@@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597,
INIT_LIST_HEAD(&dev->device_list);
list_add_tail(&dev->device_list, &r8a66597->child_device);
get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
get_port_number(r8a66597, urb->dev->devpath,
&dev->root_port, &dev->hub_port);
if (!is_child_device(urb->dev->devpath))
r8a66597->root_hub[dev->root_port].dev = dev;
@@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597,
list_del(&dev->device_list);
kfree(dev);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
for (port = 0; port < r8a66597->max_root_hub; port++) {
if (r8a66597->root_hub[port].dev == dev) {
r8a66597->root_hub[port].dev = NULL;
break;
@@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
}
static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
{
if (r8a66597->pdata->on_chip)
return MBW_32;
else
return MBW_16;
}
/* this function must be called with interrupt disabled */
static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
{
r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
unsigned short mbw = mbw_value(r8a66597);
r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
}
@@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
struct r8a66597_pipe *pipe)
{
cfifo_change(r8a66597, 0);
r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
unsigned short mbw = mbw_value(r8a66597);
r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
cfifo_change(r8a66597, 0);
r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
pipe->fifosel);
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
}
@@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
struct r8a66597_pipe *pipe,
struct urb *urb)
{
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
int i;
struct r8a66597_pipe_info *info = &pipe->info;
unsigned short mbw = mbw_value(r8a66597);
/* pipe dma is only for external controlles */
if (r8a66597->pdata->on_chip)
return;
if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
@@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
set_pipe_reg_addr(pipe, i);
cfifo_change(r8a66597, 0);
r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
MBW | CURPIPE, pipe->fifosel);
r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
mbw | CURPIPE, pipe->fifosel);
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
pipe->info.pipenum);
@@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
break;
}
}
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
}
/* this function must be called with interrupt disabled */
@@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597)
spin_lock_irqsave(&r8a66597->lock, flags);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
for (port = 0; port < r8a66597->max_root_hub; port++)
r8a66597_root_hub_control(r8a66597, port);
spin_unlock_irqrestore(&r8a66597->lock, flags);
@@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
u16 root_port, hub_port;
if (usb_address == 0) {
get_port_number(urb->dev->devpath,
get_port_number(r8a66597, urb->dev->devpath,
&root_port, &hub_port);
set_devadd_reg(r8a66597, 0,
get_r8a66597_usb_speed(urb->dev->speed),
@@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
*buf = 0; /* initialize (no change) */
for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
for (i = 0; i < r8a66597->max_root_hub; i++) {
if (r8a66597->root_hub[i].port & 0xffff0000)
*buf |= 1 << (i + 1);
}
@@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
{
desc->bDescriptorType = 0x29;
desc->bHubContrCurrent = 0;
desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
desc->bNbrPorts = r8a66597->max_root_hub;
desc->bDescLength = 9;
desc->bPwrOn2PwrGood = 0;
desc->wHubCharacteristics = cpu_to_le16(0x0011);
desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
desc->bitmap[1] = ~0;
}
@@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
}
break;
case ClearPortFeature:
if (wIndex > R8A66597_MAX_ROOT_HUB)
if (wIndex > r8a66597->max_root_hub)
goto error;
if (wLength != 0)
goto error;
@@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
*buf = 0x00;
break;
case GetPortStatus:
if (wIndex > R8A66597_MAX_ROOT_HUB)
if (wIndex > r8a66597->max_root_hub)
goto error;
*(__le32 *)buf = cpu_to_le32(rh->port);
break;
case SetPortFeature:
if (wIndex > R8A66597_MAX_ROOT_HUB)
if (wIndex > r8a66597->max_root_hub)
goto error;
if (wLength != 0)
goto error;
@@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd)
dbg("%s", __func__);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
for (port = 0; port < r8a66597->max_root_hub; port++) {
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
unsigned long dvstctr_reg = get_dvstctr_reg(port);
@@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
dbg("%s", __func__);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
for (port = 0; port < r8a66597->max_root_hub; port++) {
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
unsigned long dvstctr_reg = get_dvstctr_reg(port);
@@ -2305,16 +2323,16 @@ static struct hc_driver r8a66597_hc_driver = {
};
#if defined(CONFIG_PM)
static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
static int r8a66597_suspend(struct device *dev)
{
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
struct r8a66597 *r8a66597 = dev_get_drvdata(dev);
int port;
dbg("%s", __func__);
disable_controller(r8a66597);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
for (port = 0; port < r8a66597->max_root_hub; port++) {
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
rh->port = 0x00000000;
@@ -2323,9 +2341,9 @@ static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
static int r8a66597_resume(struct platform_device *pdev)
static int r8a66597_resume(struct device *dev)
{
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
struct r8a66597 *r8a66597 = dev_get_drvdata(dev);
struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
dbg("%s", __func__);
@@ -2335,9 +2353,17 @@ static int r8a66597_resume(struct platform_device *pdev)
return 0;
}
static struct dev_pm_ops r8a66597_dev_pm_ops = {
.suspend = r8a66597_suspend,
.resume = r8a66597_resume,
.poweroff = r8a66597_suspend,
.restore = r8a66597_resume,
};
#define R8A66597_DEV_PM_OPS (&r8a66597_dev_pm_ops)
#else /* if defined(CONFIG_PM) */
#define r8a66597_suspend NULL
#define r8a66597_resume NULL
#define R8A66597_DEV_PM_OPS NULL
#endif
static int __init_or_module r8a66597_remove(struct platform_device *pdev)
@@ -2348,8 +2374,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
del_timer_sync(&r8a66597->rh_timer);
usb_remove_hcd(hcd);
iounmap((void *)r8a66597->reg);
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
clk_put(r8a66597->clk);
#ifdef CONFIG_HAVE_CLK
if (r8a66597->pdata->on_chip)
clk_put(r8a66597->clk);
#endif
usb_put_hcd(hcd);
return 0;
@@ -2357,7 +2384,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
static int __devinit r8a66597_probe(struct platform_device *pdev)
{
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
char clk_name[8];
#endif
struct resource *res = NULL, *ires;
@@ -2419,15 +2446,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
r8a66597->pdata = pdev->dev.platform_data;
r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
r8a66597->clk = clk_get(&pdev->dev, clk_name);
if (IS_ERR(r8a66597->clk)) {
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
ret = PTR_ERR(r8a66597->clk);
goto clean_up2;
}
if (r8a66597->pdata->on_chip) {
#ifdef CONFIG_HAVE_CLK
snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
r8a66597->clk = clk_get(&pdev->dev, clk_name);
if (IS_ERR(r8a66597->clk)) {
dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
clk_name);
ret = PTR_ERR(r8a66597->clk);
goto clean_up2;
}
#endif
r8a66597->max_root_hub = 1;
} else
r8a66597->max_root_hub = 2;
spin_lock_init(&r8a66597->lock);
init_timer(&r8a66597->rh_timer);
@@ -2457,8 +2489,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
return 0;
clean_up3:
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
clk_put(r8a66597->clk);
#ifdef CONFIG_HAVE_CLK
if (r8a66597->pdata->on_chip)
clk_put(r8a66597->clk);
clean_up2:
#endif
usb_put_hcd(hcd);
@@ -2473,11 +2506,10 @@ clean_up:
static struct platform_driver r8a66597_driver = {
.probe = r8a66597_probe,
.remove = r8a66597_remove,
.suspend = r8a66597_suspend,
.resume = r8a66597_resume,
.driver = {
.name = (char *) hcd_name,
.owner = THIS_MODULE,
.pm = R8A66597_DEV_PM_OPS,
},
};

Bestand weergeven

@@ -26,390 +26,16 @@
#ifndef __R8A66597_H__
#define __R8A66597_H__
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
#include <linux/clk.h>
#endif
#include <linux/usb/r8a66597.h>
#define SYSCFG0 0x00
#define SYSCFG1 0x02
#define SYSSTS0 0x04
#define SYSSTS1 0x06
#define DVSTCTR0 0x08
#define DVSTCTR1 0x0A
#define TESTMODE 0x0C
#define PINCFG 0x0E
#define DMA0CFG 0x10
#define DMA1CFG 0x12
#define CFIFO 0x14
#define D0FIFO 0x18
#define D1FIFO 0x1C
#define CFIFOSEL 0x20
#define CFIFOCTR 0x22
#define CFIFOSIE 0x24
#define D0FIFOSEL 0x28
#define D0FIFOCTR 0x2A
#define D1FIFOSEL 0x2C
#define D1FIFOCTR 0x2E
#define INTENB0 0x30
#define INTENB1 0x32
#define INTENB2 0x34
#define BRDYENB 0x36
#define NRDYENB 0x38
#define BEMPENB 0x3A
#define SOFCFG 0x3C
#define INTSTS0 0x40
#define INTSTS1 0x42
#define INTSTS2 0x44
#define BRDYSTS 0x46
#define NRDYSTS 0x48
#define BEMPSTS 0x4A
#define FRMNUM 0x4C
#define UFRMNUM 0x4E
#define USBADDR 0x50
#define USBREQ 0x54
#define USBVAL 0x56
#define USBINDX 0x58
#define USBLENG 0x5A
#define DCPCFG 0x5C
#define DCPMAXP 0x5E
#define DCPCTR 0x60
#define PIPESEL 0x64
#define PIPECFG 0x68
#define PIPEBUF 0x6A
#define PIPEMAXP 0x6C
#define PIPEPERI 0x6E
#define PIPE1CTR 0x70
#define PIPE2CTR 0x72
#define PIPE3CTR 0x74
#define PIPE4CTR 0x76
#define PIPE5CTR 0x78
#define PIPE6CTR 0x7A
#define PIPE7CTR 0x7C
#define PIPE8CTR 0x7E
#define PIPE9CTR 0x80
#define PIPE1TRE 0x90
#define PIPE1TRN 0x92
#define PIPE2TRE 0x94
#define PIPE2TRN 0x96
#define PIPE3TRE 0x98
#define PIPE3TRN 0x9A
#define PIPE4TRE 0x9C
#define PIPE4TRN 0x9E
#define PIPE5TRE 0xA0
#define PIPE5TRN 0xA2
#define DEVADD0 0xD0
#define DEVADD1 0xD2
#define DEVADD2 0xD4
#define DEVADD3 0xD6
#define DEVADD4 0xD8
#define DEVADD5 0xDA
#define DEVADD6 0xDC
#define DEVADD7 0xDE
#define DEVADD8 0xE0
#define DEVADD9 0xE2
#define DEVADDA 0xE4
/* System Configuration Control Register */
#define XTAL 0xC000 /* b15-14: Crystal selection */
#define XTAL48 0x8000 /* 48MHz */
#define XTAL24 0x4000 /* 24MHz */
#define XTAL12 0x0000 /* 12MHz */
#define XCKE 0x2000 /* b13: External clock enable */
#define PLLC 0x0800 /* b11: PLL control */
#define SCKE 0x0400 /* b10: USB clock enable */
#define PCSDIS 0x0200 /* b9: not CS wakeup */
#define LPSME 0x0100 /* b8: Low power sleep mode */
#define HSE 0x0080 /* b7: Hi-speed enable */
#define DCFM 0x0040 /* b6: Controller function select */
#define DRPD 0x0020 /* b5: D+/- pull down control */
#define DPRPU 0x0010 /* b4: D+ pull up control */
#define USBE 0x0001 /* b0: USB module operation enable */
/* System Configuration Status Register */
#define OVCBIT 0x8000 /* b15-14: Over-current bit */
#define OVCMON 0xC000 /* b15-14: Over-current monitor */
#define SOFEA 0x0020 /* b5: SOF monitor */
#define IDMON 0x0004 /* b3: ID-pin monitor */
#define LNST 0x0003 /* b1-0: D+, D- line status */
#define SE1 0x0003 /* SE1 */
#define FS_KSTS 0x0002 /* Full-Speed K State */
#define FS_JSTS 0x0001 /* Full-Speed J State */
#define LS_JSTS 0x0002 /* Low-Speed J State */
#define LS_KSTS 0x0001 /* Low-Speed K State */
#define SE0 0x0000 /* SE0 */
/* Device State Control Register */
#define EXTLP0 0x0400 /* b10: External port */
#define VBOUT 0x0200 /* b9: VBUS output */
#define WKUP 0x0100 /* b8: Remote wakeup */
#define RWUPE 0x0080 /* b7: Remote wakeup sense */
#define USBRST 0x0040 /* b6: USB reset enable */
#define RESUME 0x0020 /* b5: Resume enable */
#define UACT 0x0010 /* b4: USB bus enable */
#define RHST 0x0007 /* b1-0: Reset handshake status */
#define HSPROC 0x0004 /* HS handshake is processing */
#define HSMODE 0x0003 /* Hi-Speed mode */
#define FSMODE 0x0002 /* Full-Speed mode */
#define LSMODE 0x0001 /* Low-Speed mode */
#define UNDECID 0x0000 /* Undecided */
/* Test Mode Register */
#define UTST 0x000F /* b3-0: Test select */
#define H_TST_PACKET 0x000C /* HOST TEST Packet */
#define H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */
#define H_TST_K 0x000A /* HOST TEST K */
#define H_TST_J 0x0009 /* HOST TEST J */
#define H_TST_NORMAL 0x0000 /* HOST Normal Mode */
#define P_TST_PACKET 0x0004 /* PERI TEST Packet */
#define P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */
#define P_TST_K 0x0002 /* PERI TEST K */
#define P_TST_J 0x0001 /* PERI TEST J */
#define P_TST_NORMAL 0x0000 /* PERI Normal Mode */
/* Data Pin Configuration Register */
#define LDRV 0x8000 /* b15: Drive Current Adjust */
#define VIF1 0x0000 /* VIF = 1.8V */
#define VIF3 0x8000 /* VIF = 3.3V */
#define INTA 0x0001 /* b1: USB INT-pin active */
/* DMAx Pin Configuration Register */
#define DREQA 0x4000 /* b14: Dreq active select */
#define BURST 0x2000 /* b13: Burst mode */
#define DACKA 0x0400 /* b10: Dack active select */
#define DFORM 0x0380 /* b9-7: DMA mode select */
#define CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */
#define CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */
#define CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */
#define SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */
#define DENDA 0x0040 /* b6: Dend active select */
#define PKTM 0x0020 /* b5: Packet mode */
#define DENDE 0x0010 /* b4: Dend enable */
#define OBUS 0x0004 /* b2: OUTbus mode */
/* CFIFO/DxFIFO Port Select Register */
#define RCNT 0x8000 /* b15: Read count mode */
#define REW 0x4000 /* b14: Buffer rewind */
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
#define DREQE 0x1000 /* b12: DREQ output enable */
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#define MBW 0x0800
#else
#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
#endif
#define MBW_8 0x0000 /* 8bit */
#define MBW_16 0x0400 /* 16bit */
#define BIGEND 0x0100 /* b8: Big endian mode */
#define BYTE_LITTLE 0x0000 /* little dendian */
#define BYTE_BIG 0x0100 /* big endifan */
#define ISEL 0x0020 /* b5: DCP FIFO port direction select */
#define CURPIPE 0x000F /* b2-0: PIPE select */
/* CFIFO/DxFIFO Port Control Register */
#define BVAL 0x8000 /* b15: Buffer valid flag */
#define BCLR 0x4000 /* b14: Buffer clear */
#define FRDY 0x2000 /* b13: FIFO ready */
#define DTLN 0x0FFF /* b11-0: FIFO received data length */
/* Interrupt Enable Register 0 */
#define VBSE 0x8000 /* b15: VBUS interrupt */
#define RSME 0x4000 /* b14: Resume interrupt */
#define SOFE 0x2000 /* b13: Frame update interrupt */
#define DVSE 0x1000 /* b12: Device state transition interrupt */
#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */
#define BEMPE 0x0400 /* b10: Buffer empty interrupt */
#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */
#define BRDYE 0x0100 /* b8: Buffer ready interrupt */
/* Interrupt Enable Register 1 */
#define OVRCRE 0x8000 /* b15: Over-current interrupt */
#define BCHGE 0x4000 /* b14: USB us chenge interrupt */
#define DTCHE 0x1000 /* b12: Detach sense interrupt */
#define ATTCHE 0x0800 /* b11: Attach sense interrupt */
#define EOFERRE 0x0040 /* b6: EOF error interrupt */
#define SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */
#define SACKE 0x0010 /* b4: SETUP ACK interrupt */
/* BRDY Interrupt Enable/Status Register */
#define BRDY9 0x0200 /* b9: PIPE9 */
#define BRDY8 0x0100 /* b8: PIPE8 */
#define BRDY7 0x0080 /* b7: PIPE7 */
#define BRDY6 0x0040 /* b6: PIPE6 */
#define BRDY5 0x0020 /* b5: PIPE5 */
#define BRDY4 0x0010 /* b4: PIPE4 */
#define BRDY3 0x0008 /* b3: PIPE3 */
#define BRDY2 0x0004 /* b2: PIPE2 */
#define BRDY1 0x0002 /* b1: PIPE1 */
#define BRDY0 0x0001 /* b1: PIPE0 */
/* NRDY Interrupt Enable/Status Register */
#define NRDY9 0x0200 /* b9: PIPE9 */
#define NRDY8 0x0100 /* b8: PIPE8 */
#define NRDY7 0x0080 /* b7: PIPE7 */
#define NRDY6 0x0040 /* b6: PIPE6 */
#define NRDY5 0x0020 /* b5: PIPE5 */
#define NRDY4 0x0010 /* b4: PIPE4 */
#define NRDY3 0x0008 /* b3: PIPE3 */
#define NRDY2 0x0004 /* b2: PIPE2 */
#define NRDY1 0x0002 /* b1: PIPE1 */
#define NRDY0 0x0001 /* b1: PIPE0 */
/* BEMP Interrupt Enable/Status Register */
#define BEMP9 0x0200 /* b9: PIPE9 */
#define BEMP8 0x0100 /* b8: PIPE8 */
#define BEMP7 0x0080 /* b7: PIPE7 */
#define BEMP6 0x0040 /* b6: PIPE6 */
#define BEMP5 0x0020 /* b5: PIPE5 */
#define BEMP4 0x0010 /* b4: PIPE4 */
#define BEMP3 0x0008 /* b3: PIPE3 */
#define BEMP2 0x0004 /* b2: PIPE2 */
#define BEMP1 0x0002 /* b1: PIPE1 */
#define BEMP0 0x0001 /* b0: PIPE0 */
/* SOF Pin Configuration Register */
#define TRNENSEL 0x0100 /* b8: Select transaction enable period */
#define BRDYM 0x0040 /* b6: BRDY clear timing */
#define INTL 0x0020 /* b5: Interrupt sense select */
#define EDGESTS 0x0010 /* b4: */
#define SOFMODE 0x000C /* b3-2: SOF pin select */
#define SOF_125US 0x0008 /* SOF OUT 125us Frame Signal */
#define SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */
#define SOF_DISABLE 0x0000 /* SOF OUT Disable */
/* Interrupt Status Register 0 */
#define VBINT 0x8000 /* b15: VBUS interrupt */
#define RESM 0x4000 /* b14: Resume interrupt */
#define SOFR 0x2000 /* b13: SOF frame update interrupt */
#define DVST 0x1000 /* b12: Device state transition interrupt */
#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */
#define BEMP 0x0400 /* b10: Buffer empty interrupt */
#define NRDY 0x0200 /* b9: Buffer not ready interrupt */
#define BRDY 0x0100 /* b8: Buffer ready interrupt */
#define VBSTS 0x0080 /* b7: VBUS input port */
#define DVSQ 0x0070 /* b6-4: Device state */
#define DS_SPD_CNFG 0x0070 /* Suspend Configured */
#define DS_SPD_ADDR 0x0060 /* Suspend Address */
#define DS_SPD_DFLT 0x0050 /* Suspend Default */
#define DS_SPD_POWR 0x0040 /* Suspend Powered */
#define DS_SUSP 0x0040 /* Suspend */
#define DS_CNFG 0x0030 /* Configured */
#define DS_ADDS 0x0020 /* Address */
#define DS_DFLT 0x0010 /* Default */
#define DS_POWR 0x0000 /* Powered */
#define DVSQS 0x0030 /* b5-4: Device state */
#define VALID 0x0008 /* b3: Setup packet detected flag */
#define CTSQ 0x0007 /* b2-0: Control transfer stage */
#define CS_SQER 0x0006 /* Sequence error */
#define CS_WRND 0x0005 /* Control write nodata status stage */
#define CS_WRSS 0x0004 /* Control write status stage */
#define CS_WRDS 0x0003 /* Control write data stage */
#define CS_RDSS 0x0002 /* Control read status stage */
#define CS_RDDS 0x0001 /* Control read data stage */
#define CS_IDST 0x0000 /* Idle or setup stage */
/* Interrupt Status Register 1 */
#define OVRCR 0x8000 /* b15: Over-current interrupt */
#define BCHG 0x4000 /* b14: USB bus chenge interrupt */
#define DTCH 0x1000 /* b12: Detach sense interrupt */
#define ATTCH 0x0800 /* b11: Attach sense interrupt */
#define EOFERR 0x0040 /* b6: EOF-error interrupt */
#define SIGN 0x0020 /* b5: Setup ignore interrupt */
#define SACK 0x0010 /* b4: Setup acknowledge interrupt */
/* Frame Number Register */
#define OVRN 0x8000 /* b15: Overrun error */
#define CRCE 0x4000 /* b14: Received data error */
#define FRNM 0x07FF /* b10-0: Frame number */
/* Micro Frame Number Register */
#define UFRNM 0x0007 /* b2-0: Micro frame number */
/* Default Control Pipe Maxpacket Size Register */
/* Pipe Maxpacket Size Register */
#define DEVSEL 0xF000 /* b15-14: Device address select */
#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */
/* Default Control Pipe Control Register */
#define BSTS 0x8000 /* b15: Buffer status */
#define SUREQ 0x4000 /* b14: Send USB request */
#define CSCLR 0x2000 /* b13: complete-split status clear */
#define CSSTS 0x1000 /* b12: complete-split status */
#define SUREQCLR 0x0800 /* b11: stop setup request */
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
#define PBUSY 0x0020 /* b5: pipe busy */
#define PINGE 0x0010 /* b4: ping enable */
#define CCPL 0x0004 /* b2: Enable control transfer complete */
#define PID 0x0003 /* b1-0: Response PID */
#define PID_STALL11 0x0003 /* STALL */
#define PID_STALL 0x0002 /* STALL */
#define PID_BUF 0x0001 /* BUF */
#define PID_NAK 0x0000 /* NAK */
/* Pipe Window Select Register */
#define PIPENM 0x0007 /* b2-0: Pipe select */
/* Pipe Configuration Register */
#define R8A66597_TYP 0xC000 /* b15-14: Transfer type */
#define R8A66597_ISO 0xC000 /* Isochronous */
#define R8A66597_INT 0x8000 /* Interrupt */
#define R8A66597_BULK 0x4000 /* Bulk */
#define R8A66597_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */
#define R8A66597_DBLB 0x0200 /* b9: Double buffer mode select */
#define R8A66597_CNTMD 0x0100 /* b8: Continuous transfer mode select */
#define R8A66597_SHTNAK 0x0080 /* b7: Transfer end NAK */
#define R8A66597_DIR 0x0010 /* b4: Transfer direction select */
#define R8A66597_EPNUM 0x000F /* b3-0: Eendpoint number select */
/* Pipe Buffer Configuration Register */
#define BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */
#define BUFNMB 0x007F /* b6-0: Pipe buffer number */
#define PIPE0BUF 256
#define PIPExBUF 64
/* Pipe Maxpacket Size Register */
#define MXPS 0x07FF /* b10-0: Maxpacket size */
/* Pipe Cycle Configuration Register */
#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */
#define IITV 0x0007 /* b2-0: Isochronous interval */
/* Pipex Control Register */
#define BSTS 0x8000 /* b15: Buffer status */
#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */
#define CSCLR 0x2000 /* b13: complete-split status clear */
#define CSSTS 0x1000 /* b12: complete-split status */
#define ATREPM 0x0400 /* b10: Auto repeat mode */
#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
#define PBUSY 0x0020 /* b5: pipe busy */
#define PID 0x0003 /* b1-0: Response PID */
/* PIPExTRE */
#define TRENB 0x0200 /* b9: Transaction counter enable */
#define TRCLR 0x0100 /* b8: Transaction counter clear */
/* PIPExTRN */
#define TRNCNT 0xFFFF /* b15-0: Transaction counter */
/* DEVADDx */
#define UPPHUB 0x7800
#define HUBPORT 0x0700
#define USBSPD 0x00C0
#define RTPORT 0x0001
#define R8A66597_MAX_NUM_PIPE 10
#define R8A66597_BUF_BSIZE 8
#define R8A66597_MAX_DEVICE 10
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#define R8A66597_MAX_ROOT_HUB 1
#else
#define R8A66597_MAX_ROOT_HUB 2
#endif
#define R8A66597_MAX_SAMPLING 5
#define R8A66597_RH_POLL_TIME 10
#define R8A66597_MAX_DMA_CHANNEL 2
@@ -487,7 +113,7 @@ struct r8a66597_root_hub {
struct r8a66597 {
spinlock_t lock;
unsigned long reg;
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
struct clk *clk;
#endif
struct r8a66597_platdata *pdata;
@@ -504,6 +130,7 @@ struct r8a66597 {
unsigned short interval_map;
unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
unsigned char dma_map;
unsigned int max_root_hub;
struct list_head child_device;
unsigned long child_connect_map[4];
@@ -550,21 +177,22 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
unsigned long offset, u16 *buf,
int len)
{
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
unsigned long fifoaddr = r8a66597->reg + offset;
unsigned long count;
count = len / 4;
insl(fifoaddr, buf, count);
if (r8a66597->pdata->on_chip) {
count = len / 4;
insl(fifoaddr, buf, count);
if (len & 0x00000003) {
unsigned long tmp = inl(fifoaddr);
memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
if (len & 0x00000003) {
unsigned long tmp = inl(fifoaddr);
memcpy((unsigned char *)buf + count * 4, &tmp,
len & 0x03);
}
} else {
len = (len + 1) / 2;
insw(fifoaddr, buf, len);
}
#else
len = (len + 1) / 2;
insw(r8a66597->reg + offset, buf, len);
#endif
}
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
@@ -578,33 +206,33 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
int len)
{
unsigned long fifoaddr = r8a66597->reg + offset;
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
unsigned long count;
unsigned char *pb;
int i;
count = len / 4;
outsl(fifoaddr, buf, count);
if (r8a66597->pdata->on_chip) {
count = len / 4;
outsl(fifoaddr, buf, count);
if (len & 0x00000003) {
pb = (unsigned char *)buf + count * 4;
for (i = 0; i < (len & 0x00000003); i++) {
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
outb(pb[i], fifoaddr + i);
else
outb(pb[i], fifoaddr + 3 - i);
if (len & 0x00000003) {
pb = (unsigned char *)buf + count * 4;
for (i = 0; i < (len & 0x00000003); i++) {
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
outb(pb[i], fifoaddr + i);
else
outb(pb[i], fifoaddr + 3 - i);
}
}
} else {
int odd = len & 0x0001;
len = len / 2;
outsw(fifoaddr, buf, len);
if (unlikely(odd)) {
buf = &buf[len];
outb((unsigned char)*buf, fifoaddr);
}
}
#else
int odd = len & 0x0001;
len = len / 2;
outsw(fifoaddr, buf, len);
if (unlikely(odd)) {
buf = &buf[len];
outb((unsigned char)*buf, fifoaddr);
}
#endif
}
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,

Bestand weergeven

@@ -719,8 +719,12 @@ retry:
/* port status seems weird until after reset, so
* force the reset and make khubd clean up later.
*/
sl811->port1 |= (1 << USB_PORT_FEAT_C_CONNECTION)
| (1 << USB_PORT_FEAT_CONNECTION);
if (sl811->stat_insrmv & 1)
sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
else
sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
} else if (irqstat & SL11H_INTMASK_RD) {
if (sl811->port1 & (1 << USB_PORT_FEAT_SUSPEND)) {

Bestand weergeven

@@ -1422,7 +1422,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
goto err_submit_failed;
/* Add this URB to the QH */
urbp->qh = qh;
list_add_tail(&urbp->node, &qh->queue);
/* If the new URB is the first and only one on this QH then either

Bestand weergeven

@@ -227,11 +227,21 @@ void scan_async_work(struct work_struct *work)
/*
* Now that the ASL is updated, complete the removal of any
* removed qsets.
*
* If the qset was to be reset, do so and reinsert it into the
* ASL if it has pending transfers.
*/
spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
qset_remove_complete(whc, qset);
if (qset->reset) {
qset_reset(whc, qset);
if (!list_empty(&qset->stds)) {
asl_qset_insert_begin(whc, qset);
queue_work(whc->workqueue, &whc->async_work);
}
}
}
spin_unlock_irq(&whc->lock);
@@ -267,7 +277,7 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
else
err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
if (!err) {
if (!qset->in_sw_list)
if (!qset->in_sw_list && !qset->remove)
asl_qset_insert_begin(whc, qset);
} else
usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);

Bestand weergeven

@@ -192,19 +192,23 @@ static void whc_endpoint_reset(struct usb_hcd *usb_hcd,
struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
struct whc *whc = wusbhc_to_whc(wusbhc);
struct whc_qset *qset;
unsigned long flags;
spin_lock_irqsave(&whc->lock, flags);
qset = ep->hcpriv;
if (qset) {
qset->remove = 1;
qset->reset = 1;
if (usb_endpoint_xfer_bulk(&ep->desc)
|| usb_endpoint_xfer_control(&ep->desc))
queue_work(whc->workqueue, &whc->async_work);
else
queue_work(whc->workqueue, &whc->periodic_work);
qset_reset(whc, qset);
}
spin_unlock_irqrestore(&whc->lock, flags);
}

Bestand weergeven

@@ -255,11 +255,21 @@ void scan_periodic_work(struct work_struct *work)
/*
* Now that the PZL is updated, complete the removal of any
* removed qsets.
*
* If the qset was to be reset, do so and reinsert it into the
* PZL if it has pending transfers.
*/
spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
qset_remove_complete(whc, qset);
if (qset->reset) {
qset_reset(whc, qset);
if (!list_empty(&qset->stds)) {
qset_insert_in_sw_list(whc, qset);
queue_work(whc->workqueue, &whc->periodic_work);
}
}
}
spin_unlock_irq(&whc->lock);
@@ -295,7 +305,7 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
else
err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
if (!err) {
if (!qset->in_sw_list)
if (!qset->in_sw_list && !qset->remove)
qset_insert_in_sw_list(whc, qset);
} else
usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);

Bestand weergeven

@@ -103,7 +103,6 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
void qset_clear(struct whc *whc, struct whc_qset *qset)
{
qset->td_start = qset->td_end = qset->ntds = 0;
qset->remove = 0;
qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
@@ -125,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
*/
void qset_reset(struct whc *whc, struct whc_qset *qset)
{
wait_for_completion(&qset->remove_complete);
qset->reset = 0;
qset->qh.status &= ~QH_STATUS_SEQ_MASK;
qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
@@ -156,6 +155,7 @@ struct whc_qset *get_qset(struct whc *whc, struct urb *urb,
void qset_remove_complete(struct whc *whc, struct whc_qset *qset)
{
qset->remove = 0;
list_del_init(&qset->list_node);
complete(&qset->remove_complete);
}

Bestand weergeven

@@ -264,6 +264,7 @@ struct whc_qset {
unsigned in_sw_list:1;
unsigned in_hw_list:1;
unsigned remove:1;
unsigned reset:1;
struct urb *pause_after_urb;
struct completion remove_complete;
int max_burst;

Bestand weergeven

@@ -413,7 +413,8 @@ void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
int i;
struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx);
dma_addr_t dma = ctx->dma +
((unsigned long)slot_ctx - (unsigned long)ctx->bytes);
int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
xhci_dbg(xhci, "Slot Context:\n");
@@ -459,7 +460,7 @@ void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
for (i = 0; i < last_ep_ctx; ++i) {
struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
dma_addr_t dma = ctx->dma +
((unsigned long)ep_ctx - (unsigned long)ctx);
((unsigned long)ep_ctx - (unsigned long)ctx->bytes);
xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",

Bestand weergeven

@@ -22,12 +22,18 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include "xhci.h"
#define DRIVER_AUTHOR "Sarah Sharp"
#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
static int link_quirk;
module_param(link_quirk, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
/* TODO: copied from ehci-hcd.c - can this be refactored? */
/*
* handshake - spin reading hc until handshake completes or fails
@@ -214,6 +220,12 @@ int xhci_init(struct usb_hcd *hcd)
xhci_dbg(xhci, "xhci_init\n");
spin_lock_init(&xhci->lock);
if (link_quirk) {
xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
xhci->quirks |= XHCI_LINK_TRB_QUIRK;
} else {
xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
}
retval = xhci_mem_init(xhci, GFP_KERNEL);
xhci_dbg(xhci, "Finished xhci_init\n");
@@ -339,13 +351,14 @@ void xhci_event_ring_work(unsigned long arg)
xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
xhci_dbg_cmd_ptrs(xhci);
for (i = 0; i < MAX_HC_SLOTS; ++i) {
if (xhci->devs[i]) {
for (j = 0; j < 31; ++j) {
if (xhci->devs[i]->ep_rings[j]) {
xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
xhci_debug_segment(xhci, xhci->devs[i]->ep_rings[j]->deq_seg);
}
}
if (!xhci->devs[i])
continue;
for (j = 0; j < 31; ++j) {
struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
if (!ring)
continue;
xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
xhci_debug_segment(xhci, ring->deq_seg);
}
}
@@ -555,13 +568,22 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
return 1 << (xhci_get_endpoint_index(desc) + 1);
}
/* Find the flag for this endpoint (for use in the control context). Use the
* endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
* bit 1, etc.
*/
unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
{
return 1 << (ep_index + 1);
}
/* Compute the last valid endpoint context index. Basically, this is the
* endpoint index plus one. For slot contexts with more than valid endpoint,
* we find the most significant bit set in the added contexts flags.
* e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
* fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
*/
static inline unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
{
return fls(added_ctxs) - 1;
}
@@ -589,6 +611,71 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
return 1;
}
static int xhci_configure_endpoint(struct xhci_hcd *xhci,
struct usb_device *udev, struct xhci_command *command,
bool ctx_change, bool must_succeed);
/*
* Full speed devices may have a max packet size greater than 8 bytes, but the
* USB core doesn't know that until it reads the first 8 bytes of the
* descriptor. If the usb_device's max packet size changes after that point,
* we need to issue an evaluate context command and wait on it.
*/
static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
unsigned int ep_index, struct urb *urb)
{
struct xhci_container_ctx *in_ctx;
struct xhci_container_ctx *out_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_ep_ctx *ep_ctx;
int max_packet_size;
int hw_max_packet_size;
int ret = 0;
out_ctx = xhci->devs[slot_id]->out_ctx;
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
if (hw_max_packet_size != max_packet_size) {
xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
max_packet_size);
xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
hw_max_packet_size);
xhci_dbg(xhci, "Issuing evaluate context command.\n");
/* Set up the modified control endpoint 0 */
xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
xhci->devs[slot_id]->out_ctx, ep_index);
in_ctx = xhci->devs[slot_id]->in_ctx;
ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
/* Set up the input context flags for the command */
/* FIXME: This won't work if a non-default control endpoint
* changes max packet sizes.
*/
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ctrl_ctx->add_flags = EP0_FLAG;
ctrl_ctx->drop_flags = 0;
xhci_dbg(xhci, "Slot %d input context\n", slot_id);
xhci_dbg_ctx(xhci, in_ctx, ep_index);
xhci_dbg(xhci, "Slot %d output context\n", slot_id);
xhci_dbg_ctx(xhci, out_ctx, ep_index);
ret = xhci_configure_endpoint(xhci, urb->dev, NULL,
true, false);
/* Clean up the input context for later use by bandwidth
* functions.
*/
ctrl_ctx->add_flags = SLOT_FLAG;
}
return ret;
}
/*
* non-error returns are a promise to giveback() the urb later
* we drop ownership so next owner (or urb unlink) can get it
@@ -600,13 +687,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
int ret = 0;
unsigned int slot_id, ep_index;
if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
return -EINVAL;
slot_id = urb->dev->slot_id;
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
spin_lock_irqsave(&xhci->lock, flags);
if (!xhci->devs || !xhci->devs[slot_id]) {
if (!in_interrupt())
dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
@@ -619,19 +706,38 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
ret = -ESHUTDOWN;
goto exit;
}
if (usb_endpoint_xfer_control(&urb->ep->desc))
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
/* Check to see if the max packet size for the default control
* endpoint changed during FS device enumeration
*/
if (urb->dev->speed == USB_SPEED_FULL) {
ret = xhci_check_maxpacket(xhci, slot_id,
ep_index, urb);
if (ret < 0)
return ret;
}
/* We have a spinlock and interrupts disabled, so we must pass
* atomic context to this function, which may allocate memory.
*/
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index);
else if (usb_endpoint_xfer_bulk(&urb->ep->desc))
spin_unlock_irqrestore(&xhci->lock, flags);
} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index);
else
spin_unlock_irqrestore(&xhci->lock, flags);
} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index);
spin_unlock_irqrestore(&xhci->lock, flags);
} else {
ret = -EINVAL;
}
exit:
spin_unlock_irqrestore(&xhci->lock, flags);
return ret;
}
@@ -674,6 +780,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
struct xhci_td *td;
unsigned int ep_index;
struct xhci_ring *ep_ring;
struct xhci_virt_ep *ep;
xhci = hcd_to_xhci(hcd);
spin_lock_irqsave(&xhci->lock, flags);
@@ -686,17 +793,18 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
xhci_dbg(xhci, "Event ring:\n");
xhci_debug_ring(xhci, xhci->event_ring);
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index];
ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
ep_ring = ep->ring;
xhci_dbg(xhci, "Endpoint ring:\n");
xhci_debug_ring(xhci, ep_ring);
td = (struct xhci_td *) urb->hcpriv;
ep_ring->cancels_pending++;
list_add_tail(&td->cancelled_td_list, &ep_ring->cancelled_td_list);
ep->cancels_pending++;
list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
/* Queue a stop endpoint command, but only if this is
* the first cancellation to be handled.
*/
if (ep_ring->cancels_pending == 1) {
if (ep->cancels_pending == 1) {
xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
xhci_ring_cmd_db(xhci);
}
@@ -930,6 +1038,141 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir
}
}
static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
struct usb_device *udev, int *cmd_status)
{
int ret;
switch (*cmd_status) {
case COMP_ENOMEM:
dev_warn(&udev->dev, "Not enough host controller resources "
"for new device state.\n");
ret = -ENOMEM;
/* FIXME: can we allocate more resources for the HC? */
break;
case COMP_BW_ERR:
dev_warn(&udev->dev, "Not enough bandwidth "
"for new device state.\n");
ret = -ENOSPC;
/* FIXME: can we go back to the old state? */
break;
case COMP_TRB_ERR:
/* the HCD set up something wrong */
dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
"add flag = 1, "
"and endpoint is not disabled.\n");
ret = -EINVAL;
break;
case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
ret = 0;
break;
default:
xhci_err(xhci, "ERROR: unexpected command completion "
"code 0x%x.\n", *cmd_status);
ret = -EINVAL;
break;
}
return ret;
}
static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
struct usb_device *udev, int *cmd_status)
{
int ret;
struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
switch (*cmd_status) {
case COMP_EINVAL:
dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
"context command.\n");
ret = -EINVAL;
break;
case COMP_EBADSLT:
dev_warn(&udev->dev, "WARN: slot not enabled for"
"evaluate context command.\n");
case COMP_CTX_STATE:
dev_warn(&udev->dev, "WARN: invalid context state for "
"evaluate context command.\n");
xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
ret = -EINVAL;
break;
case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful evaluate context command\n");
ret = 0;
break;
default:
xhci_err(xhci, "ERROR: unexpected command completion "
"code 0x%x.\n", *cmd_status);
ret = -EINVAL;
break;
}
return ret;
}
/* Issue a configure endpoint command or evaluate context command
* and wait for it to finish.
*/
static int xhci_configure_endpoint(struct xhci_hcd *xhci,
struct usb_device *udev,
struct xhci_command *command,
bool ctx_change, bool must_succeed)
{
int ret;
int timeleft;
unsigned long flags;
struct xhci_container_ctx *in_ctx;
struct completion *cmd_completion;
int *cmd_status;
struct xhci_virt_device *virt_dev;
spin_lock_irqsave(&xhci->lock, flags);
virt_dev = xhci->devs[udev->slot_id];
if (command) {
in_ctx = command->in_ctx;
cmd_completion = command->completion;
cmd_status = &command->status;
command->command_trb = xhci->cmd_ring->enqueue;
list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
} else {
in_ctx = virt_dev->in_ctx;
cmd_completion = &virt_dev->cmd_completion;
cmd_status = &virt_dev->cmd_status;
}
if (!ctx_change)
ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
udev->slot_id, must_succeed);
else
ret = xhci_queue_evaluate_context(xhci, in_ctx->dma,
udev->slot_id);
if (ret < 0) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
return -ENOMEM;
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
/* Wait for the configure endpoint command to complete */
timeleft = wait_for_completion_interruptible_timeout(
cmd_completion,
USB_CTRL_SET_TIMEOUT);
if (timeleft <= 0) {
xhci_warn(xhci, "%s while waiting for %s command\n",
timeleft == 0 ? "Timeout" : "Signal",
ctx_change == 0 ?
"configure endpoint" :
"evaluate context");
/* FIXME cancel the configure endpoint command */
return -ETIME;
}
if (!ctx_change)
return xhci_configure_endpoint_result(xhci, udev, cmd_status);
return xhci_evaluate_context_result(xhci, udev, cmd_status);
}
/* Called after one or more calls to xhci_add_endpoint() or
* xhci_drop_endpoint(). If this call fails, the USB core is expected
* to call xhci_reset_bandwidth().
@@ -944,8 +1187,6 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
{
int i;
int ret = 0;
int timeleft;
unsigned long flags;
struct xhci_hcd *xhci;
struct xhci_virt_device *virt_dev;
struct xhci_input_control_ctx *ctrl_ctx;
@@ -975,56 +1216,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
xhci_dbg_ctx(xhci, virt_dev->in_ctx,
LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
udev->slot_id);
if (ret < 0) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
return -ENOMEM;
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
/* Wait for the configure endpoint command to complete */
timeleft = wait_for_completion_interruptible_timeout(
&virt_dev->cmd_completion,
USB_CTRL_SET_TIMEOUT);
if (timeleft <= 0) {
xhci_warn(xhci, "%s while waiting for configure endpoint command\n",
timeleft == 0 ? "Timeout" : "Signal");
/* FIXME cancel the configure endpoint command */
return -ETIME;
}
switch (virt_dev->cmd_status) {
case COMP_ENOMEM:
dev_warn(&udev->dev, "Not enough host controller resources "
"for new device state.\n");
ret = -ENOMEM;
/* FIXME: can we allocate more resources for the HC? */
break;
case COMP_BW_ERR:
dev_warn(&udev->dev, "Not enough bandwidth "
"for new device state.\n");
ret = -ENOSPC;
/* FIXME: can we go back to the old state? */
break;
case COMP_TRB_ERR:
/* the HCD set up something wrong */
dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, add flag = 1, "
"and endpoint is not disabled.\n");
ret = -EINVAL;
break;
case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
break;
default:
xhci_err(xhci, "ERROR: unexpected command completion "
"code 0x%x.\n", virt_dev->cmd_status);
ret = -EINVAL;
break;
}
ret = xhci_configure_endpoint(xhci, udev, NULL,
false, false);
if (ret) {
/* Callee should call reset_bandwidth() */
return ret;
@@ -1037,10 +1230,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
xhci_zero_in_ctx(xhci, virt_dev);
/* Free any old rings */
for (i = 1; i < 31; ++i) {
if (virt_dev->new_ep_rings[i]) {
xhci_ring_free(xhci, virt_dev->ep_rings[i]);
virt_dev->ep_rings[i] = virt_dev->new_ep_rings[i];
virt_dev->new_ep_rings[i] = NULL;
if (virt_dev->eps[i].new_ring) {
xhci_ring_free(xhci, virt_dev->eps[i].ring);
virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
virt_dev->eps[i].new_ring = NULL;
}
}
@@ -1067,14 +1260,93 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
virt_dev = xhci->devs[udev->slot_id];
/* Free any rings allocated for added endpoints */
for (i = 0; i < 31; ++i) {
if (virt_dev->new_ep_rings[i]) {
xhci_ring_free(xhci, virt_dev->new_ep_rings[i]);
virt_dev->new_ep_rings[i] = NULL;
if (virt_dev->eps[i].new_ring) {
xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
virt_dev->eps[i].new_ring = NULL;
}
}
xhci_zero_in_ctx(xhci, virt_dev);
}
static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx,
u32 add_flags, u32 drop_flags)
{
struct xhci_input_control_ctx *ctrl_ctx;
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ctrl_ctx->add_flags = add_flags;
ctrl_ctx->drop_flags = drop_flags;
xhci_slot_copy(xhci, in_ctx, out_ctx);
ctrl_ctx->add_flags |= SLOT_FLAG;
xhci_dbg(xhci, "Input Context:\n");
xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags));
}
void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state)
{
struct xhci_container_ctx *in_ctx;
struct xhci_ep_ctx *ep_ctx;
u32 added_ctxs;
dma_addr_t addr;
xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
xhci->devs[slot_id]->out_ctx, ep_index);
in_ctx = xhci->devs[slot_id]->in_ctx;
ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
deq_state->new_deq_ptr);
if (addr == 0) {
xhci_warn(xhci, "WARN Cannot submit config ep after "
"reset ep command\n");
xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
deq_state->new_deq_seg,
deq_state->new_deq_ptr);
return;
}
ep_ctx->deq = addr | deq_state->new_cycle_state;
added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx,
xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs);
}
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
struct usb_device *udev, unsigned int ep_index)
{
struct xhci_dequeue_state deq_state;
struct xhci_virt_ep *ep;
xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
ep = &xhci->devs[udev->slot_id]->eps[ep_index];
/* We need to move the HW's dequeue pointer past this TD,
* or it will attempt to resend it on the next doorbell ring.
*/
xhci_find_new_dequeue_state(xhci, udev->slot_id,
ep_index, ep->stopped_td,
&deq_state);
/* HW with the reset endpoint quirk will use the saved dequeue state to
* issue a configure endpoint command later.
*/
if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
xhci_dbg(xhci, "Queueing new dequeue state\n");
xhci_queue_new_dequeue_state(xhci, udev->slot_id,
ep_index, &deq_state);
} else {
/* Better hope no one uses the input context between now and the
* reset endpoint completion!
*/
xhci_dbg(xhci, "Setting up input context for "
"configure endpoint command\n");
xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
ep_index, &deq_state);
}
}
/* Deal with stalled endpoints. The core should have sent the control message
* to clear the halt condition. However, we need to make the xHCI hardware
* reset its sequence number, since a device will expect a sequence number of
@@ -1089,8 +1361,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
unsigned int ep_index;
unsigned long flags;
int ret;
struct xhci_dequeue_state deq_state;
struct xhci_ring *ep_ring;
struct xhci_virt_ep *virt_ep;
xhci = hcd_to_xhci(hcd);
udev = (struct usb_device *) ep->hcpriv;
@@ -1100,12 +1371,16 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
if (!ep->hcpriv)
return;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ring = xhci->devs[udev->slot_id]->ep_rings[ep_index];
if (!ep_ring->stopped_td) {
virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
if (!virt_ep->stopped_td) {
xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
ep->desc.bEndpointAddress);
return;
}
if (usb_endpoint_xfer_control(&ep->desc)) {
xhci_dbg(xhci, "Control endpoint stall already handled.\n");
return;
}
xhci_dbg(xhci, "Queueing reset endpoint command\n");
spin_lock_irqsave(&xhci->lock, flags);
@@ -1116,17 +1391,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
* command. Better hope that last command worked!
*/
if (!ret) {
xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
/* We need to move the HW's dequeue pointer past this TD,
* or it will attempt to resend it on the next doorbell ring.
*/
xhci_find_new_dequeue_state(xhci, udev->slot_id,
ep_index, ep_ring->stopped_td, &deq_state);
xhci_dbg(xhci, "Queueing new dequeue state\n");
xhci_queue_new_dequeue_state(xhci, ep_ring,
udev->slot_id,
ep_index, &deq_state);
kfree(ep_ring->stopped_td);
xhci_cleanup_stalled_ring(xhci, udev, ep_index);
kfree(virt_ep->stopped_td);
xhci_ring_cmd_db(xhci);
}
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -1328,6 +1594,88 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
return 0;
}
/* Once a hub descriptor is fetched for a device, we need to update the xHC's
* internal data structures for the device.
*/
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
struct usb_tt *tt, gfp_t mem_flags)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_virt_device *vdev;
struct xhci_command *config_cmd;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_slot_ctx *slot_ctx;
unsigned long flags;
unsigned think_time;
int ret;
/* Ignore root hubs */
if (!hdev->parent)
return 0;
vdev = xhci->devs[hdev->slot_id];
if (!vdev) {
xhci_warn(xhci, "Cannot update hub desc for unknown device.\n");
return -EINVAL;
}
config_cmd = xhci_alloc_command(xhci, true, mem_flags);
if (!config_cmd) {
xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
return -ENOMEM;
}
spin_lock_irqsave(&xhci->lock, flags);
xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx);
ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
ctrl_ctx->add_flags |= SLOT_FLAG;
slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
slot_ctx->dev_info |= DEV_HUB;
if (tt->multi)
slot_ctx->dev_info |= DEV_MTT;
if (xhci->hci_version > 0x95) {
xhci_dbg(xhci, "xHCI version %x needs hub "
"TT think time and number of ports\n",
(unsigned int) xhci->hci_version);
slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild);
/* Set TT think time - convert from ns to FS bit times.
* 0 = 8 FS bit times, 1 = 16 FS bit times,
* 2 = 24 FS bit times, 3 = 32 FS bit times.
*/
think_time = tt->think_time;
if (think_time != 0)
think_time = (think_time / 666) - 1;
slot_ctx->tt_info |= TT_THINK_TIME(think_time);
} else {
xhci_dbg(xhci, "xHCI version %x doesn't need hub "
"TT think time or number of ports\n",
(unsigned int) xhci->hci_version);
}
slot_ctx->dev_state = 0;
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "Set up %s for hub device.\n",
(xhci->hci_version > 0x95) ?
"configure endpoint" : "evaluate context");
xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id);
xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0);
/* Issue and wait for the configure endpoint or
* evaluate context command.
*/
if (xhci->hci_version > 0x95)
ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
false, false);
else
ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
true, false);
xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id);
xhci_dbg_ctx(xhci, vdev->out_ctx, 0);
xhci_free_command(xhci, config_cmd);
return ret;
}
int xhci_get_frame(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);

Bestand weergeven

@@ -94,6 +94,9 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
val = prev->trbs[TRBS_PER_SEGMENT-1].link.control;
val &= ~TRB_TYPE_BITMASK;
val |= TRB_TYPE(TRB_LINK);
/* Always set the chain bit with 0.95 hardware */
if (xhci_link_trb_quirk(xhci))
val |= TRB_CHAIN;
prev->trbs[TRBS_PER_SEGMENT-1].link.control = val;
}
xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n",
@@ -141,7 +144,6 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return 0;
INIT_LIST_HEAD(&ring->td_list);
INIT_LIST_HEAD(&ring->cancelled_td_list);
if (num_segs == 0)
return ring;
@@ -262,8 +264,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
return;
for (i = 0; i < 31; ++i)
if (dev->ep_rings[i])
xhci_ring_free(xhci, dev->ep_rings[i]);
if (dev->eps[i].ring)
xhci_ring_free(xhci, dev->eps[i].ring);
if (dev->in_ctx)
xhci_free_container_ctx(xhci, dev->in_ctx);
@@ -278,6 +280,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
struct usb_device *udev, gfp_t flags)
{
struct xhci_virt_device *dev;
int i;
/* Slot ID 0 is reserved */
if (slot_id == 0 || xhci->devs[slot_id]) {
@@ -306,12 +309,17 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
(unsigned long long)dev->in_ctx->dma);
/* Initialize the cancellation list for each endpoint */
for (i = 0; i < 31; i++)
INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list);
/* Allocate endpoint 0 ring */
dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
if (!dev->ep_rings[0])
dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags);
if (!dev->eps[0].ring)
goto fail;
init_completion(&dev->cmd_completion);
INIT_LIST_HEAD(&dev->cmd_list);
/* Point to output device context in dcbaa. */
xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma;
@@ -352,9 +360,9 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
/* 3) Only the control endpoint is valid - one endpoint context */
slot_ctx->dev_info |= LAST_CTX(1);
slot_ctx->dev_info |= (u32) udev->route;
switch (udev->speed) {
case USB_SPEED_SUPER:
slot_ctx->dev_info |= (u32) udev->route;
slot_ctx->dev_info |= (u32) SLOT_SPEED_SS;
break;
case USB_SPEED_HIGH:
@@ -382,14 +390,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum);
/* Is this a LS/FS device under a HS hub? */
/*
* FIXME: I don't think this is right, where does the TT info for the
* roothub or parent hub come from?
*/
if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) &&
udev->tt) {
slot_ctx->tt_info = udev->tt->hub->slot_id;
slot_ctx->tt_info |= udev->ttport << 8;
if (udev->tt->multi)
slot_ctx->dev_info |= DEV_MTT;
}
xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
@@ -398,22 +404,35 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
/* Step 5 */
ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP);
/*
* See section 4.3 bullet 6:
* The default Max Packet size for ep0 is "8 bytes for a USB2
* LS/FS/HS device or 512 bytes for a USB3 SS device"
* XXX: Not sure about wireless USB devices.
*/
if (udev->speed == USB_SPEED_SUPER)
switch (udev->speed) {
case USB_SPEED_SUPER:
ep0_ctx->ep_info2 |= MAX_PACKET(512);
else
break;
case USB_SPEED_HIGH:
/* USB core guesses at a 64-byte max packet first for FS devices */
case USB_SPEED_FULL:
ep0_ctx->ep_info2 |= MAX_PACKET(64);
break;
case USB_SPEED_LOW:
ep0_ctx->ep_info2 |= MAX_PACKET(8);
break;
case USB_SPEED_VARIABLE:
xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
return -EINVAL;
break;
default:
/* New speed? */
BUG();
}
/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
ep0_ctx->ep_info2 |= MAX_BURST(0);
ep0_ctx->ep_info2 |= ERROR_COUNT(3);
ep0_ctx->deq =
dev->ep_rings[0]->first_seg->dma;
ep0_ctx->deq |= dev->ep_rings[0]->cycle_state;
dev->eps[0].ring->first_seg->dma;
ep0_ctx->deq |= dev->eps[0].ring->cycle_state;
/* Steps 7 and 8 were done in xhci_alloc_virt_device() */
@@ -523,10 +542,11 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
/* Set up the endpoint ring */
virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags);
if (!virt_dev->new_ep_rings[ep_index])
virt_dev->eps[ep_index].new_ring =
xhci_ring_alloc(xhci, 1, true, mem_flags);
if (!virt_dev->eps[ep_index].new_ring)
return -ENOMEM;
ep_ring = virt_dev->new_ep_rings[ep_index];
ep_ring = virt_dev->eps[ep_index].new_ring;
ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
@@ -598,6 +618,48 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
*/
}
/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy.
* Useful when you want to change one particular aspect of the endpoint and then
* issue a configure endpoint command.
*/
void xhci_endpoint_copy(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx,
unsigned int ep_index)
{
struct xhci_ep_ctx *out_ep_ctx;
struct xhci_ep_ctx *in_ep_ctx;
out_ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
in_ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
in_ep_ctx->ep_info = out_ep_ctx->ep_info;
in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2;
in_ep_ctx->deq = out_ep_ctx->deq;
in_ep_ctx->tx_info = out_ep_ctx->tx_info;
}
/* Copy output xhci_slot_ctx to the input xhci_slot_ctx.
* Useful when you want to change one particular aspect of the endpoint and then
* issue a configure endpoint command. Only the context entries field matters,
* but we'll copy the whole thing anyway.
*/
void xhci_slot_copy(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx)
{
struct xhci_slot_ctx *in_slot_ctx;
struct xhci_slot_ctx *out_slot_ctx;
in_slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
out_slot_ctx = xhci_get_slot_ctx(xhci, out_ctx);
in_slot_ctx->dev_info = out_slot_ctx->dev_info;
in_slot_ctx->dev_info2 = out_slot_ctx->dev_info2;
in_slot_ctx->tt_info = out_slot_ctx->tt_info;
in_slot_ctx->dev_state = out_slot_ctx->dev_state;
}
/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
{
@@ -695,6 +757,44 @@ static void scratchpad_free(struct xhci_hcd *xhci)
xhci->scratchpad = NULL;
}
struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
bool allocate_completion, gfp_t mem_flags)
{
struct xhci_command *command;
command = kzalloc(sizeof(*command), mem_flags);
if (!command)
return NULL;
command->in_ctx =
xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, mem_flags);
if (!command->in_ctx)
return NULL;
if (allocate_completion) {
command->completion =
kzalloc(sizeof(struct completion), mem_flags);
if (!command->completion) {
xhci_free_container_ctx(xhci, command->in_ctx);
return NULL;
}
init_completion(command->completion);
}
command->status = 0;
INIT_LIST_HEAD(&command->cmd_list);
return command;
}
void xhci_free_command(struct xhci_hcd *xhci,
struct xhci_command *command)
{
xhci_free_container_ctx(xhci,
command->in_ctx);
kfree(command->completion);
kfree(command);
}
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);

Bestand weergeven

@@ -24,6 +24,10 @@
#include "xhci.h"
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */
@@ -59,9 +63,20 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
xhci->hcs_params1 = xhci_readl(xhci, &xhci->cap_regs->hcs_params1);
xhci->hcs_params2 = xhci_readl(xhci, &xhci->cap_regs->hcs_params2);
xhci->hcs_params3 = xhci_readl(xhci, &xhci->cap_regs->hcs_params3);
xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
xhci->hci_version = HC_VERSION(xhci->hcc_params);
xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
xhci_print_registers(xhci);
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
}
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
if (retval)
@@ -121,6 +136,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
.address_device = xhci_address_device,
.update_hub_device = xhci_update_hub_device,
/*
* scheduling support

Bestand weergeven

@@ -172,8 +172,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
* have their chain bit cleared (so that each Link TRB is a separate TD).
*
* Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit
* set, but other sections talk about dealing with the chain bit set.
* Assume section 6.4.4.1 is wrong, and the chain bit can be set in a Link TRB.
* set, but other sections talk about dealing with the chain bit set. This was
* fixed in the 0.96 specification errata, but we have to assume that all 0.95
* xHCI hardware can't handle the chain bit being cleared on a link TRB.
*/
static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
{
@@ -191,8 +192,14 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
while (last_trb(xhci, ring, ring->enq_seg, next)) {
if (!consumer) {
if (ring != xhci->event_ring) {
next->link.control &= ~TRB_CHAIN;
next->link.control |= chain;
/* If we're not dealing with 0.95 hardware,
* carry over the chain bit of the previous TRB
* (which may mean the chain bit is cleared).
*/
if (!xhci_link_trb_quirk(xhci)) {
next->link.control &= ~TRB_CHAIN;
next->link.control |= chain;
}
/* Give this link TRB to the hardware */
wmb();
if (next->link.control & TRB_CYCLE)
@@ -289,16 +296,18 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci,
unsigned int slot_id,
unsigned int ep_index)
{
struct xhci_ring *ep_ring;
struct xhci_virt_ep *ep;
unsigned int ep_state;
u32 field;
__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
ep = &xhci->devs[slot_id]->eps[ep_index];
ep_state = ep->ep_state;
/* Don't ring the doorbell for this endpoint if there are pending
* cancellations because the we don't want to interrupt processing.
*/
if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)
&& !(ep_ring->state & EP_HALTED)) {
if (!ep->cancels_pending && !(ep_state & SET_DEQ_PENDING)
&& !(ep_state & EP_HALTED)) {
field = xhci_readl(xhci, db_addr) & DB_MASK;
xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
/* Flush PCI posted writes - FIXME Matthew Wilcox says this
@@ -354,7 +363,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
struct xhci_td *cur_td, struct xhci_dequeue_state *state)
{
struct xhci_virt_device *dev = xhci->devs[slot_id];
struct xhci_ring *ep_ring = dev->ep_rings[ep_index];
struct xhci_ring *ep_ring = dev->eps[ep_index].ring;
struct xhci_generic_trb *trb;
struct xhci_ep_ctx *ep_ctx;
dma_addr_t addr;
@@ -362,7 +371,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
state->new_cycle_state = 0;
xhci_dbg(xhci, "Finding segment containing stopped TRB.\n");
state->new_deq_seg = find_trb_seg(cur_td->start_seg,
ep_ring->stopped_trb,
dev->eps[ep_index].stopped_trb,
&state->new_cycle_state);
if (!state->new_deq_seg)
BUG();
@@ -442,9 +451,11 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
union xhci_trb *deq_ptr, u32 cycle_state);
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring, unsigned int slot_id,
unsigned int ep_index, struct xhci_dequeue_state *deq_state)
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state)
{
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
"new deq ptr = %p (0x%llx dma), new cycle = %u\n",
deq_state->new_deq_seg,
@@ -461,8 +472,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
* if the ring is running, and ringing the doorbell starts the
* ring running.
*/
ep_ring->state |= SET_DEQ_PENDING;
xhci_ring_cmd_db(xhci);
ep->ep_state |= SET_DEQ_PENDING;
}
/*
@@ -481,6 +491,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
unsigned int slot_id;
unsigned int ep_index;
struct xhci_ring *ep_ring;
struct xhci_virt_ep *ep;
struct list_head *entry;
struct xhci_td *cur_td = 0;
struct xhci_td *last_unlinked_td;
@@ -493,9 +504,10 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
memset(&deq_state, 0, sizeof(deq_state));
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
ep = &xhci->devs[slot_id]->eps[ep_index];
ep_ring = ep->ring;
if (list_empty(&ep_ring->cancelled_td_list))
if (list_empty(&ep->cancelled_td_list))
return;
/* Fix up the ep ring first, so HW stops executing cancelled TDs.
@@ -503,7 +515,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
* it. We're also in the event handler, so we can't get re-interrupted
* if another Stop Endpoint command completes
*/
list_for_each(entry, &ep_ring->cancelled_td_list) {
list_for_each(entry, &ep->cancelled_td_list) {
cur_td = list_entry(entry, struct xhci_td, cancelled_td_list);
xhci_dbg(xhci, "Cancelling TD starting at %p, 0x%llx (dma).\n",
cur_td->first_trb,
@@ -512,7 +524,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
* If we stopped on the TD we need to cancel, then we have to
* move the xHC endpoint ring dequeue pointer past this TD.
*/
if (cur_td == ep_ring->stopped_td)
if (cur_td == ep->stopped_td)
xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
&deq_state);
else
@@ -523,14 +535,15 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
* the cancelled TD list for URB completion later.
*/
list_del(&cur_td->td_list);
ep_ring->cancels_pending--;
ep->cancels_pending--;
}
last_unlinked_td = cur_td;
/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
xhci_queue_new_dequeue_state(xhci, ep_ring,
xhci_queue_new_dequeue_state(xhci,
slot_id, ep_index, &deq_state);
xhci_ring_cmd_db(xhci);
} else {
/* Otherwise just ring the doorbell to restart the ring */
ring_ep_doorbell(xhci, slot_id, ep_index);
@@ -543,7 +556,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
* So stop when we've completed the URB for the last TD we unlinked.
*/
do {
cur_td = list_entry(ep_ring->cancelled_td_list.next,
cur_td = list_entry(ep->cancelled_td_list.next,
struct xhci_td, cancelled_td_list);
list_del(&cur_td->cancelled_td_list);
@@ -590,7 +603,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
dev = xhci->devs[slot_id];
ep_ring = dev->ep_rings[ep_index];
ep_ring = dev->eps[ep_index].ring;
ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
@@ -634,7 +647,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
ep_ctx->deq);
}
ep_ring->state &= ~SET_DEQ_PENDING;
dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
ring_ep_doorbell(xhci, slot_id, ep_index);
}
@@ -644,18 +657,60 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
{
int slot_id;
unsigned int ep_index;
struct xhci_ring *ep_ring;
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
/* This command will only fail if the endpoint wasn't halted,
* but we don't care.
*/
xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n",
(unsigned int) GET_COMP_CODE(event->status));
/* Clear our internal halted state and restart the ring */
xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED;
ring_ep_doorbell(xhci, slot_id, ep_index);
/* HW with the reset endpoint quirk needs to have a configure endpoint
* command complete before the endpoint can be used. Queue that here
* because the HW can't handle two commands being queued in a row.
*/
if (xhci->quirks & XHCI_RESET_EP_QUIRK) {
xhci_dbg(xhci, "Queueing configure endpoint command\n");
xhci_queue_configure_endpoint(xhci,
xhci->devs[slot_id]->in_ctx->dma, slot_id,
false);
xhci_ring_cmd_db(xhci);
} else {
/* Clear our internal halted state and restart the ring */
xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
ring_ep_doorbell(xhci, slot_id, ep_index);
}
}
/* Check to see if a command in the device's command queue matches this one.
* Signal the completion or free the command, and return 1. Return 0 if the
* completed command isn't at the head of the command list.
*/
static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
struct xhci_event_cmd *event)
{
struct xhci_command *command;
if (list_empty(&virt_dev->cmd_list))
return 0;
command = list_entry(virt_dev->cmd_list.next,
struct xhci_command, cmd_list);
if (xhci->cmd_ring->dequeue != command->command_trb)
return 0;
command->status =
GET_COMP_CODE(event->status);
list_del(&command->cmd_list);
if (command->completion)
complete(command->completion);
else
xhci_free_command(xhci, command);
return 1;
}
static void handle_cmd_completion(struct xhci_hcd *xhci,
@@ -664,6 +719,11 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
int slot_id = TRB_TO_SLOT_ID(event->flags);
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_virt_device *virt_dev;
unsigned int ep_index;
struct xhci_ring *ep_ring;
unsigned int ep_state;
cmd_dma = event->cmd_trb;
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
@@ -691,6 +751,47 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_free_virt_device(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
virt_dev = xhci->devs[slot_id];
if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
break;
/*
* Configure endpoint commands can come from the USB core
* configuration or alt setting changes, or because the HW
* needed an extra configure endpoint command after a reset
* endpoint command. In the latter case, the xHCI driver is
* not waiting on the configure endpoint command.
*/
ctrl_ctx = xhci_get_input_control_ctx(xhci,
virt_dev->in_ctx);
/* Input ctx add_flags are the endpoint index plus one */
ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
if (!ep_ring) {
/* This must have been an initial configure endpoint */
xhci->devs[slot_id]->cmd_status =
GET_COMP_CODE(event->status);
complete(&xhci->devs[slot_id]->cmd_completion);
break;
}
ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
"state = %d\n", ep_index, ep_state);
if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
ep_state & EP_HALTED) {
/* Clear our internal halted state and restart ring */
xhci->devs[slot_id]->eps[ep_index].ep_state &=
~EP_HALTED;
ring_ep_doorbell(xhci, slot_id, ep_index);
} else {
xhci->devs[slot_id]->cmd_status =
GET_COMP_CODE(event->status);
complete(&xhci->devs[slot_id]->cmd_completion);
}
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
virt_dev = xhci->devs[slot_id];
if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
break;
xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
complete(&xhci->devs[slot_id]->cmd_completion);
break;
@@ -805,7 +906,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
struct xhci_transfer_event *event)
{
struct xhci_virt_device *xdev;
struct xhci_virt_ep *ep;
struct xhci_ring *ep_ring;
unsigned int slot_id;
int ep_index;
struct xhci_td *td = 0;
dma_addr_t event_dma;
@@ -814,9 +917,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
struct urb *urb = 0;
int status = -EINPROGRESS;
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
xhci_dbg(xhci, "In %s\n", __func__);
xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)];
slot_id = TRB_TO_SLOT_ID(event->flags);
xdev = xhci->devs[slot_id];
if (!xdev) {
xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n");
return -ENODEV;
@@ -825,7 +930,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* Endpoint ID is 1 based, our index is zero based */
ep_index = TRB_TO_EP_ID(event->flags) - 1;
xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
ep_ring = xdev->ep_rings[ep_index];
ep = &xdev->eps[ep_index];
ep_ring = ep->ring;
ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
@@ -870,7 +976,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
(unsigned int) event->flags);
/* Look for common error cases */
switch (GET_COMP_CODE(event->transfer_len)) {
trb_comp_code = GET_COMP_CODE(event->transfer_len);
switch (trb_comp_code) {
/* Skip codes that require special handling depending on
* transfer type
*/
@@ -885,7 +992,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
break;
case COMP_STALL:
xhci_warn(xhci, "WARN: Stalled endpoint\n");
ep_ring->state |= EP_HALTED;
ep->ep_state |= EP_HALTED;
status = -EPIPE;
break;
case COMP_TRB_ERR:
@@ -913,7 +1020,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* Was this a control transfer? */
if (usb_endpoint_xfer_control(&td->urb->ep->desc)) {
xhci_debug_trb(xhci, xhci->event_ring->dequeue);
switch (GET_COMP_CODE(event->transfer_len)) {
switch (trb_comp_code) {
case COMP_SUCCESS:
if (event_trb == ep_ring->dequeue) {
xhci_warn(xhci, "WARN: Success on ctrl setup TRB without IOC set??\n");
@@ -928,8 +1035,37 @@ static int handle_tx_event(struct xhci_hcd *xhci,
break;
case COMP_SHORT_TX:
xhci_warn(xhci, "WARN: short transfer on control ep\n");
status = -EREMOTEIO;
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
status = -EREMOTEIO;
else
status = 0;
break;
case COMP_BABBLE:
/* The 0.96 spec says a babbling control endpoint
* is not halted. The 0.96 spec says it is. Some HW
* claims to be 0.95 compliant, but it halts the control
* endpoint anyway. Check if a babble halted the
* endpoint.
*/
if (ep_ctx->ep_info != EP_STATE_HALTED)
break;
/* else fall through */
case COMP_STALL:
/* Did we transfer part of the data (middle) phase? */
if (event_trb != ep_ring->dequeue &&
event_trb != td->last_trb)
td->urb->actual_length =
td->urb->transfer_buffer_length
- TRB_LEN(event->transfer_len);
else
td->urb->actual_length = 0;
ep->stopped_td = td;
ep->stopped_trb = event_trb;
xhci_queue_reset_ep(xhci, slot_id, ep_index);
xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
xhci_ring_cmd_db(xhci);
goto td_cleanup;
default:
/* Others already handled above */
break;
@@ -943,7 +1079,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (event_trb == td->last_trb) {
if (td->urb->actual_length != 0) {
/* Don't overwrite a previously set error code */
if (status == -EINPROGRESS || status == 0)
if ((status == -EINPROGRESS ||
status == 0) &&
(td->urb->transfer_flags
& URB_SHORT_NOT_OK))
/* Did we already see a short data stage? */
status = -EREMOTEIO;
} else {
@@ -952,7 +1091,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
}
} else {
/* Maybe the event was for the data stage? */
if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) {
if (trb_comp_code != COMP_STOP_INVAL) {
/* We didn't stop on a link TRB in the middle */
td->urb->actual_length =
td->urb->transfer_buffer_length -
@@ -964,7 +1103,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
}
}
} else {
switch (GET_COMP_CODE(event->transfer_len)) {
switch (trb_comp_code) {
case COMP_SUCCESS:
/* Double check that the HW transferred everything. */
if (event_trb != td->last_trb) {
@@ -975,7 +1114,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
else
status = 0;
} else {
xhci_dbg(xhci, "Successful bulk transfer!\n");
if (usb_endpoint_xfer_bulk(&td->urb->ep->desc))
xhci_dbg(xhci, "Successful bulk "
"transfer!\n");
else
xhci_dbg(xhci, "Successful interrupt "
"transfer!\n");
status = 0;
}
break;
@@ -1001,11 +1145,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
td->urb->actual_length =
td->urb->transfer_buffer_length -
TRB_LEN(event->transfer_len);
if (td->urb->actual_length < 0) {
if (td->urb->transfer_buffer_length <
td->urb->actual_length) {
xhci_warn(xhci, "HC gave bad length "
"of %d bytes left\n",
TRB_LEN(event->transfer_len));
td->urb->actual_length = 0;
if (td->urb->transfer_flags &
URB_SHORT_NOT_OK)
status = -EREMOTEIO;
else
status = 0;
}
/* Don't overwrite a previously set error code */
if (status == -EINPROGRESS) {
@@ -1041,30 +1191,31 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* If the ring didn't stop on a Link or No-op TRB, add
* in the actual bytes transferred from the Normal TRB
*/
if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL)
if (trb_comp_code != COMP_STOP_INVAL)
td->urb->actual_length +=
TRB_LEN(cur_trb->generic.field[2]) -
TRB_LEN(event->transfer_len);
}
}
if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL ||
GET_COMP_CODE(event->transfer_len) == COMP_STOP) {
if (trb_comp_code == COMP_STOP_INVAL ||
trb_comp_code == COMP_STOP) {
/* The Endpoint Stop Command completion will take care of any
* stopped TDs. A stopped TD may be restarted, so don't update
* the ring dequeue pointer or take this TD off any lists yet.
*/
ep_ring->stopped_td = td;
ep_ring->stopped_trb = event_trb;
ep->stopped_td = td;
ep->stopped_trb = event_trb;
} else {
if (GET_COMP_CODE(event->transfer_len) == COMP_STALL) {
if (trb_comp_code == COMP_STALL ||
trb_comp_code == COMP_BABBLE) {
/* The transfer is completed from the driver's
* perspective, but we need to issue a set dequeue
* command for this stalled endpoint to move the dequeue
* pointer past the TD. We can't do that here because
* the halt condition must be cleared first.
*/
ep_ring->stopped_td = td;
ep_ring->stopped_trb = event_trb;
ep->stopped_td = td;
ep->stopped_trb = event_trb;
} else {
/* Update ring dequeue pointer */
while (ep_ring->dequeue != td->last_trb)
@@ -1072,16 +1223,41 @@ static int handle_tx_event(struct xhci_hcd *xhci,
inc_deq(xhci, ep_ring, false);
}
td_cleanup:
/* Clean up the endpoint's TD list */
urb = td->urb;
/* Do one last check of the actual transfer length.
* If the host controller said we transferred more data than
* the buffer length, urb->actual_length will be a very big
* number (since it's unsigned). Play it safe and say we didn't
* transfer anything.
*/
if (urb->actual_length > urb->transfer_buffer_length) {
xhci_warn(xhci, "URB transfer length is wrong, "
"xHC issue? req. len = %u, "
"act. len = %u\n",
urb->transfer_buffer_length,
urb->actual_length);
urb->actual_length = 0;
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
status = -EREMOTEIO;
else
status = 0;
}
list_del(&td->td_list);
/* Was this TD slated to be cancelled but completed anyway? */
if (!list_empty(&td->cancelled_td_list)) {
list_del(&td->cancelled_td_list);
ep_ring->cancels_pending--;
ep->cancels_pending--;
}
/* Leave the TD around for the reset endpoint function to use */
if (GET_COMP_CODE(event->transfer_len) != COMP_STALL) {
/* Leave the TD around for the reset endpoint function to use
* (but only if it's not a control endpoint, since we already
* queued the Set TR dequeue pointer command for stalled
* control endpoints).
*/
if (usb_endpoint_xfer_control(&urb->ep->desc) ||
(trb_comp_code != COMP_STALL &&
trb_comp_code != COMP_BABBLE)) {
kfree(td);
}
urb->hcpriv = NULL;
@@ -1094,7 +1270,7 @@ cleanup:
if (urb) {
usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb);
xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n",
urb, td->urb->actual_length, status);
urb, urb->actual_length, status);
spin_unlock(&xhci->lock);
usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status);
spin_lock(&xhci->lock);
@@ -1235,7 +1411,7 @@ static int prepare_transfer(struct xhci_hcd *xhci,
{
int ret;
struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
ret = prepare_ring(xhci, xdev->ep_rings[ep_index],
ret = prepare_ring(xhci, xdev->eps[ep_index].ring,
ep_ctx->ep_info & EP_STATE_MASK,
num_trbs, mem_flags);
if (ret)
@@ -1255,9 +1431,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
(*td)->urb = urb;
urb->hcpriv = (void *) (*td);
/* Add this TD to the tail of the endpoint ring's TD list */
list_add_tail(&(*td)->td_list, &xdev->ep_rings[ep_index]->td_list);
(*td)->start_seg = xdev->ep_rings[ep_index]->enq_seg;
(*td)->first_trb = xdev->ep_rings[ep_index]->enqueue;
list_add_tail(&(*td)->td_list, &xdev->eps[ep_index].ring->td_list);
(*td)->start_seg = xdev->eps[ep_index].ring->enq_seg;
(*td)->first_trb = xdev->eps[ep_index].ring->enqueue;
return 0;
}
@@ -1335,6 +1511,47 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
ring_ep_doorbell(xhci, slot_id, ep_index);
}
/*
* xHCI uses normal TRBs for both bulk and interrupt. When the interrupt
* endpoint is to be serviced, the xHC will consume (at most) one TD. A TD
* (comprised of sg list entries) can take several service intervals to
* transmit.
*/
int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct urb *urb, int slot_id, unsigned int ep_index)
{
struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci,
xhci->devs[slot_id]->out_ctx, ep_index);
int xhci_interval;
int ep_interval;
xhci_interval = EP_INTERVAL_TO_UFRAMES(ep_ctx->ep_info);
ep_interval = urb->interval;
/* Convert to microframes */
if (urb->dev->speed == USB_SPEED_LOW ||
urb->dev->speed == USB_SPEED_FULL)
ep_interval *= 8;
/* FIXME change this to a warning and a suggestion to use the new API
* to set the polling interval (once the API is added).
*/
if (xhci_interval != ep_interval) {
if (!printk_ratelimit())
dev_dbg(&urb->dev->dev, "Driver uses different interval"
" (%d microframe%s) than xHCI "
"(%d microframe%s)\n",
ep_interval,
ep_interval == 1 ? "" : "s",
xhci_interval,
xhci_interval == 1 ? "" : "s");
urb->interval = xhci_interval;
/* Convert back to frames for LS/FS devices */
if (urb->dev->speed == USB_SPEED_LOW ||
urb->dev->speed == USB_SPEED_FULL)
urb->interval /= 8;
}
return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
}
static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct urb *urb, int slot_id, unsigned int ep_index)
{
@@ -1350,7 +1567,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct xhci_generic_trb *start_trb;
int start_cycle;
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_sgs;
@@ -1483,7 +1700,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (urb->sg)
return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
num_trbs = 0;
/* How much data is (potentially) left before the 64KB boundary? */
@@ -1594,7 +1811,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
u32 field, length_field;
struct xhci_td *td;
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
/*
* Need to copy setup packet into setup TRB, so we can't use the setup
@@ -1677,12 +1894,27 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/**** Command Ring Operations ****/
/* Generic function for queueing a command TRB on the command ring */
static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, u32 field3, u32 field4)
/* Generic function for queueing a command TRB on the command ring.
* Check to make sure there's room on the command ring for one command TRB.
* Also check that there's room reserved for commands that must not fail.
* If this is a command that must not fail, meaning command_must_succeed = TRUE,
* then only check for the number of reserved spots.
* Don't decrement xhci->cmd_ring_reserved_trbs after we've queued the TRB
* because the command event handler may want to resubmit a failed command.
*/
static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2,
u32 field3, u32 field4, bool command_must_succeed)
{
if (!room_on_ring(xhci, xhci->cmd_ring, 1)) {
int reserved_trbs = xhci->cmd_ring_reserved_trbs;
if (!command_must_succeed)
reserved_trbs++;
if (!room_on_ring(xhci, xhci->cmd_ring, reserved_trbs)) {
if (!in_interrupt())
xhci_err(xhci, "ERR: No room for command on command ring\n");
if (command_must_succeed)
xhci_err(xhci, "ERR: Reserved TRB counting for "
"unfailable commands failed.\n");
return -ENOMEM;
}
queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
@@ -1693,7 +1925,7 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, u32 fiel
/* Queue a no-op command on the command ring */
static int queue_cmd_noop(struct xhci_hcd *xhci)
{
return queue_command(xhci, 0, 0, 0, TRB_TYPE(TRB_CMD_NOOP));
return queue_command(xhci, 0, 0, 0, TRB_TYPE(TRB_CMD_NOOP), false);
}
/*
@@ -1712,7 +1944,7 @@ void *xhci_setup_one_noop(struct xhci_hcd *xhci)
int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id)
{
return queue_command(xhci, 0, 0, 0,
TRB_TYPE(trb_type) | SLOT_ID_FOR_TRB(slot_id));
TRB_TYPE(trb_type) | SLOT_ID_FOR_TRB(slot_id), false);
}
/* Queue an address device command TRB */
@@ -1721,16 +1953,28 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
{
return queue_command(xhci, lower_32_bits(in_ctx_ptr),
upper_32_bits(in_ctx_ptr), 0,
TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id));
TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id),
false);
}
/* Queue a configure endpoint command TRB */
int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id, bool command_must_succeed)
{
return queue_command(xhci, lower_32_bits(in_ctx_ptr),
upper_32_bits(in_ctx_ptr), 0,
TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id),
command_must_succeed);
}
/* Queue an evaluate context command TRB */
int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id)
{
return queue_command(xhci, lower_32_bits(in_ctx_ptr),
upper_32_bits(in_ctx_ptr), 0,
TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id));
TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id),
false);
}
int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
@@ -1741,7 +1985,7 @@ int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
u32 type = TRB_TYPE(TRB_STOP_RING);
return queue_command(xhci, 0, 0, 0,
trb_slot_id | trb_ep_index | type);
trb_slot_id | trb_ep_index | type, false);
}
/* Set Transfer Ring Dequeue Pointer command.
@@ -1765,7 +2009,7 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
}
return queue_command(xhci, lower_32_bits(addr) | cycle_state,
upper_32_bits(addr), 0,
trb_slot_id | trb_ep_index | type);
trb_slot_id | trb_ep_index | type, false);
}
int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
@@ -1775,5 +2019,6 @@ int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);
u32 type = TRB_TYPE(TRB_RESET_EP);
return queue_command(xhci, 0, 0, 0, trb_slot_id | trb_ep_index | type);
return queue_command(xhci, 0, 0, 0, trb_slot_id | trb_ep_index | type,
false);
}

Bestand weergeven

@@ -509,6 +509,8 @@ struct xhci_slot_ctx {
#define MAX_EXIT (0xffff)
/* Root hub port number that is needed to access the USB device */
#define ROOT_HUB_PORT(p) (((p) & 0xff) << 16)
/* Maximum number of ports under a hub device */
#define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24)
/* tt_info bitmasks */
/*
@@ -522,6 +524,7 @@ struct xhci_slot_ctx {
* '0' if the device is not low or full speed.
*/
#define TT_PORT (0xff << 8)
#define TT_THINK_TIME(p) (((p) & 0x3) << 16)
/* dev_state bitmasks */
/* USB device address - assigned by the HC */
@@ -581,6 +584,7 @@ struct xhci_ep_ctx {
/* bit 15 is Linear Stream Array */
/* Interval - period between requests to an endpoint - 125u increments. */
#define EP_INTERVAL(p) ((p & 0xff) << 16)
#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff))
/* ep_info2 bitmasks */
/*
@@ -589,6 +593,7 @@ struct xhci_ep_ctx {
*/
#define FORCE_EVENT (0x1)
#define ERROR_COUNT(p) (((p) & 0x3) << 1)
#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7)
#define EP_TYPE(p) ((p) << 3)
#define ISOC_OUT_EP 1
#define BULK_OUT_EP 2
@@ -601,6 +606,8 @@ struct xhci_ep_ctx {
/* bit 7 is Host Initiate Disable - for disabling stream selection */
#define MAX_BURST(p) (((p)&0xff) << 8)
#define MAX_PACKET(p) (((p)&0xffff) << 16)
#define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
/**
@@ -616,11 +623,44 @@ struct xhci_input_control_ctx {
u32 rsvd2[6];
};
/* Represents everything that is needed to issue a command on the command ring.
* It's useful to pre-allocate these for commands that cannot fail due to
* out-of-memory errors, like freeing streams.
*/
struct xhci_command {
/* Input context for changing device state */
struct xhci_container_ctx *in_ctx;
u32 status;
/* If completion is null, no one is waiting on this command
* and the structure can be freed after the command completes.
*/
struct completion *completion;
union xhci_trb *command_trb;
struct list_head cmd_list;
};
/* drop context bitmasks */
#define DROP_EP(x) (0x1 << x)
/* add context bitmasks */
#define ADD_EP(x) (0x1 << x)
struct xhci_virt_ep {
struct xhci_ring *ring;
/* Temporary storage in case the configure endpoint command fails and we
* have to restore the device state to the previous state
*/
struct xhci_ring *new_ring;
unsigned int ep_state;
#define SET_DEQ_PENDING (1 << 0)
#define EP_HALTED (1 << 1)
/* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list;
unsigned int cancels_pending;
/* The TRB that was last reported in a stopped endpoint ring */
union xhci_trb *stopped_trb;
struct xhci_td *stopped_td;
};
struct xhci_virt_device {
/*
* Commands to the hardware are passed an "input context" that
@@ -633,16 +673,11 @@ struct xhci_virt_device {
struct xhci_container_ctx *out_ctx;
/* Used for addressing devices and configuration changes */
struct xhci_container_ctx *in_ctx;
/* FIXME when stream support is added */
struct xhci_ring *ep_rings[31];
/* Temporary storage in case the configure endpoint command fails and we
* have to restore the device state to the previous state
*/
struct xhci_ring *new_ep_rings[31];
struct xhci_virt_ep eps[31];
struct completion cmd_completion;
/* Status of the last command issued for this device */
u32 cmd_status;
struct list_head cmd_list;
};
@@ -905,6 +940,8 @@ union xhci_trb {
* It must also be greater than 16.
*/
#define TRBS_PER_SEGMENT 64
/* Allow two commands + a link TRB, along with any reserved command TRBs */
#define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3)
#define SEGMENT_SIZE (TRBS_PER_SEGMENT*16)
/* TRB buffer pointers can't cross 64KB boundaries */
#define TRB_MAX_BUFF_SHIFT 16
@@ -926,6 +963,12 @@ struct xhci_td {
union xhci_trb *last_trb;
};
struct xhci_dequeue_state {
struct xhci_segment *new_deq_seg;
union xhci_trb *new_deq_ptr;
int new_cycle_state;
};
struct xhci_ring {
struct xhci_segment *first_seg;
union xhci_trb *enqueue;
@@ -935,15 +978,6 @@ struct xhci_ring {
struct xhci_segment *deq_seg;
unsigned int deq_updates;
struct list_head td_list;
/* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list;
unsigned int cancels_pending;
unsigned int state;
#define SET_DEQ_PENDING (1 << 0)
#define EP_HALTED (1 << 1)
/* The TRB that was last reported in a stopped endpoint ring */
union xhci_trb *stopped_trb;
struct xhci_td *stopped_td;
/*
* Write the cycle state into the TRB cycle field to give ownership of
* the TRB to the host controller (if we are the producer), or to check
@@ -952,12 +986,6 @@ struct xhci_ring {
u32 cycle_state;
};
struct xhci_dequeue_state {
struct xhci_segment *new_deq_seg;
union xhci_trb *new_deq_ptr;
int new_cycle_state;
};
struct xhci_erst_entry {
/* 64-bit event ring segment address */
u64 seg_addr;
@@ -1034,6 +1062,7 @@ struct xhci_hcd {
/* data structures */
struct xhci_device_context_array *dcbaa;
struct xhci_ring *cmd_ring;
unsigned int cmd_ring_reserved_trbs;
struct xhci_ring *event_ring;
struct xhci_erst erst;
/* Scratchpad */
@@ -1058,6 +1087,9 @@ struct xhci_hcd {
int noops_submitted;
int noops_handled;
int error_bitmask;
unsigned int quirks;
#define XHCI_LINK_TRB_QUIRK (1 << 0)
#define XHCI_RESET_EP_QUIRK (1 << 1)
};
/* For testing purposes */
@@ -1136,6 +1168,13 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
writel(val_hi, ptr + 1);
}
static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
{
u32 temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
return ((HC_VERSION(temp) == 0x95) &&
(xhci->quirks & XHCI_LINK_TRB_QUIRK));
}
/* xHCI debugging */
void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
void xhci_print_registers(struct xhci_hcd *xhci);
@@ -1150,7 +1189,7 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
/* xHCI memory managment */
/* xHCI memory management */
void xhci_mem_cleanup(struct xhci_hcd *xhci);
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
@@ -1158,11 +1197,24 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
void xhci_endpoint_copy(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx,
unsigned int ep_index);
void xhci_slot_copy(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx);
int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
struct usb_device *udev, struct usb_host_endpoint *ep,
gfp_t mem_flags);
void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
bool allocate_completion, gfp_t mem_flags);
void xhci_free_command(struct xhci_hcd *xhci,
struct xhci_command *command);
#ifdef CONFIG_PCI
/* xHCI PCI glue */
@@ -1182,6 +1234,8 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd);
int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev);
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
struct usb_tt *tt, gfp_t mem_flags);
int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
@@ -1205,7 +1259,11 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index);
int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index);
int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index);
int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id, bool command_must_succeed);
int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id);
int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
unsigned int ep_index);
@@ -1213,8 +1271,13 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
struct xhci_td *cur_td, struct xhci_dequeue_state *state);
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring, unsigned int slot_id,
unsigned int ep_index, struct xhci_dequeue_state *deq_state);
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state);
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
struct usb_device *udev, unsigned int ep_index);
void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state);
/* xHCI roothub code */
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,