public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] PCI and PCI Hotplug update for 2.6.6-rc1
Date: Thu, 15 Apr 2004 10:23:45 -0700	[thread overview]
Message-ID: <1082049825923@kroah.com> (raw)
In-Reply-To: <10820498253817@kroah.com>

ChangeSet 1.1692.3.5, 2004/03/26 16:32:52-08:00, willy@debian.org

[PATCH] PCI Hotplug: Rewrite acpiphp detect_used_resource

There are two unrelated problems in acpiphp that are fixed by this patch.
First, acpiphp can be a module, so it is unsafe to probe the BARs of each
device while it initialises -- the device may be active at the time.
Second, it does not know about PCI-PCI bridge registers and so it reads
garbage for the last 4 registers of the PCI-PCI bridge card and doesn't
take into account the ranges that are forwarded by the bridge.

This patch avoids all that by using the struct resources embedded in
the pci_dev.  Note that we no longer need to recurse as all the devices
on the other side of a PCI-PCI bridge have their resources entirely
contained within the PCI-PCI bridge's ranges.


 drivers/pci/hotplug/acpiphp_pci.c |  110 ++++++++------------------------------
 1 files changed, 26 insertions(+), 84 deletions(-)


diff -Nru a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
--- a/drivers/pci/hotplug/acpiphp_pci.c	Thu Apr 15 10:05:40 2004
+++ b/drivers/pci/hotplug/acpiphp_pci.c	Thu Apr 15 10:05:40 2004
@@ -198,106 +198,42 @@
 /* detect_used_resource - subtract resource under dev from bridge */
 static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
 {
-	u32 bar, len;
-	u64 base;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
 	int count;
-	struct pci_resource *res;
 
 	dbg("Device %s\n", pci_name(dev));
 
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
+	for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
+		struct pci_resource *res;
+		struct pci_resource **head;
+		unsigned long base = dev->resource[count].start;
+		unsigned long len = dev->resource[count].end - base + 1;
+		unsigned long flags = dev->resource[count].flags;
 
-		if (!bar)	/* This BAR is not implemented */
+		if (!flags)
 			continue;
 
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
+		dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
+				base + len - 1, flags);
 
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_resource_with_base(&bridge->io_head, base, len);
-			spin_unlock(&bridge->res_lock);
-			if (res)
-				kfree(res);
+		if (flags & IORESOURCE_IO) {
+			head = &bridge->io_head;
+		} else if (flags & IORESOURCE_PREFETCH) {
+			head = &bridge->p_mem_head;
 		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->p_mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			}
+			head = &bridge->mem_head;
 		}
 
-		pci_write_config_dword(dev, address[count], bar);
+		spin_lock(&bridge->res_lock);
+		res = acpiphp_get_resource_with_base(head, base, len);
+		spin_unlock(&bridge->res_lock);
+		if (res)
+			kfree(res);
 	}
 
 	return 0;
 }
 
 
-/* detect_pci_resource_bus - subtract resource under pci_bus */
-static void detect_used_resource_bus(struct acpiphp_bridge *bridge, struct pci_bus *bus)
-{
-	struct list_head *l;
-	struct pci_dev *dev;
-
-	list_for_each (l, &bus->devices) {
-		dev = pci_dev_b(l);
-		detect_used_resource(bridge, dev);
-		/* XXX recursive call */
-		if (dev->subordinate)
-			detect_used_resource_bus(bridge, dev->subordinate);
-	}
-}
-
-
 /**
  * acpiphp_detect_pci_resource - detect resources under bridge
  * @bridge: detect all resources already used under this bridge
@@ -306,7 +242,13 @@
  */
 int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
 {
-	detect_used_resource_bus(bridge, bridge->pci_bus);
+	struct list_head *l;
+	struct pci_dev *dev;
+
+	list_for_each (l, &bridge->pci_bus->devices) {
+		dev = pci_dev_b(l);
+		detect_used_resource(bridge, dev);
+	}
 
 	return 0;
 }


  reply	other threads:[~2004-04-15 17:32 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-15 17:19 [BK PATCH] PCI and PCI Hotplug update for 2.6.6-rc1 Greg KH
2004-04-15 17:23 ` [PATCH] " Greg KH
2004-04-15 17:23   ` Greg KH
2004-04-15 17:23     ` Greg KH
2004-04-15 17:23       ` Greg KH
2004-04-15 17:23         ` Greg KH [this message]
2004-04-15 17:23           ` Greg KH
2004-04-15 17:23             ` Greg KH
2004-04-15 17:23               ` Greg KH
2004-04-15 17:23                 ` Greg KH
2004-04-15 17:23                   ` Greg KH
2004-04-15 17:23                     ` Greg KH
2004-04-15 17:23                       ` 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=1082049825923@kroah.com \
    --to=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    /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