Commit 2f0f3733 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/enumeration' into next

* pci/enumeration:
  PCI: Warn on possible RW1C corruption for sub-32 bit config writes
  PCI: Create revision file in sysfs
parents 5e0ad9f6 fb265923
...@@ -294,3 +294,10 @@ Description: ...@@ -294,3 +294,10 @@ Description:
a firmware bug to the system vendor. Writing to this file a firmware bug to the system vendor. Writing to this file
taints the kernel with TAINT_FIRMWARE_WORKAROUND, which taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
reduces the supportability of your system. reduces the supportability of your system.
What: /sys/bus/pci/devices/.../revision
Date: November 2016
Contact: Emil Velikov <emil.l.velikov@gmail.com>
Description:
This file contains the revision field of the the PCI device.
The value comes from device config space. The file is read only.
...@@ -17,6 +17,7 @@ that support it. For example, a given bus might look like this: ...@@ -17,6 +17,7 @@ that support it. For example, a given bus might look like this:
| |-- resource0 | |-- resource0
| |-- resource1 | |-- resource1
| |-- resource2 | |-- resource2
| |-- revision
| |-- rom | |-- rom
| |-- subsystem_device | |-- subsystem_device
| |-- subsystem_vendor | |-- subsystem_vendor
...@@ -41,6 +42,7 @@ files, each with their own function. ...@@ -41,6 +42,7 @@ files, each with their own function.
resource PCI resource host addresses (ascii, ro) resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap, rw[1]) resource0..N PCI resource N, if present (binary, mmap, rw[1])
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
revision PCI revision (ascii, ro)
rom PCI ROM resource, if present (binary, ro) rom PCI ROM resource, if present (binary, ro)
subsystem_device PCI subsystem device (ascii, ro) subsystem_device PCI subsystem device (ascii, ro)
subsystem_vendor PCI subsystem vendor (ascii, ro) subsystem_vendor PCI subsystem vendor (ascii, ro)
......
...@@ -142,10 +142,22 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, ...@@ -142,10 +142,22 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
if (size == 4) { if (size == 4) {
writel(val, addr); writel(val, addr);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} else {
mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
} }
/*
* In general, hardware that supports only 32-bit writes on PCI is
* not spec-compliant. For example, software may perform a 16-bit
* write. If the hardware only supports 32-bit accesses, we must
* do a 32-bit read, merge in the 16 bits we intend to write,
* followed by a 32-bit write. If the 16 bits we *don't* intend to
* write happen to have any RW1C (write-one-to-clear) bits set, we
* just inadvertently cleared something we shouldn't have.
*/
dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n",
size, pci_domain_nr(bus), bus->number,
PCI_SLOT(devfn), PCI_FUNC(devfn), where);
mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
tmp = readl(addr) & mask; tmp = readl(addr) & mask;
tmp |= val << ((where & 0x3) * 8); tmp |= val << ((where & 0x3) * 8);
writel(tmp, addr); writel(tmp, addr);
......
...@@ -293,8 +293,6 @@ static int hisi_pcie_probe(struct platform_device *pdev) ...@@ -293,8 +293,6 @@ static int hisi_pcie_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n");
return 0; return 0;
} }
......
...@@ -1187,9 +1187,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev) ...@@ -1187,9 +1187,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
pcie_bus_configure_settings(child); pcie_bus_configure_settings(child);
pci_bus_add_devices(bus); pci_bus_add_devices(bus);
dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n");
return err; return err;
err_vpcie: err_vpcie:
......
...@@ -50,6 +50,7 @@ pci_config_attr(vendor, "0x%04x\n"); ...@@ -50,6 +50,7 @@ pci_config_attr(vendor, "0x%04x\n");
pci_config_attr(device, "0x%04x\n"); pci_config_attr(device, "0x%04x\n");
pci_config_attr(subsystem_vendor, "0x%04x\n"); pci_config_attr(subsystem_vendor, "0x%04x\n");
pci_config_attr(subsystem_device, "0x%04x\n"); pci_config_attr(subsystem_device, "0x%04x\n");
pci_config_attr(revision, "0x%02x\n");
pci_config_attr(class, "0x%06x\n"); pci_config_attr(class, "0x%06x\n");
pci_config_attr(irq, "%u\n"); pci_config_attr(irq, "%u\n");
...@@ -568,6 +569,7 @@ static struct attribute *pci_dev_attrs[] = { ...@@ -568,6 +569,7 @@ static struct attribute *pci_dev_attrs[] = {
&dev_attr_device.attr, &dev_attr_device.attr,
&dev_attr_subsystem_vendor.attr, &dev_attr_subsystem_vendor.attr,
&dev_attr_subsystem_device.attr, &dev_attr_subsystem_device.attr,
&dev_attr_revision.attr,
&dev_attr_class.attr, &dev_attr_class.attr,
&dev_attr_irq.attr, &dev_attr_irq.attr,
&dev_attr_local_cpus.attr, &dev_attr_local_cpus.attr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment