RE: [PATCH] Set PCIE maxpayload for card during hotplug insertion

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

 



I have tested and verified that the patch works.
Tested-by: jordan_hargrave@xxxxxxxx

--jordan hargrave
Dell Enterprise Linux Engineering

> -----Original Message-----
> From: Hargrave, Jordan
> Sent: Tuesday, March 29, 2011 4:43 PM
> To: Iyer, Shyam; Hargrave, Jordan
> Subject: [PATCH] Set PCIE maxpayload for card during hotplug insertion
> 
> Signed-off-by: Jordan Hargrave <Jordan_Hargrave@xxxxxxxx>
> ---
>  drivers/pci/hotplug/pcihp_slot.c |   44
> ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/pcihp_slot.c
> b/drivers/pci/hotplug/pcihp_slot.c
> index 80b461c..3b628c5 100644
> --- a/drivers/pci/hotplug/pcihp_slot.c
> +++ b/drivers/pci/hotplug/pcihp_slot.c
> @@ -158,6 +158,46 @@ static void program_hpp_type2(struct pci_dev *dev,
> struct hpp_type2 *hpp)
>  	 */
>  }
> 
> +/* Program PCIE MaxPayload setting on device: ensure parent maxpayload
> <= device */
> +static int pci_set_payload(struct pci_dev *dev)
> +{
> +	int pos, ppos;
> +	u16 pctl, psz;
> +	u16 dctl, dsz, dcap, dmax;
> +	struct pci_dev *parent;
> +
> +	parent = dev->bus->self;
> +	pos = pci_pcie_cap(dev);
> +	if (!pos)
> +		return 0;
> +
> +	/* Read Device MaxPayload capability and setting */
> +	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &dctl);
> +	pci_read_config_word(dev, pos + PCI_EXP_DEVCAP, &dcap);
> +	dsz = (dctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
> +	dmax = (dcap & PCI_EXP_DEVCAP_PAYLOAD);
> +
> +	/* Read Parent MaxPayload setting */
> +	ppos = pci_pcie_cap(parent);
> +	if (!ppos)
> +		return 0;
> +	pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
> +	psz = (pctl &  PCI_EXP_DEVCTL_PAYLOAD) >> 5;
> +
> +	/* If parent payload > device max payload -> error
> +	 * If parent payload > device payload -> set speed
> +	 * If parent payload <= device payload -> do nothing
> +	 */
> +	if (psz > dmax)
> +		return -1;
> +	if (psz > dsz) {
> +		dev_info(&dev->dev, "Setting MaxPayload to %d\n", 128 <<
> psz);
> +		dctl = (dctl & ~PCI_EXP_DEVCTL_PAYLOAD) + (psz << 5);
> +		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, dctl);
> +	}
> +	return 0;
> +}
> +
>  void pci_configure_slot(struct pci_dev *dev)
>  {
>  	struct pci_dev *cdev;
> @@ -169,6 +209,10 @@ void pci_configure_slot(struct pci_dev *dev)
>  			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
>  		return;
> 
> +	ret = pci_set_payload(dev);
> +	if (ret)
> +		dev_warn(&dev->dev, "could not set device max payload\n");
> +
>  	memset(&hpp, 0, sizeof(hpp));
>  	ret = pci_get_hp_params(dev, &hpp);
>  	if (ret)
> --
> 1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux