diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2013-05-23 18:32:53 +0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2013-05-27 20:01:15 +0400 |
commit | 6eb237c41acc1cf00b3b1176ad4a0ed3f221d630 (patch) | |
tree | 01ccdea50b8a38f0ce99611edd1a86fe70f949c0 /drivers/pci | |
parent | 197fc226d96623bf25237c480d46e9954b28a75e (diff) | |
download | linux-6eb237c41acc1cf00b3b1176ad4a0ed3f221d630.tar.xz |
pci: mvebu: fix the emulation of the status register
The status register of the PCI configuration space of PCI-to-PCI
bridges contain some read-only bits, and so write-1-to-clear bits. So,
the Linux PCI core sometimes writes 0xffff to this status register,
and in the current PCI-to-PCI bridge emulation code of the Marvell
driver, we do take all those 1s being written. Even the read-only bits
are being overwritten.
For now, all the read-only bits should be emulated to have the zero
value.
The other bits, that are write-1-to-clear bits are used to report
various kind of errors, and are never set by the emulated bridge, so
there is no need to support this write-1-to-clear bits mechanism.
As a conclusion, the easiest solution is to simply emulate this status
register by returning zero when read, and ignore the writes to it.
This has two visible effects:
* The devsel is no longer 'unknown' in, i.e
Flags: bus master, 66MHz, user-definable features, ?? devsel, latency 0
becomes:
Flags: bus master, 66MHz, user-definable features, fast devsel, latency 0
in lspci -v.
This was caused by a value of 11b being read for devsel, which is
an invalid value. This 11b value being read was due to a previous
write of 0xffff into the status register.
* The capability list is no longer broken, because we indicate to the
Linux PCI core that we don't have a Capabilities Pointer in the PCI
configuration space of this bridge. The following message is
therefore no longer visible in lspci -v:
Capabilities: [fc] <chain broken>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 9f1bfbd81168..7d713024aba3 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -69,7 +69,6 @@ struct mvebu_sw_pci_bridge { u16 vendor; u16 device; u16 command; - u16 status; u16 class; u8 interface; u8 revision; @@ -359,7 +358,6 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge)); - bridge->status = PCI_STATUS_CAP_LIST; bridge->class = PCI_CLASS_BRIDGE_PCI; bridge->vendor = PCI_VENDOR_ID_MARVELL; bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID; @@ -386,7 +384,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, break; case PCI_COMMAND: - *value = bridge->status << 16 | bridge->command; + *value = bridge->command; break; case PCI_CLASS_REVISION: @@ -479,7 +477,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, switch (where & ~3) { case PCI_COMMAND: bridge->command = value & 0xffff; - bridge->status = value >> 16; break; case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: |