diff --git a/xf86drm.c b/xf86drm.c index 53eb832d..db9823da 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -64,6 +64,7 @@ #if defined(__FreeBSD__) #include +#include #endif #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -3415,6 +3416,48 @@ static int drmParsePciDeviceInfo(int maj, int min, device->subvendor_id = pinfo.subvendor_id; device->subdevice_id = pinfo.subdevice_id; + return 0; +#elif __FreeBSD__ + drmPciBusInfo info; + struct pci_conf_io pc; + struct pci_match_conf patterns[1]; + struct pci_conf results[1]; + int fd, error; + + if (get_sysctl_pci_bus_info(maj, min, &info) != 0) + return -EINVAL; + + fd = open("/dev/pci", O_RDONLY, 0); + if (fd < 0) + return -errno; + + bzero(&patterns, sizeof(patterns)); + patterns[0].pc_sel.pc_domain = info.domain; + patterns[0].pc_sel.pc_bus = info.bus; + patterns[0].pc_sel.pc_dev = info.dev; + patterns[0].pc_sel.pc_func = info.func; + patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS + | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC; + bzero(&pc, sizeof(struct pci_conf_io)); + pc.num_patterns = 1; + pc.pat_buf_len = sizeof(patterns); + pc.patterns = patterns; + pc.match_buf_len = sizeof(results); + pc.matches = results; + + if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) { + error = errno; + close(fd); + return -error; + } + close(fd); + + device->vendor_id = results[0].pc_vendor; + device->device_id = results[0].pc_device; + device->subvendor_id = results[0].pc_subvendor; + device->subdevice_id = results[0].pc_subdevice; + device->revision_id = results[0].pc_revid; + return 0; #else #warning "Missing implementation of drmParsePciDeviceInfo"