patch-2.1.93 linux/drivers/pci/proc.c

Next file: linux/drivers/pci/quirks.c
Previous file: linux/drivers/pci/pcisyms.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.92/linux/drivers/pci/proc.c linux/drivers/pci/proc.c
@@ -1,14 +1,13 @@
 /*
- *	$Id: proc.c,v 1.1 1997/12/22 17:22:31 mj Exp $
+ *	$Id: proc.c,v 1.8 1998/03/12 14:32:51 mj Exp $
  *
  *	Procfs interface for the PCI bus.
  *
- *	Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *	Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
@@ -49,14 +48,27 @@
 	int pos = *ppos;
 	unsigned char bus = dev->bus->number;
 	unsigned char dfn = dev->devfn;
-	int cnt;
+	int cnt, size;
 
-	if (pos >= PCI_CFG_SPACE_SIZE)
+	/*
+	 * Normal users can read only the standardized portion of the
+	 * configuration space as several chips lock up when trying to read
+	 * undefined locations (think of Intel PIIX4 as a typical example).
+	 */
+
+	if (fsuser())
+		size = PCI_CFG_SPACE_SIZE;
+	else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+		size = 128;
+	else
+		size = 64;
+
+	if (pos >= size)
 		return 0;
-	if (nbytes >= PCI_CFG_SPACE_SIZE)
-		nbytes = PCI_CFG_SPACE_SIZE;
-	if (pos + nbytes > PCI_CFG_SPACE_SIZE)
-		nbytes = PCI_CFG_SPACE_SIZE - pos;
+	if (nbytes >= size)
+		nbytes = size;
+	if (pos + nbytes > size)
+		nbytes = size - pos;
 	cnt = nbytes;
 
 	if (!access_ok(VERIFY_WRITE, buf, cnt))
@@ -260,16 +272,9 @@
 	get_pci_dev_info
 };
 
-__initfunc(void proc_bus_pci_init(void))
+__initfunc(void proc_bus_pci_add(struct pci_bus *bus, struct proc_dir_entry *proc_pci))
 {
-	struct proc_dir_entry *proc_pci;
-	struct pci_bus *bus;
-
-	if (!pcibios_present())
-		return;
-	proc_pci = create_proc_entry("pci", S_IFDIR, proc_bus);
-	proc_register(proc_pci, &proc_pci_devices);
-	for(bus = &pci_root; bus; bus = bus->next) {
+	while (bus) {
 		char name[16];
 		struct proc_dir_entry *de;
 		struct pci_dev *dev;
@@ -287,5 +292,19 @@
 			e->data = dev;
 			e->size = PCI_CFG_SPACE_SIZE;
 		}
+		if (bus->children)
+			proc_bus_pci_add(bus->children, proc_pci);
+		bus = bus->next;
 	}
+}
+
+__initfunc(void proc_bus_pci_init(void))
+{
+	struct proc_dir_entry *proc_pci;
+
+	if (!pci_present())
+		return;
+	proc_pci = create_proc_entry("pci", S_IFDIR, proc_bus);
+	proc_register(proc_pci, &proc_pci_devices);
+	proc_bus_pci_add(&pci_root, proc_pci);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov