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>

Reply via email to