/* * Set up MSI-X */ static int xhci_setup_msix(struct xhci_hcd *xhci) { int i, ret = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* * calculate number of msi-x vectors supported. * - HCS_MAX_INTRS: the max number of interrupts the host can handle, * with max number of interrupters based on the xhci HCSPARAMS1. * - num_online_cpus: maximum msi-x vectors per CPUs core. * Add additional 1 vector to ensure always available interrupt. */ xhci->msix_count = min(num_online_cpus() + 1, HCS_MAX_INTRS(xhci->hcs_params1)); xhci->msix_entries = kmalloc((sizeof(struct msix_entry))*xhci->msix_count, GFP_KERNEL); if (!xhci->msix_entries) { xhci_err(xhci, "Failed to allocate MSI-X entries\n"); return -ENOMEM; } for (i = 0; i < xhci->msix_count; i++) { xhci->msix_entries[i].entry = i; xhci->msix_entries[i].vector = 0; } ret = pci_enable_msix_exact(pdev, xhci->msix_entries, xhci->msix_count); if (ret) { xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Failed to enable MSI-X"); goto free_entries; } for (i = 0; i < xhci->msix_count; i++) { ret = request_irq(xhci->msix_entries[i].vector, xhci_msi_irq, 0, "xhci_hcd", xhci_to_hcd(xhci)); if (ret) goto disable_msix; } hcd->msix_enabled = 1; return ret; disable_msix: xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI-X interrupt"); xhci_free_irq(xhci); pci_disable_msix(pdev); free_entries: kfree(xhci->msix_entries); xhci->msix_entries = NULL; return ret; }
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_cap_regs(struct xhci_hcd *xhci) { u32 temp; u32 hci_version; xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs); temp = readl(&xhci->cap_regs->hc_capbase); hci_version = HC_VERSION(temp); 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", hci_version); temp = readl(&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 = readl(&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 = readl(&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 = readl(&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"); xhci_dbg(xhci, " HC %s Contiguous Frame ID Capability\n", HCC_CFC(temp) ? "has" : "hasn't"); xhci_dbg(xhci, " HC %s generate Stopped - Short Package event\n", HCC_SPC(temp) ? "can" : "can't"); /* FIXME */ xhci_dbg(xhci, " FIXME: more HCCPARAMS debugging\n"); temp = readl(&xhci->cap_regs->run_regs_off); xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK); /* xhci 1.1 controllers have the HCCPARAMS2 register */ if (hci_version > 0x100) { temp = readl(&xhci->cap_regs->hcc_params2); xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp); xhci_dbg(xhci, " HC %s Force save context capability", HCC2_FSC(temp) ? "supports" : "doesn't support"); xhci_dbg(xhci, " HC %s Large ESIT Payload Capability", HCC2_LEC(temp) ? "supports" : "doesn't support"); xhci_dbg(xhci, " HC %s Extended TBC capability", HCC2_ETC(temp) ? "supports" : "doesn't support"); } }