Commit b2fb5cc5 authored by Honghui Zhang's avatar Honghui Zhang Committed by Bjorn Helgaas

PCI: Rely on config space header type, not class code

The PCI configuration space header type tells us whether the device is a
bridge, a CardBus bridge, or a normal device, and defines the layout of the
rest of the header (PCI r3.0 sec 6.1, PCIe r4.0 sec 7.5.1.1.9).

When we rely on the header format, e.g., when we're dealing with bridge
windows, we should check the header type, not the class code.  The class
code is loosely related to the header type, but is often incorrect and the
spec doesn't actually require it to be related to the header format.
Suggested-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarHonghui Zhang <honghui.zhang@mediatek.com>
[bhelgaas: changelog, keep the PCI_CLASS_BRIDGE_HOST check]
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 01b37f85
...@@ -6000,8 +6000,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) ...@@ -6000,8 +6000,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
* to enable the kernel to reassign new resource * to enable the kernel to reassign new resource
* window later on. * window later on.
*/ */
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
r = &dev->resource[i]; r = &dev->resource[i];
if (!(r->flags & IORESOURCE_MEM)) if (!(r->flags & IORESOURCE_MEM))
......
...@@ -1779,9 +1779,6 @@ int pci_setup_device(struct pci_dev *dev) ...@@ -1779,9 +1779,6 @@ int pci_setup_device(struct pci_dev *dev)
break; break;
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
/* /*
* The PCI-to-PCI bridge spec requires that subtractive * The PCI-to-PCI bridge spec requires that subtractive
* decoding (i.e. transparent) bridge must have programming * decoding (i.e. transparent) bridge must have programming
......
...@@ -1186,12 +1186,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) ...@@ -1186,12 +1186,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
if (!b) if (!b)
continue; continue;
switch (dev->class >> 8) { switch (dev->hdr_type) {
case PCI_CLASS_BRIDGE_CARDBUS: case PCI_HEADER_TYPE_CARDBUS:
pci_bus_size_cardbus(b, realloc_head); pci_bus_size_cardbus(b, realloc_head);
break; break;
case PCI_CLASS_BRIDGE_PCI: case PCI_HEADER_TYPE_BRIDGE:
default: default:
__pci_bus_size_bridges(b, realloc_head); __pci_bus_size_bridges(b, realloc_head);
break; break;
...@@ -1202,12 +1202,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) ...@@ -1202,12 +1202,12 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
if (pci_is_root_bus(bus)) if (pci_is_root_bus(bus))
return; return;
switch (bus->self->class >> 8) { switch (bus->self->hdr_type) {
case PCI_CLASS_BRIDGE_CARDBUS: case PCI_HEADER_TYPE_CARDBUS:
/* don't size cardbuses yet. */ /* don't size cardbuses yet. */
break; break;
case PCI_CLASS_BRIDGE_PCI: case PCI_HEADER_TYPE_BRIDGE:
pci_bridge_check_ranges(bus); pci_bridge_check_ranges(bus);
if (bus->self->is_hotplug_bridge) { if (bus->self->is_hotplug_bridge) {
additional_io_size = pci_hotplug_io_size; additional_io_size = pci_hotplug_io_size;
...@@ -1356,13 +1356,13 @@ void __pci_bus_assign_resources(const struct pci_bus *bus, ...@@ -1356,13 +1356,13 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
__pci_bus_assign_resources(b, realloc_head, fail_head); __pci_bus_assign_resources(b, realloc_head, fail_head);
switch (dev->class >> 8) { switch (dev->hdr_type) {
case PCI_CLASS_BRIDGE_PCI: case PCI_HEADER_TYPE_BRIDGE:
if (!pci_is_enabled(dev)) if (!pci_is_enabled(dev))
pci_setup_bridge(b); pci_setup_bridge(b);
break; break;
case PCI_CLASS_BRIDGE_CARDBUS: case PCI_HEADER_TYPE_CARDBUS:
pci_setup_cardbus(b); pci_setup_cardbus(b);
break; break;
......
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