Merge commit 'origin/master' into next

This commit is contained in:
Benjamin Herrenschmidt
2009-06-18 11:16:55 +10:00
1229 changed files with 141539 additions and 15499 deletions

View File

@@ -17,6 +17,26 @@ config USB_C67X00_HCD
To compile this driver as a module, choose M here: the
module will be called c67x00.
config USB_XHCI_HCD
tristate "xHCI HCD (USB 3.0) support (EXPERIMENTAL)"
depends on USB && PCI && EXPERIMENTAL
---help---
The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
"SuperSpeed" host controller hardware.
To compile this driver as a module, choose M here: the
module will be called xhci-hcd.
config USB_XHCI_HCD_DEBUGGING
bool "Debugging for the xHCI host controller"
depends on USB_XHCI_HCD
---help---
Say 'Y' to turn on debugging for the xHCI host controller driver.
This will spew debugging output, even in interrupt context.
This should only be used for debugging xHCI driver bugs.
If unsure, say N.
config USB_EHCI_HCD
tristate "EHCI HCD (USB 2.0) support"
depends on USB && USB_ARCH_HAS_EHCI

View File

@@ -12,6 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \
ifeq ($(CONFIG_FHCI_DEBUG),y)
fhci-objs += fhci-dbg.o
endif
xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
obj-$(CONFIG_USB_WHCI_HCD) += whci/
@@ -23,6 +24,7 @@ obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-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
obj-$(CONFIG_USB_XHCI_HCD) += xhci.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o

View File

@@ -97,6 +97,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support

View File

@@ -309,6 +309,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support

View File

@@ -1024,6 +1024,51 @@ done:
return;
}
static void
ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct ehci_qh *qh;
int eptype = usb_endpoint_type(&ep->desc);
if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
return;
rescan:
spin_lock_irq(&ehci->lock);
qh = ep->hcpriv;
/* For Bulk and Interrupt endpoints we maintain the toggle state
* in the hardware; the toggle bits in udev aren't used at all.
* When an endpoint is reset by usb_clear_halt() we must reset
* the toggle bit in the QH.
*/
if (qh) {
if (!list_empty(&qh->qtd_list)) {
WARN_ONCE(1, "clear_halt for a busy endpoint\n");
} else if (qh->qh_state == QH_STATE_IDLE) {
qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
} else {
/* It's not safe to write into the overlay area
* while the QH is active. Unlink it first and
* wait for the unlink to complete.
*/
if (qh->qh_state == QH_STATE_LINKED) {
if (eptype == USB_ENDPOINT_XFER_BULK) {
unlink_async(ehci, qh);
} else {
intr_deschedule(ehci, qh);
(void) qh_schedule(ehci, qh);
}
}
spin_unlock_irq(&ehci->lock);
schedule_timeout_uninterruptible(1);
goto rescan;
}
}
spin_unlock_irq(&ehci->lock);
}
static int ehci_get_frame (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
@@ -1097,7 +1142,7 @@ static int __init ehci_hcd_init(void)
sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
#ifdef DEBUG
ehci_debug_root = debugfs_create_dir("ehci", NULL);
ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root);
if (!ehci_debug_root) {
retval = -ENOENT;
goto err_debug;

View File

@@ -391,7 +391,7 @@ static inline void create_companion_file(struct ehci_hcd *ehci)
/* with integrated TT there is no companion! */
if (!ehci_is_TDI(ehci))
i = device_create_file(ehci_to_hcd(ehci)->self.dev,
i = device_create_file(ehci_to_hcd(ehci)->self.controller,
&dev_attr_companion);
}
@@ -399,7 +399,7 @@ static inline void remove_companion_file(struct ehci_hcd *ehci)
{
/* with integrated TT there is no companion! */
if (!ehci_is_TDI(ehci))
device_remove_file(ehci_to_hcd(ehci)->self.dev,
device_remove_file(ehci_to_hcd(ehci)->self.controller,
&dev_attr_companion);
}

View File

@@ -51,6 +51,7 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
.get_frame_number = ehci_get_frame,
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,

View File

@@ -149,6 +149,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support
@@ -187,7 +188,7 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
static int __init ehci_orion_drv_probe(struct platform_device *pdev)
static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
{
struct orion_ehci_data *pd = pdev->dev.platform_data;
struct resource *res;

View File

@@ -268,7 +268,7 @@ done:
* Also they depend on separate root hub suspend/resume.
*/
static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
static int ehci_pci_suspend(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned long flags;
@@ -293,12 +293,6 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
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);
bail:
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -309,7 +303,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
return rc;
}
static int ehci_pci_resume(struct usb_hcd *hcd)
static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
@@ -322,10 +316,12 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
/* Mark hardware accessible again as we are out of D3 state by now */
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
/* If CF is still set, we maintained PCI Vaux power.
/* If CF is still set and we aren't resuming from hibernation
* then we maintained PCI Vaux power.
* Just undo the effect of ehci_pci_suspend().
*/
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF &&
!hibernated) {
int mask = INTR_MASK;
if (!hcd->self.root_hub->do_remote_wakeup)
@@ -335,7 +331,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
return 0;
}
ehci_dbg(ehci, "lost power, restarting\n");
usb_root_hub_lost_power(hcd->self.root_hub);
/* Else reset, to cope with power loss or flush-to-storage
@@ -393,6 +388,7 @@ static const struct hc_driver ehci_pci_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support
@@ -429,10 +425,11 @@ static struct pci_driver ehci_pci_driver = {
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif
.shutdown = usb_hcd_pci_shutdown,
#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &usb_hcd_pci_pm_ops
},
#endif
};

View File

@@ -61,6 +61,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support

View File

@@ -65,6 +65,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
.get_frame_number = ehci_get_frame,
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,

View File

@@ -93,22 +93,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
qh->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))) {
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;
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
qh->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);
@@ -850,7 +834,6 @@ done:
qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_hc32(ehci, info1);
qh->hw_info2 = cpu_to_hc32(ehci, info2);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
qh_refresh (ehci, qh);
return qh;
}
@@ -881,7 +864,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
}
/* clear halt and/or toggle; and maybe recover from silicon quirk */
/* clear halt and maybe recover from silicon quirk */
if (qh->qh_state == QH_STATE_IDLE)
qh_refresh (ehci, qh);

View File

@@ -760,8 +760,10 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
if (status) {
/* "normal" case, uframing flexible except with splits */
if (qh->period) {
frame = qh->period - 1;
do {
int i;
for (i = qh->period; status && i > 0; --i) {
frame = ++ehci->random_frame % qh->period;
for (uframe = 0; uframe < 8; uframe++) {
status = check_intr_schedule (ehci,
frame, uframe, qh,
@@ -769,7 +771,7 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
if (status == 0)
break;
}
} while (status && frame--);
}
/* qh->period == 0 means every uframe */
} else {

View File

@@ -116,6 +116,7 @@ struct ehci_hcd { /* one per controller */
struct timer_list watchdog;
unsigned long actions;
unsigned stamp;
unsigned random_frame;
unsigned long next_statechange;
u32 command;

View File

@@ -108,7 +108,7 @@ void fhci_dfs_create(struct fhci_hcd *fhci)
{
struct device *dev = fhci_to_hcd(fhci)->self.controller;
fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
fhci->dfs_root = debugfs_create_dir(dev_name(dev), usb_debug_root);
if (!fhci->dfs_root) {
WARN_ON(1);
return;

View File

@@ -172,25 +172,6 @@ error_cluster_id_get:
}
static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
{
struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
dev_err(wusbhc->dev, "%s (%p [%p], 0x%lx) UNIMPLEMENTED\n", __func__,
usb_hcd, hwahc, *(unsigned long *) &msg);
return -ENOSYS;
}
static int hwahc_op_resume(struct usb_hcd *usb_hcd)
{
struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
usb_hcd, hwahc);
return -ENOSYS;
}
/*
* No need to abort pipes, as when this is called, all the children
* has been disconnected and that has done it [through
@@ -598,8 +579,6 @@ static struct hc_driver hwahc_hc_driver = {
.flags = HCD_USB2, /* FIXME */
.reset = hwahc_op_reset,
.start = hwahc_op_start,
.pci_suspend = hwahc_op_suspend,
.pci_resume = hwahc_op_resume,
.stop = hwahc_op_stop,
.get_frame_number = hwahc_op_get_frame_number,
.urb_enqueue = hwahc_op_urb_enqueue,

View File

@@ -431,7 +431,7 @@ static struct dentry *ohci_debug_root;
struct debug_buffer {
ssize_t (*fill_func)(struct debug_buffer *); /* fill method */
struct device *dev;
struct ohci_hcd *ohci;
struct mutex mutex; /* protect filling of buffer */
size_t count; /* number of characters filled into buffer */
char *page;
@@ -505,15 +505,11 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
static ssize_t fill_async_buffer(struct debug_buffer *buf)
{
struct usb_bus *bus;
struct usb_hcd *hcd;
struct ohci_hcd *ohci;
size_t temp;
unsigned long flags;
bus = dev_get_drvdata(buf->dev);
hcd = bus_to_hcd(bus);
ohci = hcd_to_ohci(hcd);
ohci = buf->ohci;
/* display control and bulk lists together, for simplicity */
spin_lock_irqsave (&ohci->lock, flags);
@@ -529,8 +525,6 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
{
struct usb_bus *bus;
struct usb_hcd *hcd;
struct ohci_hcd *ohci;
struct ed **seen, *ed;
unsigned long flags;
@@ -542,9 +536,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
return 0;
seen_count = 0;
bus = (struct usb_bus *)dev_get_drvdata(buf->dev);
hcd = bus_to_hcd(bus);
ohci = hcd_to_ohci(hcd);
ohci = buf->ohci;
next = buf->page;
size = PAGE_SIZE;
@@ -626,7 +618,6 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
static ssize_t fill_registers_buffer(struct debug_buffer *buf)
{
struct usb_bus *bus;
struct usb_hcd *hcd;
struct ohci_hcd *ohci;
struct ohci_regs __iomem *regs;
@@ -635,9 +626,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
char *next;
u32 rdata;
bus = (struct usb_bus *)dev_get_drvdata(buf->dev);
hcd = bus_to_hcd(bus);
ohci = hcd_to_ohci(hcd);
ohci = buf->ohci;
hcd = ohci_to_hcd(ohci);
regs = ohci->regs;
next = buf->page;
size = PAGE_SIZE;
@@ -710,7 +700,7 @@ done:
return PAGE_SIZE - size;
}
static struct debug_buffer *alloc_buffer(struct device *dev,
static struct debug_buffer *alloc_buffer(struct ohci_hcd *ohci,
ssize_t (*fill_func)(struct debug_buffer *))
{
struct debug_buffer *buf;
@@ -718,7 +708,7 @@ static struct debug_buffer *alloc_buffer(struct device *dev,
buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
if (buf) {
buf->dev = dev;
buf->ohci = ohci;
buf->fill_func = fill_func;
mutex_init(&buf->mutex);
}
@@ -810,26 +800,25 @@ static int debug_registers_open(struct inode *inode, struct file *file)
static inline void create_debug_files (struct ohci_hcd *ohci)
{
struct usb_bus *bus = &ohci_to_hcd(ohci)->self;
struct device *dev = bus->dev;
ohci->debug_dir = debugfs_create_dir(bus->bus_name, ohci_debug_root);
if (!ohci->debug_dir)
goto dir_error;
ohci->debug_async = debugfs_create_file("async", S_IRUGO,
ohci->debug_dir, dev,
ohci->debug_dir, ohci,
&debug_async_fops);
if (!ohci->debug_async)
goto async_error;
ohci->debug_periodic = debugfs_create_file("periodic", S_IRUGO,
ohci->debug_dir, dev,
ohci->debug_dir, ohci,
&debug_periodic_fops);
if (!ohci->debug_periodic)
goto periodic_error;
ohci->debug_registers = debugfs_create_file("registers", S_IRUGO,
ohci->debug_dir, dev,
ohci->debug_dir, ohci,
&debug_registers_fops);
if (!ohci->debug_registers)
goto registers_error;

View File

@@ -571,7 +571,7 @@ static int ohci_init (struct ohci_hcd *ohci)
*/
static int ohci_run (struct ohci_hcd *ohci)
{
u32 mask, temp;
u32 mask, val;
int first = ohci->fminterval == 0;
struct usb_hcd *hcd = ohci_to_hcd(ohci);
@@ -580,8 +580,8 @@ static int ohci_run (struct ohci_hcd *ohci)
/* boot firmware should have set this up (5.1.1.3.1) */
if (first) {
temp = ohci_readl (ohci, &ohci->regs->fminterval);
ohci->fminterval = temp & 0x3fff;
val = ohci_readl (ohci, &ohci->regs->fminterval);
ohci->fminterval = val & 0x3fff;
if (ohci->fminterval != FI)
ohci_dbg (ohci, "fminterval delta %d\n",
ohci->fminterval - FI);
@@ -600,25 +600,25 @@ static int ohci_run (struct ohci_hcd *ohci)
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
temp = 0;
val = 0;
break;
case OHCI_USB_SUSPEND:
case OHCI_USB_RESUME:
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_USB_RESUME;
temp = 10 /* msec wait */;
val = 10 /* msec wait */;
break;
// case OHCI_USB_RESET:
default:
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_USB_RESET;
temp = 50 /* msec wait */;
val = 50 /* msec wait */;
break;
}
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
// flush the writes
(void) ohci_readl (ohci, &ohci->regs->control);
msleep(temp);
msleep(val);
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
@@ -628,9 +628,9 @@ static int ohci_run (struct ohci_hcd *ohci)
retry:
/* HC Reset requires max 10 us delay */
ohci_writel (ohci, OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */
val = 30; /* ... allow extra time */
while ((ohci_readl (ohci, &ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
if (--temp == 0) {
if (--val == 0) {
spin_unlock_irq (&ohci->lock);
ohci_err (ohci, "USB HC reset timed out!\n");
return -1;
@@ -699,23 +699,23 @@ retry:
ohci_writel (ohci, mask, &ohci->regs->intrenable);
/* handle root hub init quirks ... */
temp = roothub_a (ohci);
temp &= ~(RH_A_PSM | RH_A_OCPM);
val = roothub_a (ohci);
val &= ~(RH_A_PSM | RH_A_OCPM);
if (ohci->flags & OHCI_QUIRK_SUPERIO) {
/* NSC 87560 and maybe others */
temp |= RH_A_NOCP;
temp &= ~(RH_A_POTPGT | RH_A_NPS);
ohci_writel (ohci, temp, &ohci->regs->roothub.a);
val |= RH_A_NOCP;
val &= ~(RH_A_POTPGT | RH_A_NPS);
ohci_writel (ohci, val, &ohci->regs->roothub.a);
} else if ((ohci->flags & OHCI_QUIRK_AMD756) ||
(ohci->flags & OHCI_QUIRK_HUB_POWER)) {
/* hub power always on; required for AMD-756 and some
* Mac platforms. ganged overcurrent reporting, if any.
*/
temp |= RH_A_NPS;
ohci_writel (ohci, temp, &ohci->regs->roothub.a);
val |= RH_A_NPS;
ohci_writel (ohci, val, &ohci->regs->roothub.a);
}
ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status);
ohci_writel (ohci, (temp & RH_A_NPS) ? 0 : RH_B_PPCM,
ohci_writel (ohci, (val & RH_A_NPS) ? 0 : RH_B_PPCM,
&ohci->regs->roothub.b);
// flush those writes
(void) ohci_readl (ohci, &ohci->regs->control);
@@ -724,7 +724,7 @@ retry:
spin_unlock_irq (&ohci->lock);
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((temp >> 23) & 0x1fe);
mdelay ((val >> 23) & 0x1fe);
hcd->state = HC_STATE_RUNNING;
if (quirk_zfmicro(ohci)) {
@@ -1105,7 +1105,7 @@ static int __init ohci_hcd_mod_init(void)
set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
#ifdef DEBUG
ohci_debug_root = debugfs_create_dir("ohci", NULL);
ohci_debug_root = debugfs_create_dir("ohci", usb_debug_root);
if (!ohci_debug_root) {
retval = -ENOENT;
goto error_debug;

View File

@@ -372,7 +372,7 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
#ifdef CONFIG_PM
static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
static int ohci_pci_suspend(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
@@ -394,10 +394,6 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
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);
bail:
spin_unlock_irqrestore (&ohci->lock, flags);
@@ -406,9 +402,14 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
}
static int ohci_pci_resume (struct usb_hcd *hcd)
static int ohci_pci_resume(struct usb_hcd *hcd, bool hibernated)
{
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
/* Make sure resume from hibernation re-enumerates everything */
if (hibernated)
ohci_usb_reset(hcd_to_ohci(hcd));
ohci_finish_controller_resume(hcd);
return 0;
}
@@ -484,12 +485,11 @@ static struct pci_driver ohci_pci_driver = {
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif
.shutdown = usb_hcd_pci_shutdown,
};
#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &usb_hcd_pci_pm_ops
},
#endif
};

View File

@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/acpi.h>
#include "pci-quirks.h"
#include "xhci-ext-caps.h"
#define UHCI_USBLEGSUP 0xc0 /* legacy support */
@@ -341,7 +342,127 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
return;
}
/*
* handshake - spin reading a register until handshake completes
* @ptr: address of hc register to be read
* @mask: bits to look at in result of read
* @done: value of those bits when handshake succeeds
* @wait_usec: timeout in microseconds
* @delay_usec: delay in microseconds to wait between polling
*
* Polls a register every delay_usec microseconds.
* Returns 0 when the mask bits have the value done.
* Returns -ETIMEDOUT if this condition is not true after
* wait_usec microseconds have passed.
*/
static int handshake(void __iomem *ptr, u32 mask, u32 done,
int wait_usec, int delay_usec)
{
u32 result;
do {
result = readl(ptr);
result &= mask;
if (result == done)
return 0;
udelay(delay_usec);
wait_usec -= delay_usec;
} while (wait_usec > 0);
return -ETIMEDOUT;
}
/**
* PCI Quirks for xHCI.
*
* Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS.
* It signals to the BIOS that the OS wants control of the host controller,
* and then waits 5 seconds for the BIOS to hand over control.
* If we timeout, assume the BIOS is broken and take control anyway.
*/
static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
{
void __iomem *base;
int ext_cap_offset;
void __iomem *op_reg_base;
u32 val;
int timeout;
if (!mmio_resource_enabled(pdev, 0))
return;
base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (base == NULL)
return;
/*
* Find the Legacy Support Capability register -
* this is optional for xHCI host controllers.
*/
ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET);
do {
if (!ext_cap_offset)
/* We've reached the end of the extended capabilities */
goto hc_init;
val = readl(base + ext_cap_offset);
if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)
break;
ext_cap_offset = xhci_find_next_cap_offset(base, ext_cap_offset);
} while (1);
/* If the BIOS owns the HC, signal that the OS wants it, and wait */
if (val & XHCI_HC_BIOS_OWNED) {
writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset);
/* Wait for 5 seconds with 10 microsecond polling interval */
timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,
0, 5000, 10);
/* Assume a buggy BIOS and take HC ownership anyway */
if (timeout) {
dev_warn(&pdev->dev, "xHCI BIOS handoff failed"
" (BIOS bug ?) %08x\n", val);
writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
}
}
/* Disable any BIOS SMIs */
writel(XHCI_LEGACY_DISABLE_SMI,
base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
hc_init:
op_reg_base = base + XHCI_HC_LENGTH(readl(base));
/* Wait for the host controller to be ready before writing any
* operational or runtime registers. Wait 5 seconds and no more.
*/
timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0,
5000, 10);
/* Assume a buggy HC and start HC initialization anyway */
if (timeout) {
val = readl(op_reg_base + XHCI_STS_OFFSET);
dev_warn(&pdev->dev,
"xHCI HW not ready after 5 sec (HC bug?) "
"status = 0x%x\n", val);
}
/* Send the halt and disable interrupts command */
val = readl(op_reg_base + XHCI_CMD_OFFSET);
val &= ~(XHCI_CMD_RUN | XHCI_IRQS);
writel(val, op_reg_base + XHCI_CMD_OFFSET);
/* Wait for the HC to halt - poll every 125 usec (one microframe). */
timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_HALT, 1,
XHCI_MAX_HALT_USEC, 125);
if (timeout) {
val = readl(op_reg_base + XHCI_STS_OFFSET);
dev_warn(&pdev->dev,
"xHCI HW did not halt within %d usec "
"status = 0x%x\n", XHCI_MAX_HALT_USEC, val);
}
iounmap(base);
}
static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
{
@@ -351,5 +472,7 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
quirk_usb_handoff_ohci(pdev);
else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI)
quirk_usb_disable_ehci(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);

View File

@@ -46,31 +46,10 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yoshihiro Shimoda");
MODULE_ALIAS("platform:r8a66597_hcd");
#define DRIVER_VERSION "10 Apr 2008"
#define DRIVER_VERSION "2009-05-26"
static const char hcd_name[] = "r8a66597_hcd";
/* module parameters */
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
static unsigned short clock = XTAL12;
module_param(clock, ushort, 0644);
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
"(default=0)");
#endif
static unsigned short vif = LDRV;
module_param(vif, ushort, 0644);
MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)");
static unsigned short endian;
module_param(endian, ushort, 0644);
MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
static unsigned short irq_sense = 0xff;
module_param(irq_sense, ushort, 0644);
MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
"(default=32)");
static void packet_write(struct r8a66597 *r8a66597, u16 pipenum);
static int r8a66597_get_frame(struct usb_hcd *hcd);
@@ -136,7 +115,8 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
}
} while ((tmp & USBE) != USBE);
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
r8a66597_mdfy(r8a66597, clock, XTAL, SYSCFG0);
r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
SYSCFG0);
i = 0;
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
@@ -203,6 +183,9 @@ static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port)
static int enable_controller(struct r8a66597 *r8a66597)
{
int ret, port;
u16 vif = r8a66597->pdata->vif ? LDRV : 0;
u16 irq_sense = r8a66597->irq_sense_low ? INTL : 0;
u16 endian = r8a66597->pdata->endian ? BIGEND : 0;
ret = r8a66597_clock_enable(r8a66597);
if (ret < 0)
@@ -2373,7 +2356,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
return 0;
}
static int __init r8a66597_probe(struct platform_device *pdev)
static int __devinit r8a66597_probe(struct platform_device *pdev)
{
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
char clk_name[8];
@@ -2418,6 +2401,12 @@ static int __init r8a66597_probe(struct platform_device *pdev)
goto clean_up;
}
if (pdev->dev.platform_data == NULL) {
dev_err(&pdev->dev, "no platform data\n");
ret = -ENODEV;
goto clean_up;
}
/* initialize hcd */
hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
if (!hcd) {
@@ -2428,6 +2417,8 @@ static int __init r8a66597_probe(struct platform_device *pdev)
r8a66597 = hcd_to_r8a66597(hcd);
memset(r8a66597, 0, sizeof(struct r8a66597));
dev_set_drvdata(&pdev->dev, r8a66597);
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);
@@ -2458,29 +2449,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
hcd->rsrc_start = res->start;
/* irq_sense setting on cmdline takes precedence over resource
* settings, so the introduction of irqflags in IRQ resourse
* won't disturb existing setups */
switch (irq_sense) {
case INTL:
irq_trigger = IRQF_TRIGGER_LOW;
break;
case 0:
irq_trigger = IRQF_TRIGGER_FALLING;
break;
case 0xff:
if (irq_trigger)
irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ?
INTL : 0;
else {
irq_sense = INTL;
irq_trigger = IRQF_TRIGGER_LOW;
}
break;
default:
dev_err(&pdev->dev, "Unknown irq_sense value.\n");
}
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to add hcd\n");

View File

@@ -30,6 +30,8 @@
#include <linux/clk.h>
#endif
#include <linux/usb/r8a66597.h>
#define SYSCFG0 0x00
#define SYSCFG1 0x02
#define SYSSTS0 0x04
@@ -488,6 +490,7 @@ struct r8a66597 {
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
struct clk *clk;
#endif
struct r8a66597_platdata *pdata;
struct r8a66597_device device0;
struct r8a66597_root_hub root_hub[R8A66597_MAX_ROOT_HUB];
struct list_head pipe_queue[R8A66597_MAX_NUM_PIPE];
@@ -506,6 +509,7 @@ struct r8a66597 {
unsigned long child_connect_map[4];
unsigned bus_suspended:1;
unsigned irq_sense_low:1;
};
static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd)
@@ -660,10 +664,36 @@ static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port,
{
unsigned long dvstctr_reg = get_dvstctr_reg(port);
if (power)
r8a66597_bset(r8a66597, VBOUT, dvstctr_reg);
else
r8a66597_bclr(r8a66597, VBOUT, dvstctr_reg);
if (r8a66597->pdata->port_power) {
r8a66597->pdata->port_power(port, power);
} else {
if (power)
r8a66597_bset(r8a66597, VBOUT, dvstctr_reg);
else
r8a66597_bclr(r8a66597, VBOUT, dvstctr_reg);
}
}
static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
{
u16 clock = 0;
switch (pdata->xtal) {
case R8A66597_PLATDATA_XTAL_12MHZ:
clock = XTAL12;
break;
case R8A66597_PLATDATA_XTAL_24MHZ:
clock = XTAL24;
break;
case R8A66597_PLATDATA_XTAL_48MHZ:
clock = XTAL48;
break;
default:
printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
break;
}
return clock;
}
#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2)

View File

@@ -769,7 +769,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
return rc;
}
static int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
static int uhci_pci_suspend(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int rc = 0;
@@ -795,10 +795,6 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
/* FIXME: Enable non-PME# remote wakeup? */
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW)
uhci_hc_died(uhci);
done_okay:
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
done:
@@ -806,7 +802,7 @@ done:
return rc;
}
static int uhci_pci_resume(struct usb_hcd *hcd)
static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -820,6 +816,10 @@ static int uhci_pci_resume(struct usb_hcd *hcd)
spin_lock_irq(&uhci->lock);
/* Make sure resume from hibernation re-enumerates everything */
if (hibernated)
uhci_hc_died(uhci);
/* FIXME: Disable non-PME# remote wakeup? */
/* The firmware or a boot kernel may have changed the controller
@@ -940,10 +940,11 @@ static struct pci_driver uhci_pci_driver = {
.remove = usb_hcd_pci_remove,
.shutdown = uhci_shutdown,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif /* PM */
#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &usb_hcd_pci_pm_ops
},
#endif
};
static int __init uhci_hcd_init(void)
@@ -961,7 +962,7 @@ static int __init uhci_hcd_init(void)
errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
if (!errbuf)
goto errbuf_failed;
uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
uhci_debugfs_root = debugfs_create_dir("uhci", usb_debug_root);
if (!uhci_debugfs_root)
goto debug_failed;
}

View File

@@ -260,7 +260,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
INIT_LIST_HEAD(&qh->node);
if (udev) { /* Normal QH */
qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
qh->type = usb_endpoint_type(&hep->desc);
if (qh->type != USB_ENDPOINT_XFER_ISOC) {
qh->dummy_td = uhci_alloc_td(uhci);
if (!qh->dummy_td) {

485
drivers/usb/host/xhci-dbg.c Normal file
View File

@@ -0,0 +1,485 @@
/*
* xHCI host controller driver
*
* Copyright (C) 2008 Intel Corp.
*
* Author: Sarah Sharp
* Some code borrowed from the Linux EHCI driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "xhci.h"
#define XHCI_INIT_VALUE 0x0
/* Add verbose debugging later, just print everything for now */
void xhci_dbg_regs(struct xhci_hcd *xhci)
{
u32 temp;
xhci_dbg(xhci, "// xHCI capability registers at %p:\n",
xhci->cap_regs);
temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
xhci_dbg(xhci, "// @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n",
&xhci->cap_regs->hc_capbase, temp);
xhci_dbg(xhci, "// CAPLENGTH: 0x%x\n",
(unsigned int) HC_LENGTH(temp));
#if 0
xhci_dbg(xhci, "// HCIVERSION: 0x%x\n",
(unsigned int) HC_VERSION(temp));
#endif
xhci_dbg(xhci, "// xHCI operational registers at %p:\n", xhci->op_regs);
temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off);
xhci_dbg(xhci, "// @%p = 0x%x RTSOFF\n",
&xhci->cap_regs->run_regs_off,
(unsigned int) temp & RTSOFF_MASK);
xhci_dbg(xhci, "// xHCI runtime registers at %p:\n", xhci->run_regs);
temp = xhci_readl(xhci, &xhci->cap_regs->db_off);
xhci_dbg(xhci, "// @%p = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);
xhci_dbg(xhci, "// Doorbell array at %p:\n", xhci->dba);
}
static void xhci_print_cap_regs(struct xhci_hcd *xhci)
{
u32 temp;
xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs);
temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
xhci_dbg(xhci, "CAPLENGTH AND HCIVERSION 0x%x:\n",
(unsigned int) temp);
xhci_dbg(xhci, "CAPLENGTH: 0x%x\n",
(unsigned int) HC_LENGTH(temp));
xhci_dbg(xhci, "HCIVERSION: 0x%x\n",
(unsigned int) HC_VERSION(temp));
temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params1);
xhci_dbg(xhci, "HCSPARAMS 1: 0x%x\n",
(unsigned int) temp);
xhci_dbg(xhci, " Max device slots: %u\n",
(unsigned int) HCS_MAX_SLOTS(temp));
xhci_dbg(xhci, " Max interrupters: %u\n",
(unsigned int) HCS_MAX_INTRS(temp));
xhci_dbg(xhci, " Max ports: %u\n",
(unsigned int) HCS_MAX_PORTS(temp));
temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params2);
xhci_dbg(xhci, "HCSPARAMS 2: 0x%x\n",
(unsigned int) temp);
xhci_dbg(xhci, " Isoc scheduling threshold: %u\n",
(unsigned int) HCS_IST(temp));
xhci_dbg(xhci, " Maximum allowed segments in event ring: %u\n",
(unsigned int) HCS_ERST_MAX(temp));
temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3);
xhci_dbg(xhci, "HCSPARAMS 3 0x%x:\n",
(unsigned int) temp);
xhci_dbg(xhci, " Worst case U1 device exit latency: %u\n",
(unsigned int) HCS_U1_LATENCY(temp));
xhci_dbg(xhci, " Worst case U2 device exit latency: %u\n",
(unsigned int) HCS_U2_LATENCY(temp));
temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
xhci_dbg(xhci, "HCC PARAMS 0x%x:\n", (unsigned int) temp);
xhci_dbg(xhci, " HC generates %s bit addresses\n",
HCC_64BIT_ADDR(temp) ? "64" : "32");
/* FIXME */
xhci_dbg(xhci, " FIXME: more HCCPARAMS debugging\n");
temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off);
xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK);
}
static void xhci_print_command_reg(struct xhci_hcd *xhci)
{
u32 temp;
temp = xhci_readl(xhci, &xhci->op_regs->command);
xhci_dbg(xhci, "USBCMD 0x%x:\n", temp);
xhci_dbg(xhci, " HC is %s\n",
(temp & CMD_RUN) ? "running" : "being stopped");
xhci_dbg(xhci, " HC has %sfinished hard reset\n",
(temp & CMD_RESET) ? "not " : "");
xhci_dbg(xhci, " Event Interrupts %s\n",
(temp & CMD_EIE) ? "enabled " : "disabled");
xhci_dbg(xhci, " Host System Error Interrupts %s\n",
(temp & CMD_EIE) ? "enabled " : "disabled");
xhci_dbg(xhci, " HC has %sfinished light reset\n",
(temp & CMD_LRESET) ? "not " : "");
}
static void xhci_print_status(struct xhci_hcd *xhci)
{
u32 temp;
temp = xhci_readl(xhci, &xhci->op_regs->status);
xhci_dbg(xhci, "USBSTS 0x%x:\n", temp);
xhci_dbg(xhci, " Event ring is %sempty\n",
(temp & STS_EINT) ? "not " : "");
xhci_dbg(xhci, " %sHost System Error\n",
(temp & STS_FATAL) ? "WARNING: " : "No ");
xhci_dbg(xhci, " HC is %s\n",
(temp & STS_HALT) ? "halted" : "running");
}
static void xhci_print_op_regs(struct xhci_hcd *xhci)
{
xhci_dbg(xhci, "xHCI operational registers at %p:\n", xhci->op_regs);
xhci_print_command_reg(xhci);
xhci_print_status(xhci);
}
static void xhci_print_ports(struct xhci_hcd *xhci)
{
u32 __iomem *addr;
int i, j;
int ports;
char *names[NUM_PORT_REGS] = {
"status",
"power",
"link",
"reserved",
};
ports = HCS_MAX_PORTS(xhci->hcs_params1);
addr = &xhci->op_regs->port_status_base;
for (i = 0; i < ports; i++) {
for (j = 0; j < NUM_PORT_REGS; ++j) {
xhci_dbg(xhci, "%p port %s reg = 0x%x\n",
addr, names[j],
(unsigned int) xhci_readl(xhci, addr));
addr++;
}
}
}
void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num)
{
void *addr;
u32 temp;
addr = &ir_set->irq_pending;
temp = xhci_readl(xhci, addr);
if (temp == XHCI_INIT_VALUE)
return;
xhci_dbg(xhci, " %p: ir_set[%i]\n", ir_set, set_num);
xhci_dbg(xhci, " %p: ir_set.pending = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->irq_control;
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.control = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->erst_size;
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.erst_size = 0x%x\n", addr,
(unsigned int)temp);
addr = &ir_set->rsvd;
temp = xhci_readl(xhci, addr);
if (temp != XHCI_INIT_VALUE)
xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n",
addr, (unsigned int)temp);
addr = &ir_set->erst_base[0];
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.erst_base[0] = 0x%x\n",
addr, (unsigned int) temp);
addr = &ir_set->erst_base[1];
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.erst_base[1] = 0x%x\n",
addr, (unsigned int) temp);
addr = &ir_set->erst_dequeue[0];
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.erst_dequeue[0] = 0x%x\n",
addr, (unsigned int) temp);
addr = &ir_set->erst_dequeue[1];
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, " %p: ir_set.erst_dequeue[1] = 0x%x\n",
addr, (unsigned int) temp);
}
void xhci_print_run_regs(struct xhci_hcd *xhci)
{
u32 temp;
int i;
xhci_dbg(xhci, "xHCI runtime registers at %p:\n", xhci->run_regs);
temp = xhci_readl(xhci, &xhci->run_regs->microframe_index);
xhci_dbg(xhci, " %p: Microframe index = 0x%x\n",
&xhci->run_regs->microframe_index,
(unsigned int) temp);
for (i = 0; i < 7; ++i) {
temp = xhci_readl(xhci, &xhci->run_regs->rsvd[i]);
if (temp != XHCI_INIT_VALUE)
xhci_dbg(xhci, " WARN: %p: Rsvd[%i] = 0x%x\n",
&xhci->run_regs->rsvd[i],
i, (unsigned int) temp);
}
}
void xhci_print_registers(struct xhci_hcd *xhci)
{
xhci_print_cap_regs(xhci);
xhci_print_op_regs(xhci);
xhci_print_ports(xhci);
}
void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb)
{
int i;
for (i = 0; i < 4; ++i)
xhci_dbg(xhci, "Offset 0x%x = 0x%x\n",
i*4, trb->generic.field[i]);
}
/**
* Debug a transfer request block (TRB).
*/
void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
{
u64 address;
u32 type = xhci_readl(xhci, &trb->link.control) & TRB_TYPE_BITMASK;
switch (type) {
case TRB_TYPE(TRB_LINK):
xhci_dbg(xhci, "Link TRB:\n");
xhci_print_trb_offsets(xhci, trb);
address = trb->link.segment_ptr[0] +
(((u64) trb->link.segment_ptr[1]) << 32);
xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address);
xhci_dbg(xhci, "Interrupter target = 0x%x\n",
GET_INTR_TARGET(trb->link.intr_target));
xhci_dbg(xhci, "Cycle bit = %u\n",
(unsigned int) (trb->link.control & TRB_CYCLE));
xhci_dbg(xhci, "Toggle cycle bit = %u\n",
(unsigned int) (trb->link.control & LINK_TOGGLE));
xhci_dbg(xhci, "No Snoop bit = %u\n",
(unsigned int) (trb->link.control & TRB_NO_SNOOP));
break;
case TRB_TYPE(TRB_TRANSFER):
address = trb->trans_event.buffer[0] +
(((u64) trb->trans_event.buffer[1]) << 32);
/*
* FIXME: look at flags to figure out if it's an address or if
* the data is directly in the buffer field.
*/
xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
break;
case TRB_TYPE(TRB_COMPLETION):
address = trb->event_cmd.cmd_trb[0] +
(((u64) trb->event_cmd.cmd_trb[1]) << 32);
xhci_dbg(xhci, "Command TRB pointer = %llu\n", address);
xhci_dbg(xhci, "Completion status = %u\n",
(unsigned int) GET_COMP_CODE(trb->event_cmd.status));
xhci_dbg(xhci, "Flags = 0x%x\n", (unsigned int) trb->event_cmd.flags);
break;
default:
xhci_dbg(xhci, "Unknown TRB with TRB type ID %u\n",
(unsigned int) type>>10);
xhci_print_trb_offsets(xhci, trb);
break;
}
}
/**
* Debug a segment with an xHCI ring.
*
* @return The Link TRB of the segment, or NULL if there is no Link TRB
* (which is a bug, since all segments must have a Link TRB).
*
* Prints out all TRBs in the segment, even those after the Link TRB.
*
* XXX: should we print out TRBs that the HC owns? As long as we don't
* write, that should be fine... We shouldn't expect that the memory pointed to
* by the TRB is valid at all. Do we care about ones the HC owns? Probably,
* for HC debugging.
*/
void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
{
int i;
u32 addr = (u32) seg->dma;
union xhci_trb *trb = seg->trbs;
for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
trb = &seg->trbs[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr,
(unsigned int) trb->link.segment_ptr[0],
(unsigned int) trb->link.segment_ptr[1],
(unsigned int) trb->link.intr_target,
(unsigned int) trb->link.control);
addr += sizeof(*trb);
}
}
void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring)
{
xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n",
ring->dequeue,
(unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg,
ring->dequeue));
xhci_dbg(xhci, "Ring deq updated %u times\n",
ring->deq_updates);
xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n",
ring->enqueue,
(unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg,
ring->enqueue));
xhci_dbg(xhci, "Ring enq updated %u times\n",
ring->enq_updates);
}
/**
* Debugging for an xHCI ring, which is a queue broken into multiple segments.
*
* Print out each segment in the ring. Check that the DMA address in
* each link segment actually matches the segment's stored DMA address.
* Check that the link end bit is only set at the end of the ring.
* Check that the dequeue and enqueue pointers point to real data in this ring
* (not some other ring).
*/
void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring)
{
/* FIXME: Throw an error if any segment doesn't have a Link TRB */
struct xhci_segment *seg;
struct xhci_segment *first_seg = ring->first_seg;
xhci_debug_segment(xhci, first_seg);
if (!ring->enq_updates && !ring->deq_updates) {
xhci_dbg(xhci, " Ring has not been updated\n");
return;
}
for (seg = first_seg->next; seg != first_seg; seg = seg->next)
xhci_debug_segment(xhci, seg);
}
void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
{
u32 addr = (u32) erst->erst_dma_addr;
int i;
struct xhci_erst_entry *entry;
for (i = 0; i < erst->num_entries; ++i) {
entry = &erst->entries[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n",
(unsigned int) addr,
(unsigned int) entry->seg_addr[0],
(unsigned int) entry->seg_addr[1],
(unsigned int) entry->seg_size,
(unsigned int) entry->rsvd);
addr += sizeof(*entry);
}
}
void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
{
u32 val;
val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = 0x%x\n", val);
val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[1]);
xhci_dbg(xhci, "// xHC command ring deq ptr high bits = 0x%x\n", val);
}
void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
{
int i, j;
int last_ep_ctx = 31;
/* Fields are 32 bits wide, DMA addresses are in bytes */
int field_size = 32 / 8;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
&ctx->drop_flags, (unsigned long long)dma,
ctx->drop_flags);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
&ctx->add_flags, (unsigned long long)dma,
ctx->add_flags);
dma += field_size;
for (i = 0; i > 6; ++i) {
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
&ctx->rsvd[i], (unsigned long long)dma,
ctx->rsvd[i], i);
dma += field_size;
}
xhci_dbg(xhci, "Slot Context:\n");
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
&ctx->slot.dev_info,
(unsigned long long)dma, ctx->slot.dev_info);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
&ctx->slot.dev_info2,
(unsigned long long)dma, ctx->slot.dev_info2);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
&ctx->slot.tt_info,
(unsigned long long)dma, ctx->slot.tt_info);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
&ctx->slot.dev_state,
(unsigned long long)dma, ctx->slot.dev_state);
dma += field_size;
for (i = 0; i > 4; ++i) {
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
&ctx->slot.reserved[i], (unsigned long long)dma,
ctx->slot.reserved[i], i);
dma += field_size;
}
if (last_ep < 31)
last_ep_ctx = last_ep + 1;
for (i = 0; i < last_ep_ctx; ++i) {
xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
&ctx->ep[i].ep_info,
(unsigned long long)dma, ctx->ep[i].ep_info);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
&ctx->ep[i].ep_info2,
(unsigned long long)dma, ctx->ep[i].ep_info2);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[0]\n",
&ctx->ep[i].deq[0],
(unsigned long long)dma, ctx->ep[i].deq[0]);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[1]\n",
&ctx->ep[i].deq[1],
(unsigned long long)dma, ctx->ep[i].deq[1]);
dma += field_size;
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
&ctx->ep[i].tx_info,
(unsigned long long)dma, ctx->ep[i].tx_info);
dma += field_size;
for (j = 0; j < 3; ++j) {
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
&ctx->ep[i].reserved[j],
(unsigned long long)dma,
ctx->ep[i].reserved[j], j);
dma += field_size;
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* xHCI host controller driver
*
* Copyright (C) 2008 Intel Corp.
*
* Author: Sarah Sharp
* Some code borrowed from the Linux EHCI driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Up to 16 microframes to halt an HC - one microframe is 125 microsectonds */
#define XHCI_MAX_HALT_USEC (16*125)
/* HC not running - set to 1 when run/stop bit is cleared. */
#define XHCI_STS_HALT (1<<0)
/* HCCPARAMS offset from PCI base address */
#define XHCI_HCC_PARAMS_OFFSET 0x10
/* HCCPARAMS contains the first extended capability pointer */
#define XHCI_HCC_EXT_CAPS(p) (((p)>>16)&0xffff)
/* Command and Status registers offset from the Operational Registers address */
#define XHCI_CMD_OFFSET 0x00
#define XHCI_STS_OFFSET 0x04
#define XHCI_MAX_EXT_CAPS 50
/* Capability Register */
/* bits 7:0 - how long is the Capabilities register */
#define XHCI_HC_LENGTH(p) (((p)>>00)&0x00ff)
/* Extended capability register fields */
#define XHCI_EXT_CAPS_ID(p) (((p)>>0)&0xff)
#define XHCI_EXT_CAPS_NEXT(p) (((p)>>8)&0xff)
#define XHCI_EXT_CAPS_VAL(p) ((p)>>16)
/* Extended capability IDs - ID 0 reserved */
#define XHCI_EXT_CAPS_LEGACY 1
#define XHCI_EXT_CAPS_PROTOCOL 2
#define XHCI_EXT_CAPS_PM 3
#define XHCI_EXT_CAPS_VIRT 4
#define XHCI_EXT_CAPS_ROUTE 5
/* IDs 6-9 reserved */
#define XHCI_EXT_CAPS_DEBUG 10
/* USB Legacy Support Capability - section 7.1.1 */
#define XHCI_HC_BIOS_OWNED (1 << 16)
#define XHCI_HC_OS_OWNED (1 << 24)
/* USB Legacy Support Capability - section 7.1.1 */
/* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
#define XHCI_LEGACY_SUPPORT_OFFSET (0x00)
/* USB Legacy Support Control and Status Register - section 7.1.2 */
/* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
#define XHCI_LEGACY_CONTROL_OFFSET (0x04)
/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
/* command register values to disable interrupts and halt the HC */
/* start/stop HC execution - do not write unless HC is halted*/
#define XHCI_CMD_RUN (1 << 0)
/* Event Interrupt Enable - get irq when EINT bit is set in USBSTS register */
#define XHCI_CMD_EIE (1 << 2)
/* Host System Error Interrupt Enable - get irq when HSEIE bit set in USBSTS */
#define XHCI_CMD_HSEIE (1 << 3)
/* Enable Wrap Event - '1' means xHC generates an event when MFINDEX wraps. */
#define XHCI_CMD_EWE (1 << 10)
#define XHCI_IRQS (XHCI_CMD_EIE | XHCI_CMD_HSEIE | XHCI_CMD_EWE)
/* true: Controller Not Ready to accept doorbell or op reg writes after reset */
#define XHCI_STS_CNR (1 << 11)
#include <linux/io.h>
/**
* Return the next extended capability pointer register.
*
* @base PCI register base address.
*
* @ext_offset Offset of the 32-bit register that contains the extended
* capabilites pointer. If searching for the first extended capability, pass
* in XHCI_HCC_PARAMS_OFFSET. If searching for the next extended capability,
* pass in the offset of the current extended capability register.
*
* Returns 0 if there is no next extended capability register or returns the register offset
* from the PCI registers base address.
*/
static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset)
{
u32 next;
next = readl(base + ext_offset);
if (ext_offset == XHCI_HCC_PARAMS_OFFSET)
/* Find the first extended capability */
next = XHCI_HCC_EXT_CAPS(next);
else
/* Find the next extended capability */
next = XHCI_EXT_CAPS_NEXT(next);
if (!next)
return 0;
/*
* Address calculation from offset of extended capabilities
* (or HCCPARAMS) register - see section 5.3.6 and section 7.
*/
return ext_offset + (next << 2);
}
/**
* Find the offset of the extended capabilities with capability ID id.
*
* @base PCI MMIO registers base address.
* @ext_offset Offset from base of the first extended capability to look at,
* or the address of HCCPARAMS.
* @id Extended capability ID to search for.
*
* This uses an arbitrary limit of XHCI_MAX_EXT_CAPS extended capabilities
* to make sure that the list doesn't contain a loop.
*/
static inline int xhci_find_ext_cap_by_id(void __iomem *base, int ext_offset, int id)
{
u32 val;
int limit = XHCI_MAX_EXT_CAPS;
while (ext_offset && limit > 0) {
val = readl(base + ext_offset);
if (XHCI_EXT_CAPS_ID(val) == id)
break;
ext_offset = xhci_find_next_cap_offset(base, ext_offset);
limit--;
}
if (limit > 0)
return ext_offset;
return 0;
}

1274
drivers/usb/host/xhci-hcd.c Normal file

File diff suppressed because it is too large Load Diff

308
drivers/usb/host/xhci-hub.c Normal file
View File

@@ -0,0 +1,308 @@
/*
* xHCI host controller driver
*
* Copyright (C) 2008 Intel Corp.
*
* Author: Sarah Sharp
* Some code borrowed from the Linux EHCI driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <asm/unaligned.h>
#include "xhci.h"
static void xhci_hub_descriptor(struct xhci_hcd *xhci,
struct usb_hub_descriptor *desc)
{
int ports;
u16 temp;
ports = HCS_MAX_PORTS(xhci->hcs_params1);
/* USB 3.0 hubs have a different descriptor, but we fake this for now */
desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.9 says 20ms max */
desc->bHubContrCurrent = 0;
desc->bNbrPorts = ports;
temp = 1 + (ports / 8);
desc->bDescLength = 7 + 2 * temp;
/* Why does core/hcd.h define bitmap? It's just confusing. */
memset(&desc->DeviceRemovable[0], 0, temp);
memset(&desc->DeviceRemovable[temp], 0xff, temp);
/* Ugh, these should be #defines, FIXME */
/* Using table 11-13 in USB 2.0 spec. */
temp = 0;
/* Bits 1:0 - support port power switching, or power always on */
if (HCC_PPC(xhci->hcc_params))
temp |= 0x0001;
else
temp |= 0x0002;
/* Bit 2 - root hubs are not part of a compound device */
/* Bits 4:3 - individual port over current protection */
temp |= 0x0008;
/* Bits 6:5 - no TTs in root ports */
/* Bit 7 - no port indicators */
desc->wHubCharacteristics = (__force __u16) cpu_to_le16(temp);
}
static unsigned int xhci_port_speed(unsigned int port_status)
{
if (DEV_LOWSPEED(port_status))
return 1 << USB_PORT_FEAT_LOWSPEED;
if (DEV_HIGHSPEED(port_status))
return 1 << USB_PORT_FEAT_HIGHSPEED;
if (DEV_SUPERSPEED(port_status))
return 1 << USB_PORT_FEAT_SUPERSPEED;
/*
* FIXME: Yes, we should check for full speed, but the core uses that as
* a default in portspeed() in usb/core/hub.c (which is the only place
* USB_PORT_FEAT_*SPEED is used).
*/
return 0;
}
/*
* These bits are Read Only (RO) and should be saved and written to the
* registers: 0, 3, 10:13, 30
* connect status, over-current status, port speed, and device removable.
* connect status and port speed are also sticky - meaning they're in
* the AUX well and they aren't changed by a hot, warm, or cold reset.
*/
#define XHCI_PORT_RO ((1<<0) | (1<<3) | (0xf<<10) | (1<<30))
/*
* These bits are RW; writing a 0 clears the bit, writing a 1 sets the bit:
* bits 5:8, 9, 14:15, 25:27
* link state, port power, port indicator state, "wake on" enable state
*/
#define XHCI_PORT_RWS ((0xf<<5) | (1<<9) | (0x3<<14) | (0x7<<25))
/*
* These bits are RW; writing a 1 sets the bit, writing a 0 has no effect:
* bit 4 (port reset)
*/
#define XHCI_PORT_RW1S ((1<<4))
/*
* These bits are RW; writing a 1 clears the bit, writing a 0 has no effect:
* bits 1, 17, 18, 19, 20, 21, 22, 23
* port enable/disable, and
* change bits: connect, PED, warm port reset changed (reserved zero for USB 2.0 ports),
* over-current, reset, link state, and L1 change
*/
#define XHCI_PORT_RW1CS ((1<<1) | (0x7f<<17))
/*
* Bit 16 is RW, and writing a '1' to it causes the link state control to be
* latched in
*/
#define XHCI_PORT_RW ((1<<16))
/*
* These bits are Reserved Zero (RsvdZ) and zero should be written to them:
* bits 2, 24, 28:31
*/
#define XHCI_PORT_RZ ((1<<2) | (1<<24) | (0xf<<28))
/*
* Given a port state, this function returns a value that would result in the
* port being in the same state, if the value was written to the port status
* control register.
* Save Read Only (RO) bits and save read/write bits where
* writing a 0 clears the bit and writing a 1 sets the bit (RWS).
* For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect.
*/
static u32 xhci_port_state_to_neutral(u32 state)
{
/* Save read-only status and port state */
return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS);
}
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ports;
unsigned long flags;
u32 temp, status;
int retval = 0;
u32 __iomem *addr;
char *port_change_bit;
ports = HCS_MAX_PORTS(xhci->hcs_params1);
spin_lock_irqsave(&xhci->lock, flags);
switch (typeReq) {
case GetHubStatus:
/* No power source, over-current reported per port */
memset(buf, 0, 4);
break;
case GetHubDescriptor:
xhci_hub_descriptor(xhci, (struct usb_hub_descriptor *) buf);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
status = 0;
addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff);
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
/* wPortChange bits */
if (temp & PORT_CSC)
status |= 1 << USB_PORT_FEAT_C_CONNECTION;
if (temp & PORT_PEC)
status |= 1 << USB_PORT_FEAT_C_ENABLE;
if ((temp & PORT_OCC))
status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
/*
* FIXME ignoring suspend, reset, and USB 2.1/3.0 specific
* changes
*/
if (temp & PORT_CONNECT) {
status |= 1 << USB_PORT_FEAT_CONNECTION;
status |= xhci_port_speed(temp);
}
if (temp & PORT_PE)
status |= 1 << USB_PORT_FEAT_ENABLE;
if (temp & PORT_OC)
status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
if (temp & PORT_RESET)
status |= 1 << USB_PORT_FEAT_RESET;
if (temp & PORT_POWER)
status |= 1 << USB_PORT_FEAT_POWER;
xhci_dbg(xhci, "Get port status returned 0x%x\n", status);
put_unaligned(cpu_to_le32(status), (__le32 *) buf);
break;
case SetPortFeature:
wIndex &= 0xff;
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff);
temp = xhci_readl(xhci, addr);
temp = xhci_port_state_to_neutral(temp);
switch (wValue) {
case USB_PORT_FEAT_POWER:
/*
* Turn on ports, even if there isn't per-port switching.
* HC will report connect events even before this is set.
* However, khubd will ignore the roothub events until
* the roothub is registered.
*/
xhci_writel(xhci, temp | PORT_POWER, addr);
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
xhci_writel(xhci, temp, addr);
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
break;
default:
goto error;
}
temp = xhci_readl(xhci, addr); /* unblock any posted writes */
break;
case ClearPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
addr = &xhci->op_regs->port_status_base +
NUM_PORT_REGS*(wIndex & 0xff);
temp = xhci_readl(xhci, addr);
temp = xhci_port_state_to_neutral(temp);
switch (wValue) {
case USB_PORT_FEAT_C_RESET:
status = PORT_RC;
port_change_bit = "reset";
break;
case USB_PORT_FEAT_C_CONNECTION:
status = PORT_CSC;
port_change_bit = "connect";
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
status = PORT_OCC;
port_change_bit = "over-current";
break;
default:
goto error;
}
/* Change bits are all write 1 to clear */
xhci_writel(xhci, temp | status, addr);
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, "clear port %s change, actual port %d status = 0x%x\n",
port_change_bit, wIndex, temp);
temp = xhci_readl(xhci, addr); /* unblock any posted writes */
break;
default:
error:
/* "stall" on error */
retval = -EPIPE;
}
spin_unlock_irqrestore(&xhci->lock, flags);
return retval;
}
/*
* Returns 0 if the status hasn't changed, or the number of bytes in buf.
* Ports are 0-indexed from the HCD point of view,
* and 1-indexed from the USB core pointer of view.
* xHCI instances can have up to 127 ports, so FIXME if you see more than 15.
*
* Note that the status change bits will be cleared as soon as a port status
* change event is generated, so we use the saved status from that event.
*/
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
{
unsigned long flags;
u32 temp, status;
int i, retval;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ports;
u32 __iomem *addr;
ports = HCS_MAX_PORTS(xhci->hcs_params1);
/* Initial status is no changes */
buf[0] = 0;
status = 0;
if (ports > 7) {
buf[1] = 0;
retval = 2;
} else {
retval = 1;
}
spin_lock_irqsave(&xhci->lock, flags);
/* For each port, did anything change? If so, set that bit in buf. */
for (i = 0; i < ports; i++) {
addr = &xhci->op_regs->port_status_base +
NUM_PORT_REGS*i;
temp = xhci_readl(xhci, addr);
if (temp & (PORT_CSC | PORT_PEC | PORT_OCC)) {
if (i < 7)
buf[0] |= 1 << (i + 1);
else
buf[1] |= 1 << (i - 7);
status = 1;
}
}
spin_unlock_irqrestore(&xhci->lock, flags);
return status ? retval : 0;
}

769
drivers/usb/host/xhci-mem.c Normal file
View File

@@ -0,0 +1,769 @@
/*
* xHCI host controller driver
*
* Copyright (C) 2008 Intel Corp.
*
* Author: Sarah Sharp
* Some code borrowed from the Linux EHCI driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/usb.h>
#include <linux/pci.h>
#include <linux/dmapool.h>
#include "xhci.h"
/*
* Allocates a generic ring segment from the ring pool, sets the dma address,
* initializes the segment to zero, and sets the private next pointer to NULL.
*
* Section 4.11.1.1:
* "All components of all Command and Transfer TRBs shall be initialized to '0'"
*/
static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, gfp_t flags)
{
struct xhci_segment *seg;
dma_addr_t dma;
seg = kzalloc(sizeof *seg, flags);
if (!seg)
return 0;
xhci_dbg(xhci, "Allocating priv segment structure at %p\n", seg);
seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma);
if (!seg->trbs) {
kfree(seg);
return 0;
}
xhci_dbg(xhci, "// Allocating segment at %p (virtual) 0x%llx (DMA)\n",
seg->trbs, (unsigned long long)dma);
memset(seg->trbs, 0, SEGMENT_SIZE);
seg->dma = dma;
seg->next = NULL;
return seg;
}
static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg)
{
if (!seg)
return;
if (seg->trbs) {
xhci_dbg(xhci, "Freeing DMA segment at %p (virtual) 0x%llx (DMA)\n",
seg->trbs, (unsigned long long)seg->dma);
dma_pool_free(xhci->segment_pool, seg->trbs, seg->dma);
seg->trbs = NULL;
}
xhci_dbg(xhci, "Freeing priv segment structure at %p\n", seg);
kfree(seg);
}
/*
* Make the prev segment point to the next segment.
*
* Change the last TRB in the prev segment to be a Link TRB which points to the
* DMA address of the next segment. The caller needs to set any Link TRB
* related flags, such as End TRB, Toggle Cycle, and no snoop.
*/
static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
struct xhci_segment *next, bool link_trbs)
{
u32 val;
if (!prev || !next)
return;
prev->next = next;
if (link_trbs) {
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr[0] = next->dma;
/* Set the last TRB in the segment to have a TRB type ID of Link TRB */
val = prev->trbs[TRBS_PER_SEGMENT-1].link.control;
val &= ~TRB_TYPE_BITMASK;
val |= TRB_TYPE(TRB_LINK);
prev->trbs[TRBS_PER_SEGMENT-1].link.control = val;
}
xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n",
(unsigned long long)prev->dma,
(unsigned long long)next->dma);
}
/* XXX: Do we need the hcd structure in all these functions? */
void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
{
struct xhci_segment *seg;
struct xhci_segment *first_seg;
if (!ring || !ring->first_seg)
return;
first_seg = ring->first_seg;
seg = first_seg->next;
xhci_dbg(xhci, "Freeing ring at %p\n", ring);
while (seg != first_seg) {
struct xhci_segment *next = seg->next;
xhci_segment_free(xhci, seg);
seg = next;
}
xhci_segment_free(xhci, first_seg);
ring->first_seg = NULL;
kfree(ring);
}
/**
* Create a new ring with zero or more segments.
*
* Link each segment together into a ring.
* Set the end flag and the cycle toggle bit on the last segment.
* See section 4.9.1 and figures 15 and 16.
*/
static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
unsigned int num_segs, bool link_trbs, gfp_t flags)
{
struct xhci_ring *ring;
struct xhci_segment *prev;
ring = kzalloc(sizeof *(ring), flags);
xhci_dbg(xhci, "Allocating ring at %p\n", ring);
if (!ring)
return 0;
INIT_LIST_HEAD(&ring->td_list);
INIT_LIST_HEAD(&ring->cancelled_td_list);
if (num_segs == 0)
return ring;
ring->first_seg = xhci_segment_alloc(xhci, flags);
if (!ring->first_seg)
goto fail;
num_segs--;
prev = ring->first_seg;
while (num_segs > 0) {
struct xhci_segment *next;
next = xhci_segment_alloc(xhci, flags);
if (!next)
goto fail;
xhci_link_segments(xhci, prev, next, link_trbs);
prev = next;
num_segs--;
}
xhci_link_segments(xhci, prev, ring->first_seg, link_trbs);
if (link_trbs) {
/* See section 4.9.2.1 and 6.4.4.1 */
prev->trbs[TRBS_PER_SEGMENT-1].link.control |= (LINK_TOGGLE);
xhci_dbg(xhci, "Wrote link toggle flag to"
" segment %p (virtual), 0x%llx (DMA)\n",
prev, (unsigned long long)prev->dma);
}
/* The ring is empty, so the enqueue pointer == dequeue pointer */
ring->enqueue = ring->first_seg->trbs;
ring->enq_seg = ring->first_seg;
ring->dequeue = ring->enqueue;
ring->deq_seg = ring->first_seg;
/* The ring is initialized to 0. The producer must write 1 to the cycle
* bit to handover ownership of the TRB, so PCS = 1. The consumer must
* compare CCS to the cycle bit to check ownership, so CCS = 1.
*/
ring->cycle_state = 1;
return ring;
fail:
xhci_ring_free(xhci, ring);
return 0;
}
/* All the xhci_tds in the ring's TD list should be freed at this point */
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_virt_device *dev;
int i;
/* Slot ID 0 is reserved */
if (slot_id == 0 || !xhci->devs[slot_id])
return;
dev = xhci->devs[slot_id];
xhci->dcbaa->dev_context_ptrs[2*slot_id] = 0;
xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0;
if (!dev)
return;
for (i = 0; i < 31; ++i)
if (dev->ep_rings[i])
xhci_ring_free(xhci, dev->ep_rings[i]);
if (dev->in_ctx)
dma_pool_free(xhci->device_pool,
dev->in_ctx, dev->in_ctx_dma);
if (dev->out_ctx)
dma_pool_free(xhci->device_pool,
dev->out_ctx, dev->out_ctx_dma);
kfree(xhci->devs[slot_id]);
xhci->devs[slot_id] = 0;
}
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
struct usb_device *udev, gfp_t flags)
{
dma_addr_t dma;
struct xhci_virt_device *dev;
/* Slot ID 0 is reserved */
if (slot_id == 0 || xhci->devs[slot_id]) {
xhci_warn(xhci, "Bad Slot ID %d\n", slot_id);
return 0;
}
xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags);
if (!xhci->devs[slot_id])
return 0;
dev = xhci->devs[slot_id];
/* Allocate the (output) device context that will be used in the HC */
dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
if (!dev->out_ctx)
goto fail;
dev->out_ctx_dma = dma;
xhci_dbg(xhci, "Slot %d output ctx = 0x%llx (dma)\n", slot_id,
(unsigned long long)dma);
memset(dev->out_ctx, 0, sizeof(*dev->out_ctx));
/* Allocate the (input) device context for address device command */
dev->in_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
if (!dev->in_ctx)
goto fail;
dev->in_ctx_dma = dma;
xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
(unsigned long long)dma);
memset(dev->in_ctx, 0, sizeof(*dev->in_ctx));
/* Allocate endpoint 0 ring */
dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
if (!dev->ep_rings[0])
goto fail;
init_completion(&dev->cmd_completion);
/*
* Point to output device context in dcbaa; skip the output control
* context, which is eight 32 bit fields (or 32 bytes long)
*/
xhci->dcbaa->dev_context_ptrs[2*slot_id] =
(u32) dev->out_ctx_dma + (32);
xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
slot_id,
&xhci->dcbaa->dev_context_ptrs[2*slot_id],
(unsigned long long)dev->out_ctx_dma);
xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0;
return 1;
fail:
xhci_free_virt_device(xhci, slot_id);
return 0;
}
/* Setup an xHCI virtual device for a Set Address command */
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev)
{
struct xhci_virt_device *dev;
struct xhci_ep_ctx *ep0_ctx;
struct usb_device *top_dev;
dev = xhci->devs[udev->slot_id];
/* Slot ID 0 is reserved */
if (udev->slot_id == 0 || !dev) {
xhci_warn(xhci, "Slot ID %d is not assigned to this device\n",
udev->slot_id);
return -EINVAL;
}
ep0_ctx = &dev->in_ctx->ep[0];
/* 2) New slot context and endpoint 0 context are valid*/
dev->in_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
/* 3) Only the control endpoint is valid - one endpoint context */
dev->in_ctx->slot.dev_info |= LAST_CTX(1);
switch (udev->speed) {
case USB_SPEED_SUPER:
dev->in_ctx->slot.dev_info |= (u32) udev->route;
dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_SS;
break;
case USB_SPEED_HIGH:
dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_HS;
break;
case USB_SPEED_FULL:
dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_FS;
break;
case USB_SPEED_LOW:
dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_LS;
break;
case USB_SPEED_VARIABLE:
xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
return -EINVAL;
break;
default:
/* Speed was set earlier, this shouldn't happen. */
BUG();
}
/* Find the root hub port this device is under */
for (top_dev = udev; top_dev->parent && top_dev->parent->parent;
top_dev = top_dev->parent)
/* Found device below root hub */;
dev->in_ctx->slot.dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum);
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) {
dev->in_ctx->slot.tt_info = udev->tt->hub->slot_id;
dev->in_ctx->slot.tt_info |= udev->ttport << 8;
}
xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
/* Step 4 - ring already allocated */
/* 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)
ep0_ctx->ep_info2 |= MAX_PACKET(512);
else
ep0_ctx->ep_info2 |= MAX_PACKET(8);
/* 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[0] =
dev->ep_rings[0]->first_seg->dma;
ep0_ctx->deq[0] |= dev->ep_rings[0]->cycle_state;
ep0_ctx->deq[1] = 0;
/* Steps 7 and 8 were done in xhci_alloc_virt_device() */
return 0;
}
/* Return the polling or NAK interval.
*
* The polling interval is expressed in "microframes". If xHCI's Interval field
* is set to N, it will service the endpoint every 2^(Interval)*125us.
*
* The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval
* is set to 0.
*/
static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
struct usb_host_endpoint *ep)
{
unsigned int interval = 0;
switch (udev->speed) {
case USB_SPEED_HIGH:
/* Max NAK rate */
if (usb_endpoint_xfer_control(&ep->desc) ||
usb_endpoint_xfer_bulk(&ep->desc))
interval = ep->desc.bInterval;
/* Fall through - SS and HS isoc/int have same decoding */
case USB_SPEED_SUPER:
if (usb_endpoint_xfer_int(&ep->desc) ||
usb_endpoint_xfer_isoc(&ep->desc)) {
if (ep->desc.bInterval == 0)
interval = 0;
else
interval = ep->desc.bInterval - 1;
if (interval > 15)
interval = 15;
if (interval != ep->desc.bInterval + 1)
dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n",
ep->desc.bEndpointAddress, 1 << interval);
}
break;
/* Convert bInterval (in 1-255 frames) to microframes and round down to
* nearest power of 2.
*/
case USB_SPEED_FULL:
case USB_SPEED_LOW:
if (usb_endpoint_xfer_int(&ep->desc) ||
usb_endpoint_xfer_isoc(&ep->desc)) {
interval = fls(8*ep->desc.bInterval) - 1;
if (interval > 10)
interval = 10;
if (interval < 3)
interval = 3;
if ((1 << interval) != 8*ep->desc.bInterval)
dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n",
ep->desc.bEndpointAddress, 1 << interval);
}
break;
default:
BUG();
}
return EP_INTERVAL(interval);
}
static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
struct usb_host_endpoint *ep)
{
int in;
u32 type;
in = usb_endpoint_dir_in(&ep->desc);
if (usb_endpoint_xfer_control(&ep->desc)) {
type = EP_TYPE(CTRL_EP);
} else if (usb_endpoint_xfer_bulk(&ep->desc)) {
if (in)
type = EP_TYPE(BULK_IN_EP);
else
type = EP_TYPE(BULK_OUT_EP);
} else if (usb_endpoint_xfer_isoc(&ep->desc)) {
if (in)
type = EP_TYPE(ISOC_IN_EP);
else
type = EP_TYPE(ISOC_OUT_EP);
} else if (usb_endpoint_xfer_int(&ep->desc)) {
if (in)
type = EP_TYPE(INT_IN_EP);
else
type = EP_TYPE(INT_OUT_EP);
} else {
BUG();
}
return type;
}
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)
{
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
struct xhci_ring *ep_ring;
unsigned int max_packet;
unsigned int max_burst;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = &virt_dev->in_ctx->ep[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])
return -ENOMEM;
ep_ring = virt_dev->new_ep_rings[ep_index];
ep_ctx->deq[0] = ep_ring->first_seg->dma | ep_ring->cycle_state;
ep_ctx->deq[1] = 0;
ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
/* FIXME dig Mult and streams info out of ep companion desc */
/* Allow 3 retries for everything but isoc */
if (!usb_endpoint_xfer_isoc(&ep->desc))
ep_ctx->ep_info2 = ERROR_COUNT(3);
else
ep_ctx->ep_info2 = ERROR_COUNT(0);
ep_ctx->ep_info2 |= xhci_get_endpoint_type(udev, ep);
/* Set the max packet size and max burst */
switch (udev->speed) {
case USB_SPEED_SUPER:
max_packet = ep->desc.wMaxPacketSize;
ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
/* dig out max burst from ep companion desc */
max_packet = ep->ss_ep_comp->desc.bMaxBurst;
ep_ctx->ep_info2 |= MAX_BURST(max_packet);
break;
case USB_SPEED_HIGH:
/* bits 11:12 specify the number of additional transaction
* opportunities per microframe (USB 2.0, section 9.6.6)
*/
if (usb_endpoint_xfer_isoc(&ep->desc) ||
usb_endpoint_xfer_int(&ep->desc)) {
max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
ep_ctx->ep_info2 |= MAX_BURST(max_burst);
}
/* Fall through */
case USB_SPEED_FULL:
case USB_SPEED_LOW:
max_packet = ep->desc.wMaxPacketSize & 0x3ff;
ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
break;
default:
BUG();
}
/* FIXME Debug endpoint context */
return 0;
}
void xhci_endpoint_zero(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
struct usb_host_endpoint *ep)
{
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = &virt_dev->in_ctx->ep[ep_index];
ep_ctx->ep_info = 0;
ep_ctx->ep_info2 = 0;
ep_ctx->deq[0] = 0;
ep_ctx->deq[1] = 0;
ep_ctx->tx_info = 0;
/* Don't free the endpoint ring until the set interface or configuration
* request succeeds.
*/
}
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
int size;
int i;
/* Free the Event Ring Segment Table and the actual Event Ring */
xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
xhci_writel(xhci, 0, &xhci->ir_set->erst_base[0]);
xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]);
xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[0]);
xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[1]);
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
if (xhci->erst.entries)
pci_free_consistent(pdev, size,
xhci->erst.entries, xhci->erst.erst_dma_addr);
xhci->erst.entries = NULL;
xhci_dbg(xhci, "Freed ERST\n");
if (xhci->event_ring)
xhci_ring_free(xhci, xhci->event_ring);
xhci->event_ring = NULL;
xhci_dbg(xhci, "Freed event ring\n");
xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[0]);
xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[1]);
if (xhci->cmd_ring)
xhci_ring_free(xhci, xhci->cmd_ring);
xhci->cmd_ring = NULL;
xhci_dbg(xhci, "Freed command ring\n");
for (i = 1; i < MAX_HC_SLOTS; ++i)
xhci_free_virt_device(xhci, i);
if (xhci->segment_pool)
dma_pool_destroy(xhci->segment_pool);
xhci->segment_pool = NULL;
xhci_dbg(xhci, "Freed segment pool\n");
if (xhci->device_pool)
dma_pool_destroy(xhci->device_pool);
xhci->device_pool = NULL;
xhci_dbg(xhci, "Freed device context pool\n");
xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]);
xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]);
if (xhci->dcbaa)
pci_free_consistent(pdev, sizeof(*xhci->dcbaa),
xhci->dcbaa, xhci->dcbaa->dma);
xhci->dcbaa = NULL;
xhci->page_size = 0;
xhci->page_shift = 0;
}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
dma_addr_t dma;
struct device *dev = xhci_to_hcd(xhci)->self.controller;
unsigned int val, val2;
struct xhci_segment *seg;
u32 page_size;
int i;
page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
for (i = 0; i < 16; i++) {
if ((0x1 & page_size) != 0)
break;
page_size = page_size >> 1;
}
if (i < 16)
xhci_dbg(xhci, "Supported page size of %iK\n", (1 << (i+12)) / 1024);
else
xhci_warn(xhci, "WARN: no supported page size\n");
/* Use 4K pages, since that's common and the minimum the HC supports */
xhci->page_shift = 12;
xhci->page_size = 1 << xhci->page_shift;
xhci_dbg(xhci, "HCD page size set to %iK\n", xhci->page_size / 1024);
/*
* Program the Number of Device Slots Enabled field in the CONFIG
* register with the max value of slots the HC can handle.
*/
val = HCS_MAX_SLOTS(xhci_readl(xhci, &xhci->cap_regs->hcs_params1));
xhci_dbg(xhci, "// xHC can handle at most %d device slots.\n",
(unsigned int) val);
val2 = xhci_readl(xhci, &xhci->op_regs->config_reg);
val |= (val2 & ~HCS_SLOTS_MASK);
xhci_dbg(xhci, "// Setting Max device slots reg = 0x%x.\n",
(unsigned int) val);
xhci_writel(xhci, val, &xhci->op_regs->config_reg);
/*
* Section 5.4.8 - doorbell array must be
* "physically contiguous and 64-byte (cache line) aligned".
*/
xhci->dcbaa = pci_alloc_consistent(to_pci_dev(dev),
sizeof(*xhci->dcbaa), &dma);
if (!xhci->dcbaa)
goto fail;
memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
xhci->dcbaa->dma = dma;
xhci_dbg(xhci, "// Device context base array address = 0x%llx (DMA), %p (virt)\n",
(unsigned long long)xhci->dcbaa->dma, xhci->dcbaa);
xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]);
xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]);
/*
* Initialize the ring segment pool. The ring must be a contiguous
* structure comprised of TRBs. The TRBs must be 16 byte aligned,
* however, the command ring segment needs 64-byte aligned segments,
* so we pick the greater alignment need.
*/
xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
SEGMENT_SIZE, 64, xhci->page_size);
/* See Table 46 and Note on Figure 55 */
/* FIXME support 64-byte contexts */
xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
sizeof(struct xhci_device_control),
64, xhci->page_size);
if (!xhci->segment_pool || !xhci->device_pool)
goto fail;
/* Set up the command ring to have one segments for now. */
xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, flags);
if (!xhci->cmd_ring)
goto fail;
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
(unsigned long long)xhci->cmd_ring->first_seg->dma);
/* Set the address in the Command Ring Control register */
val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
val = (val & ~CMD_RING_ADDR_MASK) |
(xhci->cmd_ring->first_seg->dma & CMD_RING_ADDR_MASK) |
xhci->cmd_ring->cycle_state;
xhci_dbg(xhci, "// Setting command ring address low bits to 0x%x\n", val);
xhci_writel(xhci, val, &xhci->op_regs->cmd_ring[0]);
xhci_dbg(xhci, "// Setting command ring address high bits to 0x0\n");
xhci_writel(xhci, (u32) 0, &xhci->op_regs->cmd_ring[1]);
xhci_dbg_cmd_ptrs(xhci);
val = xhci_readl(xhci, &xhci->cap_regs->db_off);
val &= DBOFF_MASK;
xhci_dbg(xhci, "// Doorbell array is located at offset 0x%x"
" from cap regs base addr\n", val);
xhci->dba = (void *) xhci->cap_regs + val;
xhci_dbg_regs(xhci);
xhci_print_run_regs(xhci);
/* Set ir_set to interrupt register set 0 */
xhci->ir_set = (void *) xhci->run_regs->ir_set;
/*
* Event ring setup: Allocate a normal ring, but also setup
* the event ring segment table (ERST). Section 4.9.3.
*/
xhci_dbg(xhci, "// Allocating event ring\n");
xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags);
if (!xhci->event_ring)
goto fail;
xhci->erst.entries = pci_alloc_consistent(to_pci_dev(dev),
sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS, &dma);
if (!xhci->erst.entries)
goto fail;
xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n",
(unsigned long long)dma);
memset(xhci->erst.entries, 0, sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS);
xhci->erst.num_entries = ERST_NUM_SEGS;
xhci->erst.erst_dma_addr = dma;
xhci_dbg(xhci, "Set ERST to 0; private num segs = %i, virt addr = %p, dma addr = 0x%llx\n",
xhci->erst.num_entries,
xhci->erst.entries,
(unsigned long long)xhci->erst.erst_dma_addr);
/* set ring base address and size for each segment table entry */
for (val = 0, seg = xhci->event_ring->first_seg; val < ERST_NUM_SEGS; val++) {
struct xhci_erst_entry *entry = &xhci->erst.entries[val];
entry->seg_addr[0] = seg->dma;
entry->seg_addr[1] = 0;
entry->seg_size = TRBS_PER_SEGMENT;
entry->rsvd = 0;
seg = seg->next;
}
/* set ERST count with the number of entries in the segment table */
val = xhci_readl(xhci, &xhci->ir_set->erst_size);
val &= ERST_SIZE_MASK;
val |= ERST_NUM_SEGS;
xhci_dbg(xhci, "// Write ERST size = %i to ir_set 0 (some bits preserved)\n",
val);
xhci_writel(xhci, val, &xhci->ir_set->erst_size);
xhci_dbg(xhci, "// Set ERST entries to point to event ring.\n");
/* set the segment table base address */
xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n",
(unsigned long long)xhci->erst.erst_dma_addr);
val = xhci_readl(xhci, &xhci->ir_set->erst_base[0]);
val &= ERST_PTR_MASK;
val |= (xhci->erst.erst_dma_addr & ~ERST_PTR_MASK);
xhci_writel(xhci, val, &xhci->ir_set->erst_base[0]);
xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]);
/* Set the event ring dequeue address */
xhci_set_hc_event_deq(xhci);
xhci_dbg(xhci, "Wrote ERST address to ir_set 0.\n");
xhci_print_ir_set(xhci, xhci->ir_set, 0);
/*
* XXX: Might need to set the Interrupter Moderation Register to
* something other than the default (~1ms minimum between interrupts).
* See section 5.5.1.2.
*/
init_completion(&xhci->addr_dev);
for (i = 0; i < MAX_HC_SLOTS; ++i)
xhci->devs[i] = 0;
return 0;
fail:
xhci_warn(xhci, "Couldn't initialize memory\n");
xhci_mem_cleanup(xhci);
return -ENOMEM;
}

166
drivers/usb/host/xhci-pci.c Normal file
View File

@@ -0,0 +1,166 @@
/*
* xHCI host controller driver PCI Bus Glue.
*
* Copyright (C) 2008 Intel Corp.
*
* Author: Sarah Sharp
* Some code borrowed from the Linux EHCI driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/pci.h>
#include "xhci.h"
static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */
static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
{
/*
* TODO: Implement finding debug ports later.
* TODO: see if there are any quirks that need to be added to handle
* new extended capabilities.
*/
/* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */
if (!pci_set_mwi(pdev))
xhci_dbg(xhci, "MWI active\n");
xhci_dbg(xhci, "Finished xhci_pci_reinit\n");
return 0;
}
/* called during probe() after chip reset completes */
static int xhci_pci_setup(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
int retval;
xhci->cap_regs = hcd->regs;
xhci->op_regs = hcd->regs +
HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
xhci->run_regs = hcd->regs +
(xhci_readl(xhci, &xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
/* Cache read-only capability registers */
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->hcc_params);
xhci_print_registers(xhci);
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
if (retval)
return retval;
xhci_dbg(xhci, "Resetting HCD\n");
/* Reset the internal HC memory state and registers. */
retval = xhci_reset(xhci);
if (retval)
return retval;
xhci_dbg(xhci, "Reset complete\n");
xhci_dbg(xhci, "Calling HCD init\n");
/* Initialize HCD and host controller data structures. */
retval = xhci_init(hcd);
if (retval)
return retval;
xhci_dbg(xhci, "Called HCD init\n");
pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
/* Find any debug ports */
return xhci_pci_reinit(xhci, pdev);
}
static const struct hc_driver xhci_pci_hc_driver = {
.description = hcd_name,
.product_desc = "xHCI Host Controller",
.hcd_priv_size = sizeof(struct xhci_hcd),
/*
* generic hardware linkage
*/
.irq = xhci_irq,
.flags = HCD_MEMORY | HCD_USB3,
/*
* basic lifecycle operations
*/
.reset = xhci_pci_setup,
.start = xhci_run,
/* suspend and resume implemented later */
.stop = xhci_stop,
.shutdown = xhci_shutdown,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = xhci_urb_enqueue,
.urb_dequeue = xhci_urb_dequeue,
.alloc_dev = xhci_alloc_dev,
.free_dev = xhci_free_dev,
.add_endpoint = xhci_add_endpoint,
.drop_endpoint = xhci_drop_endpoint,
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
.address_device = xhci_address_device,
/*
* scheduling support
*/
.get_frame_number = xhci_get_frame,
/* Root hub support */
.hub_control = xhci_hub_control,
.hub_status_data = xhci_hub_status_data,
};
/*-------------------------------------------------------------------------*/
/* PCI driver selection metadata; PCI hotplugging uses this */
static const struct pci_device_id pci_ids[] = { {
/* handle any USB 3.0 xHCI controller */
PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
.driver_data = (unsigned long) &xhci_pci_hc_driver,
},
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, pci_ids);
/* pci driver glue; this is a "new style" PCI driver module */
static struct pci_driver xhci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
/* suspend and resume implemented later */
.shutdown = usb_hcd_pci_shutdown,
};
int xhci_register_pci()
{
return pci_register_driver(&xhci_pci_driver);
}
void xhci_unregister_pci()
{
pci_unregister_driver(&xhci_pci_driver);
}

1648
drivers/usb/host/xhci-ring.c Normal file

File diff suppressed because it is too large Load Diff

1157
drivers/usb/host/xhci.h Normal file

File diff suppressed because it is too large Load Diff