Commit 93de6901 authored by Bjorn Helgaas's avatar Bjorn Helgaas

PCI: Check for PCI_HEADER_TYPE_BRIDGE equality, not bitmask

Bit 7 of the "Header Type" register indicates a multi-function device when
set.  Bits 0-6 contain encoded values, where 0x1 indicates a PCI-PCI
bridge.  It is incorrect to test this as though it were a mask.

For example, while the PCI 3.0 spec only defines values 0x0, 0x1, and 0x2,
it's conceivable that a future spec could define 0x3 to mean something
else; then tests for "(hdr_type & 0x7f) & PCI_HEADER_TYPE_BRIDGE" would
incorrectly succeed for this new 0x3 header type.

Test bits 0-6 of the Header Type for equality with PCI_HEADER_TYPE_BRIDGE.
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 1ec21837
...@@ -400,7 +400,7 @@ static void *eeh_rmv_device(void *data, void *userdata) ...@@ -400,7 +400,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
* support EEH. So we just care about PCI devices for * support EEH. So we just care about PCI devices for
* simplicity here. * simplicity here.
*/ */
if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) if (!dev || (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE))
return NULL; return NULL;
/* /*
......
...@@ -1119,7 +1119,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno) ...@@ -1119,7 +1119,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type behind the bridge is %x\n", hdr_type); debug ("hdr_type behind the bridge is %x\n", hdr_type);
if (hdr_type & PCI_HEADER_TYPE_BRIDGE) { if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
err ("embedded bridges not supported for hot-plugging.\n"); err ("embedded bridges not supported for hot-plugging.\n");
amount->not_correct = 1; amount->not_correct = 1;
return amount; return amount;
......
...@@ -246,7 +246,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) ...@@ -246,7 +246,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
!dev->driver->err_handler || !dev->driver->err_handler ||
!dev->driver->err_handler->error_detected) { !dev->driver->err_handler->error_detected) {
if (result_data->state == pci_channel_io_frozen && if (result_data->state == pci_channel_io_frozen &&
!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) { dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
/* /*
* In case of fatal recovery, if one of down- * In case of fatal recovery, if one of down-
* stream device has no driver. We might be * stream device has no driver. We might be
...@@ -269,7 +269,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) ...@@ -269,7 +269,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
* without recovery. * without recovery.
*/ */
if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
vote = PCI_ERS_RESULT_NO_AER_DRIVER; vote = PCI_ERS_RESULT_NO_AER_DRIVER;
else else
vote = PCI_ERS_RESULT_NONE; vote = PCI_ERS_RESULT_NONE;
...@@ -369,7 +369,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, ...@@ -369,7 +369,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
else else
result_data.result = PCI_ERS_RESULT_RECOVERED; result_data.result = PCI_ERS_RESULT_RECOVERED;
if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
/* /*
* If the error is reported by a bridge, we think this error * If the error is reported by a bridge, we think this error
* is related to the downstream link of the bridge, so we * is related to the downstream link of the bridge, so we
...@@ -440,7 +440,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev) ...@@ -440,7 +440,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
pci_ers_result_t status; pci_ers_result_t status;
struct pcie_port_service_driver *driver; struct pcie_port_service_driver *driver;
if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
/* Reset this port for all subordinates */ /* Reset this port for all subordinates */
udev = dev; udev = dev;
} else { } else {
...@@ -660,7 +660,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) ...@@ -660,7 +660,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
&info->mask); &info->mask);
if (!(info->status & ~info->mask)) if (!(info->status & ~info->mask))
return 0; return 0;
} else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE || } else if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
info->severity == AER_NONFATAL) { info->severity == AER_NONFATAL) {
/* Link is still healthy for IO reads */ /* Link is still healthy for IO reads */
......
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