diff options
author | Alex Chiang <achiang@hp.com> | 2010-03-08 12:24:29 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-05-11 15:01:07 -0400 |
commit | 75568f8094eb0333e9c2109b23cbc8b82d318a3c (patch) | |
tree | bdbd169b2220e067bc03f7445e2471aa2f8499a7 /drivers/pci/pci-sysfs.c | |
parent | fc2a093e7ad23e935aa29e349bc27173c92f1a95 (diff) |
PCI: create function symlinks in /sys/bus/pci/slots/N/
Create convenience symlinks in sysfs, linking slots to device
functions, and vice versa. These links make it easier for users to
figure out which devices actually live in what slots.
For example:
sapphire:/sys/bus/pci/slots # ls
1 10 2 3 4 5 6 7 8 9
sapphire:/sys/bus/pci/slots # ls -l 3
total 0
-r--r--r-- 1 root root 65536 Aug 18 14:10 address
lrwxrwxrwx 1 root root 0 Aug 18 14:10 function0 ->
../../../../devices/pci0000:23/0000:23:01.0
lrwxrwxrwx 1 root root 0 Aug 18 14:10 function1 ->
../../../../devices/pci0000:23/0000:23:01.1
sapphire:/sys/bus/pci/slots # ls -l 3/function0/slot
lrwxrwxrwx 1 root root 0 Aug 18 14:13 3/function0/slot ->
../../../bus/pci/slots/3
The original form of this patch was written by Matthew Wilcox,
and was enhanced to include links from the sysfs slots/ directory
pointing back at the device functions.
Cc: willy@linux.intel.com
Signed-off-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r-- | drivers/pci/pci-sysfs.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fad93983bfed..941e939d1da9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -1011,6 +1011,39 @@ error: | |||
1011 | return retval; | 1011 | return retval; |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | static void pci_remove_slot_links(struct pci_dev *dev) | ||
1015 | { | ||
1016 | char func[10]; | ||
1017 | struct pci_slot *slot; | ||
1018 | |||
1019 | sysfs_remove_link(&dev->dev.kobj, "slot"); | ||
1020 | list_for_each_entry(slot, &dev->bus->slots, list) { | ||
1021 | if (slot->number != PCI_SLOT(dev->devfn)) | ||
1022 | continue; | ||
1023 | snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); | ||
1024 | sysfs_remove_link(&slot->kobj, func); | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | static int pci_create_slot_links(struct pci_dev *dev) | ||
1029 | { | ||
1030 | int result = 0; | ||
1031 | char func[10]; | ||
1032 | struct pci_slot *slot; | ||
1033 | |||
1034 | list_for_each_entry(slot, &dev->bus->slots, list) { | ||
1035 | if (slot->number != PCI_SLOT(dev->devfn)) | ||
1036 | continue; | ||
1037 | result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot"); | ||
1038 | if (result) | ||
1039 | goto out; | ||
1040 | snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); | ||
1041 | result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func); | ||
1042 | } | ||
1043 | out: | ||
1044 | return result; | ||
1045 | } | ||
1046 | |||
1014 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | 1047 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) |
1015 | { | 1048 | { |
1016 | int retval; | 1049 | int retval; |
@@ -1073,6 +1106,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1073 | if (retval) | 1106 | if (retval) |
1074 | goto err_vga_file; | 1107 | goto err_vga_file; |
1075 | 1108 | ||
1109 | pci_create_slot_links(pdev); | ||
1110 | |||
1076 | return 0; | 1111 | return 0; |
1077 | 1112 | ||
1078 | err_vga_file: | 1113 | err_vga_file: |
@@ -1122,6 +1157,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
1122 | if (!sysfs_initialized) | 1157 | if (!sysfs_initialized) |
1123 | return; | 1158 | return; |
1124 | 1159 | ||
1160 | pci_remove_slot_links(pdev); | ||
1161 | |||
1125 | pci_remove_capabilities_sysfs(pdev); | 1162 | pci_remove_capabilities_sysfs(pdev); |
1126 | 1163 | ||
1127 | if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) | 1164 | if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) |