mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Grant Grundler <grundler@cup.hp.com>,
	Paul Mackerras <paulus@samba.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	davidm@hpl.hp.com,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	greg@kroah.com
Subject: Re: [patch 2.5] 2-pass PCI probing, generic part
Date: Tue, 14 Jan 2003 19:39:57 +0300	[thread overview]
Message-ID: <20030114193957.A1115@jurassic.park.msu.ru> (raw)
In-Reply-To: <20030110163503.A4486@jurassic.park.msu.ru>; from ink@jurassic.park.msu.ru on Fri, Jan 10, 2003 at 04:35:03PM +0300

We know for a fact that current probing code works fine on
a vast majority of systems, so _not_ disabling all types of
bridges during the probing seems to be a reasonable default
behavior (which can be overridden by PCI quirks, of course).
This should work on x86 and ia64 without any additional fixups,
ppc will need only minimal changes - skip probe for I/O ASIC
and perhaps certain host bridges, no need to care about P2P ones.

Here's updated patch vs. 2.5.58.

Ivan.

--- 2.5.58/drivers/pci/probe.c	Tue Jan 14 13:38:12 2003
+++ linux/drivers/pci/probe.c	Tue Jan 14 15:08:46 2003
@@ -43,12 +43,37 @@ static u32 pci_size(u32 base, unsigned l
 	return size-1;			/* extent = size - 1 */
 }
 
+/* By default, disable I/O & memory decoding while we size the BARs
+   for all devices except bridges. */
+static inline void set_probing_method(struct pci_dev *dev, u16 oldcmd)
+{
+	u16 cmd = oldcmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+	switch (dev->probe) {
+	case PCI_PROBE_CMD_ENABLED:
+		break;
+	case PCI_PROBE_DEFAULT:
+		if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+			break;
+	case PCI_PROBE_CMD_DISABLED:
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+}
+
 static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 {
 	unsigned int pos, reg, next;
 	u32 l, sz;
+	u16 cmd;
 	struct resource *res;
 
+	if (dev->probe == PCI_PROBE_SKIP)
+		return;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+	set_probing_method(dev, cmd);
+
 	for(pos=0; pos<howmany; pos = next) {
 		next = pos+1;
 		res = &dev->resource[pos];
@@ -96,6 +121,9 @@ static void pci_read_bases(struct pci_de
 #endif
 		}
 	}
+
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
 	if (rom) {
 		dev->rom_base_reg = rom;
 		res = &dev->resource[PCI_ROM_RESOURCE];
@@ -338,7 +366,7 @@ static void pci_read_irq(struct pci_dev 
  * @dev: the device structure to fill
  *
  * Initialize the device structure with information about the device's 
- * vendor,class,memory and IO-space addresses,IRQ lines etc.
+ * vendor, memory and IO-space addresses, IRQ lines etc.
  * Called at initialisation of the PCI subsystem and by CardBus services.
  * Returns 0 on success and -1 if unknown type of device (not normal, bridge
  * or CardBus).
@@ -347,14 +375,9 @@ int pci_setup_device(struct pci_dev * de
 {
 	u32 class;
 
-	sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	sprintf(dev->dev.name, "PCI device %04x:%04x", dev->vendor, dev->device);
 	INIT_LIST_HEAD(&dev->pools);
 	
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
-	class >>= 8;				    /* upper 3 bytes */
-	dev->class = class;
-	class >>= 8;
+	class = dev->class >> 8;
 
 	DBG("Found %02x:%02x [%04x/%04x] %06x %02x\n", dev->bus->number, dev->devfn, dev->vendor, dev->device, class, dev->hdr_type);
 
@@ -406,8 +429,8 @@ int pci_setup_device(struct pci_dev * de
 }
 
 /*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
+ * Read the config data for a PCI device and fill in
+ * the dev structure...
  */
 struct pci_dev * __devinit pci_scan_device(struct pci_dev *temp)
 {
@@ -429,18 +452,23 @@ struct pci_dev * __devinit pci_scan_devi
 	dev->vendor = l & 0xffff;
 	dev->device = (l >> 16) & 0xffff;
 
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &l);
+	dev->class = l >> 8;			    /* upper 3 bytes */
+
 	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
 	   set this higher, assuming the system even supports it.  */
 	dev->dma_mask = 0xffffffff;
-	if (pci_setup_device(dev) < 0) {
-		kfree(dev);
-		return NULL;
-	}
 
 	pci_name_device(dev);
 
+	sprintf(dev->slot_name, "%02x:%02x.%d",
+		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+
+	/* Early fixups, before probing the BARs */
+	pci_fixup_device(PCI_FIXUP_EARLY, dev);
+
 	/* now put in global tree */
-	strcpy(dev->dev.bus_id,dev->slot_name);
+	strcpy(dev->dev.bus_id, dev->slot_name);
 	dev->dev.dma_mask = &dev->dma_mask;
 
 	device_register(&dev->dev);
@@ -476,13 +504,12 @@ struct pci_dev * __devinit pci_scan_slot
 		 * the per-bus list of devices and add the /proc entry.
 		 */
 		pci_insert_device (dev, bus);
-
-		/* Fix up broken headers */
-		pci_fixup_device(PCI_FIXUP_HEADER, dev);
 	}
 	return first_dev;
 }
 
+/* First phase of device discovery. Build the bus tree, collect header types,
+   class codes, device and vendor IDs. Perform early fixups. */
 unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
 {
 	unsigned int devfn, max, pass;
@@ -506,11 +533,8 @@ unsigned int __devinit pci_do_scan_bus(s
 	}
 
 	/*
-	 * After performing arch-dependent fixup of the bus, look behind
-	 * all PCI-to-PCI bridges on this bus.
+	 * Look behind all PCI-to-PCI bridges on this bus.
 	 */
-	DBG("Fixups for bus %02x\n", bus->number);
-	pcibios_fixup_bus(bus);
 	for (pass=0; pass < 2; pass++)
 		for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
 			dev = pci_dev_b(ln);
@@ -541,6 +565,38 @@ int __devinit pci_bus_exists(const struc
 	return 0;
 }
 
+/* Second phase of device discovery. Probe the BARs, fill in the rest
+   of pci_dev structure, perform device and bus fixups. */
+void __devinit pci_probe_resources(struct pci_bus *bus)
+{
+	struct list_head *ln;
+
+	if (!bus)
+		return;
+
+	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+
+		if (pci_setup_device(dev) < 0) {
+			pci_remove_device(dev);
+			kfree(dev);
+		}
+
+		/* Fix up broken headers */
+		pci_fixup_device(PCI_FIXUP_HEADER, dev);
+	}
+
+	/*
+	 * After performing arch-dependent fixup of the bus, look behind
+	 * all PCI-to-PCI bridges on this bus.
+	 */
+	DBG("Fixups for bus %02x\n", bus->number);
+	pcibios_fixup_bus(bus);
+
+	for (ln = bus->children.next; ln != &bus->children; ln = ln->next)
+		pci_probe_resources(pci_bus_b(ln));
+}
+
 struct pci_bus * __devinit pci_alloc_primary_bus_parented(struct device *parent, int bus)
 {
 	struct pci_bus *b;
@@ -594,6 +650,7 @@ EXPORT_SYMBOL(pci_setup_device);
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_do_scan_bus);
 EXPORT_SYMBOL(pci_scan_slot);
-EXPORT_SYMBOL(pci_scan_bus);
+EXPORT_SYMBOL(pci_scan_bus_parented);
 EXPORT_SYMBOL(pci_scan_bridge);
+EXPORT_SYMBOL(pci_probe_resources);
 #endif
--- 2.5.58/include/linux/pci.h	Fri Jan 10 23:11:51 2003
+++ linux/include/linux/pci.h	Tue Jan 14 14:33:56 2003
@@ -361,6 +361,12 @@ enum pci_mmap_state {
 
 #define PCI_ANY_ID (~0)
 
+/* This defines methods for probing the BARs (dev->probe bits) */
+#define PCI_PROBE_DEFAULT	0
+#define PCI_PROBE_CMD_DISABLED	1
+#define PCI_PROBE_CMD_ENABLED	2
+#define PCI_PROBE_SKIP		3
+
 /*
  * The pci_dev structure is used to describe PCI devices.
  */
@@ -412,7 +418,9 @@ struct pci_dev {
 	char		slot_name[8];	/* slot name */
 
 	/* These fields are used by common fixups */
-	unsigned int	transparent:1;	/* Transparent PCI bridge */
+	unsigned int	transparent:1,	/* Transparent PCI bridge */
+			probe:2;	/* Override default BAR probing
+					   behavior */
 };
 
 #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
@@ -544,11 +552,14 @@ void pcibios_fixup_pbus_ranges(struct pc
 
 /* Generic PCI functions used internally */
 
+void pci_probe_resources(struct pci_bus *bus);
 int pci_bus_exists(const struct list_head *list, int nr);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
 static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
 {
-	return pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	struct pci_bus *pbus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	pci_probe_resources(pbus);
+	return pbus;
 }
 struct pci_bus *pci_alloc_primary_bus_parented(struct device * parent, int bus);
 static inline struct pci_bus *pci_alloc_primary_bus(int bus)
@@ -809,8 +820,11 @@ struct pci_fixup {
 
 extern struct pci_fixup pcibios_fixups[];
 
-#define PCI_FIXUP_HEADER	1		/* Called immediately after reading configuration header */
-#define PCI_FIXUP_FINAL		2		/* Final phase of device fixups */
+#define PCI_FIXUP_EARLY		1	/* Called immediately after reading
+					   device/vendor IDs and class code */
+#define PCI_FIXUP_HEADER	2	/* Called after reading configuration
+					   header (including BARs) */
+#define PCI_FIXUP_FINAL		3	/* Final phase of device fixups */
 
 void pci_fixup_device(int pass, struct pci_dev *dev);
 

  reply	other threads:[~2003-01-14 16:34 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-12-19 21:37 PATCH 2.5.x disable BAR when sizing Grant Grundler
2002-12-20  2:54 ` Alan Cox
2002-12-20  2:27   ` David Mosberger
2002-12-20  6:05     ` Linus Torvalds
2002-12-20 19:50   ` Grant Grundler
2002-12-20 20:14     ` Linus Torvalds
2002-12-20 21:22       ` Grant Grundler
2002-12-21 18:34       ` Maciej W. Rozycki
2002-12-20 20:37     ` Richard B. Johnson
2002-12-20 21:29       ` Grant Grundler
2002-12-20  5:57 ` Linus Torvalds
2002-12-20  9:42   ` David Mosberger
2002-12-20 12:53     ` Ivan Kokshaysky
2002-12-20 17:05     ` Linus Torvalds
2002-12-20 18:26       ` David Mosberger
2002-12-20 19:28         ` Linus Torvalds
2002-12-21 22:06         ` Eric W. Biederman
2002-12-21 22:44           ` Linus Torvalds
2002-12-22  7:15             ` Paul Mackerras
2002-12-22 15:03               ` Benjamin Herrenschmidt
2002-12-22 19:21                 ` Ivan Kokshaysky
2002-12-23  0:29                   ` Paul Mackerras
2002-12-23 15:26                     ` Ivan Kokshaysky
2003-01-05 12:37                     ` [patch 2.5] PCI: allow alternative methods for probing the BARs Ivan Kokshaysky
2003-01-06  0:29                       ` Anton Blanchard
2003-01-06  4:14                       ` Linus Torvalds
2003-01-06  5:22                         ` Eric W. Biederman
2003-01-06 10:31                         ` Benjamin Herrenschmidt
2003-01-06 11:32                           ` Andrew Walrond
2003-01-06 22:01                             ` Grant Grundler
2003-01-06 19:45                           ` Grant Grundler
2003-01-07 17:05                             ` Ivan Kokshaysky
2003-01-07 17:46                               ` Linus Torvalds
2003-01-07 20:17                               ` Grant Grundler
2003-01-08 14:47                                 ` Ivan Kokshaysky
2003-01-08 22:34                                   ` Grant Grundler
2003-01-06 15:33                         ` Ivan Kokshaysky
2003-01-06 21:52                           ` Grant Grundler
2003-01-06 23:19                             ` Linus Torvalds
2003-01-07  0:13                               ` Grant Grundler
2003-01-07 12:33                                 ` Alan Cox
2003-01-07 17:27                                   ` Ivan Kokshaysky
2003-01-07 18:46                                     ` Alan Cox
2003-01-07 17:44                                   ` Linus Torvalds
2003-01-08 16:55                                     ` Ivan Kokshaysky
2003-01-09 17:46                                     ` [patch 2.5] 2-pass PCI probing, generic part Ivan Kokshaysky
2003-01-09 17:52                                       ` Benjamin Herrenschmidt
2003-01-09 22:09                                         ` Ivan Kokshaysky
2003-01-09 22:16                                           ` Linus Torvalds
2003-01-09 22:26                                             ` Benjamin Herrenschmidt
2003-01-10  3:49                                               ` Alan Cox
2003-01-09 23:19                                             ` Ivan Kokshaysky
2003-01-09 23:35                                               ` Linus Torvalds
2003-01-10  1:09                                                 ` Grant Grundler
2003-01-10  7:56                                                   ` Eric W. Biederman
2003-01-10 19:00                                                     ` Grant Grundler
2003-01-10 21:42                                                       ` Ivan Kokshaysky
2003-01-10 23:07                                                         ` Grant Grundler
2003-01-11 19:39                                                         ` Scott Murray
2003-01-12  7:19                                                           ` Greg KH
2003-01-13  6:28                                                             ` Scott Murray
2003-01-10 13:35                                                 ` Ivan Kokshaysky
2003-01-14 16:39                                                   ` Ivan Kokshaysky [this message]
2003-01-09 18:36                                       ` David Mosberger
2003-01-09 19:52                                       ` Grant Grundler
2003-01-09 22:40                                         ` Ivan Kokshaysky
2003-01-09 17:48                                     ` [patch 2.5] 2-pass PCI probing, hotplug changes Ivan Kokshaysky
2003-01-09 17:51                                     ` [patch 2.5] 2-pass PCI probing, i386 USB quirk Ivan Kokshaysky
2003-01-07 17:12                                 ` [patch 2.5] PCI: allow alternative methods for probing the BARs Ivan Kokshaysky
2003-01-07 17:06                             ` Ivan Kokshaysky
2002-12-22 19:51               ` PATCH 2.5.x disable BAR when sizing Linus Torvalds
2002-12-22 19:57                 ` Eric W. Biederman
2002-12-22 10:38             ` Eric W. Biederman
2002-12-22 18:39               ` Ivan Kokshaysky
2002-12-22 19:47                 ` Eric W. Biederman
2002-12-22 21:05                   ` Ivan Kokshaysky
2002-12-20 18:50       ` Ivan Kokshaysky
2002-12-20 19:11         ` Linus Torvalds

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=20030114193957.A1115@jurassic.park.msu.ru \
    --to=ink@jurassic.park.msu.ru \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=benh@kernel.crashing.org \
    --cc=davidm@hpl.hp.com \
    --cc=ebiederm@xmission.com \
    --cc=greg@kroah.com \
    --cc=grundler@cup.hp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulus@samba.org \
    --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®