version 1.4.2.5, 2017/08/28 17:51:56 |
version 1.5, 2015/08/11 04:04:36 |
Line 36 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 36 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/errno.h> |
#include <sys/errno.h> |
#include <sys/kmem.h> |
#include <sys/kmem.h> |
|
#include <sys/malloc.h> |
#include <sys/mutex.h> |
#include <sys/mutex.h> |
|
|
#include <dev/pci/pcivar.h> |
#include <dev/pci/pcivar.h> |
|
|
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
#include <machine/i82489var.h> |
|
#include <machine/i82093reg.h> |
#include <machine/i82093reg.h> |
#include <machine/i82093var.h> |
#include <machine/i82093var.h> |
#include <machine/pic.h> |
#include <machine/pic.h> |
Line 237 msipic_construct_common_msi_pic(const st |
|
Line 237 msipic_construct_common_msi_pic(const st |
|
int devid; |
int devid; |
|
|
pic = kmem_alloc(sizeof(*pic), KM_SLEEP); |
pic = kmem_alloc(sizeof(*pic), KM_SLEEP); |
|
if (pic == NULL) |
|
return NULL; |
|
|
msipic = kmem_zalloc(sizeof(*msipic), KM_SLEEP); |
msipic = kmem_zalloc(sizeof(*msipic), KM_SLEEP); |
|
if (msipic == NULL) { |
|
kmem_free(pic, sizeof(*pic)); |
|
return NULL; |
|
} |
|
|
mutex_enter(&msipic_list_lock); |
mutex_enter(&msipic_list_lock); |
|
|
Line 250 msipic_construct_common_msi_pic(const st |
|
Line 257 msipic_construct_common_msi_pic(const st |
|
} |
} |
|
|
memcpy(pic, pic_tmpl, sizeof(*pic)); |
memcpy(pic, pic_tmpl, sizeof(*pic)); |
pic->pic_edge_stubs = x2apic_mode ? x2apic_edge_stubs : ioapic_edge_stubs, |
|
pic->pic_msipic = msipic; |
pic->pic_msipic = msipic; |
msipic->mp_pic = pic; |
msipic->mp_pic = pic; |
pci_decompose_tag(pa->pa_pc, pa->pa_tag, |
pci_decompose_tag(pa->pa_pc, pa->pa_tag, |
Line 425 static struct pic msi_pic_tmpl = { |
|
Line 431 static struct pic msi_pic_tmpl = { |
|
.pic_hwunmask = msi_hwunmask, |
.pic_hwunmask = msi_hwunmask, |
.pic_addroute = msi_addroute, |
.pic_addroute = msi_addroute, |
.pic_delroute = msi_delroute, |
.pic_delroute = msi_delroute, |
|
.pic_edge_stubs = ioapic_edge_stubs, |
|
.pic_ioapic = NULL, |
}; |
}; |
|
|
/* |
/* |
Line 485 msix_set_vecctl_mask(struct pic *pic, in |
|
Line 493 msix_set_vecctl_mask(struct pic *pic, in |
|
vecctl = bus_space_read_4(bstag, bshandle, |
vecctl = bus_space_read_4(bstag, bshandle, |
entry_base + PCI_MSIX_TABLE_ENTRY_VECTCTL); |
entry_base + PCI_MSIX_TABLE_ENTRY_VECTCTL); |
if (flag == MSIX_VECCTL_HWMASK) |
if (flag == MSIX_VECCTL_HWMASK) |
vecctl |= PCI_MSIX_VECTCTL_MASK; |
vecctl |= PCI_MSIX_VECTCTL_HWMASK_MASK; |
else |
else |
vecctl &= ~PCI_MSIX_VECTCTL_MASK; |
vecctl &= ~PCI_MSIX_VECTCTL_HWMASK_MASK; |
|
|
bus_space_write_4(bstag, bshandle, |
bus_space_write_4(bstag, bshandle, |
entry_base + PCI_MSIX_TABLE_ENTRY_VECTCTL, vecctl); |
entry_base + PCI_MSIX_TABLE_ENTRY_VECTCTL, vecctl); |
Line 595 static struct pic msix_pic_tmpl = { |
|
Line 603 static struct pic msix_pic_tmpl = { |
|
.pic_hwunmask = msix_hwunmask, |
.pic_hwunmask = msix_hwunmask, |
.pic_addroute = msix_addroute, |
.pic_addroute = msix_addroute, |
.pic_delroute = msix_delroute, |
.pic_delroute = msix_delroute, |
|
.pic_edge_stubs = ioapic_edge_stubs, |
}; |
}; |
|
|
struct pic * |
struct pic * |
Line 610 msipic_construct_msix_pic(const struct p |
|
Line 619 msipic_construct_msix_pic(const struct p |
|
size_t table_size; |
size_t table_size; |
uint32_t table_offset; |
uint32_t table_offset; |
u_int memtype; |
u_int memtype; |
bus_addr_t memaddr; |
|
int flags; |
|
int bir, bar, err, off, table_nentry; |
int bir, bar, err, off, table_nentry; |
char pic_name_buf[MSIPICNAMEBUF]; |
char pic_name_buf[MSIPICNAMEBUF]; |
|
|
table_nentry = pci_msix_count(pa->pa_pc, pa->pa_tag); |
table_nentry = pci_msix_count(pa); |
if (table_nentry == 0) { |
if (table_nentry == 0) { |
DPRINTF(("MSI-X table entry is 0.\n")); |
DPRINTF(("MSI-X table entry is 0.\n")); |
return NULL; |
return NULL; |
Line 677 msipic_construct_msix_pic(const struct p |
|
Line 684 msipic_construct_msix_pic(const struct p |
|
* - Message Lower Address (32bit) |
* - Message Lower Address (32bit) |
*/ |
*/ |
table_size = table_nentry * PCI_MSIX_TABLE_ENTRY_SIZE; |
table_size = table_nentry * PCI_MSIX_TABLE_ENTRY_SIZE; |
#if 0 |
|
err = pci_mapreg_submap(pa, bar, memtype, BUS_SPACE_MAP_LINEAR, |
err = pci_mapreg_submap(pa, bar, memtype, BUS_SPACE_MAP_LINEAR, |
roundup(table_size, PAGE_SIZE), table_offset, |
roundup(table_size, PAGE_SIZE), table_offset, |
&bstag, &bshandle, NULL, &bssize); |
&bstag, &bshandle, NULL, &bssize); |
#else |
|
/* |
|
* Workaround for PCI prefetchable bit. Some chips (e.g. Intel 82599) |
|
* report SERR and MSI-X doesn't work. This problem might not be the |
|
* driver's bug but our PCI common part or VMs' bug. Until we find a |
|
* real reason, we ignore the prefetchable bit. |
|
*/ |
|
if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, memtype, |
|
&memaddr, NULL, &flags) != 0) { |
|
DPRINTF(("cannot get a map info.\n")); |
|
msipic_destruct_common_msi_pic(msix_pic); |
|
return NULL; |
|
} |
|
if ((flags & BUS_SPACE_MAP_PREFETCHABLE) != 0) { |
|
DPRINTF(( "clear prefetchable bit\n")); |
|
flags &= ~BUS_SPACE_MAP_PREFETCHABLE; |
|
} |
|
bssize = roundup(table_size, PAGE_SIZE); |
|
err = bus_space_map(pa->pa_memt, memaddr + table_offset, bssize, flags, |
|
&bshandle); |
|
bstag = pa->pa_memt; |
|
#endif |
|
if (err) { |
if (err) { |
DPRINTF(("cannot map msix table.\n")); |
DPRINTF(("cannot map msix table.\n")); |
msipic_destruct_common_msi_pic(msix_pic); |
msipic_destruct_common_msi_pic(msix_pic); |