• xf86-video-intel源码分析6 —— intel_device.c和intel_driver.h(1)


    intel_driver.h

    intel_driver.h位于src目录下,内容为:

    1. #ifndef INTEL_DRIVER_H
    2. #define INTEL_DRIVER_H
    3. struct xf86_platform_device;
    4. #define INTEL_VERSION 4000
    5. #define INTEL_NAME "intel"
    6. #define INTEL_DRIVER_NAME "intel"
    7. #define INTEL_VERSION_MAJOR PACKAGE_VERSION_MAJOR
    8. #define INTEL_VERSION_MINOR PACKAGE_VERSION_MINOR
    9. #define INTEL_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL
    10. #define PCI_CHIP_I810 0x7121
    11. #define PCI_CHIP_I810_DC100 0x7123
    12. #define PCI_CHIP_I810_E 0x7125
    13. #define PCI_CHIP_I815 0x1132
    14. #define PCI_CHIP_I830_M 0x3577
    15. #define PCI_CHIP_845_G 0x2562
    16. #define PCI_CHIP_I854 0x358E
    17. #define PCI_CHIP_I855_GM 0x3582
    18. #define PCI_CHIP_I865_G 0x2572
    19. #define PCI_CHIP_I915_G 0x2582
    20. #define PCI_CHIP_I915_GM 0x2592
    21. #define PCI_CHIP_E7221_G 0x258A
    22. #define PCI_CHIP_I945_G 0x2772
    23. #define PCI_CHIP_I945_GM 0x27A2
    24. #define PCI_CHIP_I945_GME 0x27AE
    25. #define PCI_CHIP_PINEVIEW_M 0xA011
    26. #define PCI_CHIP_PINEVIEW_G 0xA001
    27. #define PCI_CHIP_Q35_G 0x29B2
    28. #define PCI_CHIP_G33_G 0x29C2
    29. #define PCI_CHIP_Q33_G 0x29D2
    30. #define PCI_CHIP_G35_G 0x2982
    31. #define PCI_CHIP_I965_Q 0x2992
    32. #define PCI_CHIP_I965_G 0x29A2
    33. #define PCI_CHIP_I946_GZ 0x2972
    34. #define PCI_CHIP_I965_GM 0x2A02
    35. #define PCI_CHIP_I965_GME 0x2A12
    36. #define PCI_CHIP_GM45_GM 0x2A42
    37. #define PCI_CHIP_G45_E_G 0x2E02
    38. #define PCI_CHIP_G45_G 0x2E22
    39. #define PCI_CHIP_Q45_G 0x2E12
    40. #define PCI_CHIP_G41_G 0x2E32
    41. #define PCI_CHIP_B43_G 0x2E42
    42. #define PCI_CHIP_B43_G1 0x2E92
    43. #define PCI_CHIP_IRONLAKE_D_G 0x0042
    44. #define PCI_CHIP_IRONLAKE_M_G 0x0046
    45. #define PCI_CHIP_SANDYBRIDGE_GT1 0x0102
    46. #define PCI_CHIP_SANDYBRIDGE_GT2 0x0112
    47. #define PCI_CHIP_SANDYBRIDGE_GT2_PLUS 0x0122
    48. #define PCI_CHIP_SANDYBRIDGE_M_GT1 0x0106
    49. #define PCI_CHIP_SANDYBRIDGE_M_GT2 0x0116
    50. #define PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS 0x0126
    51. #define PCI_CHIP_SANDYBRIDGE_S_GT 0x010A
    52. #define PCI_CHIP_IVYBRIDGE_M_GT1 0x0156
    53. #define PCI_CHIP_IVYBRIDGE_M_GT2 0x0166
    54. #define PCI_CHIP_IVYBRIDGE_D_GT1 0x0152
    55. #define PCI_CHIP_IVYBRIDGE_D_GT2 0x0162
    56. #define PCI_CHIP_IVYBRIDGE_S_GT1 0x015a
    57. #define PCI_CHIP_IVYBRIDGE_S_GT2 0x016a
    58. #define PCI_CHIP_HASWELL_D_GT1 0x0402
    59. #define PCI_CHIP_HASWELL_D_GT2 0x0412
    60. #define PCI_CHIP_HASWELL_D_GT3 0x0422
    61. #define PCI_CHIP_HASWELL_M_GT1 0x0406
    62. #define PCI_CHIP_HASWELL_M_GT2 0x0416
    63. #define PCI_CHIP_HASWELL_M_GT3 0x0426
    64. #define PCI_CHIP_HASWELL_S_GT1 0x040A
    65. #define PCI_CHIP_HASWELL_S_GT2 0x041A
    66. #define PCI_CHIP_HASWELL_S_GT3 0x042A
    67. #define PCI_CHIP_HASWELL_B_GT1 0x040B
    68. #define PCI_CHIP_HASWELL_B_GT2 0x041B
    69. #define PCI_CHIP_HASWELL_B_GT3 0x042B
    70. #define PCI_CHIP_HASWELL_E_GT1 0x040E
    71. #define PCI_CHIP_HASWELL_E_GT2 0x041E
    72. #define PCI_CHIP_HASWELL_E_GT3 0x042E
    73. #define PCI_CHIP_HASWELL_ULT_D_GT1 0x0A02
    74. #define PCI_CHIP_HASWELL_ULT_D_GT2 0x0A12
    75. #define PCI_CHIP_HASWELL_ULT_D_GT3 0x0A22
    76. #define PCI_CHIP_HASWELL_ULT_M_GT1 0x0A06
    77. #define PCI_CHIP_HASWELL_ULT_M_GT2 0x0A16
    78. #define PCI_CHIP_HASWELL_ULT_M_GT3 0x0A26
    79. #define PCI_CHIP_HASWELL_ULT_S_GT1 0x0A0A
    80. #define PCI_CHIP_HASWELL_ULT_S_GT2 0x0A1A
    81. #define PCI_CHIP_HASWELL_ULT_S_GT3 0x0A2A
    82. #define PCI_CHIP_HASWELL_ULT_B_GT1 0x0A0B
    83. #define PCI_CHIP_HASWELL_ULT_B_GT2 0x0A1B
    84. #define PCI_CHIP_HASWELL_ULT_B_GT3 0x0A2B
    85. #define PCI_CHIP_HASWELL_ULT_E_GT1 0x0A0E
    86. #define PCI_CHIP_HASWELL_ULT_E_GT2 0x0A1E
    87. #define PCI_CHIP_HASWELL_ULT_E_GT3 0x0A2E
    88. #define PCI_CHIP_HASWELL_CRW_D_GT1 0x0D02
    89. #define PCI_CHIP_HASWELL_CRW_D_GT2 0x0D12
    90. #define PCI_CHIP_HASWELL_CRW_D_GT3 0x0D22
    91. #define PCI_CHIP_HASWELL_CRW_M_GT1 0x0D06
    92. #define PCI_CHIP_HASWELL_CRW_M_GT2 0x0D16
    93. #define PCI_CHIP_HASWELL_CRW_M_GT3 0x0D26
    94. #define PCI_CHIP_HASWELL_CRW_S_GT1 0x0D0A
    95. #define PCI_CHIP_HASWELL_CRW_S_GT2 0x0D1A
    96. #define PCI_CHIP_HASWELL_CRW_S_GT3 0x0D2A
    97. #define PCI_CHIP_HASWELL_CRW_B_GT1 0x0D0B
    98. #define PCI_CHIP_HASWELL_CRW_B_GT2 0x0D1B
    99. #define PCI_CHIP_HASWELL_CRW_B_GT3 0x0D2B
    100. #define PCI_CHIP_HASWELL_CRW_E_GT1 0x0D0E
    101. #define PCI_CHIP_HASWELL_CRW_E_GT2 0x0D1E
    102. #define PCI_CHIP_HASWELL_CRW_E_GT3 0x0D2E
    103. struct intel_device_info {
    104. int gen;
    105. };
    106. struct intel_device;
    107. int intel_entity_get_devid(int index);
    108. int intel_open_device(int entity_num,
    109. const struct pci_device *pci,
    110. struct xf86_platform_device *dev);
    111. void intel_close_device(int entity_num);
    112. int __intel_peek_fd(ScrnInfoPtr scrn);
    113. struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd);
    114. int intel_has_render_node(struct intel_device *dev);
    115. const char *intel_get_master_name(struct intel_device *dev);
    116. const char *intel_get_client_name(struct intel_device *dev);
    117. int intel_get_client_fd(struct intel_device *dev);
    118. int intel_get_device_id(struct intel_device *dev);
    119. int intel_get_master(struct intel_device *dev);
    120. int intel_put_master(struct intel_device *dev);
    121. void intel_put_device(struct intel_device *dev);
    122. void intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev);
    123. #define IS_DEFAULT_ACCEL_METHOD(x) ({ \
    124. enum { NOACCEL, SNA, UXA } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
    125. default_accel_method__ == x; \
    126. })
    127. #define hosted() (0)
    128. #endif /* INTEL_DRIVER_H */

    intel_driver.h中声明了intel_device.c中实现的函数,虽然名字一个叫driver、一个叫device。其中内容在下边分析inter_device.c的时候再做讲解。

    intel_device.c

    intel_device.c位于src目录下,文件内容较长(将近850行),因此在此不全部列出,而是一个函数一个函数来分析。

    • intel_open_device
    1. int intel_open_device(int entity_num,
    2. const struct pci_device *pci,
    3. struct xf86_platform_device *platform)
    4. {
    5. struct intel_device *dev;
    6. char *path;
    7. int fd, master_count;
    8. if (intel_device_key == -1)
    9. intel_device_key = xf86AllocateEntityPrivateIndex();
    10. if (intel_device_key == -1)
    11. return -1;
    12. dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
    13. if (dev)
    14. return dev->fd;
    15. path = get_path(platform);
    16. master_count = 1; /* DRM_MASTER is managed by Xserver */
    17. fd = get_fd(platform);
    18. if (fd == -1) {
    19. fd = __intel_open_device(pci, path);
    20. if (fd == -1)
    21. goto err_path;
    22. master_count = 0;
    23. }
    24. if (path == NULL) {
    25. path = find_master_node(fd);
    26. if (path == NULL)
    27. goto err_close;
    28. }
    29. if (!__intel_check_device(fd))
    30. goto err_close;
    31. dev = malloc(sizeof(*dev));
    32. if (dev == NULL)
    33. goto err_close;
    34. /* If hosted under a system compositor, just pretend to be master */
    35. if (hosted())
    36. master_count++;
    37. /* Non-root user holding MASTER, don't let go */
    38. if (geteuid() && is_master(fd))
    39. master_count++;
    40. if (pci)
    41. dev->device_id = pci->device_id;
    42. else
    43. dev->device_id = __intel_get_device_id(fd);
    44. dev->idx = entity_num;
    45. dev->fd = fd;
    46. dev->open_count = master_count;
    47. dev->master_count = master_count;
    48. dev->master_node = path;
    49. dev->render_node = find_render_node(fd);
    50. if (dev->render_node == NULL)
    51. dev->render_node = dev->master_node;
    52. xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev;
    53. return fd;
    54. err_close:
    55. if (master_count == 0) /* Don't close server-fds */
    56. close(fd);
    57. err_path:
    58. free(path);
    59. return -1;
    60. }

    这个函数本身也不短,分块来分析。先看第1段:

    1. if (intel_device_key == -1)
    2. intel_device_key = xf86AllocateEntityPrivateIndex();
    3. if (intel_device_key == -1)
    4. return -1;

    intel_device_key在同文件中定义,为静态全局变量:

    static int intel_device_key = -1;

    初始时intel_device_key的值为-1,必定会调用xf86AllocateEntityPrivateIndex()。xf86AllocateEntityPrivateIndex函数在xorg-server源码的hw/xfree86/common/xf86Bus.c中,代码如下:

    1. /*
    2. * Allocate a private in the entities.
    3. */
    4. int
    5. xf86AllocateEntityPrivateIndex(void)
    6. {
    7. int idx, i;
    8. EntityPtr pEnt;
    9. DevUnion *nprivs;
    10. idx = xf86EntityPrivateCount++;
    11. for (i = 0; i < xf86NumEntities; i++) {
    12. pEnt = xf86Entities[i];
    13. nprivs = xnfreallocarray(pEnt->entityPrivates,
    14. xf86EntityPrivateCount, sizeof(DevUnion));
    15. /* Zero the new private */
    16. memset(&nprivs[idx], 0, sizeof(DevUnion));
    17. pEnt->entityPrivates = nprivs;
    18. }
    19. return idx;
    20. }

    再来看第2段:

    1. dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
    2. if (dev)
    3. return dev->fd;

    xf86GetEntityPrivate函数同在xorg-server源码的hw/xfree86/common/xf86Bus.c中,就在xf86AllocateEntityPrivateIndex函数实现的下边,代码如下:

    1. DevUnion *
    2. xf86GetEntityPrivate(int entityIndex, int privIndex)
    3. {
    4. if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
    5. return NULL;
    6. return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
    7. }

    接下来看第3段:

    path = get_path(platform);

    path是函数内部定义的局部变量:char *path;。

    这段代码的意思是根据intel_open_device函数的入参struct xf86_platform_device *platform即平台设备指针获得相应的路径。

    get_path函数在同文件中实现,代码如下:

    1. #if defined(ODEV_ATTRIB_PATH)
    2. static char *get_path(struct xf86_platform_device *dev)
    3. {
    4. const char *path;
    5. if (dev == NULL)
    6. return NULL;
    7. path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
    8. if (path == NULL)
    9. return NULL;
    10. return strdup(path);
    11. }
    12. #else
    13. static char *get_path(struct xf86_platform_device *dev)
    14. {
    15. return NULL;
    16. }
    17. #endif

    接下来看第4段:

    1. master_count = 1; /* DRM_MASTER is managed by Xserver */
    2. fd = get_fd(platform);
    3. if (fd == -1) {
    4. fd = __intel_open_device(pci, path);
    5. if (fd == -1)
    6. goto err_path;
    7. master_count = 0;
    8. }

    这段代码的意思是根据intel_open_device函数的入参struct xf86_platform_device *platform即平台设备指针获得相应的文件描述符。如果获取不到,则调用__intel_open_device函数根据intel_open_device函数的入参pci打开设备。

    get_path函数在同文件中实现,代码如下:

    1. #if defined(ODEV_ATTRIB_FD)
    2. static int get_fd(struct xf86_platform_device *dev)
    3. {
    4. if (dev == NULL)
    5. return -1;
    6. return xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
    7. }
    8. #else
    9. static int get_fd(struct xf86_platform_device *dev)
    10. {
    11. return -1;
    12. }
    13. #endif

    __intel_open_device函数在同文件中实现,代码如下:

    1. static int __intel_open_device(const struct pci_device *pci, const char *path)
    2. {
    3. int fd;
    4. if (path == NULL) {
    5. if (pci == NULL)
    6. return -1;
    7. fd = __intel_open_device__pci(pci);
    8. if (fd == -1)
    9. fd = __intel_open_device__legacy(pci);
    10. } else
    11. fd = open_cloexec(path);
    12. return fd;
    13. }

    __intel_open_device函数中包含的2个函数都比较大,我们在下一篇文章中进行分析。

  • 相关阅读:
    分享:互信息在对比学习中的应用
    Jmeter跨线程参数关联无需脚本
    resnet152 辣椒病虫害图像识别1.0
    第十四章 手动创建 REST 服务(二)
    Docker常见面试题集锦
    python数学建模--时间序列模型--指数平滑
    SpringBoot+Shiro+Vue实现身份验证
    通过canvas获取图片的颜色值
    Rust 中 Actor 并发模型的实践与使用
    ChatGPT手机电脑浏览器中使用免费的ChatGPT
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/128033468