To pull pci information from the kernel for drm devices we need a common
drm ioctl. This is a requirement for implementing functions in libdrm
which are used by Mesa >= 13.
To not clash with drm headers this is added via pciio.h at kettenis'
suggestion.
The ioctl number reuses that of DRM_IOCTL_ADD_MAP, a DRI1 ioctl
we dropped support for, to avoid using a number that might be later
used in linux.
The currently unused values in the latest linux drm.h seem to be
0x0e
0x0f
0x2f
0x3b
0x3c
0x3d
0x3e
0xbf - 0xff ?
(driver specific ioctls 0x40 -> 0x9f)
Index: dev/pci/drm/drm_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_drv.c,v
retrieving revision 1.149
diff -u -p -r1.149 drm_drv.c
--- dev/pci/drm/drm_drv.c 15 Sep 2016 02:00:17 -0000 1.149
+++ dev/pci/drm/drm_drv.c 19 Nov 2016 07:12:06 -0000
@@ -50,6 +50,7 @@
#include <sys/systm.h>
#include <sys/ttycom.h> /* for TIOCSGRP */
#include <sys/vnode.h>
+#include <sys/pciio.h> /* for DRM_IOCTL_GET_PCIINFO */
#include <uvm/uvm.h>
#include <uvm/uvm_device.h>
@@ -81,6 +82,7 @@ int drm_version(struct drm_device *, vo
int drm_setversion(struct drm_device *, void *, struct drm_file *);
int drm_getmagic(struct drm_device *, void *, struct drm_file *);
int drm_authmagic(struct drm_device *, void *, struct drm_file *);
+int drm_getpciinfo(struct drm_device *, void *, struct drm_file *);
int drm_file_cmp(struct drm_file *, struct drm_file *);
SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp);
@@ -120,6 +122,8 @@ static struct drm_ioctl_desc drm_ioctls[
DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx,
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
#else
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_PCIINFO, drm_getpciinfo, 0),
+
DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_noop,
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_noop, DRM_AUTH),
#endif
@@ -254,11 +258,12 @@ pledge_ioctl_drm(struct proc *p, long co
if (ioctl->flags & DRM_RENDER_ALLOW)
return 0;
+ switch (com) {
+ case DRM_IOCTL_GET_PCIINFO:
/*
* These are dangerous, but we have to allow them until we
* have prime/dma-buf support.
*/
- switch (com) {
case DRM_IOCTL_GET_MAGIC:
case DRM_IOCTL_GEM_OPEN:
return 0;
@@ -1345,5 +1350,23 @@ int drm_pcie_get_speed_cap_mask(struct d
DRM_INFO("probing gen 2 caps for device 0x%04x:0x%04x = %x/%x\n",
PCI_VENDOR(id), PCI_PRODUCT(id), lnkcap, lnkcap2);
+ return 0;
+}
+
+int
+drm_getpciinfo(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_pciinfo *info = data;
+
+ info->domain = 0;
+ info->bus = dev->pdev->bus->number;
+ info->dev = PCI_SLOT(dev->pdev->devfn);
+ info->func = PCI_FUNC(dev->pdev->devfn);
+ info->vendor_id = dev->pdev->vendor;
+ info->device_id = dev->pdev->device;
+ info->subvendor_id = dev->pdev->subsystem_vendor;
+ info->subdevice_id = dev->pdev->subsystem_device;
+ info->revision_id = 0;
+
return 0;
}
Index: sys/pciio.h
===================================================================
RCS file: /cvs/src/sys/sys/pciio.h,v
retrieving revision 1.7
diff -u -p -r1.7 pciio.h
--- sys/pciio.h 5 Sep 2010 18:14:33 -0000 1.7
+++ sys/pciio.h 19 Nov 2016 07:12:06 -0000
@@ -60,6 +60,18 @@ struct pci_vga {
int pv_decode;
};
+struct drm_pciinfo {
+ uint16_t domain;
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t func;
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint16_t subvendor_id;
+ uint16_t subdevice_id;
+ uint8_t revision_id;
+};
+
#define PCI_VGA_UNLOCK 0x00
#define PCI_VGA_LOCK 0x01
#define PCI_VGA_TRYLOCK 0x02
@@ -74,5 +86,7 @@ struct pci_vga {
#define PCIOCGETVGA _IOWR('p', 6, struct pci_vga)
#define PCIOCSETVGA _IOWR('p', 7, struct pci_vga)
#define PCIOCREADMASK _IOWR('p', 8, struct pci_io)
+
+#define DRM_IOCTL_GET_PCIINFO _IOR('d', 0x15, struct drm_pciinfo)
#endif /* !_SYS_PCIIO_H_ */