Module Name: src Committed By: pgoyette Date: Mon May 24 20:29:41 UTC 2010
Modified Files: src/distrib/sets/lists/modules: mi src/sys/dev/pci: files.pci pci.c pci_subr.c pcivar.h src/sys/modules: Makefile Added Files: src/sys/dev/pci: pci_verbose.c src/sys/modules/pciverbose: Makefile Log Message: Extract the vendor/product tables and related access routines into a separate kernel module. Update pci bus attach routine to load the module (if available) when we're about to start scanning the bus, and unload the module after the scan is finished. On architectures which support loading of modules by the boot loader, the 'pciverbose' module can be loaded and executed without needing to rebuild the kernel. On all architectures, using 'options PCIVERBOSE' in the kernel configuration file will create a 'builtin' module which is functionally equivalent to previous behavior. XXX Although not nearly as large as the vendor and product tables, XXX the PCI class and subclass tables might also be offloaded into XXX the module at a future time. XXX Cardbus (and possibly other) drivers should also be modified to XXX load the module before scanning/attaching devices. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/distrib/sets/lists/modules/mi cvs rdiff -u -r1.328 -r1.329 src/sys/dev/pci/files.pci cvs rdiff -u -r1.127 -r1.128 src/sys/dev/pci/pci.c cvs rdiff -u -r1.79 -r1.80 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r0 -r1.1 src/sys/dev/pci/pci_verbose.c cvs rdiff -u -r1.86 -r1.87 src/sys/dev/pci/pcivar.h cvs rdiff -u -r1.41 -r1.42 src/sys/modules/Makefile cvs rdiff -u -r0 -r1.1 src/sys/modules/pciverbose/Makefile Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/modules/mi diff -u src/distrib/sets/lists/modules/mi:1.13 src/distrib/sets/lists/modules/mi:1.14 --- src/distrib/sets/lists/modules/mi:1.13 Mon Apr 12 14:12:43 2010 +++ src/distrib/sets/lists/modules/mi Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.13 2010/04/12 14:12:43 ahoka Exp $ +# $NetBSD: mi,v 1.14 2010/05/24 20:29:41 pgoyette Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -80,6 +80,8 @@ ./@MODULEDIR@/null/null.kmod base-kernel-modules kmod ./@MODULEDIR@/overlay base-kernel-modules kmod ./@MODULEDIR@/overlay/overlay.kmod base-kernel-modules kmod +./@MODULEDIR@/pciverbose base-kernel-modules kmod +./@MODULEDIR@/pciverbose/pciverbose.kmod base-kernel-modules kmod ./@MODULEDIR@/pf base-kernel-modules kmod ./@MODULEDIR@/pf/pf.kmod base-kernel-modules kmod ./@MODULEDIR@/portal base-obsolete obsolete Index: src/sys/dev/pci/files.pci diff -u src/sys/dev/pci/files.pci:1.328 src/sys/dev/pci/files.pci:1.329 --- src/sys/dev/pci/files.pci:1.328 Thu Apr 1 04:04:11 2010 +++ src/sys/dev/pci/files.pci Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.328 2010/04/01 04:04:11 jakllsch Exp $ +# $NetBSD: files.pci,v 1.329 2010/05/24 20:29:41 pgoyette Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -26,6 +26,8 @@ file dev/pci/pcibusprint.c pcibus +file dev/pci/pci_verbose.c pci & pciverbose + # Cypress 82c693 hyperCache(tm) Stand-Alone PCI Peripheral Controller # with USB. This is a combo chip: # Index: src/sys/dev/pci/pci.c diff -u src/sys/dev/pci/pci.c:1.127 src/sys/dev/pci/pci.c:1.128 --- src/sys/dev/pci/pci.c:1.127 Wed Feb 24 22:38:01 2010 +++ src/sys/dev/pci/pci.c Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: pci.c,v 1.127 2010/02/24 22:38:01 dyoung Exp $ */ +/* $NetBSD: pci.c,v 1.128 2010/05/24 20:29:41 pgoyette Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 @@ -36,12 +36,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.127 2010/02/24 22:38:01 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.128 2010/05/24 20:29:41 pgoyette Exp $"); #include "opt_pci.h" #include <sys/param.h> #include <sys/malloc.h> +#include <sys/module.h> #include <sys/systm.h> #include <sys/device.h> @@ -106,7 +107,12 @@ KASSERT(ifattr && !strcmp(ifattr, "pci")); KASSERT(locators); + pci_verbose_ctl(true); /* Try to load the pciverbose module */ + pci_enumerate_bus(sc, locators, NULL, NULL); + + pci_verbose_ctl(false); /* Now try to unload it */ + return 0; } Index: src/sys/dev/pci/pci_subr.c diff -u src/sys/dev/pci/pci_subr.c:1.79 src/sys/dev/pci/pci_subr.c:1.80 --- src/sys/dev/pci/pci_subr.c:1.79 Thu Mar 4 22:55:20 2010 +++ src/sys/dev/pci/pci_subr.c Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.79 2010/03/04 22:55:20 dyoung Exp $ */ +/* $NetBSD: pci_subr.c,v 1.80 2010/05/24 20:29:41 pgoyette Exp $ */ /* * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.79 2010/03/04 22:55:20 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.80 2010/05/24 20:29:41 pgoyette Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -51,6 +51,7 @@ #ifdef _KERNEL #include <sys/systm.h> #include <sys/intr.h> +#include <sys/module.h> #else #include <pci.h> #include <stdbool.h> @@ -60,9 +61,8 @@ #include <dev/pci/pcireg.h> #ifdef _KERNEL #include <dev/pci/pcivar.h> -#endif -#ifdef PCIVERBOSE -#include <dev/pci/pcidevs.h> +#else +const char *pci_null(pcireg_t); #endif /* @@ -295,78 +295,47 @@ NULL, }, }; -#ifdef PCIVERBOSE +#if defined(_KERNEL) /* - * Descriptions of of known vendors and devices ("products"). + * In kernel, these routines are provided and linked via the + * pciverbose module. */ - -#include <dev/pci/pcidevs_data.h> -#endif /* PCIVERBOSE */ - -#ifdef PCIVERBOSE -#ifndef _KERNEL -#include <string.h> +const char *(*pci_findvendor_vec)(pcireg_t id_reg) = pci_null; +const char *(*pci_findproduct_vec)(pcireg_t id_reg) = pci_null; +const char *pci_unmatched = ""; +#else +/* + * For userland we just set the vectors here. + */ +const char *(*pci_findvendor_vec)(pcireg_t id_reg) = pci_findvendor; +const char *(*pci_findproduct_vec)(pcireg_t id_reg) = pci_findproduct; +const char *pci_unmatched = "unmatched "; #endif -static const char * -pci_untokenstring(const uint16_t *token, char *buf, size_t len) -{ - char *cp = buf; - - buf[0] = '\0'; - for (; *token != 0; token++) { - cp = buf + strlcat(buf, pci_words + *token, len - 2); - cp[0] = ' '; - cp[1] = '\0'; - } - *cp = '\0'; - return cp != buf ? buf : NULL; -} -#endif /* PCIVERBOSE */ const char * -pci_findvendor(pcireg_t id_reg) +pci_null(pcireg_t id_reg) { -#ifdef PCIVERBOSE - static char buf[256]; - pci_vendor_id_t vendor = PCI_VENDOR(id_reg); - size_t n; - - for (n = 0; n < __arraycount(pci_vendors); n++) { - if (pci_vendors[n] == vendor) - return pci_untokenstring(&pci_vendors[n+1], buf, - sizeof(buf)); - - /* Skip Tokens */ - n++; - while (pci_vendors[n] != 0 && n < __arraycount(pci_vendors)) - n++; - } -#endif return (NULL); } -const char * -pci_findproduct(pcireg_t id_reg) +#if defined(_KERNEL) +/* + * Routine to load/unload the pciverbose kernel module as needed + */ +void pci_verbose_ctl(bool load) { -#ifdef PCIVERBOSE - static char buf[256]; - pci_vendor_id_t vendor = PCI_VENDOR(id_reg); - pci_product_id_t product = PCI_PRODUCT(id_reg); - size_t n; - - for (n = 0; n < __arraycount(pci_products); n++) { - if (pci_products[n] == vendor && pci_products[n+1] == product) - return pci_untokenstring(&pci_products[n+2], buf, - sizeof(buf)); - - /* Skip Tokens */ - n += 2; - while (pci_products[n] != 0 && n < __arraycount(pci_products)) - n++; + static int loaded = 0; + + if (load) { + if (loaded++ == 0) + module_load("pciverbose", MODCTL_LOAD_FORCE, NULL, + MODULE_CLASS_MISC); + return; } -#endif - return (NULL); + if (--loaded == 0) + module_unload("pciverbose"); } +#endif void pci_devinfo(pcireg_t id_reg, pcireg_t class_reg, int showclass, char *cp, @@ -378,13 +347,9 @@ pci_subclass_t subclass; pci_interface_t interface; pci_revision_t revision; + const char *unmatched = pci_unmatched; const char *vendor_namep, *product_namep; const struct pci_class *classp, *subclassp; -#ifdef PCIVERBOSE - const char *unmatched = "unknown "; -#else - const char *unmatched = ""; -#endif char *ep; ep = cp + l; @@ -397,8 +362,8 @@ interface = PCI_INTERFACE(class_reg); revision = PCI_REVISION(class_reg); - vendor_namep = pci_findvendor(id_reg); - product_namep = pci_findproduct(id_reg); + vendor_namep = pci_findvendor_vec(id_reg); + product_namep = pci_findproduct_vec(id_reg); classp = pci_class; while (classp->name != NULL) { @@ -474,13 +439,13 @@ pcireg_t rval; rval = regs[o2i(PCI_ID_REG)]; - name = pci_findvendor(rval); + name = pci_findvendor_vec(rval); if (name) printf(" Vendor Name: %s (0x%04x)\n", name, PCI_VENDOR(rval)); else printf(" Vendor ID: 0x%04x\n", PCI_VENDOR(rval)); - name = pci_findproduct(rval); + name = pci_findproduct_vec(rval); if (name) printf(" Device Name: %s (0x%04x)\n", name, PCI_PRODUCT(rval)); Index: src/sys/dev/pci/pcivar.h diff -u src/sys/dev/pci/pcivar.h:1.86 src/sys/dev/pci/pcivar.h:1.87 --- src/sys/dev/pci/pcivar.h:1.86 Wed Apr 28 20:33:52 2010 +++ src/sys/dev/pci/pcivar.h Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: pcivar.h,v 1.86 2010/04/28 20:33:52 dyoung Exp $ */ +/* $NetBSD: pcivar.h,v 1.87 2010/05/24 20:29:41 pgoyette Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -281,6 +281,13 @@ */ const char *pci_findvendor(pcireg_t); const char *pci_findproduct(pcireg_t); +const char *pci_null(pcireg_t); +void pci_verbose_ctl(bool); + +extern const char *(*pci_findvendor_vec)(pcireg_t); +extern const char *(*pci_findproduct_vec)(pcireg_t); +extern const char *pci_unmatched; + int pci_find_device(struct pci_attach_args *pa, int (*match)(struct pci_attach_args *)); int pci_dma64_available(struct pci_attach_args *); Index: src/sys/modules/Makefile diff -u src/sys/modules/Makefile:1.41 src/sys/modules/Makefile:1.42 --- src/sys/modules/Makefile:1.41 Mon Apr 12 14:08:58 2010 +++ src/sys/modules/Makefile Mon May 24 20:29:41 2010 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.41 2010/04/12 14:08:58 ahoka Exp $ +# $NetBSD: Makefile,v 1.42 2010/05/24 20:29:41 pgoyette Exp $ .include <bsd.own.mk> @@ -36,6 +36,7 @@ SUBDIR+= ntfs SUBDIR+= null SUBDIR+= overlay +SUBDIR+= pciverbose SUBDIR+= pf SUBDIR+= ppp_bsdcomp SUBDIR+= ppp_deflate Added files: Index: src/sys/dev/pci/pci_verbose.c diff -u /dev/null src/sys/dev/pci/pci_verbose.c:1.1 --- /dev/null Mon May 24 20:29:41 2010 +++ src/sys/dev/pci/pci_verbose.c Mon May 24 20:29:40 2010 @@ -0,0 +1,155 @@ +/* $NetBSD: pci_verbose.c,v 1.1 2010/05/24 20:29:40 pgoyette Exp $ */ + +/* + * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. + * Copyright (c) 1995, 1996, 1998, 2000 + * Christopher G. Demetriou. All rights reserved. + * Copyright (c) 1994 Charles M. Hannum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Charles M. Hannum. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * PCI autoconfiguration support functions. + * + * Note: This file is also built into a userland library (libpci). + * Pay attention to this when you make modifications. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: pci_verbose.c,v 1.1 2010/05/24 20:29:40 pgoyette Exp $"); + +#ifdef _KERNEL_OPT +#include "opt_pci.h" +#endif + +#include <sys/param.h> + +#ifdef _KERNEL +#include <sys/module.h> +#else +#include <pci.h> +#endif + +#include <dev/pci/pcireg.h> +#ifdef _KERNEL +#include <dev/pci/pcivar.h> +#endif + +#include <dev/pci/pcidevs.h> + +/* + * Descriptions of of known vendors and devices ("products"). + */ + +#include <dev/pci/pcidevs_data.h> + +#ifndef _KERNEL +#include <string.h> +#endif + +#ifdef _KERNEL +static int pciverbose_modcmd(modcmd_t, void *); + +MODULE(MODULE_CLASS_MISC, pciverbose, NULL); + +static int +pciverbose_modcmd(modcmd_t cmd, void *arg) +{ + aprint_normal("%s: cmd %d\n", __func__, cmd); /* XXX */ + switch (cmd) { + case MODULE_CMD_INIT: + pci_findvendor_vec = pci_findvendor; + pci_findproduct_vec = pci_findproduct; + pci_unmatched = "unmatched "; + return 0; + case MODULE_CMD_FINI: + pci_findvendor_vec = pci_null; + pci_findproduct_vec = pci_null; + pci_unmatched = ""; + return 0; + default: + return ENOTTY; + } +} +#endif /* KERNEL */ + +static const char * +pci_untokenstring(const uint16_t *token, char *buf, size_t len) +{ + char *cp = buf; + + buf[0] = '\0'; + for (; *token != 0; token++) { + cp = buf + strlcat(buf, pci_words + *token, len - 2); + cp[0] = ' '; + cp[1] = '\0'; + } + *cp = '\0'; + return cp != buf ? buf : NULL; +} + +const char * +pci_findvendor(pcireg_t id_reg) +{ + static char buf[256]; + pci_vendor_id_t vendor = PCI_VENDOR(id_reg); + size_t n; + + for (n = 0; n < __arraycount(pci_vendors); n++) { + if (pci_vendors[n] == vendor) + return pci_untokenstring(&pci_vendors[n+1], buf, + sizeof(buf)); + + /* Skip Tokens */ + n++; + while (pci_vendors[n] != 0 && n < __arraycount(pci_vendors)) + n++; + } + return (NULL); +} + +const char * +pci_findproduct(pcireg_t id_reg) +{ + static char buf[256]; + pci_vendor_id_t vendor = PCI_VENDOR(id_reg); + pci_product_id_t product = PCI_PRODUCT(id_reg); + size_t n; + + for (n = 0; n < __arraycount(pci_products); n++) { + if (pci_products[n] == vendor && pci_products[n+1] == product) + return pci_untokenstring(&pci_products[n+2], buf, + sizeof(buf)); + + /* Skip Tokens */ + n += 2; + while (pci_products[n] != 0 && n < __arraycount(pci_products)) + n++; + } + return (NULL); +} + Index: src/sys/modules/pciverbose/Makefile diff -u /dev/null src/sys/modules/pciverbose/Makefile:1.1 --- /dev/null Mon May 24 20:29:41 2010 +++ src/sys/modules/pciverbose/Makefile Mon May 24 20:29:41 2010 @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.1 2010/05/24 20:29:41 pgoyette Exp $ + +.include "../Makefile.inc" + +KMOD= pciverbose + +.PATH: ${S}/dev/pci +SRCS= pci_verbose.c + +.include <bsd.kmodule.mk>