[4.2.y-ckt stable] Patch "PCI: spear: Fix dw_pcie_cfg_read/write() usage" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Mon Jan 4 23:22:07 UTC 2016
This is a note to let you know that I have just added a patch titled
PCI: spear: Fix dw_pcie_cfg_read/write() usage
to the linux-4.2.y-queue branch of the 4.2.y-ckt extended stable tree
which can be found at:
http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-4.2.y-queue
This patch is scheduled to be released in version 4.2.8-ckt1.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 4.2.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From 8cf87b4acdca26fc0f0d84328357ed0fce53740f Mon Sep 17 00:00:00 2001
From: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Date: Thu, 8 Oct 2015 14:27:38 -0500
Subject: PCI: spear: Fix dw_pcie_cfg_read/write() usage
commit fa3b7cbab548b15da438b0cc13aa515f7f291f4d upstream.
The first argument of dw_pcie_cfg_read/write() is a 32-bit aligned address.
The second argument is the byte offset into a 32-bit word, and
dw_pcie_cfg_read/write() only look at the low two bits.
SPEAr13xx used dw_pcie_cfg_read() and dw_pcie_cfg_write() incorrectly: it
passed important address bits in the second argument, where they were
ignored.
Pass the complete 32-bit word address in the first argument and only the
2-bit offset into that word in the second argument.
Without this fix, SPEAr13xx host will never work with few buggy gen1 card
which connects with only gen1 host and also with any endpoint which would
generate a read request of more than 128 bytes.
[bhelgaas: changelog]
Reported-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Pratyush Anand <panand at redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
drivers/pci/host/pcie-spear13xx.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index c49fbdc..4086268 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -163,34 +163,36 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
* default value in capability register is 512 bytes. So force
* it to 128 here.
*/
- dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, &val);
+ dw_pcie_cfg_read(pp->dbi_base + exp_cap_off + PCI_EXP_DEVCTL,
+ 0, 2, &val);
val &= ~PCI_EXP_DEVCTL_READRQ;
- dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, val);
+ dw_pcie_cfg_write(pp->dbi_base + exp_cap_off + PCI_EXP_DEVCTL,
+ 0, 2, val);
- dw_pcie_cfg_write(pp->dbi_base, PCI_VENDOR_ID, 2, 0x104A);
- dw_pcie_cfg_write(pp->dbi_base, PCI_DEVICE_ID, 2, 0xCD80);
+ dw_pcie_cfg_write(pp->dbi_base + PCI_VENDOR_ID, 0, 2, 0x104A);
+ dw_pcie_cfg_write(pp->dbi_base + PCI_VENDOR_ID, 2, 2, 0xCD80);
/*
* if is_gen1 is set then handle it, so that some buggy card
* also works
*/
if (spear13xx_pcie->is_gen1) {
- dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCAP, 4,
- &val);
+ dw_pcie_cfg_read(pp->dbi_base + exp_cap_off + PCI_EXP_LNKCAP,
+ 0, 4, &val);
if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
val &= ~((u32)PCI_EXP_LNKCAP_SLS);
val |= PCI_EXP_LNKCAP_SLS_2_5GB;
- dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
- PCI_EXP_LNKCAP, 4, val);
+ dw_pcie_cfg_write(pp->dbi_base + exp_cap_off +
+ PCI_EXP_LNKCAP, 0, 4, val);
}
- dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCTL2, 4,
- &val);
+ dw_pcie_cfg_read(pp->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2,
+ 0, 2, &val);
if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
val &= ~((u32)PCI_EXP_LNKCAP_SLS);
val |= PCI_EXP_LNKCAP_SLS_2_5GB;
- dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
- PCI_EXP_LNKCTL2, 4, val);
+ dw_pcie_cfg_write(pp->dbi_base + exp_cap_off +
+ PCI_EXP_LNKCTL2, 0, 2, val);
}
}
--
1.9.1
More information about the kernel-team
mailing list