接上一篇文章《xf86-video-intel源码分析6 —— intel_device.c和intel_driver.h(1)》,链接为:
xf86-video-intel源码分析6 —— intel_device.c和intel_driver.h(1)_蓝天居士的博客-CSDN博客
上一篇文章分析到了__intel_open_device函数,再列一下代码:
static int __intel_open_device(const struct pci_device *pci, const char *path)
{int fd;if (path == NULL) {if (pci == NULL)return -1;fd = __intel_open_device__pci(pci);if (fd == -1)fd = __intel_open_device__legacy(pci);} elsefd = open_cloexec(path);return fd;
}
可以看到,函数共分为3条路径:
(1)当path和pci同时为空的时候,直接返回-1,甭往下走了;
(2)如果path为空而pci不为空,那么可以通过入参指针pci进行设备的打开。如果__intel_open_device_pci函数无法打开,还可以通过老版本__intel_open_device__legacy函数尝试打开;
(3)如果path本身就不空,也就是直接指定了路径,则直接通过open_cloexec函数打开。
我们由浅入深地进行分析,先来看第2个函数__intel_open_device_pci__legacy。
__intel_open_device__legacy函数在同文件中实现,代码如下:
static int __intel_open_device__legacy(const struct pci_device *pci)
{char id[20];int ret;snprintf(id, sizeof(id),"pci:%04x:%02x:%02x.%d",pci->domain, pci->bus, pci->dev, pci->func);ret = drmCheckModesettingSupported(id);if (ret) {if (load_i915_kernel_module() == 0)ret = drmCheckModesettingSupported(id);if (ret)return -1;/* Be nice to the user and load fbcon too */(void)xf86LoadKernelModule("fbcon");}return fd_set_nonblock(drmOpen(NULL, id));
}
一上来先通过snprintf函数生成id,id的内容为"pci:xxxx:xx:xx.x"。4个为x的部分分别代表域、总线、设备和功能。通过lspci命令可以看到相关内容,笔者电脑中的信息为:
$ lspci | cut -d : -f1-3
0000:00:00.0 Host bridge
0000:00:02.0 VGA compatible controller
0000:00:04.0 Signal processing controller
0000:00:06.0 System peripheral
0000:00:07.0 PCI bridge
0000:00:0d.0 USB controller
0000:00:0d.2 USB controller
0000:00:0e.0 RAID bus controller
0000:00:14.0 USB controller
0000:00:14.2 RAM memory
0000:00:14.3 Network controller
0000:00:15.0 Serial bus controller
0000:00:15.3 Serial bus controller
0000:00:16.0 Communication controller
0000:00:17.0 System peripheral
0000:00:1d.0 PCI bridge
0000:00:1d.1 PCI bridge
0000:00:1f.0 ISA bridge
0000:00:1f.3 Multimedia audio controller
0000:00:1f.4 SMBus
0000:00:1f.5 Serial bus controller
0000:2b:00.0 Ethernet controller
0000:2c:00.0 Unassigned class [ff00]
10000:e0:06.0 PCI bridge
10000:e0:17.0 SATA controller
10000:e1:00.0 Non-Volatile memory controller
因此,对于比着电脑来说,id的值应该为"pci:0000:00:02.0"(信息取自于VGA那一行)。
接下来调用drmCheckModesettingSupported函数对生成的id进行检查,看modesetting是否支持。drmCheckModesettingSupported函数当然不在xf86-video-intel源码中,也不在xorg-server源码中。那么它属于哪个包?
仍然用之前的方法,在/usr/include/下进行搜索,结果如下:
$ grep -rn "drmCheckModesettingSupported" /usr/include/
/usr/include/xf86drmMode.h:403:extern int drmCheckModesettingSupported(const char *busid);
而xf86drmMode.h来自于libdrm。链接暨上游地址为:
Mesa / drm · GitLab