intel_driver.h位于src目录下,内容为:
- #ifndef INTEL_DRIVER_H
- #define INTEL_DRIVER_H
-
- struct xf86_platform_device;
-
- #define INTEL_VERSION 4000
- #define INTEL_NAME "intel"
- #define INTEL_DRIVER_NAME "intel"
-
- #define INTEL_VERSION_MAJOR PACKAGE_VERSION_MAJOR
- #define INTEL_VERSION_MINOR PACKAGE_VERSION_MINOR
- #define INTEL_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL
-
- #define PCI_CHIP_I810 0x7121
- #define PCI_CHIP_I810_DC100 0x7123
- #define PCI_CHIP_I810_E 0x7125
- #define PCI_CHIP_I815 0x1132
-
- #define PCI_CHIP_I830_M 0x3577
- #define PCI_CHIP_845_G 0x2562
- #define PCI_CHIP_I854 0x358E
- #define PCI_CHIP_I855_GM 0x3582
- #define PCI_CHIP_I865_G 0x2572
-
- #define PCI_CHIP_I915_G 0x2582
- #define PCI_CHIP_I915_GM 0x2592
- #define PCI_CHIP_E7221_G 0x258A
- #define PCI_CHIP_I945_G 0x2772
- #define PCI_CHIP_I945_GM 0x27A2
- #define PCI_CHIP_I945_GME 0x27AE
- #define PCI_CHIP_PINEVIEW_M 0xA011
- #define PCI_CHIP_PINEVIEW_G 0xA001
- #define PCI_CHIP_Q35_G 0x29B2
- #define PCI_CHIP_G33_G 0x29C2
- #define PCI_CHIP_Q33_G 0x29D2
-
- #define PCI_CHIP_G35_G 0x2982
- #define PCI_CHIP_I965_Q 0x2992
- #define PCI_CHIP_I965_G 0x29A2
- #define PCI_CHIP_I946_GZ 0x2972
- #define PCI_CHIP_I965_GM 0x2A02
- #define PCI_CHIP_I965_GME 0x2A12
- #define PCI_CHIP_GM45_GM 0x2A42
- #define PCI_CHIP_G45_E_G 0x2E02
- #define PCI_CHIP_G45_G 0x2E22
- #define PCI_CHIP_Q45_G 0x2E12
- #define PCI_CHIP_G41_G 0x2E32
- #define PCI_CHIP_B43_G 0x2E42
- #define PCI_CHIP_B43_G1 0x2E92
-
- #define PCI_CHIP_IRONLAKE_D_G 0x0042
- #define PCI_CHIP_IRONLAKE_M_G 0x0046
-
- #define PCI_CHIP_SANDYBRIDGE_GT1 0x0102
- #define PCI_CHIP_SANDYBRIDGE_GT2 0x0112
- #define PCI_CHIP_SANDYBRIDGE_GT2_PLUS 0x0122
- #define PCI_CHIP_SANDYBRIDGE_M_GT1 0x0106
- #define PCI_CHIP_SANDYBRIDGE_M_GT2 0x0116
- #define PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS 0x0126
- #define PCI_CHIP_SANDYBRIDGE_S_GT 0x010A
-
- #define PCI_CHIP_IVYBRIDGE_M_GT1 0x0156
- #define PCI_CHIP_IVYBRIDGE_M_GT2 0x0166
- #define PCI_CHIP_IVYBRIDGE_D_GT1 0x0152
- #define PCI_CHIP_IVYBRIDGE_D_GT2 0x0162
- #define PCI_CHIP_IVYBRIDGE_S_GT1 0x015a
- #define PCI_CHIP_IVYBRIDGE_S_GT2 0x016a
-
- #define PCI_CHIP_HASWELL_D_GT1 0x0402
- #define PCI_CHIP_HASWELL_D_GT2 0x0412
- #define PCI_CHIP_HASWELL_D_GT3 0x0422
- #define PCI_CHIP_HASWELL_M_GT1 0x0406
- #define PCI_CHIP_HASWELL_M_GT2 0x0416
- #define PCI_CHIP_HASWELL_M_GT3 0x0426
- #define PCI_CHIP_HASWELL_S_GT1 0x040A
- #define PCI_CHIP_HASWELL_S_GT2 0x041A
- #define PCI_CHIP_HASWELL_S_GT3 0x042A
- #define PCI_CHIP_HASWELL_B_GT1 0x040B
- #define PCI_CHIP_HASWELL_B_GT2 0x041B
- #define PCI_CHIP_HASWELL_B_GT3 0x042B
- #define PCI_CHIP_HASWELL_E_GT1 0x040E
- #define PCI_CHIP_HASWELL_E_GT2 0x041E
- #define PCI_CHIP_HASWELL_E_GT3 0x042E
-
- #define PCI_CHIP_HASWELL_ULT_D_GT1 0x0A02
- #define PCI_CHIP_HASWELL_ULT_D_GT2 0x0A12
- #define PCI_CHIP_HASWELL_ULT_D_GT3 0x0A22
- #define PCI_CHIP_HASWELL_ULT_M_GT1 0x0A06
- #define PCI_CHIP_HASWELL_ULT_M_GT2 0x0A16
- #define PCI_CHIP_HASWELL_ULT_M_GT3 0x0A26
- #define PCI_CHIP_HASWELL_ULT_S_GT1 0x0A0A
- #define PCI_CHIP_HASWELL_ULT_S_GT2 0x0A1A
- #define PCI_CHIP_HASWELL_ULT_S_GT3 0x0A2A
- #define PCI_CHIP_HASWELL_ULT_B_GT1 0x0A0B
- #define PCI_CHIP_HASWELL_ULT_B_GT2 0x0A1B
- #define PCI_CHIP_HASWELL_ULT_B_GT3 0x0A2B
- #define PCI_CHIP_HASWELL_ULT_E_GT1 0x0A0E
- #define PCI_CHIP_HASWELL_ULT_E_GT2 0x0A1E
- #define PCI_CHIP_HASWELL_ULT_E_GT3 0x0A2E
-
- #define PCI_CHIP_HASWELL_CRW_D_GT1 0x0D02
- #define PCI_CHIP_HASWELL_CRW_D_GT2 0x0D12
- #define PCI_CHIP_HASWELL_CRW_D_GT3 0x0D22
- #define PCI_CHIP_HASWELL_CRW_M_GT1 0x0D06
- #define PCI_CHIP_HASWELL_CRW_M_GT2 0x0D16
- #define PCI_CHIP_HASWELL_CRW_M_GT3 0x0D26
- #define PCI_CHIP_HASWELL_CRW_S_GT1 0x0D0A
- #define PCI_CHIP_HASWELL_CRW_S_GT2 0x0D1A
- #define PCI_CHIP_HASWELL_CRW_S_GT3 0x0D2A
- #define PCI_CHIP_HASWELL_CRW_B_GT1 0x0D0B
- #define PCI_CHIP_HASWELL_CRW_B_GT2 0x0D1B
- #define PCI_CHIP_HASWELL_CRW_B_GT3 0x0D2B
- #define PCI_CHIP_HASWELL_CRW_E_GT1 0x0D0E
- #define PCI_CHIP_HASWELL_CRW_E_GT2 0x0D1E
- #define PCI_CHIP_HASWELL_CRW_E_GT3 0x0D2E
-
- struct intel_device_info {
- int gen;
- };
- struct intel_device;
-
- int intel_entity_get_devid(int index);
-
- int intel_open_device(int entity_num,
- const struct pci_device *pci,
- struct xf86_platform_device *dev);
- void intel_close_device(int entity_num);
- int __intel_peek_fd(ScrnInfoPtr scrn);
- struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd);
- int intel_has_render_node(struct intel_device *dev);
- const char *intel_get_master_name(struct intel_device *dev);
- const char *intel_get_client_name(struct intel_device *dev);
- int intel_get_client_fd(struct intel_device *dev);
- int intel_get_device_id(struct intel_device *dev);
- int intel_get_master(struct intel_device *dev);
- int intel_put_master(struct intel_device *dev);
- void intel_put_device(struct intel_device *dev);
-
- void intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev);
-
- #define IS_DEFAULT_ACCEL_METHOD(x) ({ \
- enum { NOACCEL, SNA, UXA } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
- default_accel_method__ == x; \
- })
-
- #define hosted() (0)
-
- #endif /* INTEL_DRIVER_H */
intel_driver.h中声明了intel_device.c中实现的函数,虽然名字一个叫driver、一个叫device。其中内容在下边分析inter_device.c的时候再做讲解。
intel_device.c位于src目录下,文件内容较长(将近850行),因此在此不全部列出,而是一个函数一个函数来分析。
- int intel_open_device(int entity_num,
- const struct pci_device *pci,
- struct xf86_platform_device *platform)
- {
- struct intel_device *dev;
- char *path;
- int fd, master_count;
-
- if (intel_device_key == -1)
- intel_device_key = xf86AllocateEntityPrivateIndex();
- if (intel_device_key == -1)
- return -1;
-
- dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
- if (dev)
- return dev->fd;
-
- path = get_path(platform);
-
- master_count = 1; /* DRM_MASTER is managed by Xserver */
- fd = get_fd(platform);
- if (fd == -1) {
- fd = __intel_open_device(pci, path);
- if (fd == -1)
- goto err_path;
-
- master_count = 0;
- }
-
- if (path == NULL) {
- path = find_master_node(fd);
- if (path == NULL)
- goto err_close;
- }
-
- if (!__intel_check_device(fd))
- goto err_close;
-
- dev = malloc(sizeof(*dev));
- if (dev == NULL)
- goto err_close;
-
- /* If hosted under a system compositor, just pretend to be master */
- if (hosted())
- master_count++;
-
- /* Non-root user holding MASTER, don't let go */
- if (geteuid() && is_master(fd))
- master_count++;
-
- if (pci)
- dev->device_id = pci->device_id;
- else
- dev->device_id = __intel_get_device_id(fd);
-
- dev->idx = entity_num;
- dev->fd = fd;
- dev->open_count = master_count;
- dev->master_count = master_count;
- dev->master_node = path;
- dev->render_node = find_render_node(fd);
- if (dev->render_node == NULL)
- dev->render_node = dev->master_node;
-
- xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev;
-
- return fd;
-
- err_close:
- if (master_count == 0) /* Don't close server-fds */
- close(fd);
- err_path:
- free(path);
- return -1;
- }
这个函数本身也不短,分块来分析。先看第1段:
- if (intel_device_key == -1)
- intel_device_key = xf86AllocateEntityPrivateIndex();
- if (intel_device_key == -1)
- return -1;
intel_device_key在同文件中定义,为静态全局变量:
static int intel_device_key = -1;
初始时intel_device_key的值为-1,必定会调用xf86AllocateEntityPrivateIndex()。xf86AllocateEntityPrivateIndex函数在xorg-server源码的hw/xfree86/common/xf86Bus.c中,代码如下:
- /*
- * Allocate a private in the entities.
- */
-
- int
- xf86AllocateEntityPrivateIndex(void)
- {
- int idx, i;
- EntityPtr pEnt;
- DevUnion *nprivs;
-
- idx = xf86EntityPrivateCount++;
- for (i = 0; i < xf86NumEntities; i++) {
- pEnt = xf86Entities[i];
- nprivs = xnfreallocarray(pEnt->entityPrivates,
- xf86EntityPrivateCount, sizeof(DevUnion));
- /* Zero the new private */
- memset(&nprivs[idx], 0, sizeof(DevUnion));
- pEnt->entityPrivates = nprivs;
- }
- return idx;
- }
再来看第2段:
- dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
- if (dev)
- return dev->fd;
xf86GetEntityPrivate函数同在xorg-server源码的hw/xfree86/common/xf86Bus.c中,就在xf86AllocateEntityPrivateIndex函数实现的下边,代码如下:
- DevUnion *
- xf86GetEntityPrivate(int entityIndex, int privIndex)
- {
- if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
- return NULL;
-
- return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
- }
接下来看第3段:
path = get_path(platform);
path是函数内部定义的局部变量:char *path;。
这段代码的意思是根据intel_open_device函数的入参struct xf86_platform_device *platform即平台设备指针获得相应的路径。
get_path函数在同文件中实现,代码如下:
- #if defined(ODEV_ATTRIB_PATH)
- static char *get_path(struct xf86_platform_device *dev)
- {
- const char *path;
-
- if (dev == NULL)
- return NULL;
-
- path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
- if (path == NULL)
- return NULL;
-
- return strdup(path);
- }
-
- #else
-
- static char *get_path(struct xf86_platform_device *dev)
- {
- return NULL;
- }
- #endif
接下来看第4段:
- master_count = 1; /* DRM_MASTER is managed by Xserver */
- fd = get_fd(platform);
- if (fd == -1) {
- fd = __intel_open_device(pci, path);
- if (fd == -1)
- goto err_path;
-
- master_count = 0;
- }
这段代码的意思是根据intel_open_device函数的入参struct xf86_platform_device *platform即平台设备指针获得相应的文件描述符。如果获取不到,则调用__intel_open_device函数根据intel_open_device函数的入参pci打开设备。
get_path函数在同文件中实现,代码如下:
- #if defined(ODEV_ATTRIB_FD)
- static int get_fd(struct xf86_platform_device *dev)
- {
- if (dev == NULL)
- return -1;
-
- return xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
- }
-
- #else
-
- static int get_fd(struct xf86_platform_device *dev)
- {
- return -1;
- }
- #endif
__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);
- } else
- fd = open_cloexec(path);
-
- return fd;
- }
__intel_open_device函数中包含的2个函数都比较大,我们在下一篇文章中进行分析。