20.PCI代码导读-8.PCI_SYSFS-《计算机知识》

admin 2025-11-02 22:26:34 系统网络 来源:ZONE.CI 全球网 0 阅读模式
  • PCI SYSFS
    • 相关宏
    • bus操作接口
      • rescan 重新扫描所有PCI设备
    • device接口
    • pci_setup_device(pci设备初始化)

    PCI SYSFS

    我们在调试时最长在PCI SYSFS目录下进行调试,这个目录是怎么生成的?

    1. /sys/bus/pci/devices/0000:26:00.0$ ls
    2. aer_dev_correctable broken_parity_status current_link_speed dma_mask_bits iommu_group max_link_speed numa_node reset revision sriov_offset subsystem vendor
    3. aer_dev_fatal class current_link_width driver_override irq max_link_width power resource rom sriov_stride subsystem_device
    4. aer_dev_nonfatal config d3cold_allowed enable local_cpulist modalias remove resource0 sriov_drivers_autoprobe sriov_totalvfs subsystem_vendor
    5. ari_enabled consistent_dma_mask_bits device iommu local_cpus msi_bus rescan resource2 sriov_numvfs sriov_vf_device uevent

    /sys/bus/pci目录在 pci_driver_init 生成并注册

    相关宏

    1. // linux-5.7.14/include/linux/device/bus.h
    2. #define BUS_ATTR_RW(_name) \
    3. struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
    4. #define BUS_ATTR_RO(_name) \
    5. struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
    6. #define BUS_ATTR_WO(_name) \
    7. struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
    8. // linux-5.7.14/include/linux/device.h
    9. #define DEVICE_ATTR(_name, _mode, _show, _store) \
    10. struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
    11. #define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \
    12. struct device_attribute dev_attr_##_name = \
    13. __ATTR_PREALLOC(_name, _mode, _show, _store)
    14. #define DEVICE_ATTR_RW(_name) \
    15. struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
    16. #define DEVICE_ATTR_RO(_name) \
    17. struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
    18. #define DEVICE_ATTR_WO(_name) \
    19. struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
    20. #define DEVICE_ULONG_ATTR(_name, _mode, _var) \
    21. struct dev_ext_attribute dev_attr_##_name = \
    22. { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
    23. #define DEVICE_INT_ATTR(_name, _mode, _var) \
    24. struct dev_ext_attribute dev_attr_##_name = \
    25. { __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) }
    26. #define DEVICE_BOOL_ATTR(_name, _mode, _var) \
    27. struct dev_ext_attribute dev_attr_##_name = \
    28. { __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
    29. #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
    30. struct device_attribute dev_attr_##_name = \
    31. __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
    32. // linux-5.7.14/include/linux/sysfs.h
    33. #define __ATTR(_name, _mode, _show, _store) { \
    34. .attr = {.name = __stringify(_name), \
    35. .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
    36. .show = _show, \
    37. .store = _store, \
    38. }
    39. #define __ATTR_PREALLOC(_name, _mode, _show, _store) { \
    40. .attr = {.name = __stringify(_name), \
    41. .mode = SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\
    42. .show = _show, \
    43. .store = _store, \
    44. }
    45. #define __ATTR_RO(_name) { \
    46. .attr = { .name = __stringify(_name), .mode = 0444 }, \
    47. .show = _name##_show, \
    48. }
    49. #define __ATTR_RO_MODE(_name, _mode) { \
    50. .attr = { .name = __stringify(_name), \
    51. .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
    52. .show = _name##_show, \
    53. }
    54. #define __ATTR_WO(_name) { \
    55. .attr = { .name = __stringify(_name), .mode = 0200 }, \
    56. .store = _name##_store, \
    57. }
    58. #define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)
    59. #define __ATTR_NULL { .attr = { .name = NULL } }
    1. // linux-5.7.14/drivers/pci/pci-driver.c
    2. struct bus_type pci_bus_type = {
    3. .name = "pci",
    4. ......
    5. .dev_groups = pci_dev_groups,
    6. .bus_groups = pci_bus_groups,
    7. .drv_groups = pci_drv_groups,
    8. .....
    9. };
    10. pci_driver_init
    11. bus_register(&pcie_port_bus_type);
    12. priv->devices_kset = kset_create_and_add("devices", NULL,
    13. &priv->subsys.kobj);
    14. kset_create_and_add("drivers", NULL,
    15. &priv->subsys.kobj);
    16. bus_add_groups(bus, bus->bus_groups);
    17. sysfs_create_groups(&bus->p->subsys.kobj, groups); // 参考bus操作接口
    18. // linux-5.7.14/drivers/pci/pci-sysfs.c
    19. pci_bus_add_device
    20. pci_create_sysfs_dev_files(dev);
    21. sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); // config接口
    22. sysfs_create_bin_file(&pdev->dev.kobj, attr); // if (rom_size) ;option Rom接口

    bus操作接口

    rescan 重新扫描所有PCI设备

    1. // linux-5.7.14/drivers/pci/pci-sysfs.c
    2. recan属性:WO,
    3. ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count);
    4. static BUS_ATTR_WO(rescan); ===>
    5. struct bus_attribute bus_attr_rescan = {
    6. .attr = { .rescan = __stringify(rescan), .mode = 0200 }, \
    7. .store = rescan_store,
    8. };
    9. static struct attribute *pci_bus_attrs[] = {
    10. &bus_attr_rescan.attr,
    11. NULL,
    12. };
    13. static const struct attribute_group pci_bus_group = {
    14. .attrs = pci_bus_attrs,
    15. };
    16. const struct attribute_group *pci_bus_groups[] = {
    17. &pci_bus_group,
    18. NULL,
    19. };

    device接口

    提供了一大波device的操作接口,太多,不一一列举。

    1. /* show configuration fields */
    2. #define pci_config_attr(field, format_string) \
    3. static ssize_t \
    4. field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
    5. { \
    6. struct pci_dev *pdev; \
    7. \
    8. pdev = to_pci_dev(dev); \
    9. return sprintf(buf, format_string, pdev->field); \
    10. } \
    11. static DEVICE_ATTR_RO(field)
    12. pci_config_attr(vendor, "0x%04x\n"); // 一大波show接口
    13. pci_config_attr(device, "0x%04x\n");
    14. pci_config_attr(subsystem_vendor, "0x%04x\n");
    15. pci_config_attr(subsystem_device, "0x%04x\n");
    16. pci_config_attr(revision, "0x%02x\n");
    17. pci_config_attr(class, "0x%06x\n");
    18. pci_config_attr(irq, "%u\n");
    19. static DEVICE_ATTR_RW(enable); // enable接口
    20. static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
    21. char *buf)
    22. static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
    23. const char *buf, size_t count)
    24. static struct attribute *pci_dev_attrs[] = {
    25. &dev_attr_resource.attr,
    26. &dev_attr_vendor.attr,
    27. &dev_attr_device.attr,
    28. &dev_attr_subsystem_vendor.attr,
    29. &dev_attr_subsystem_device.attr,
    30. &dev_attr_revision.attr,
    31. &dev_attr_class.attr,
    32. &dev_attr_irq.attr,
    33. &dev_attr_local_cpus.attr,
    34. &dev_attr_local_cpulist.attr,
    35. &dev_attr_modalias.attr,
    36. #ifdef CONFIG_NUMA
    37. &dev_attr_numa_node.attr,
    38. #endif
    39. &dev_attr_dma_mask_bits.attr,
    40. &dev_attr_consistent_dma_mask_bits.attr,
    41. &dev_attr_enable.attr,
    42. &dev_attr_broken_parity_status.attr,
    43. &dev_attr_msi_bus.attr,
    44. #if defined(CONFIG_PM) && defined(CONFIG_ACPI)
    45. &dev_attr_d3cold_allowed.attr,
    46. #endif
    47. #ifdef CONFIG_OF
    48. &dev_attr_devspec.attr,
    49. #endif
    50. &dev_attr_driver_override.attr,
    51. &dev_attr_ari_enabled.attr,
    52. NULL,
    53. };
    54. static const struct attribute_group pci_dev_group = {
    55. .attrs = pci_dev_attrs,
    56. };
    57. const struct attribute_group *pci_dev_groups[] = {
    58. &pci_dev_group,
    59. NULL,
    60. };

    pci_setup_device(pci设备初始化)

    PCI是怎么获取配置空间大小的 ???pdev->cfg_size 在什么地方填充?

    1. pci_scan_device
    2. pci_setup_device
    3. pci_setup_device
    4. hdr_type = pci_hdr_type(dev); // 读取头部信息
    5. set_pcie_port_type
    6. pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); // PCIE一定有0x10的ID配置
    7. __pci_bus_find_cap_start
    8. // 读取pci配置空间的状态位,判断是否capabilities list位是否使能
    9. pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
    10. // 如果没使能,那配置空间也就0x00-0x3f
    11. // 如果使能,返回PCI_CAPABILITY_LIST 0x34,也就是capability指针位置
    12. __pci_find_next_cap //
    13. pci_bus_read_config_byte(bus, devfn, pos, &pos); // 读取指针,寻找next
    14. ....// 开始遍历capability,寻找ID符合的。也就是PCI_CAP_ID_EXP
    15. pci_cfg_space_size // 获取配置空间大小
    16. // 桥设备暂时不考虑
    17. if (pci_is_pcie(dev)) // 根据前边获取到的信息,判断是否是pcie设备
    18. return pci_cfg_space_size_ext(dev); // 这里边就是尝试读取下0x100以后的数据,
    01-shell脚本介绍-《shell脚本》 系统网络

    01-shell脚本介绍-《shell脚本》

    一、shell脚本是什么二、为什么要学shell,而不是其他计算机语言三、学习这门课程的优势四、学了能干什么五、学习什么内容六、学习的技巧七、成长路径八、学习环
    评论:0   参与:  0