RE: [PATCH] PCI: Max Payload Size BIOS workaround

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hmm. I just added very similar code for setting PCIEmaxpayload during PCIE hotplug insertion.
perhaps these two should be merged?

--jordan hargrave
Dell Enterprise Linux Engineering

> -----Original Message-----
> From: linux-pci-owner@xxxxxxxxxxxxxxx [mailto:linux-pci-
> owner@xxxxxxxxxxxxxxx] On Behalf Of Jon Mason
> Sent: Wednesday, May 25, 2011 2:01 PM
> To: Jesse Barnes
> Cc: linux-pci@xxxxxxxxxxxxxxx; Andrew Gallatin
> Subject: [PATCH] PCI: Max Payload Size BIOS workaround
> 
> Ensure that the max payload size on the root port is the same as the
> max
> payload size on all intermediate bridges and devices.  This is required
> to work around buggy BIOS revisions found on various whitebox
> motherboards which do not configure mps beyond one level below the root
> port.
> 
> Signed-off-by: Jon Mason <mason@xxxxxxxx>
> Signed-off-by: Andrew Gallatin <gallatin@xxxxxxxx>
> ---
>  drivers/pci/bus.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 69546e9..fc16b67 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -175,6 +175,49 @@ int pci_bus_add_child(struct pci_bus *bus)
>  	return retval;
>  }
> 
> +/*
> + * Ensure that the max payload size on the root port is the same as
> the max
> + * payload size on all intermediate bridges.  This is required to work
> around
> + * buggy BIOS revisions found on various whitebox motherboards which
> do not
> + * configure mps beyond one level below the root port.
> + */
> +static void pci_mps_workaround(struct pci_dev *child, struct pci_dev
> *parent)
> +{
> +	u16 val, pmps, cmps;
> +	int cap, rc;
> +
> +	if (!parent)
> +		return;
> +
> +	cap = pci_find_capability(parent, PCI_CAP_ID_EXP);
> +	if (!cap)
> +		return;
> +
> +	rc = pci_read_config_word(parent, cap + PCI_EXP_DEVCTL, &val);
> +	if (rc)
> +		return;
> +
> +	pmps = val & PCI_EXP_DEVCTL_PAYLOAD;
> +
> +	cap = pci_find_capability(child, PCI_CAP_ID_EXP);
> +	if (!cap)
> +		return;
> +
> +	rc = pci_read_config_word(child, cap + PCI_EXP_DEVCTL, &val);
> +	if (rc)
> +		return;
> +
> +	cmps = val & PCI_EXP_DEVCTL_PAYLOAD;
> +
> +	if (pmps != cmps) {
> +		printk(KERN_WARNING "Child MPS of %d != Parent MPS of %d!
> "
> +		       "Most likely caused by bad BIOS.  Working
> around...\n",
> +		       128 << (cmps >> 5), 128 << (pmps >> 5));
> +		val = (val & ~ PCI_EXP_DEVCTL_PAYLOAD) | pmps;
> +		pci_write_config_word(child, cap + PCI_EXP_DEVCTL, val);
> +	}
> +}
> +
>  /**
>   * pci_bus_add_devices - insert newly discovered PCI devices
>   * @bus: bus to check for new devices
> @@ -194,6 +237,7 @@ void pci_bus_add_devices(const struct pci_bus *bus)
>  	int retval;
> 
>  	list_for_each_entry(dev, &bus->devices, bus_list) {
> +		pci_mps_workaround(dev, dev->bus->self);
>  		/* Skip already-added devices */
>  		if (dev->is_added)
>  			continue;
> --
> 1.7.4.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux