Module Name:    src
Committed By:   msaitoh
Date:           Fri Dec  7 08:28:44 UTC 2018

Modified Files:
        src/sys/dev/pci: xhci_pci.c

Log Message:
 xHCI uses BAR0 to map memory space. If a chip has MSI-X capability and it
points to BAR0, reserve the space. Almost the same as nvme_pci.c.

XXX Is it possible to make a nice API?


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/pci/xhci_pci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/xhci_pci.c
diff -u src/sys/dev/pci/xhci_pci.c:1.18 src/sys/dev/pci/xhci_pci.c:1.19
--- src/sys/dev/pci/xhci_pci.c:1.18	Fri Nov 30 17:47:54 2018
+++ src/sys/dev/pci/xhci_pci.c	Fri Dec  7 08:28:44 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci_pci.c,v 1.18 2018/11/30 17:47:54 jdolecek Exp $	*/
+/*	$NetBSD: xhci_pci.c,v 1.19 2018/12/07 08:28:44 msaitoh Exp $	*/
 /*	OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp	*/
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.18 2018/11/30 17:47:54 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.19 2018/12/07 08:28:44 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_xhci_pci.h"
@@ -125,9 +125,11 @@ xhci_pci_attach(device_t parent, device_
 	const pcitag_t tag = pa->pa_tag;
 	char const *intrstr;
 	pcireg_t csr, memtype, usbrev;
-	int err;
 	uint32_t hccparams;
 	char intrbuf[PCI_INTRSTR_LEN];
+	bus_addr_t memaddr;
+	int flags, msixoff;
+	int err;
 
 	sc->sc_dev = self;
 
@@ -146,22 +148,41 @@ xhci_pci_attach(device_t parent, device_
 
 	/* map MMIO registers */
 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_CBMEM);
-	switch (memtype) {
-	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
-	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
-		if (pci_mapreg_map(pa, PCI_CBMEM, memtype, 0,
-			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) {
-			sc->sc_ios = 0;
-			aprint_error_dev(self, "can't map mem space\n");
-			return;
-		}
-		break;
-	default:
+	if (PCI_MAPREG_TYPE(memtype) != PCI_MAPREG_TYPE_MEM) {
 		sc->sc_ios = 0;
 		aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n");
 		return;
 	}
 
+	sc->sc_iot = pa->pa_memt;
+	if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_CBMEM, memtype,
+	    &memaddr, &sc->sc_ios, &flags) != 0) {
+		sc->sc_ios = 0;
+		aprint_error_dev(self, "can't get map info\n");
+		return;
+	}
+
+	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSIX, &msixoff,
+	    NULL)) {
+		pcireg_t msixtbl;
+		uint32_t table_offset;
+		int bir;
+
+		msixtbl = pci_conf_read(pa->pa_pc, pa->pa_tag,
+		    msixoff + PCI_MSIX_TBLOFFSET);
+		table_offset = msixtbl & PCI_MSIX_TBLOFFSET_MASK;
+		bir = msixtbl & PCI_MSIX_PBABIR_MASK;
+		/* Shrink map area for MSI-X table */
+		if (bir == PCI_MAPREG_NUM(PCI_CBMEM))
+			sc->sc_ios = table_offset;
+	}
+	if (bus_space_map(sc->sc_iot, memaddr, sc->sc_ios, flags,
+	    &sc->sc_ioh)) {
+		sc->sc_ios = 0;
+		aprint_error_dev(self, "can't map mem space\n");
+		return;
+	}
+
 	psc->sc_pc = pc;
 	psc->sc_tag = tag;
 

Reply via email to