The symbolic link points to the PCI device sysfs entry of the
Physical Function this device associates with.
-
-What: /sys/bus/pci/slots/...
-Date: April 2005 (possibly older)
-KernelVersion: 2.6.12 (possibly older)
-Contact: linux-pci@vger.kernel.org
-Description:
- When the appropriate driver is loaded, it will create a
- directory per claimed physical PCI slot in
- /sys/bus/pci/slots/. The names of these directories are
- specific to the driver, which in turn, are specific to the
- platform, but in general, should match the label on the
- machine's physical chassis.
-
- The drivers that can create slot directories include the
- PCI hotplug drivers, and as of 2.6.27, the pci_slot driver.
-
- The slot directories contain, at a minimum, a file named
- 'address' which contains the PCI bus:device:function tuple.
- Other files may appear as well, but are specific to the
- driver.
-
-What: /sys/bus/pci/slots/.../function[0-7]
-Date: March 2010
-KernelVersion: 2.6.35
-Contact: linux-pci@vger.kernel.org
-Description:
- If PCI slot directories (as described above) are created,
- and the physical slot is actually populated with a device,
- symbolic links in the slot directory pointing to the
- device's PCI functions are created as well.
-
-What: /sys/bus/pci/devices/.../slot
-Date: March 2010
-KernelVersion: 2.6.35
-Contact: linux-pci@vger.kernel.org
-Description:
- If PCI slot directories (as described above) are created,
- a symbolic link pointing to the slot directory will be
- created as well.
-
What: /sys/bus/pci/slots/.../module
Date: June 2009
Contact: linux-pci@vger.kernel.org
return retval;
}
-static void pci_remove_slot_links(struct pci_dev *dev)
-{
- char func[10];
- struct pci_slot *slot;
-
- sysfs_remove_link(&dev->dev.kobj, "slot");
- list_for_each_entry(slot, &dev->bus->slots, list) {
- if (slot->number != PCI_SLOT(dev->devfn))
- continue;
- snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
- sysfs_remove_link(&slot->kobj, func);
- }
-}
-
-static int pci_create_slot_links(struct pci_dev *dev)
-{
- int result = 0;
- char func[10];
- struct pci_slot *slot;
-
- list_for_each_entry(slot, &dev->bus->slots, list) {
- if (slot->number != PCI_SLOT(dev->devfn))
- continue;
- result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
- if (result)
- goto out;
- snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
- result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
- }
-out:
- return result;
-}
-
int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
int retval;
if (retval)
goto err_vga_file;
- pci_create_slot_links(pdev);
-
return 0;
err_vga_file:
if (!sysfs_initialized)
return;
- pci_remove_slot_links(pdev);
-
pci_remove_capabilities_sysfs(pdev);
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
return bus_speed_read(slot->bus->cur_bus_speed, buf);
}
-static void remove_sysfs_files(struct pci_slot *slot)
-{
- char func[10];
- struct list_head *tmp;
-
- list_for_each(tmp, &slot->bus->devices) {
- struct pci_dev *dev = pci_dev_b(tmp);
- if (PCI_SLOT(dev->devfn) != slot->number)
- continue;
- sysfs_remove_link(&dev->dev.kobj, "slot");
-
- snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
- sysfs_remove_link(&slot->kobj, func);
- }
-}
-
-static int create_sysfs_files(struct pci_slot *slot)
-{
- int result;
- char func[10];
- struct list_head *tmp;
-
- list_for_each(tmp, &slot->bus->devices) {
- struct pci_dev *dev = pci_dev_b(tmp);
- if (PCI_SLOT(dev->devfn) != slot->number)
- continue;
-
- result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
- if (result)
- goto fail;
-
- snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
- result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
- if (result)
- goto fail;
- }
-
- return 0;
-
-fail:
- remove_sysfs_files(slot);
- return result;
-}
-
static void pci_slot_release(struct kobject *kobj)
{
struct pci_dev *dev;
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = NULL;
- remove_sysfs_files(slot);
-
list_del(&slot->list);
kfree(slot);
INIT_LIST_HEAD(&slot->list);
list_add(&slot->list, &parent->slots);
- create_sysfs_files(slot);
-
list_for_each_entry(dev, &parent->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot;