mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
To: David Brownell <david-b@pacbell.net>,
	Jeff Garzik <jgarzik@pobox.com>, Greg KH <greg@kroah.com>,
	Russell King <rmk@arm.linux.org.uk>,
	Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: [patch 2.5] PCI MWI cacheline size fix
Date: Thu, 20 Mar 2003 13:59:50 +0300	[thread overview]
Message-ID: <20030320135950.A2333@jurassic.park.msu.ru> (raw)

This is rather conservative variant of previous patch:
- no changes required for drivers or architectures with HAVE_ARCH_PCI_MWI;
- do respect BIOS settings: if the cacheline size is multiple
  of that we have expected, assume that this is on purpose;
- assume cacheline size of 32 bytes for all x86s except K7/K8 and P4.
  Actually it's good for 386/486s as quite a few PCI devices do not support
  smaller values.

If you all are fine with it, I can make a 2.4 counterpart.

As for more aggressive changes: I'd prefer to wait until pending
stuff from rmk and myself gets in and the whole thing stabilizes.
Then we can start fine tuning of MWI, FBB, latency timers and so on.

Ivan.

--- 2.5/drivers/pci/pci.c	Tue Feb 18 11:49:44 2003
+++ linux/drivers/pci/pci.c	Thu Mar 20 11:55:38 2003
@@ -584,6 +584,9 @@ pci_set_master(struct pci_dev *dev)
 }
 
 #ifndef HAVE_ARCH_PCI_MWI
+/* This can be overridden by arch code. */
+u8 pci_cache_line_size = L1_CACHE_BYTES >> 2;
+
 /**
  * pci_generic_prep_mwi - helper function for pci_set_mwi
  * @dev: the PCI device for which MWI is enabled
@@ -597,32 +600,29 @@ pci_set_master(struct pci_dev *dev)
 static int
 pci_generic_prep_mwi(struct pci_dev *dev)
 {
-	int rc = 0;
-	u8 cache_size;
+	u8 cacheline_size;
+
+	if (!pci_cache_line_size)
+		return -EINVAL;		/* The system doesn't support MWI. */
+
+	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
+	   equal to or multiple of the right value. */
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
+	if (cacheline_size >= pci_cache_line_size &&
+	    (cacheline_size % pci_cache_line_size) == 0)
+		return 0;
+
+	/* Write the correct value. */
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
+	/* Read it back. */
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
+	if (cacheline_size == pci_cache_line_size)
+		return 0;
 
-	/*
-	 * Looks like this is necessary to deal with on all architectures,
-	 * even this %$#%$# N440BX Intel based thing doesn't get it right.
-	 * Ie. having two NICs in the machine, one will have the cache
-	 * line set at boot time, the other will not.
-	 */
-	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cache_size);
-	cache_size <<= 2;
-	if (cache_size != SMP_CACHE_BYTES) {
-		printk(KERN_WARNING "PCI: %s PCI cache line size set "
-		       "incorrectly (%i bytes) by BIOS/FW, ",
-		       dev->slot_name, cache_size);
-		if (cache_size > SMP_CACHE_BYTES) {
-			printk("expecting %i\n", SMP_CACHE_BYTES);
-			rc = -EINVAL;
-		} else {
-			printk("correcting to %i\n", SMP_CACHE_BYTES);
-			pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
-					      SMP_CACHE_BYTES >> 2);
-		}
-	}
+	printk(KERN_WARNING "PCI: cache line size of %d is not supported "
+	       "by device %s\n", pci_cache_line_size << 2, dev->slot_name);
 
-	return rc;
+	return -EINVAL;
 }
 #endif /* !HAVE_ARCH_PCI_MWI */
 
--- 2.5/arch/i386/pci/common.c	Tue Mar 18 11:05:39 2003
+++ linux/arch/i386/pci/common.c	Thu Mar 20 00:28:55 2003
@@ -120,12 +120,22 @@ struct pci_bus * __devinit pcibios_scan_
 	return pci_scan_bus(busnum, pci_root_ops, NULL);
 }
 
+extern u8 pci_cache_line_size;
+
 static int __init pcibios_init(void)
 {
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
 	if (!pci_root_ops) {
 		printk("PCI: System does not support PCI\n");
 		return 0;
 	}
+
+	pci_cache_line_size = 32 >> 2;
+	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
+		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
+	else if (c->x86 > 6)
+		pci_cache_line_size = 128 >> 2;	/* P4 */
 
 	pcibios_resource_survey();
 

             reply	other threads:[~2003-03-20 10:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-20 10:59 Ivan Kokshaysky [this message]
2003-03-20 11:55 ` Dave Jones
2003-03-20 12:29   ` Ivan Kokshaysky
2003-03-20 12:54     ` Dave Jones
2003-03-20 14:33 ` Jeff Garzik
2003-03-20 15:29 ` David Brownell
2003-03-20 22:26 ` Greg KH

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=20030320135950.A2333@jurassic.park.msu.ru \
    --to=ink@jurassic.park.msu.ru \
    --cc=david-b@pacbell.net \
    --cc=greg@kroah.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rmk@arm.linux.org.uk \
    --cc=torvalds@transmeta.com \
    /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

all inboxes | Powered by JetHome®