lkml.org 
[lkml]   [1997]   [Sep]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Subject/proc/pcibus patch
Date
From

The included patch introduces the /proc/pcibus directory and the config
selection to turn it on/off. This is the first step in getting the
vendor and device strings out of the kernel and into user land.

The idea of this job is *not* to save kernel memory, as a few people
have been presuming, but to get the PCI list *administration* out of
the kernel. The only use of the kernel list is getting a pretty display
of the installed devices.

I have yet to remove /proc/pci.

So now how 'bout the people who have been administering the pci.c and pci.h
files that have all the vendor strings in them. We need to arrange for a
program in user mode that displays in ascii the contents of the /proc/pcibus
directory.
--
Steve Williams
steve@icarus.com
steve@picturel.com

"The woods are lovely, dark and deep. But I have promises to keep,
And lines to code before I sleep, And lines to code before I sleep."


diff -Ncr -X ../exclude ./Documentation/Configure.help
/usr/src/linux-2.1.55/Documentation/Configure.help
*** ./Documentation/Configure.help Sat Sep 6 10:43:49 1997
--- /usr/src/linux-2.1.55/Documentation/Configure.help Sat Sep 13 11:02:38 1997
***************
*** 4243,4249 ****
trouble if two devices are mistakenly configured to use the same
IRQ). Several programs depend on this, so everyone should say Y
here.
!
NFS filesystem support
CONFIG_NFS_FS
If you are connected to some other (usually local) Unix computer
--- 4243,4256 ----
trouble if two devices are mistakenly configured to use the same
IRQ). Several programs depend on this, so everyone should say Y
here.
!
! /proc/pcibus support
! CONFIG_PROC_PCIBUS
! This adds support for the pcibus directory under /proc. It allows
! the query of the configuration space of all the pci devices on the
! local computer.
!
!
NFS filesystem support
CONFIG_NFS_FS
If you are connected to some other (usually local) Unix computer
diff -Ncr -X ../exclude ./Documentation/pcibus.txt
/usr/src/linux-2.1.55/Documentation/pcibus.txt
*** ./Documentation/pcibus.txt Wed Dec 31 16:00:00 1969
--- /usr/src/linux-2.1.55/Documentation/pcibus.txt Sat Sep 13 16:36:48 1997
***************
*** 0 ****
--- 1,21 ----
+
+ The /proc/pcibus directory provides support for access to the
+ configuration space of installed PCI devices. The directory contains a
+ file for every discovered function unit in the system. The file name
+ is a hex represent of the 16 bits arranged as follows:
+
+ 15 - 8 7 - 3 2 - 0
+ +------------+-----+-----+
+ | BUS Number | dev | fn# |
+ +------------+-----+-----+
+
+ The numbers (except for the fn#) are assigned to the slot in a
+ mother-board specific way. The fn# allows for a device to have up to 8
+ distinct functional units.
+
+ Each file contains exactly 256 bytes. This is the official size of the
+ PCI configuration space for a device/function. Reading the bytes gets
+ the contents of the cnfiguration space directly from the
+ hardware. (Writing is currently not supported.) The layout of the
+ configuration space is defined by the ``PCI Local Bus Specification.''
+
diff -Ncr -X ../exclude ./Makefile /usr/src/linux-2.1.55/Makefile
*** ./Makefile Mon Sep 8 21:57:58 1997
--- /usr/src/linux-2.1.55/Makefile Thu Sep 11 16:56:47 1997
***************
*** 11,17 ****
#
# NOTE! SMP is experimental. See the file Documentation/SMP.txt
#
! SMP = 1
#
# SMP profiling options
# SMP_PROF = 1
--- 11,17 ----
#
# NOTE! SMP is experimental. See the file Documentation/SMP.txt
#
! # SMP = 1
#
# SMP profiling options
# SMP_PROF = 1
diff -Ncr -X ../exclude ./fs/Config.in /usr/src/linux-2.1.55/fs/Config.in
*** ./fs/Config.in Sat Aug 16 09:53:08 1997
--- /usr/src/linux-2.1.55/fs/Config.in Sat Sep 13 11:02:16 1997
***************
*** 16,21 ****
--- 16,25 ----
dep_tristate 'umsdos: Unix like fs on top of std MSDOS FAT fs'
CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS

bool '/proc filesystem support' CONFIG_PROC_FS
+ if [ "$CONFIG_PROC_FS" = "y" -a "$CONFIG_PCI" = "y" ]; then
+ bool '/proc/pcibus support' CONFIG_PROC_PCIBUS
+ fi
+
if [ "$CONFIG_INET" = "y" ]; then
tristate 'NFS filesystem support' CONFIG_NFS_FS
if [ "$CONFIG_NFS_FS" = "y" ]; then
diff -Ncr -X ../exclude ./fs/proc/Makefile /usr/src/linux-2.1.55/fs/proc/Makefi
le
*** ./fs/proc/Makefile Sat Aug 16 09:53:08 1997
--- /usr/src/linux-2.1.55/fs/proc/Makefile Sat Sep 13 10:49:03 1997
***************
*** 28,31 ****
--- 28,35 ----
O_OBJS += proc_devtree.o
endif

+ ifeq ($(CONFIG_PROC_PCIBUS),y)
+ O_OBJS += pcibus.o
+ endif
+
include $(TOPDIR)/Rules.make
diff -Ncr -X ../exclude ./fs/proc/pcibus.c /usr/src/linux-2.1.55/fs/proc/pcibus
.c
*** ./fs/proc/pcibus.c Wed Dec 31 16:00:00 1969
--- /usr/src/linux-2.1.55/fs/proc/pcibus.c Sat Sep 13 15:40:31 1997
***************
*** 0 ****
--- 1,151 ----
+ /*
+ * Copyright (c) 1997 Stephen Williams (steve@icarus.com)
+ *
+ * This source code is free software; you can redistribute it
+ * and/or modify it in source code form under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version. In order to redistribute the software in
+ * binary form, you will need a Picture Elements Binary Software
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA
+ */
+
+ /*
+ * The /proc/pcibus directory contains files for all the known PCI
+ * devices. The contents of each file is the configuration space of
+ * the device and can only be read.
+ */
+
+ # include <linux/proc_fs.h>
+ # include <linux/bios32.h>
+ # include <linux/pci.h>
+ # include <linux/malloc.h>
+ # include <linux/init.h>
+ # include <asm/uaccess.h>
+
+ /*
+ * Do the actual read of PCI configuration space. Access only DWORD
+ * values because there are PCI BIOSs out there that cannot properly
+ * do otherwise. Anyhow, there is no real point of doing less on a
+ * 32bit wide bus.
+ *
+ * The device to manipulate is passed as the data pointer, which was
+ * in turn set up by the init function when it created the file inode.
+ */
+ static int pcibus_read(char*page, char **start, off_t off,
+ int cnt, int *eof, void *data)
+ {
+ struct pci_dev*dev = (struct pci_dev*)data;
+ unsigned tpos = off;
+ unsigned long tcnt;
+ unsigned *valp;
+
+ if (tpos >= 256) { *eof = 1; return 0; }
+ if ((tpos + cnt) >= 256) { *eof = 1; cnt = 256 - tpos; }
+
+ tcnt = cnt;
+ if (tpos & 3) {
+ tcnt += tpos & 3;
+ tpos &= ~3;
+ }
+
+ tcnt = (tcnt + 3) & ~3;
+
+ valp = (unsigned*)(page + tpos);
+ while (tcnt) {
+ int rc = pcibios_read_config_dword(dev->bus->number,
+ dev->devfn, tpos,
+ valp);
+ if (rc != PCIBIOS_SUCCESSFUL) {
+ printk("/proc/pcibus: Error %d reading config space.\n", rc);
+ return -EIO;
+ }
+ tcnt -= 4;
+ valp += 1;
+ }
+
+ *start = page + off;
+ return cnt;
+ }
+
+ static struct proc_dir_entry proc_root_pcibus = {
+ 0, /* Get the inode number dynamically */
+ 6, "pcibus",
+ S_IFDIR | S_IRUGO | S_IXUGO,
+ 2,
+ 0, 0,
+ 0,
+ &proc_dir_inode_operations,
+ 0, 0,
+ 0, 0, 0,
+ 0,
+ NULL, NULL };
+
+ static const struct proc_dir_entry proc_root_dev_sample __initdata = {
+ 0, /* Get the inode number dynamically */
+ 4, 0, /* All fine names are 4 characters, filled in later. */
+ S_IFREG | S_IRUGO,
+ 1,
+ 0, 0,
+ 256,
+ NULL,
+ 0, 0,
+ 0, 0, 0,
+ 0,
+ pcibus_read, NULL };
+
+
+ __initfunc(void proc_pcibus_init(void))
+ {
+ struct proc_dir_entry*dev_table = 0;
+ struct pci_dev*dev;
+ struct proc_dir_entry*curp;
+ char*strp;
+ unsigned dev_count;
+
+ if (!pcibios_present()) return;
+
+ proc_register(&proc_root, &proc_root_pcibus);
+
+ /* Count the PCI devices. I need the count to size the various
+ tables following. */
+ dev_count = 0;
+ for (dev = pci_devices ; dev ; dev = dev->next)
+ dev_count += 1;
+
+ if (dev_count == 0) return;
+
+ /* This hack of allocating a single chunk of memory to hold
+ all my stuff is an attempt to reduce the malloc
+ overhead. Anyhow, it does the job with little fuss. */
+ dev_table = kmalloc(dev_count * sizeof(struct proc_dir_entry)
+ + 5 * dev_count, GFP_KERNEL);
+ if (! dev_table) {
+ printk("/proc/pcibios: Not enough memory.\n");
+ return;
+ }
+
+ curp = dev_table;
+ strp = (char*)(dev_table + dev_count);
+
+ for (dev = pci_devices ; dev ; dev = dev->next) {
+ *curp = proc_root_dev_sample;
+ curp->name = strp;
+ curp->data = dev;
+ sprintf(strp, "%02x%02x", dev->bus->number, dev->devfn);
+
+ proc_register(&proc_root_pcibus, curp);
+
+ curp += 1;
+ strp += 5;
+ }
+ }
diff -Ncr -X ../exclude ./fs/proc/root.c /usr/src/linux-2.1.55/fs/proc/root.c
*** ./fs/proc/root.c Sun Sep 7 14:00:24 1997
--- /usr/src/linux-2.1.55/fs/proc/root.c Sat Sep 13 10:51:27 1997
***************
*** 284,289 ****
--- 284,293 ----
extern void openpromfs_init (void);
#endif /* CONFIG_SUN_OPENPROMFS */

+ #ifdef CONFIG_PROC_PCIBUS
+ extern void proc_pcibus_init(void);
+ #endif
+
static int make_inode_number(void)
{
int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
***************
*** 635,640 ****
--- 639,647 ----
#endif
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init();
+ #endif
+ #ifdef CONFIG_PROC_PCIBUS
+ proc_pcibus_init();
#endif
}




\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.060 / U:0.648 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site