1 --- ./Makefile.orig 2003-01-04 04:53:01.000000000 -0800
2 +++ ./Makefile 2003-02-20 23:22:56.000000000 -0800
7 -all: lib lspci setpci lspci.8 setpci.8 update-pciids update-pciids.8 pci.ids
8 +all: lib lspci setpci pcimodules lspci.8 setpci.8 update-pciids update-pciids.8 pcimodules.8 pci.ids
14 cd lib && ./configure $(SHAREDIR) $(VERSION)
16 +pcimodules: pcimodules.o common.o lib/$(PCILIB)
17 lspci: lspci.o common.o lib/$(PCILIB)
18 setpci: setpci.o common.o lib/$(PCILIB)
20 +pcimodules.o: pcimodules.c pciutils.h
21 lspci.o: lspci.c pciutils.h
22 setpci.o: setpci.c pciutils.h
23 common.o: common.c pciutils.h
26 # -c is ignored on Linux, but required on FreeBSD
27 $(DIRINSTALL) -m 755 $(SBINDIR) $(SHAREDIR) $(MANDIR)/man8
28 - $(INSTALL) -c -m 755 -s lspci setpci $(SBINDIR)
29 + $(INSTALL) -c -m 755 lspci setpci pcimodules $(SBINDIR)
30 $(INSTALL) -c -m 755 update-pciids $(SBINDIR)
31 $(INSTALL) -c -m 644 pci.ids $(SHAREDIR)
32 - $(INSTALL) -c -m 644 lspci.8 setpci.8 update-pciids.8 $(MANDIR)/man8
33 + $(INSTALL) -c -m 644 lspci.8 setpci.8 update-pciids.8 pcimodules.8 $(MANDIR)/man8
36 - rm -f $(SBINDIR)/lspci $(SBINDIR)/setpci $(SBINDIR)/update-pciids
37 + rm -f $(SBINDIR)/lspci $(SBINDIR)/setpci $(SBINDIR)/update-pciids $(SBINDIR)/pcimodules
38 rm -f $(SHAREDIR)/pci.ids
39 - rm -f $(MANDIR)/man8/lspci.8 $(MANDIR)/man8/setpci.8 $(MANDIR)/man8/update-pciids.8
40 + rm -f $(MANDIR)/man8/lspci.8 $(MANDIR)/man8/setpci.8 $(MANDIR)/man8/update-pciids.8 $(MANDIR)/man8/pcimodules.8
43 cp ~/tree/pciids/pci.ids pci.ids
44 --- ./lspci.c.orig 2002-12-26 12:24:50.000000000 -0800
45 +++ ./lspci.c 2003-02-20 23:22:36.000000000 -0800
47 d = xmalloc(sizeof(struct device));
50 - if (!pci_read_block(p, 0, d->config, how_much))
51 - die("Unable to read %d bytes of configuration space.", how_much);
52 + if (!pci_read_block(p, 0, d->config, how_much)) {
53 + fprintf(stderr, "Unable to read %d bytes of configuration space.",
57 if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
59 /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */
60 --- ./pcimodules.c.orig 2003-02-20 23:22:36.000000000 -0800
61 +++ ./pcimodules.c 2003-02-20 23:22:36.000000000 -0800
64 + * pcimodules: Load all kernel modules for PCI device currently
65 + * plugged into any PCI slot.
67 + * Copyright 2000 Yggdrasil Computing, Incorporated
68 + * This file may be copied under the terms and conditions of version
69 + * two of the GNU General Public License, as published by the Free
70 + * Software Foundation (Cambridge, Massachusetts, USA).
72 + * This file is based on pciutils/lib/example.c, which has the following
73 + * authorship and copyright statement:
75 + * Written by Martin Mares and put to public domain. You can do
76 + * with it anything you want, but I don't give you any warranty.
84 +#include <sys/utsname.h>
85 +#include <sys/param.h>
86 +#include <sys/types.h>
91 +#include "pciutils.h"
93 +#define MODDIR "/lib/modules"
94 +#define PCIMAP "modules.pcimap"
96 +#define LINELENGTH 8000
98 +#define DEVICE_ANY 0xffffffff
99 +#define VENDOR_ANY 0xffffffff
101 +#include "lib/pci.h"
103 +struct pcimap_entry {
104 + unsigned int vendor, subsys_vendor, dev, subsys_dev, class, class_mask;
106 + struct pcimap_entry *next;
109 +static struct pcimap_entry *pcimap_list = NULL;
111 +#define OPT_STRING "h"
112 +static struct option long_options[] = {
113 + {"class", required_argument, NULL, 'c'},
114 + {"classmask", required_argument, NULL, 'm'},
115 + {"help", no_argument, NULL, 'h'},
119 +static unsigned long desired_class;
120 +static unsigned long desired_classmask; /* Default is 0: accept all classes.*/
125 + struct utsname utsname;
126 + char filename[MAXPATHLEN];
128 + char line[LINELENGTH];
129 + struct pcimap_entry *entry;
130 + unsigned int driver_data;
131 + char *prevmodule = "";
132 + char module[LINELENGTH];
134 + if (uname(&utsname) < 0) {
138 + sprintf(filename, "%s/%s/%s", MODDIR, utsname.release, PCIMAP);
139 + if ((pcimap_file = fopen(filename, "r")) == NULL) {
144 + while(fgets(line, LINELENGTH, pcimap_file) != NULL) {
145 + if (line[0] == '#')
148 + entry = xmalloc(sizeof(struct pcimap_entry));
150 + if (sscanf(line, "%s 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
152 + &entry->vendor, &entry->dev,
153 + &entry->subsys_vendor, &entry->subsys_dev,
154 + &entry->class, &entry->class_mask,
155 + &driver_data) != 8) {
157 + "modules.pcimap unparsable line: %s.\n", line);
162 + /* Optimize memory allocation a bit, in case someday we
163 + have Linux systems with ~100,000 modules. It also
164 + allows us to just compare pointers to avoid trying
165 + to load a module twice. */
166 + if (strcmp(module, prevmodule) != 0) {
167 + prevmodule = xmalloc(strlen(module)+1);
168 + strcpy(prevmodule, module);
170 + entry->module = prevmodule;
171 + entry->next = pcimap_list;
172 + pcimap_list = entry;
174 + fclose(pcimap_file);
177 +/* Return a filled in pci_access->dev tree, with the device classes
178 + stored in dev->aux.
181 +match_pci_modules(void)
183 + struct pci_access *pacc;
184 + struct pci_dev *dev;
185 + unsigned int class, subsys_dev, subsys_vendor;
186 + struct pcimap_entry *map;
187 + const char *prevmodule = "";
189 + pacc = pci_alloc(); /* Get the pci_access structure */
190 + /* Set all options you want -- here we stick with the defaults */
191 + pci_init(pacc); /* Initialize the PCI library */
192 + pci_scan_bus(pacc); /* We want to get the list of devices */
193 + for(dev=pacc->devices; dev; dev=dev->next) {
194 + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES);
195 + class = (pci_read_word(dev, PCI_CLASS_DEVICE) << 8)
196 + | pci_read_byte(dev, PCI_CLASS_PROG);
197 + subsys_dev = pci_read_word(dev, PCI_SUBSYSTEM_ID);
198 + subsys_vendor = pci_read_word(dev,PCI_SUBSYSTEM_VENDOR_ID);
199 + for(map = pcimap_list; map != NULL; map = map->next) {
200 + if (((map->class ^ class) & map->class_mask) == 0 &&
201 + ((desired_class ^ class) & desired_classmask)==0 &&
202 + (map->dev == DEVICE_ANY ||
203 + map->dev == dev->device_id) &&
204 + (map->vendor == VENDOR_ANY ||
205 + map->vendor == dev->vendor_id) &&
206 + (map->subsys_dev == DEVICE_ANY ||
207 + map->subsys_dev == subsys_dev) &&
208 + (map->subsys_vendor == VENDOR_ANY ||
209 + map->subsys_vendor == subsys_vendor) &&
210 + prevmodule != map->module) {
211 + printf("%s\n", map->module);
212 + prevmodule = map->module;
221 +main (int argc, char **argv)
226 + while ((opt = getopt_long(argc, argv, OPT_STRING, long_options,
227 + &opt_index)) != -1) {
230 + desired_class = strtol(optarg, NULL, 0);
233 + desired_classmask = strtol(optarg, NULL, 0);
236 + printf ("Usage: pcimodules [--help]\n"
237 + " Lists kernel modules corresponding to PCI devices currently plugged"
238 + " into the computer.\n");
243 + match_pci_modules();
246 --- ./pcimodules.man.orig 2003-02-20 23:22:36.000000000 -0800
247 +++ ./pcimodules.man 2003-02-20 23:22:36.000000000 -0800
249 +.TH pcimodules 8 "@TODAY@" "@VERSION@" "Linux PCI Utilities"
252 +pcimodules \- List kernel driver modules available for all currently plugged
256 +.RB [ --class class_id ]
257 +.RB [ --classmask mask ]
261 +lists all driver modules for all currently plugged in PCI devices.
263 +should be run at boot time, and whenever a PCI device is "hot plugged"
264 +into the system. This can be done by the following Bourne shell syntax:
266 + for module in $(pcimodules) ; do
268 + modprobe -s -k "$module"
272 +When a PCI device is removed from the system, the Linux kernel will
273 +decrement a usage count on PCI driver module. If this count drops
274 +to zero (i.e., there are no PCI drivers), then the
276 +process that is normally configured to run from cron every few minutes
277 +will eventually remove the unneeded module.
279 +The --class and --classmask arguments can be used to limit the search
280 +to certain classes of PCI devices. This is useful, for example, to
281 +generate a list of ethernet card drivers to be loaded when the kernel
282 +has indicated that it is trying to resolve an unknown network interface.
284 +Modules are listed in the order in which the PCI devices are physically
285 +arranged so that the computer owner can arrange things like having scsi
286 +device 0 be on a controller that is not alphabetically the first scsi
290 +.B --class class --classmask mask
292 +--class and --classmask limit the search to PCI
293 +cards in particular classes. These arguments are always used together.
294 +The arguments to --class and --classmask
295 +can be given as hexadecimal numbers by prefixing a leading "0x".
296 +Note that the classes used by pcimodules are in "Linux" format,
297 +meaning the class value that you see with lspci would be shifted
298 +left eight bits, with the new low eight bits programming interface ID.
299 +An examples of how to use class and classmask is provided below.
301 +Print a help message and exit.
305 +lists all modules corresponding to currently plugged in PCI devices.
307 +pcimodules --class 0x200000 --classmask 0xffff00
308 +lists all modules corresponding to currently plugged in ethernet PCI devices.
311 +.B /lib/modules/<kernel-version>/modules.pcimap
312 +This file is automatically generated by
316 +to determine which modules correspond to which PCI ID's.
319 +An interface to PCI bus configuration space provided by the post-2.1.82 Linux
320 +kernels. Contains per-bus subdirectories with per-card config space files and a
322 +file containing a list of all PCI devices.
328 +The Linux PCI Utilities are maintained by Martin Mares <mj@suse.cz>.
332 +was written by Adam J. Richter <adam@yggdrasil.com>, based on public
333 +domain example code by Martin Mares <mj@suse.cz>.
337 +is copyright 2000, Yggdrasil Computing, Incorporated, and may
338 +be copied under the terms and conditions of version 2 of the GNU
339 +General Public License as published by the Free Software Foundation
340 +(Cambrige, Massachusetts, United States of America).