#if defined(__FreeBSD__)
#include <sys/param.h>
+#include <sys/pciio.h>
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
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"
return -EINVAL;