>From 8cd5b6a3b380b730893cf67e7d611fe256baeaed Mon Sep 17 00:00:00 2001 From: Dirk Gouders Date: Fri, 12 Sep 2014 21:31:53 +0200 Subject: [PATCH 4/4] PCI: Add link_disable in /sysfs for pcie device Found PCIe cards from one vendor, will not respond to scan from bridge, if we change bus number setting in bridge device. Have to do link disable/enable on the pcie root port. So try to expose link disable bit of pcie link control register. We can use echo 1 > /sys/..../link_disable echo 0 > /sys/..../link_disable to bring the pcie device back to respond to scan. Signed-off-by: Yinghai Lu --- drivers/pci/pcie-sysfs.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/pci/pcie-sysfs.c b/drivers/pci/pcie-sysfs.c index b65e065..d4f6d4f 100644 --- a/drivers/pci/pcie-sysfs.c +++ b/drivers/pci/pcie-sysfs.c @@ -1,7 +1,35 @@ #include #include +static ssize_t +pcie_link_disable_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + return sprintf(buf, "%u\n", pcie_link_disable_get(pdev)); +} +static ssize_t +pcie_link_disable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pci_dev *pdev = to_pci_dev(dev); + unsigned long val; + + if (kstrtoul(buf, 0, &val) < 0) + return -EINVAL; + + pcie_link_disable_set(pdev, val); + + return count; +} + +static struct device_attribute pcie_link_disable_attr = + __ATTR(pcie_link_disable, 0644, + pcie_link_disable_show, pcie_link_disable_store); + static struct attribute *pci_dev_pcie_dev_attrs[] = { + &pcie_link_disable_attr.attr, NULL, }; @@ -14,6 +42,11 @@ static umode_t pci_dev_pcie_attrs_are_visible(struct kobject *kobj, if (!pci_is_pcie(pdev)) return 0; + if (a == &pcie_link_disable_attr.attr) + if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) && + (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)) + return 0; + return a->mode; } -- 2.1.0