summaryrefslogtreecommitdiff
path: root/sys/dev/usb/xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/xhci.c')
-rw-r--r--sys/dev/usb/xhci.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index d68f98e..46ec4af 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -37,6 +37,7 @@
#include <dev/usb/xhciregs.h>
#include <dev/usb/xhcivar.h>
#include <dev/pci/pci.h>
+#include <dev/pci/pciregs.h>
#include <dev/acpi/acpi.h>
#include <vm/physmem.h>
#include <vm/dynalloc.h>
@@ -56,10 +57,11 @@
static struct pci_device *hci_dev;
static struct timer tmr;
-__attribute__((__interrupt__)) static void
-xhci_common_isr(void *sf)
+static int
+xhci_intr(void *sf)
{
pr_trace("received xHCI interrupt (via PCI MSI-X)\n");
+ return 1; /* handled */
}
/*
@@ -174,6 +176,7 @@ xhci_init_scratchpads(struct xhci_hc *hc)
struct xhci_caps *caps = XHCI_CAPS(hc->base);
uint16_t max_bufs_lo, max_bufs_hi;
uint16_t max_bufs;
+ size_t len;
uintptr_t *bufarr, tmp;
max_bufs_lo = XHCI_MAX_SP_LO(caps->hcsparams1);
@@ -187,8 +190,9 @@ xhci_init_scratchpads(struct xhci_hc *hc)
return 0;
}
- pr_trace("using %d pages for xHC scratchpads\n");
- bufarr = dynalloc_memalign(sizeof(uintptr_t)*max_bufs, 0x1000);
+ len = sizeof(uint64_t) * max_bufs;
+ pr_trace("using %d bytes for xHC scratchpads\n", len);
+ bufarr = dynalloc_memalign(len, 0x1000);
if (bufarr == NULL) {
pr_error("failed to allocate scratchpad buffer array\n");
return -1;
@@ -232,7 +236,7 @@ xhci_init_msix(struct xhci_hc *hc)
struct msi_intr intr;
intr.name = "xHCI MSI-X";
- intr.handler = xhci_common_isr;
+ intr.handler = xhci_intr;
return pci_enable_msix(hci_dev, &intr);
}
@@ -254,7 +258,7 @@ xhci_init_evring(struct xhci_hc *hc)
memset(segtab, 0, DEFAULT_PAGESIZE);
/* Set the size of the event ring segment table */
- erst_size = PTR_OFFSET(runtime, 0x28);
+ erst_size = PTR_OFFSET(runtime, XHCI_RT_ERSTSZ);
mmio_write32(erst_size, 1);
/* Allocate the event ring segment */
@@ -268,20 +272,20 @@ xhci_init_evring(struct xhci_hc *hc)
segtab->size = XHCI_EVRING_LEN;
/* Setup the event ring dequeue pointer */
- erdp = PTR_OFFSET(runtime, 0x38);
+ erdp = PTR_OFFSET(runtime, XHCI_RT_ERDP);
mmio_write64(erdp, segtab->base);
/* Point ERSTBA to our event ring segment */
- erstba = PTR_OFFSET(runtime, 0x30);
+ erstba = PTR_OFFSET(runtime, XHCI_RT_ERSTBA);
mmio_write64(erstba, VIRT_TO_PHYS(segtab));
hc->evring = PHYS_TO_VIRT(segtab->base);
/* Setup interrupt moderation */
- imod = PTR_OFFSET(runtime, 0x24);
+ imod = PTR_OFFSET(runtime, XHCI_RT_IMOD);
mmio_write32(imod, XHCI_IMOD_DEFAULT);
/* Enable interrupts */
- iman = PTR_OFFSET(runtime, 0x20);
+ iman = PTR_OFFSET(runtime, XHCI_RT_IMAN);
tmp = mmio_read32(iman);
mmio_write32(iman, tmp | XHCI_IMAN_IE);
}
@@ -495,6 +499,16 @@ xhci_init_hc(struct xhci_hc *hc)
return 0;
}
+static void
+xhci_init_pci(void)
+{
+ uint32_t tmp;
+
+ tmp = pci_readl(hci_dev, PCIREG_CMDSTATUS);
+ tmp |= (PCI_BUS_MASTERING | PCI_MEM_SPACE);
+ pci_writel(hci_dev, PCIREG_CMDSTATUS, tmp);
+}
+
static int
xhci_init(void)
{
@@ -527,6 +541,7 @@ xhci_init(void)
return -ENODEV;
}
+ xhci_init_pci();
return xhci_init_hc(&xhc);
}