Today mpi@ reminded me that I had written support for MSI-X some time
ago.  Since he is interested in using multiple vectors, I extended the
code I had a bit to support that feature as well.  This introduces a
new function:

int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);

You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
pass it a vector number as the 2nd argument.  Typically you'll pass 0,
wich will map the 1st vector, which is always there on hardware with
MSI-X support.  Some hardware supports more than 1 vector.  Typical
examples are network cards that support multiple rings.  Please be
aware that on architectures like i386 and amd64, the number of
interrupt vectors at each level is limited.  If you consume too many
of them, devices may fail to attach.

As for the implementation.  This only adds code for amd64.  I'll
probably add support for sparc64 as well.  I'm hesitant about i386
because it has even less available interrupt vectors than amd64.

Notice that the amd64 implementation uses _bus_space_map() and
_bus_space_unmap().  That is deliberate.  The MSI-X registers miht
share a BAR with other registers that our drivers already map.  The
underscored versions of the mapping routines make sure that we don't
fail to map things in that case.

ok?


Index: arch/alpha/pci/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/alpha/pci/pci_machdep.h,v
retrieving revision 1.29
diff -u -p -r1.29 pci_machdep.h
--- arch/alpha/pci/pci_machdep.h        26 Jul 2015 05:09:44 -0000      1.29
+++ arch/alpha/pci/pci_machdep.h        3 May 2016 19:26:30 -0000
@@ -104,6 +104,7 @@ int alpha_sysctl_chipset(int *, u_int, c
 #define        pci_conf_write(c, t, r, v)                                      
\
     (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
 #define        pci_intr_map_msi(pa, ihp)       (-1)
+#define        pci_intr_map_msix(pa, vec, ihp) (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_line(c, ih)                                            
\
Index: arch/amd64/include/i82093var.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/i82093var.h,v
retrieving revision 1.4
diff -u -p -r1.4 i82093var.h
--- arch/amd64/include/i82093var.h      21 May 2011 15:58:27 -0000      1.4
+++ arch/amd64/include/i82093var.h      3 May 2016 19:26:30 -0000
@@ -70,6 +70,7 @@ struct ioapic_softc {
 
 #define APIC_INT_VIA_APIC      0x10000000
 #define APIC_INT_VIA_MSG       0x20000000
+#define APIC_INT_VIA_MSGX      0x40000000
 #define APIC_INT_APIC_MASK     0x00ff0000
 #define APIC_INT_APIC_SHIFT    16
 #define APIC_INT_PIN_MASK      0x0000ff00
Index: arch/amd64/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
retrieving revision 1.24
diff -u -p -r1.24 pci_machdep.h
--- arch/amd64/include/pci_machdep.h    29 Oct 2015 23:08:45 -0000      1.24
+++ arch/amd64/include/pci_machdep.h    3 May 2016 19:26:30 -0000
@@ -82,7 +82,10 @@ int          pci_conf_size(pci_chipset_tag_t, pc
 pcireg_t       pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
 void           pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
                    pcireg_t);
-int            pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
+int            pci_intr_map_msi(struct pci_attach_args *,
+                   pci_intr_handle_t *);
+int            pci_intr_map_msix(struct pci_attach_args *,
+                   int, pci_intr_handle_t *);
 int            pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 const char     *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 void           *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
Index: arch/amd64/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.62
diff -u -p -r1.62 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c        14 Mar 2015 03:38:46 -0000      1.62
+++ arch/amd64/pci/pci_machdep.c        3 May 2016 19:26:30 -0000
@@ -395,6 +395,143 @@ pci_intr_map_msi(struct pci_attach_args 
        return 0;
 }
 
+void msix_hwmask(struct pic *, int);
+void msix_hwunmask(struct pic *, int);
+void msix_addroute(struct pic *, struct cpu_info *, int, int, int);
+void msix_delroute(struct pic *, struct cpu_info *, int, int, int);
+
+struct pic msix_pic = {
+       {0, {NULL}, NULL, 0, "msix", NULL, 0, 0},
+       PIC_MSI,
+#ifdef MULTIPROCESSOR
+       {},
+#endif
+       msix_hwmask,
+       msix_hwunmask,
+       msix_addroute,
+       msix_delroute,
+       NULL,
+       ioapic_edge_stubs
+};
+
+/*
+ * We pack the MSI-X vector number into the lower 8 bits of the PCI
+ * tag and use that as the MSI-X "PIC" pin number.  This allows us to
+ * address 256 MSI-X vectors which ought to be enough for anybody.
+ */
+#define PCI_MSIX_VEC_MASK      0xff
+#define PCI_MSIX_VEC(pin)      ((pin) & PCI_MSIX_VEC_MASK)
+#define PCI_MSIX_TAG(pin)      ((pin) & ~PCI_MSIX_VEC_MASK)
+#define PCI_MSIX_PIN(tag, vec) ((tag) | (vec))
+
+void
+msix_hwmask(struct pic *pic, int pin)
+{
+}
+
+void
+msix_hwunmask(struct pic *pic, int pin)
+{
+}
+
+void
+msix_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
+{
+       pci_chipset_tag_t pc = NULL; /* XXX */
+       bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
+       bus_space_handle_t memh;
+       bus_addr_t base;
+       pcitag_t tag = PCI_MSIX_TAG(pin);
+       int entry = PCI_MSIX_VEC(pin);
+       pcireg_t reg, addr, table;
+       uint32_t ctrl;
+       int bir, offset;
+       int off, tblsz;
+
+       if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, &reg) == 0)
+               panic("%s: no msix capability", __func__);
+
+       addr = 0xfee00000UL | (ci->ci_apicid << 12);
+
+       table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
+       bir = (table & PCI_MSIX_TABLE_BIR);
+       offset = (table & PCI_MSIX_TABLE_OFF);
+       tblsz = (reg & PCI_MSIX_MC_TBLSZ) + 1;
+
+       bir = PCI_MAPREG_START + bir * 4;
+       if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
+           _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
+               panic("%s: cannot map registers", __func__);
+
+       bus_space_write_8(memt, memh, PCI_MSIX_MA(entry), addr);
+       bus_space_write_4(memt, memh, PCI_MSIX_MD(entry), vec);
+       bus_space_barrier(memt, memh, PCI_MSIX_MA(entry), 16,
+           BUS_SPACE_BARRIER_WRITE);
+       ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
+       bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
+           ctrl & ~PCI_MSIX_VC_MASK);
+
+       _bus_space_unmap(memt, memh, tblsz * 16, NULL);
+
+       pci_conf_write(pc, tag, off, reg | PCI_MSIX_MC_MSIXE);
+}
+
+void
+msix_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
+{
+       pci_chipset_tag_t pc = NULL; /* XXX */
+       bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
+       bus_space_handle_t memh;
+       bus_addr_t base;
+       pcitag_t tag = PCI_MSIX_TAG(pin);
+       int entry = PCI_MSIX_VEC(pin);
+       pcireg_t reg, table;
+       uint32_t ctrl;
+       int bir, offset;
+       int off, tblsz;
+
+       if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, &reg) == 0)
+               return;
+
+       table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
+       bir = (table & PCI_MSIX_TABLE_BIR);
+       offset = (table & PCI_MSIX_TABLE_OFF);
+       tblsz = (reg & PCI_MSIX_MC_TBLSZ) + 1;
+
+       bir = PCI_MAPREG_START + bir * 4;
+       if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
+           _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
+               panic("%s: cannot map registers", __func__);
+
+       ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
+       bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
+           ctrl | PCI_MSIX_VC_MASK);
+
+       _bus_space_unmap(memt, memh, tblsz * 16, NULL);
+}
+
+int
+pci_intr_map_msix(struct pci_attach_args *pa, int vec, pci_intr_handle_t *ihp)
+{
+       pci_chipset_tag_t pc = pa->pa_pc;
+       pcitag_t tag = pa->pa_tag;
+       pcireg_t reg;
+
+       KASSERT(PCI_MSIX_VEC(vec) == vec);
+
+       if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
+           pci_get_capability(pc, tag, PCI_CAP_MSIX, NULL, NULL) == 0)
+               return 1;
+
+       if (vec > (reg & PCI_MSIX_MC_TBLSZ))
+               return 1;
+
+       ihp->tag = PCI_MSIX_PIN(tag, vec);
+       ihp->line = APIC_INT_VIA_MSGX;
+       ihp->pin = 0;
+       return 0;
+}
+
 int
 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
 {
@@ -527,6 +664,8 @@ pci_intr_string(pci_chipset_tag_t pc, pc
 
        if (ih.line & APIC_INT_VIA_MSG)
                return ("msi");
+       if (ih.line & APIC_INT_VIA_MSGX)
+               return ("msix");
 
 #if NIOAPIC > 0
        if (ih.line & APIC_INT_VIA_APIC)
@@ -557,6 +696,10 @@ pci_intr_establish(pci_chipset_tag_t pc,
 
        if (ih.line & APIC_INT_VIA_MSG) {
                return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
+                   func, arg, what);
+       }
+       if (ih.line & APIC_INT_VIA_MSGX) {
+               return intr_establish(-1, &msix_pic, tag, IST_PULSE, level,
                    func, arg, what);
        }
 
Index: arch/arm/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/pci_machdep.h,v
retrieving revision 1.13
diff -u -p -r1.13 pci_machdep.h
--- arch/arm/include/pci_machdep.h      5 Nov 2013 10:12:35 -0000       1.13
+++ arch/arm/include/pci_machdep.h      3 May 2016 19:26:30 -0000
@@ -93,6 +93,7 @@ struct arm32_pci_chipset {
 #define        pci_intr_map(pa, ihp)                                           
\
     (*(pa)->pa_pc->pc_intr_map)((pa), (ihp))
 #define        pci_intr_map_msi(pa, ihp)       (-1)
+#define        pci_intr_map_msix(pa, vec, ihp) (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_establish(c, ih, l, h, a, n)                           
\
Index: arch/hppa/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/pci_machdep.h,v
retrieving revision 1.11
diff -u -p -r1.11 pci_machdep.h
--- arch/hppa/include/pci_machdep.h     5 Nov 2013 10:12:35 -0000       1.11
+++ arch/hppa/include/pci_machdep.h     3 May 2016 19:26:30 -0000
@@ -81,6 +81,7 @@ struct hppa_pci_chipset_tag {
 #define        pci_intr_map(p, ihp)                                            
\
     (*(p)->pa_pc->pc_intr_map)((p), (ihp))
 #define        pci_intr_map_msi(p, ihp)        (-1)
+#define        pci_intr_map_msix(p, vec, ihp)  (-1)
 #define        pci_intr_line(c, ih)    (ih)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->_cookie, (ih))
Index: arch/hppa64/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa64/include/pci_machdep.h,v
retrieving revision 1.11
diff -u -p -r1.11 pci_machdep.h
--- arch/hppa64/include/pci_machdep.h   5 Nov 2013 10:12:35 -0000       1.11
+++ arch/hppa64/include/pci_machdep.h   3 May 2016 19:26:31 -0000
@@ -72,6 +72,7 @@ struct hppa64_pci_chipset_tag {
 #define        pci_intr_map(p, ihp)                                            
\
     (*(p)->pa_pc->pc_intr_map)((p), (ihp))
 #define        pci_intr_map_msi(p, ihp)        (-1)
+#define        pci_intr_map_msix(p, vec, ihp)  (-1)
 #define        pci_intr_line(c, ih)    (ih)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->_cookie, (ih))
Index: arch/i386/pci/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/pci/pci_machdep.h,v
retrieving revision 1.27
diff -u -p -r1.27 pci_machdep.h
--- arch/i386/pci/pci_machdep.h 17 Jul 2015 22:42:09 -0000      1.27
+++ arch/i386/pci/pci_machdep.h 3 May 2016 19:26:31 -0000
@@ -99,6 +99,7 @@ void          pci_conf_write(pci_chipset_tag_t, 
 struct pci_attach_args;
 int            pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
 int            pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
+#define                pci_intr_map_msix(p, vec, ihp)  (-1)
 #define                pci_intr_line(c, ih)    ((ih).line)
 const char     *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 void           *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
Index: arch/landisk/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/landisk/include/pci_machdep.h,v
retrieving revision 1.9
diff -u -p -r1.9 pci_machdep.h
--- arch/landisk/include/pci_machdep.h  5 Nov 2013 10:12:35 -0000       1.9
+++ arch/landisk/include/pci_machdep.h  3 May 2016 19:26:31 -0000
@@ -76,6 +76,7 @@ void landisk_pci_conf_interrupt(void *v,
 #define        pci_intr_map(pa, ihp) \
        landisk_pci_intr_map(pa, ihp)
 #define        pci_intr_map_msi(pa, ihp)       (-1)
+#define        pci_intr_map_msix(pa, vec, ihp) (-1)
 #define        pci_intr_string(v, ih) \
        landisk_pci_intr_string(v, ih)
 #define        pci_intr_establish(v, ih, level, ih_fun, ih_arg, ih_name) \
Index: arch/loongson/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/loongson/include/pci_machdep.h,v
retrieving revision 1.9
diff -u -p -r1.9 pci_machdep.h
--- arch/loongson/include/pci_machdep.h 27 Mar 2014 22:16:03 -0000      1.9
+++ arch/loongson/include/pci_machdep.h 3 May 2016 19:26:31 -0000
@@ -76,6 +76,7 @@ struct mips_pci_chipset {
 #define        pci_intr_map(c, ihp)                            \
     (*(c)->pa_pc->pc_intr_map)((c), (ihp))
 #define        pci_intr_map_msi(c, ihp)        (-1)
+#define        pci_intr_map_msix(c, vec, ihp)  (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_establish(c, ih, l, h, a, nm)                          
\
Index: arch/macppc/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/macppc/include/pci_machdep.h,v
retrieving revision 1.2
diff -u -p -r1.2 pci_machdep.h
--- arch/macppc/include/pci_machdep.h   5 Nov 2013 10:12:35 -0000       1.2
+++ arch/macppc/include/pci_machdep.h   3 May 2016 19:26:31 -0000
@@ -85,6 +85,7 @@ pcireg_t      pci_conf_read(pci_chipset_tag_t
 void           pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
 int            pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 int            pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
+#define                pci_intr_map_msix(p, vec, ihp)  (-1)
 int            pci_intr_line(pci_chipset_tag_t, pci_intr_handle_t);
 const char     *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 void           *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
Index: arch/octeon/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/octeon/include/pci_machdep.h,v
retrieving revision 1.7
diff -u -p -r1.7 pci_machdep.h
--- arch/octeon/include/pci_machdep.h   5 Nov 2013 10:12:35 -0000       1.7
+++ arch/octeon/include/pci_machdep.h   3 May 2016 19:26:31 -0000
@@ -104,6 +104,7 @@ static inline void pci_conf_write_db(voi
 #define        pci_intr_map(c, ihp)                            \
     (*(c)->pa_pc->pc_intr_map)((c), (ihp))
 #define        pci_intr_map_msi(c, ihp)        (-1)
+#define        pci_intr_map_msix(c, vec, ihp)  (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_establish(c, ih, l, h, a, nm)                          
\
Index: arch/sgi/pci/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/sgi/pci/pci_machdep.h,v
retrieving revision 1.16
diff -u -p -r1.16 pci_machdep.h
--- arch/sgi/pci/pci_machdep.h  5 Nov 2013 10:12:35 -0000       1.16
+++ arch/sgi/pci/pci_machdep.h  3 May 2016 19:26:31 -0000
@@ -87,6 +87,7 @@ struct mips_pci_chipset {
 #define        pci_intr_map(c, ihp)                                            
\
     (*(c)->pa_pc->pc_intr_map)((c), (ihp))
 #define        pci_intr_map_msi(c, ihp)        (-1)
+#define        pci_intr_map_msix(c, vec, ihp)  (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_establish(c, ih, l, h, a, nm)                          
\
Index: arch/socppc/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/socppc/include/pci_machdep.h,v
retrieving revision 1.2
diff -u -p -r1.2 pci_machdep.h
--- arch/socppc/include/pci_machdep.h   5 Nov 2013 10:12:35 -0000       1.2
+++ arch/socppc/include/pci_machdep.h   3 May 2016 19:26:31 -0000
@@ -86,6 +86,7 @@ struct ppc_pci_chipset {
     (*((pa)->pa_pc)->pc_intr_map)((pa)->pa_pc->pc_intr_v,              \
        (pa)->pa_intrtag, (pa)->pa_intrpin, (pa)->pa_intrline, (ihp))
 #define        pci_intr_map_msi(pa, ihp)       (-1)
+#define        pci_intr_map_msix(pa, vec, ihp) (-1)
 #define        pci_intr_string(c, ih)                                          
\
     (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #define        pci_intr_line(c, ih)                                            
\
Index: arch/sparc64/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/pci_machdep.h,v
retrieving revision 1.32
diff -u -p -r1.32 pci_machdep.h
--- arch/sparc64/include/pci_machdep.h  5 Nov 2013 10:12:35 -0000       1.32
+++ arch/sparc64/include/pci_machdep.h  3 May 2016 19:26:31 -0000
@@ -88,6 +88,7 @@ void          pci_conf_write(pci_chipset_tag_t, 
                                    pcireg_t);
 int            pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 int            pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
+#define                pci_intr_map_msix(pa, vec, ihp) (-1)
 int            pci_intr_line(pci_chipset_tag_t, pci_intr_handle_t);
 const char     *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 void           *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
Index: dev/pci/if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.331
diff -u -p -r1.331 if_em.c
--- dev/pci/if_em.c     13 Apr 2016 10:34:32 -0000      1.331
+++ dev/pci/if_em.c     3 May 2016 19:26:32 -0000
@@ -1673,7 +1673,7 @@ em_allocate_pci_resources(struct em_soft
         }
 
        sc->legacy_irq = 0;
-       if (pci_intr_map_msi(pa, &ih)) {
+       if (pci_intr_map_msix(pa, 0, &ih) && pci_intr_map_msi(pa, &ih)) {
                if (pci_intr_map(pa, &ih)) {
                        printf(": couldn't map interrupt\n");
                        return (ENXIO);
Index: dev/pci/pcireg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/pcireg.h,v
retrieving revision 1.48
diff -u -p -r1.48 pcireg.h
--- dev/pci/pcireg.h    2 Jun 2015 15:26:19 -0000       1.48
+++ dev/pci/pcireg.h    3 May 2016 19:26:32 -0000
@@ -594,6 +594,21 @@ typedef u_int8_t pci_revision_t;
 #define PCI_PCIE_LCAP2         0x2c
 
 /*
+ * Extended Message Signaled Interrups; access via capability pointer.
+ */
+#define PCI_MSIX_MC_MSIXE      0x80000000
+#define PCI_MSIX_MC_TBLSZ      0x000007ff
+#define PCI_MSIX_TABLE         0x04
+#define  PCI_MSIX_TABLE_BIR    0x00000007
+#define  PCI_MSIX_TABLE_OFF    ~(PCI_MSIX_TABLE_BIR)
+
+#define PCI_MSIX_MA(i)         ((i) * 16 + 0)
+#define PCI_MSIX_MAU32(i)      ((i) * 16 + 0)
+#define PCI_MSIX_MD(i)         ((i) * 16 + 8)
+#define PCI_MSIX_VC(i)         ((i) * 16 + 12)
+#define  PCI_MSIX_VC_MASK      0x00000001
+
+/*
  * Interrupt Configuration Register; contains interrupt pin and line.
  */
 #define        PCI_INTERRUPT_REG               0x3c
Index: dev/pci/xhci_pci.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/xhci_pci.c,v
retrieving revision 1.7
diff -u -p -r1.7 xhci_pci.c
--- dev/pci/xhci_pci.c  2 Nov 2015 14:53:10 -0000       1.7
+++ dev/pci/xhci_pci.c  3 May 2016 19:26:32 -0000
@@ -158,7 +158,8 @@ xhci_pci_attach(struct device *parent, s
        }
 
        /* Map and establish the interrupt. */
-       if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
+       if (pci_intr_map_msix(pa, 0, &ih) != 0 &&
+           pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
                printf(": couldn't map interrupt\n");
                goto unmap_ret;
        }

Reply via email to