On Wed, May 04, 2016 at 08:50:53AM +0200, Mark Kettenis wrote: > > Date: Tue, 3 May 2016 15:23:07 -0700 > > From: Mike Larkin <mlar...@azathoth.net> > > > > On Tue, May 03, 2016 at 09:40:28PM +0200, Mark Kettenis wrote: > > > 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? > > > > > > > Did you want to include the if_em and xhci bits too? > > Yes. They seem to work. But I can leave them out if people deem this > too risky. They'll be separate commits anyway. >
Just checking. ok mlarkin@ if you didn't move on this already. > > > 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, ®) == 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, ®) == 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; > > > } > > > > >