linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Hemminger <shemminger@osdl.org>
To: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-pci@atrey.karlin.mff.cuni.cz, linux-kernel@vger.kernel.org
Subject: [PATCH 1/6] PCI-X Max Read Byte Count interface
Date: Fri, 08 Dec 2006 10:22:42 -0800	[thread overview]
Message-ID: <20061208182500.407073000@osdl.org> (raw)
In-Reply-To: 20061208182241.786324000@osdl.org

[-- Attachment #1: pci-x-mmrbc --]
[-- Type: text/plain, Size: 4745 bytes --]

Add interface to allow setting PCI-X Max Memory Read Byte Count
The get interface is commented out because there are no drivers
that need it.

The AMD 8131 chipset has a number of errata's related to PCI-X
configuration. The BIOS sets initial value correctly, but if a
device changes MMRBC it could cause data corruption. There are
some more settings of MMRBC that could be allowed but 
determining the safe values is more effort than it is worth.


Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
---
 drivers/pci/pci.c    |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/quirks.c |   19 +++++++++++-
 include/linux/pci.h  |    5 ++-
 3 files changed, 102 insertions(+), 2 deletions(-)

--- pci-x.orig/drivers/pci/pci.c
+++ pci-x/drivers/pci/pci.c
@@ -1059,6 +1059,86 @@ pci_set_consistent_dma_mask(struct pci_d
 	return 0;
 }
 #endif
+
+
+#if 0
+/**
+ * pcix_get_mmrbc - get PCI-X maximum memory read byte count
+ * @dev: PCI device to query
+ *
+ * Returns mmrbc: maximum memory read count in bytes
+ *    or appropriate error value.
+ */
+int pcix_get_mmrbc(struct pci_dev *dev)
+{
+	int ret, cap;
+	u32 cmd;
+
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (!cap)
+		return -EINVAL;
+
+	ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
+	if (!ret)
+		ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
+
+	return ret;
+}
+EXPORT_SYMBOL(pcix_get_mmrbc);
+#endif
+
+/**
+ * pcix_set_mmrbc - set PCI-X maximum memory read byte count
+ * @dev: PCI device to query
+ * @mmrbc: maximum memory read count in bytes
+ *    valid values are 512, 1024, 2048, 4096
+ *
+ * If possible sets maximum memory read byte count, some bridges have erratas
+ * that prevent this.
+ */
+int
+pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
+{
+	int cap, err = -EINVAL;
+	u32 stat, cmd, v, o;
+
+	if (mmrbc < 512 || mmrbc > 4096 || (mmrbc & (mmrbc-1)))
+		goto out;
+
+	v = ffs(mmrbc) - 10;
+
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (!cap)
+		goto out;	/* not PCI-X */
+
+	err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
+	if (err)
+		goto out;
+
+	if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
+		return -E2BIG;
+
+	err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
+	if (err)
+		goto out;
+
+	o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
+	if (o != v) {
+		/* Increasing can cause problems o some broken bridges */
+		if (v > o && dev->bus &&
+		    (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
+			return -EIO;
+
+		cmd &= ~PCI_X_CMD_MAX_READ;
+		cmd |= v << 2;
+		err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
+	}
+
+out:
+	return err;
+}
+EXPORT_SYMBOL(pcix_set_mmrbc);
+
      
 static int __devinit pci_init(void)
 {
--- pci-x.orig/drivers/pci/quirks.c
+++ pci-x/drivers/pci/quirks.c
@@ -615,9 +615,26 @@ static void __init quirk_amd_8131_ioapic
                 pci_write_config_byte( dev, AMD8131_MISC, tmp);
         }
 } 
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131o_ioapic);
 #endif /* CONFIG_X86_IO_APIC */
 
+/*
+ * Some settings of MMRBC can lead to data corruption so block changes.
+ * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide
+ */
+static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev)
+{
+	unsigned char revid;
+
+        pci_read_config_byte(dev, PCI_REVISION_ID, &revid);
+        if (dev->subordinate && revid <= 0x12) {
+                printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X MMRBC\n",
+		       revid);
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
+        }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc);
+
 
 /*
  * FIXME: it is questionable that quirk_via_acpi
--- pci-x.orig/include/linux/pci.h
+++ pci-x/include/linux/pci.h
@@ -98,7 +98,8 @@ enum pci_channel_state {
 
 typedef unsigned short __bitwise pci_bus_flags_t;
 enum pci_bus_flags {
-	PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
+	PCI_BUS_FLAGS_NO_MSI   = (__force pci_bus_flags_t) 1,
+	PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
 };
 
 struct pci_cap_saved_state {
@@ -511,6 +512,8 @@ void pci_clear_mwi(struct pci_dev *dev);
 void pci_intx(struct pci_dev *dev, int enable);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
+int pcix_get_mmrbc(struct pci_dev *dev);
+int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);

-- 


  reply	other threads:[~2006-12-08 18:27 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-08 18:22 [PATCH 0/6] PCI-X/PCI-Express read control interfaces Stephen Hemminger
2006-12-08 18:22 ` Stephen Hemminger [this message]
2006-12-08 22:56   ` [PATCH 1/6] PCI-X Max Read Byte Count interface (v2) Stephen Hemminger
2006-12-08 18:22 ` [PATCH 2/6] e1000: use pcix_set_mmrbc Stephen Hemminger
2006-12-08 21:45   ` Roland Dreier
2006-12-08 22:43     ` Stephen Hemminger
2006-12-08 22:58       ` Auke Kok
2006-12-08 23:38         ` Jeff Kirsher
2006-12-08 18:22 ` [PATCH 3/6] PCI Express get/set read request size Stephen Hemminger
2006-12-08 18:22 ` [PATCH 4/6] MTHCA driver (infiniband) use new pci interfaces Stephen Hemminger
2006-12-08 21:46   ` Roland Dreier
2006-12-11  3:55   ` Benjamin Herrenschmidt
2006-12-11  5:56     ` Grant Grundler
2006-12-12  1:38     ` Roland Dreier
2006-12-12  1:59       ` Benjamin Herrenschmidt
2006-12-08 18:22 ` [PATCH 5/6] QLA2 use pci read tuning interface Stephen Hemminger
2006-12-08 18:22 ` [PATCH 6/6] PCI-X relaxed ordering interface Stephen Hemminger
2006-12-11  3:48 ` [PATCH 0/6] PCI-X/PCI-Express read control interfaces Benjamin Herrenschmidt
2006-12-14  0:17   ` Stephen Hemminger
2006-12-14  0:34     ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061208182500.407073000@osdl.org \
    --to=shemminger@osdl.org \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@atrey.karlin.mff.cuni.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).