summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/pci
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-22 14:59:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:41 +0200
commit3489e3b6396ee9944a6a2e19e675ca54c36993b4 (patch)
treecd55cfac1c96ff4b888a9606fd6a0d8eb65bb446 /freebsd/sys/dev/pci
parentck: Define CK_MD_PPC32_LWSYNC if available (diff)
downloadrtems-libbsd-3489e3b6396ee9944a6a2e19e675ca54c36993b4.tar.bz2
Update to FreeBSD head 2018-09-17
Git mirror commit 6c2192b1ef8c50788c751f878552526800b1e319. Update #3472.
Diffstat (limited to 'freebsd/sys/dev/pci')
-rw-r--r--freebsd/sys/dev/pci/pci.c257
-rw-r--r--freebsd/sys/dev/pci/pci_user.c113
-rw-r--r--freebsd/sys/dev/pci/pcivar.h64
3 files changed, 424 insertions, 10 deletions
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 55a21320..512e8636 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -401,6 +401,11 @@ static int pci_enable_ari = 1;
SYSCTL_INT(_hw_pci, OID_AUTO, enable_ari, CTLFLAG_RDTUN, &pci_enable_ari,
0, "Enable support for PCIe Alternative RID Interpretation");
+static int pci_clear_aer_on_attach = 0;
+SYSCTL_INT(_hw_pci, OID_AUTO, clear_aer_on_attach, CTLFLAG_RWTUN,
+ &pci_clear_aer_on_attach, 0,
+ "Clear port and device AER state on driver attach");
+
static int
pci_has_quirk(uint32_t devid, int quirk)
{
@@ -4214,17 +4219,98 @@ pci_create_iov_child_method(device_t bus, device_t pf, uint16_t rid,
}
#endif
+static void
+pci_add_child_clear_aer(device_t dev, struct pci_devinfo *dinfo)
+{
+ int aer;
+ uint32_t r;
+ uint16_t r2;
+
+ if (dinfo->cfg.pcie.pcie_location != 0 &&
+ dinfo->cfg.pcie.pcie_type == PCIEM_TYPE_ROOT_PORT) {
+ r2 = pci_read_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_ROOT_CTL, 2);
+ r2 &= ~(PCIEM_ROOT_CTL_SERR_CORR |
+ PCIEM_ROOT_CTL_SERR_NONFATAL | PCIEM_ROOT_CTL_SERR_FATAL);
+ pci_write_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_ROOT_CTL, r2, 2);
+ }
+ if (pci_find_extcap(dev, PCIZ_AER, &aer) == 0) {
+ r = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4);
+ pci_write_config(dev, aer + PCIR_AER_UC_STATUS, r, 4);
+ if (r != 0 && bootverbose) {
+ pci_printf(&dinfo->cfg,
+ "clearing AER UC 0x%08x -> 0x%08x\n",
+ r, pci_read_config(dev, aer + PCIR_AER_UC_STATUS,
+ 4));
+ }
+
+ r = pci_read_config(dev, aer + PCIR_AER_UC_MASK, 4);
+ r &= ~(PCIM_AER_UC_TRAINING_ERROR |
+ PCIM_AER_UC_DL_PROTOCOL_ERROR |
+ PCIM_AER_UC_SURPRISE_LINK_DOWN |
+ PCIM_AER_UC_POISONED_TLP |
+ PCIM_AER_UC_FC_PROTOCOL_ERROR |
+ PCIM_AER_UC_COMPLETION_TIMEOUT |
+ PCIM_AER_UC_COMPLETER_ABORT |
+ PCIM_AER_UC_UNEXPECTED_COMPLETION |
+ PCIM_AER_UC_RECEIVER_OVERFLOW |
+ PCIM_AER_UC_MALFORMED_TLP |
+ PCIM_AER_UC_ECRC_ERROR |
+ PCIM_AER_UC_UNSUPPORTED_REQUEST |
+ PCIM_AER_UC_ACS_VIOLATION |
+ PCIM_AER_UC_INTERNAL_ERROR |
+ PCIM_AER_UC_MC_BLOCKED_TLP |
+ PCIM_AER_UC_ATOMIC_EGRESS_BLK |
+ PCIM_AER_UC_TLP_PREFIX_BLOCKED);
+ pci_write_config(dev, aer + PCIR_AER_UC_MASK, r, 4);
+
+ r = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4);
+ pci_write_config(dev, aer + PCIR_AER_COR_STATUS, r, 4);
+ if (r != 0 && bootverbose) {
+ pci_printf(&dinfo->cfg,
+ "clearing AER COR 0x%08x -> 0x%08x\n",
+ r, pci_read_config(dev, aer + PCIR_AER_COR_STATUS,
+ 4));
+ }
+
+ r = pci_read_config(dev, aer + PCIR_AER_COR_MASK, 4);
+ r &= ~(PCIM_AER_COR_RECEIVER_ERROR |
+ PCIM_AER_COR_BAD_TLP |
+ PCIM_AER_COR_BAD_DLLP |
+ PCIM_AER_COR_REPLAY_ROLLOVER |
+ PCIM_AER_COR_REPLAY_TIMEOUT |
+ PCIM_AER_COR_ADVISORY_NF_ERROR |
+ PCIM_AER_COR_INTERNAL_ERROR |
+ PCIM_AER_COR_HEADER_LOG_OVFLOW);
+ pci_write_config(dev, aer + PCIR_AER_COR_MASK, r, 4);
+
+ r = pci_read_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_CTL, 2);
+ r |= PCIEM_CTL_COR_ENABLE | PCIEM_CTL_NFER_ENABLE |
+ PCIEM_CTL_FER_ENABLE | PCIEM_CTL_URR_ENABLE;
+ pci_write_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_CTL, r, 2);
+ }
+}
+
void
pci_add_child(device_t bus, struct pci_devinfo *dinfo)
{
- dinfo->cfg.dev = device_add_child(bus, NULL, -1);
- device_set_ivars(dinfo->cfg.dev, dinfo);
+ device_t dev;
+
+ dinfo->cfg.dev = dev = device_add_child(bus, NULL, -1);
+ device_set_ivars(dev, dinfo);
resource_list_init(&dinfo->resources);
- pci_cfg_save(dinfo->cfg.dev, dinfo, 0);
- pci_cfg_restore(dinfo->cfg.dev, dinfo);
+ pci_cfg_save(dev, dinfo, 0);
+ pci_cfg_restore(dev, dinfo);
pci_print_verbose(dinfo);
- pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
+ pci_add_resources(bus, dev, 0, 0);
pci_child_added(dinfo->cfg.dev);
+
+ if (pci_clear_aer_on_attach)
+ pci_add_child_clear_aer(dev, dinfo);
+
EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev);
}
@@ -6263,3 +6349,164 @@ pcie_flr(device_t dev, u_int max_delay, bool force)
pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
return (true);
}
+
+const struct pci_device_table *
+pci_match_device(device_t child, const struct pci_device_table *id, size_t nelt)
+{
+ bool match;
+ uint16_t vendor, device, subvendor, subdevice, class, subclass, revid;
+
+ vendor = pci_get_vendor(child);
+ device = pci_get_device(child);
+ subvendor = pci_get_subvendor(child);
+ subdevice = pci_get_subdevice(child);
+ class = pci_get_class(child);
+ subclass = pci_get_subclass(child);
+ revid = pci_get_revid(child);
+ while (nelt-- > 0) {
+ match = true;
+ if (id->match_flag_vendor)
+ match &= vendor == id->vendor;
+ if (id->match_flag_device)
+ match &= device == id->device;
+ if (id->match_flag_subvendor)
+ match &= subvendor == id->subvendor;
+ if (id->match_flag_subdevice)
+ match &= subdevice == id->subdevice;
+ if (id->match_flag_class)
+ match &= class == id->class_id;
+ if (id->match_flag_subclass)
+ match &= subclass == id->subclass;
+ if (id->match_flag_revid)
+ match &= revid == id->revid;
+ if (match)
+ return (id);
+ id++;
+ }
+ return (NULL);
+}
+
+static void
+pci_print_faulted_dev_name(const struct pci_devinfo *dinfo)
+{
+ const char *dev_name;
+ device_t dev;
+
+ dev = dinfo->cfg.dev;
+ printf("pci%d:%d:%d:%d", dinfo->cfg.domain, dinfo->cfg.bus,
+ dinfo->cfg.slot, dinfo->cfg.func);
+ dev_name = device_get_name(dev);
+ if (dev_name != NULL)
+ printf(" (%s%d)", dev_name, device_get_unit(dev));
+}
+
+void
+pci_print_faulted_dev(void)
+{
+ struct pci_devinfo *dinfo;
+ device_t dev;
+ int aer, i;
+ uint32_t r1, r2;
+ uint16_t status;
+
+ STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
+ dev = dinfo->cfg.dev;
+ status = pci_read_config(dev, PCIR_STATUS, 2);
+ status &= PCIM_STATUS_MDPERR | PCIM_STATUS_STABORT |
+ PCIM_STATUS_RTABORT | PCIM_STATUS_RMABORT |
+ PCIM_STATUS_SERR | PCIM_STATUS_PERR;
+ if (status != 0) {
+ pci_print_faulted_dev_name(dinfo);
+ printf(" error 0x%04x\n", status);
+ }
+ if (dinfo->cfg.pcie.pcie_location != 0) {
+ status = pci_read_config(dev,
+ dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_STA, 2);
+ if ((status & (PCIEM_STA_CORRECTABLE_ERROR |
+ PCIEM_STA_NON_FATAL_ERROR | PCIEM_STA_FATAL_ERROR |
+ PCIEM_STA_UNSUPPORTED_REQ)) != 0) {
+ pci_print_faulted_dev_name(dinfo);
+ printf(" PCIe DEVCTL 0x%04x DEVSTA 0x%04x\n",
+ pci_read_config(dev,
+ dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_CTL, 2),
+ status);
+ }
+ }
+ if (pci_find_extcap(dev, PCIZ_AER, &aer) == 0) {
+ r1 = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4);
+ r2 = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4);
+ if (r1 != 0 || r2 != 0) {
+ pci_print_faulted_dev_name(dinfo);
+ printf(" AER UC 0x%08x Mask 0x%08x Svr 0x%08x\n"
+ " COR 0x%08x Mask 0x%08x Ctl 0x%08x\n",
+ r1, pci_read_config(dev, aer +
+ PCIR_AER_UC_MASK, 4),
+ pci_read_config(dev, aer +
+ PCIR_AER_UC_SEVERITY, 4),
+ r2, pci_read_config(dev, aer +
+ PCIR_AER_COR_MASK, 4),
+ pci_read_config(dev, aer +
+ PCIR_AER_CAP_CONTROL, 4));
+ for (i = 0; i < 4; i++) {
+ r1 = pci_read_config(dev, aer +
+ PCIR_AER_HEADER_LOG + i * 4, 4);
+ printf(" HL%d: 0x%08x\n", i, r1);
+ }
+ }
+ }
+ }
+}
+
+#ifdef DDB
+DB_SHOW_COMMAND(pcierr, pci_print_faulted_dev_db)
+{
+
+ pci_print_faulted_dev();
+}
+
+static void
+db_clear_pcie_errors(const struct pci_devinfo *dinfo)
+{
+ device_t dev;
+ int aer;
+ uint32_t r;
+
+ dev = dinfo->cfg.dev;
+ r = pci_read_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_STA, 2);
+ pci_write_config(dev, dinfo->cfg.pcie.pcie_location +
+ PCIER_DEVICE_STA, r, 2);
+
+ if (pci_find_extcap(dev, PCIZ_AER, &aer) != 0)
+ return;
+ r = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4);
+ if (r != 0)
+ pci_write_config(dev, aer + PCIR_AER_UC_STATUS, r, 4);
+ r = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4);
+ if (r != 0)
+ pci_write_config(dev, aer + PCIR_AER_COR_STATUS, r, 4);
+}
+
+DB_COMMAND(pci_clearerr, db_pci_clearerr)
+{
+ struct pci_devinfo *dinfo;
+ device_t dev;
+ uint16_t status, status1;
+
+ STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
+ dev = dinfo->cfg.dev;
+ status1 = status = pci_read_config(dev, PCIR_STATUS, 2);
+ status1 &= PCIM_STATUS_MDPERR | PCIM_STATUS_STABORT |
+ PCIM_STATUS_RTABORT | PCIM_STATUS_RMABORT |
+ PCIM_STATUS_SERR | PCIM_STATUS_PERR;
+ if (status1 != 0) {
+ status &= ~status1;
+ pci_write_config(dev, PCIR_STATUS, status, 2);
+ }
+ if (dinfo->cfg.pcie.pcie_location != 0)
+ db_clear_pcie_errors(dinfo);
+ }
+}
+#endif
diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c
index c9d500a8..b3a2e9e2 100644
--- a/freebsd/sys/dev/pci/pci_user.c
+++ b/freebsd/sys/dev/pci/pci_user.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_bus.h> /* XXX trim includes */
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -41,13 +42,19 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/mman.h>
#include <sys/proc.h>
#include <sys/queue.h>
-#include <sys/types.h>
+#include <sys/rwlock.h>
+#include <sys/sglist.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -441,6 +448,14 @@ pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches,
}
}
+/*
+ * Like PVE_NEXT but takes an explicit length since 'pve' is a user
+ * pointer that cannot be dereferenced.
+ */
+#define PVE_NEXT_LEN(pve, datalen) \
+ ((struct pci_vpd_element *)((char *)(pve) + \
+ sizeof(struct pci_vpd_element) + (datalen)))
+
static int
pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
{
@@ -489,7 +504,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
strlen(vpd->vpd_ident));
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
vpd_element.pve_flags = 0;
for (i = 0; i < vpd->vpd_rocnt; i++) {
vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0];
@@ -502,7 +517,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
vpd->vpd_ros[i].len);
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
}
vpd_element.pve_flags = PVE_FLAG_RW;
for (i = 0; i < vpd->vpd_wcnt; i++) {
@@ -516,7 +531,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
vpd->vpd_w[i].len);
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
}
KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len,
("length mismatch"));
@@ -698,6 +713,79 @@ pci_conf_for_copyout(const struct pci_conf *pcp, union pci_conf_union *pcup,
}
}
+#ifndef __rtems__
+static int
+pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm)
+{
+ vm_map_t map;
+ vm_object_t obj;
+ struct thread *td;
+ struct sglist *sg;
+ struct pci_map *pm;
+ vm_paddr_t pbase;
+ vm_size_t plen;
+ vm_offset_t addr;
+ vm_prot_t prot;
+ int error, flags;
+
+ td = curthread;
+ map = &td->td_proc->p_vmspace->vm_map;
+ if ((pbm->pbm_flags & ~(PCIIO_BAR_MMAP_FIXED | PCIIO_BAR_MMAP_EXCL |
+ PCIIO_BAR_MMAP_RW | PCIIO_BAR_MMAP_ACTIVATE)) != 0 ||
+ pbm->pbm_memattr != (vm_memattr_t)pbm->pbm_memattr ||
+ !pmap_is_valid_memattr(map->pmap, pbm->pbm_memattr))
+ return (EINVAL);
+
+ /* Fetch the BAR physical base and length. */
+ pm = pci_find_bar(pcidev, pbm->pbm_reg);
+ if (pm == NULL)
+ return (EINVAL);
+ if (!pci_bar_enabled(pcidev, pm))
+ return (EBUSY); /* XXXKIB enable if _ACTIVATE */
+ if (!PCI_BAR_MEM(pm->pm_value))
+ return (EIO);
+ pbase = trunc_page(pm->pm_value);
+ plen = round_page(pm->pm_value + ((pci_addr_t)1 << pm->pm_size)) -
+ pbase;
+ prot = VM_PROT_READ | (((pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0) ?
+ VM_PROT_WRITE : 0);
+
+ /* Create vm structures and mmap. */
+ sg = sglist_alloc(1, M_WAITOK);
+ error = sglist_append_phys(sg, pbase, plen);
+ if (error != 0)
+ goto out;
+ obj = vm_pager_allocate(OBJT_SG, sg, plen, prot, 0, td->td_ucred);
+ if (obj == NULL) {
+ error = EIO;
+ goto out;
+ }
+ obj->memattr = pbm->pbm_memattr;
+ flags = MAP_SHARED;
+ addr = 0;
+ if ((pbm->pbm_flags & PCIIO_BAR_MMAP_FIXED) != 0) {
+ addr = (uintptr_t)pbm->pbm_map_base;
+ flags |= MAP_FIXED;
+ }
+ if ((pbm->pbm_flags & PCIIO_BAR_MMAP_EXCL) != 0)
+ flags |= MAP_CHECK_EXCL;
+ error = vm_mmap_object(map, &addr, plen, prot, prot, flags, obj, 0,
+ FALSE, td);
+ if (error != 0) {
+ vm_object_deallocate(obj);
+ goto out;
+ }
+ pbm->pbm_map_base = (void *)addr;
+ pbm->pbm_map_length = plen;
+ pbm->pbm_bar_off = pm->pm_value - pbase;
+ pbm->pbm_bar_length = (pci_addr_t)1 << pm->pm_size;
+
+out:
+ sglist_free(sg);
+ return (error);
+}
+#endif /* __rtems__ */
+
static int
pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
@@ -711,6 +799,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
struct pci_list_vpd_io *lvio;
struct pci_match_conf *pattern_buf;
struct pci_map *pm;
+#ifndef __rtems__
+ struct pci_bar_mmap *pbm;
+#endif /* __rtems__ */
size_t confsz, iolen;
int error, ionum, i, num_patterns;
union pci_conf_union pcu;
@@ -1055,6 +1146,20 @@ getconfexit:
}
error = pci_list_vpd(pcidev, lvio);
break;
+
+#ifndef __rtems__
+ case PCIOCBARMMAP:
+ pbm = (struct pci_bar_mmap *)data;
+ if ((flag & FWRITE) == 0 &&
+ (pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0)
+ return (EPERM);
+ pcidev = pci_find_dbsf(pbm->pbm_sel.pc_domain,
+ pbm->pbm_sel.pc_bus, pbm->pbm_sel.pc_dev,
+ pbm->pbm_sel.pc_func);
+ error = pcidev == NULL ? ENODEV : pci_bar_mmap(pcidev, pbm);
+ break;
+#endif /* __rtems__ */
+
default:
error = ENOTTY;
break;
diff --git a/freebsd/sys/dev/pci/pcivar.h b/freebsd/sys/dev/pci/pcivar.h
index 492b7117..21d9bd03 100644
--- a/freebsd/sys/dev/pci/pcivar.h
+++ b/freebsd/sys/dev/pci/pcivar.h
@@ -259,6 +259,66 @@ typedef struct {
extern uint32_t pci_numdevs;
+struct pci_device_table {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint16_t
+ match_flag_vendor:1,
+ match_flag_device:1,
+ match_flag_subvendor:1,
+ match_flag_subdevice:1,
+ match_flag_class:1,
+ match_flag_subclass:1,
+ match_flag_revid:1,
+ match_flag_unused:9;
+#else
+ uint16_t
+ match_flag_unused:9,
+ match_flag_revid:1,
+ match_flag_subclass:1,
+ match_flag_class:1,
+ match_flag_subdevice:1,
+ match_flag_subvendor:1,
+ match_flag_device:1,
+ match_flag_vendor:1;
+#endif
+ uint16_t vendor;
+ uint16_t device;
+ uint16_t subvendor;
+ uint16_t subdevice;
+ uint16_t class_id;
+ uint16_t subclass;
+ uint16_t revid;
+ uint16_t unused;
+ uintptr_t driver_data;
+ char *descr;
+};
+
+#define PCI_DEV(v, d) \
+ .match_flag_vendor = 1, .vendor = (v), \
+ .match_flag_device = 1, .device = (d)
+#define PCI_SUBDEV(sv, sd) \
+ .match_flag_subvendor = 1, .subvendor = (sv), \
+ .match_flag_subdevice = 1, .subdevice = (sd)
+#define PCI_CLASS(x) \
+ .match_flag_class = 1, .class_id = (x)
+#define PCI_SUBCLASS(x) \
+ .match_flag_subclass = 1, .subclass = (x)
+#define PCI_REVID(x) \
+ .match_flag_revid = 1, .revid = (x)
+#define PCI_DESCR(x) \
+ .descr = (x)
+#define PCI_PNP_STR \
+ "M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;" \
+ "U16:class;U16:subclass;U16:revid;"
+#define PCI_PNP_INFO(table) \
+ MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \
+ sizeof(table) / sizeof(table[0]))
+
+const struct pci_device_table *pci_match_device(device_t child,
+ const struct pci_device_table *id, size_t nelt);
+#define PCI_MATCH(child, table) \
+ pci_match_device(child, (table), nitems(table));
+
/* Only if the prerequisites are present */
#if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
struct pci_devinfo {
@@ -416,7 +476,7 @@ pci_get_vpd_readonly(device_t dev, const char *kw, const char **vptr)
static __inline int
pci_is_vga_ioport_range(rman_res_t start, rman_res_t end)
{
-
+
return (((start >= 0x3b0 && end <= 0x3bb) ||
(start >= 0x3c0 && end <= 0x3df)) ? 1 : 0);
}
@@ -622,6 +682,8 @@ bool pcie_flr(device_t dev, u_int max_delay, bool force);
int pcie_get_max_completion_timeout(device_t dev);
bool pcie_wait_for_pending_transactions(device_t dev, u_int max_delay);
+void pci_print_faulted_dev(void);
+
#ifdef BUS_SPACE_MAXADDR
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
#define PCI_DMA_BOUNDARY 0x100000000