Linus?
Have you left the office yet? ;-)
PCI probing in drivers really sucks. The attached patch against 2.3.18
is small, self-contained, and should be incredibly valuable to PCI
driver writers. I myself have duplicated this code in no less than
_four_ drivers.
My patch adds a PCI probing function which takes an array of PCI ids
(typically __initdata tables in a driver), and probes for each in turn.
It calls a callback function to do the actual registration work. The
architecture is very flexible, and should be useful to most people
supporting drivers with more than one chipset, or more than one board.
Can we sneak this small, totally-zero-impact, easy-to-review, tested
patch in? ;-)
Regards,
Jeff
-- Custom driver development | Never worry about theory as long Open source programming | as the machinery does what it's | supposed to do. -- R. A. Heinlein --------------BE8D44F8C9555BB8F8EA530E Content-Type: text/plain; charset=us-ascii; name="patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch"--- include/linux/pci.h.orig Fri Sep 10 18:04:27 1999 +++ include/linux/pci.h Fri Sep 10 18:23:33 1999 @@ -1598,5 +1598,24 @@ void pci_fixup_device(int pass, struct pci_dev *dev); + +/* + * semi-automated pci probing for drivers + * + * callback should return >= 0 on success (continue probing), or + * negative value on error (stop probing) + */ +struct pci_probe_entry { + void *drvr_data; + unsigned short vendor; + unsigned short device; +}; +typedef int (*pci_probe_callback) (struct pci_dev *dev, int match_num, + void *drvr_data); +int pci_driver_probe (struct pci_probe_entry *list, size_t list_len, + int one_match_only, pci_probe_callback cb, + void *drvr_data); + + #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */ --- drivers/pci/pci.c.orig Fri Sep 10 18:04:40 1999 +++ drivers/pci/pci.c Fri Sep 10 18:22:34 1999 @@ -114,6 +114,51 @@ /* + * pci_driver_probe + * + * Probe for a list of PCI ids, calling a callback function for + * each successful match. + * + * Returns number of matches (>= 0), or negative on error. + */ + +int pci_driver_probe (struct pci_probe_entry *list, size_t list_len, + int one_match_only, pci_probe_callback cb, + void *drvr_data) +{ + size_t i, matches = 0; + int rc; + struct pci_dev *dev; + struct pci_probe_entry *ent; + + if (!list || !cb) + return -1; + + ent = list; + for (i = 0; i < list_len; i++) { + dev = pci_find_device (ent->vendor, ent->device, NULL); + while (dev) { + rc = (* cb) (dev, matches, drvr_data); + if (rc < 0) + return rc; + + if (one_match_only && matches) + return matches; + + matches++; + dev = pci_find_device (ent->vendor, ent->device, dev); + } + + ent++; + } + + return matches; +} + + + + +/* * For given resource region of given device, return the resource * region of parent bus the given region is contained in or where * it should be allocated from.
--------------BE8D44F8C9555BB8F8EA530E--
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/