PCI / ACPI fix for v4.1-rc6
This fixes a bug uncovered by a recent driver core change that modified the implementation of the ACPI_COMPANION_SET() macro to strictly rely on its second argument to be either NULL or a valid pointer to struct acpi_device. As it turns out, pcibios_root_bridge_prepare() on x86 and ia64 works with the assumption that the only code path calling pci_create_root_bus() is pci_acpi_scan_root() and therefore the sysdata argument passed to it will always match the expectations of pcibios_root_bridge_prepare(). That need not be the case, however, and in particular it is not the case for the Xen pcifront driver that passes a pointer to its own private data strcture as sysdata to pci_scan_bus_parented() which then passes it to pci_create_root_bus() and it ends up being used incorrectly by pcibios_root_bridge_prepare(). / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJVaP1HAAoJEILEb/54YlRxpwEQAJn+6phfcLZiBkwRCvGAmWwv Hi5UhcLCZb8r0RX+CssrwDxmiTD+OO5Kume7yqzb9R1EJfEWcx7dOnvrtl6mfy9E sfWuU/ILF9TW57bqEHBde921VwtRh3BQ4fOCbp4qYEEXjFx+N/UOYHRefgWzvgYP 0j9U7HvwBatIjOC6gPWDyoOI7AYZwBVh4lhjYTPfOTta7QqbjFPD1b+EaAqSyNsl TqrTQDgtxMTL02u50fP1hLJtOibdp7gOTRlEyfCJru4JjHBTRxBlaefymGi4e2Nw 5bFyXlDv4SVAGpE2XFDIJftAkAs+lXPjfIt7aHPB+DSa01axBesyqLITQV9wDoL8 AETnGomgoe+fsymJ1Pk4JOar6bKJmezAwDibi7bDcUoZkTD91VREwZiaLR+kEvzH msujMNV0SdVS+PIZUNIwYE6t/ffSDnHjdGjGnsAhNt2JtFFcDKyNkf21O4NYlV99 iLLx/YY+kxmTBuV+L9pjEefS/u9g60cdjslPFBzffXIZ8N9g2uKOqB6ulfg2dSm/ tB5u8gyTuR++jmm/f+rlpCCzQ4EMG9ciZnZJfce3m961Sac2kNacGARMMIAe6xMq ijuOgcVZZibGBviG5v64ntTQki9qgmImZiPCSoOn+3UgrkCExJfUNDSVl5tQA6MP oJEj4WRvH2LrFd/PjPlW =ulKW -----END PGP SIGNATURE----- Merge tag 'acpi-pci-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull PCI / ACPI fix from Rafael Wysocki: "This fixes a bug uncovered by a recent driver core change that modified the implementation of the ACPI_COMPANION_SET() macro to strictly rely on its second argument to be either NULL or a valid pointer to struct acpi_device. As it turns out, pcibios_root_bridge_prepare() on x86 and ia64 works with the assumption that the only code path calling pci_create_root_bus() is pci_acpi_scan_root() and therefore the sysdata argument passed to it will always match the expectations of pcibios_root_bridge_prepare(). That need not be the case, however, and in particular it is not the case for the Xen pcifront driver that passes a pointer to its own private data strcture as sysdata to pci_scan_bus_parented() which then passes it to pci_create_root_bus() and it ends up being used incorrectly by pcibios_root_bridge_prepare()" * tag 'acpi-pci-4.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PCI / ACPI: Do not set ACPI companions for host bridges with parents
This commit is contained in:
commit
aaa20fc233
|
@ -478,9 +478,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||||
|
|
||||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||||
{
|
{
|
||||||
struct pci_controller *controller = bridge->bus->sysdata;
|
/*
|
||||||
|
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||||
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
* here, pci_create_root_bus() has been called by someone else and
|
||||||
|
* sysdata is likely to be different from what we expect. Let it go in
|
||||||
|
* that case.
|
||||||
|
*/
|
||||||
|
if (!bridge->dev.parent) {
|
||||||
|
struct pci_controller *controller = bridge->bus->sysdata;
|
||||||
|
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,9 +482,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||||
|
|
||||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||||
{
|
{
|
||||||
struct pci_sysdata *sd = bridge->bus->sysdata;
|
/*
|
||||||
|
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||||
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
* here, pci_create_root_bus() has been called by someone else and
|
||||||
|
* sysdata is likely to be different from what we expect. Let it go in
|
||||||
|
* that case.
|
||||||
|
*/
|
||||||
|
if (!bridge->dev.parent) {
|
||||||
|
struct pci_sysdata *sd = bridge->bus->sysdata;
|
||||||
|
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue