1*7eb99bdaSLionel Sambuc /* $NetBSD: pci_verbose.c,v 1.8 2011/08/29 14:47:08 jmcneill Exp $ */ 2*7eb99bdaSLionel Sambuc 3*7eb99bdaSLionel Sambuc /* 4*7eb99bdaSLionel Sambuc * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. 5*7eb99bdaSLionel Sambuc * Copyright (c) 1995, 1996, 1998, 2000 6*7eb99bdaSLionel Sambuc * Christopher G. Demetriou. All rights reserved. 7*7eb99bdaSLionel Sambuc * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 8*7eb99bdaSLionel Sambuc * 9*7eb99bdaSLionel Sambuc * Redistribution and use in source and binary forms, with or without 10*7eb99bdaSLionel Sambuc * modification, are permitted provided that the following conditions 11*7eb99bdaSLionel Sambuc * are met: 12*7eb99bdaSLionel Sambuc * 1. Redistributions of source code must retain the above copyright 13*7eb99bdaSLionel Sambuc * notice, this list of conditions and the following disclaimer. 14*7eb99bdaSLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 15*7eb99bdaSLionel Sambuc * notice, this list of conditions and the following disclaimer in the 16*7eb99bdaSLionel Sambuc * documentation and/or other materials provided with the distribution. 17*7eb99bdaSLionel Sambuc * 3. All advertising materials mentioning features or use of this software 18*7eb99bdaSLionel Sambuc * must display the following acknowledgement: 19*7eb99bdaSLionel Sambuc * This product includes software developed by Charles M. Hannum. 20*7eb99bdaSLionel Sambuc * 4. The name of the author may not be used to endorse or promote products 21*7eb99bdaSLionel Sambuc * derived from this software without specific prior written permission. 22*7eb99bdaSLionel Sambuc * 23*7eb99bdaSLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24*7eb99bdaSLionel Sambuc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25*7eb99bdaSLionel Sambuc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26*7eb99bdaSLionel Sambuc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27*7eb99bdaSLionel Sambuc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28*7eb99bdaSLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29*7eb99bdaSLionel Sambuc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30*7eb99bdaSLionel Sambuc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31*7eb99bdaSLionel Sambuc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32*7eb99bdaSLionel Sambuc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33*7eb99bdaSLionel Sambuc */ 34*7eb99bdaSLionel Sambuc 35*7eb99bdaSLionel Sambuc /* 36*7eb99bdaSLionel Sambuc * PCI autoconfiguration support functions. 37*7eb99bdaSLionel Sambuc * 38*7eb99bdaSLionel Sambuc * Note: This file is also built into a userland library (libpci). 39*7eb99bdaSLionel Sambuc * Pay attention to this when you make modifications. 40*7eb99bdaSLionel Sambuc */ 41*7eb99bdaSLionel Sambuc 42*7eb99bdaSLionel Sambuc #include <sys/cdefs.h> 43*7eb99bdaSLionel Sambuc __KERNEL_RCSID(0, "$NetBSD: pci_verbose.c,v 1.8 2011/08/29 14:47:08 jmcneill Exp $"); 44*7eb99bdaSLionel Sambuc 45*7eb99bdaSLionel Sambuc #include <sys/param.h> 46*7eb99bdaSLionel Sambuc 47*7eb99bdaSLionel Sambuc #ifdef _KERNEL 48*7eb99bdaSLionel Sambuc #include <sys/module.h> 49*7eb99bdaSLionel Sambuc #else 50*7eb99bdaSLionel Sambuc #include <pci.h> 51*7eb99bdaSLionel Sambuc #endif 52*7eb99bdaSLionel Sambuc 53*7eb99bdaSLionel Sambuc #include <dev/pci/pcireg.h> 54*7eb99bdaSLionel Sambuc #include <dev/pci/pcidevs.h> 55*7eb99bdaSLionel Sambuc #ifdef _KERNEL 56*7eb99bdaSLionel Sambuc #include <dev/pci/pci_verbose.h> 57*7eb99bdaSLionel Sambuc #endif 58*7eb99bdaSLionel Sambuc 59*7eb99bdaSLionel Sambuc /* 60*7eb99bdaSLionel Sambuc * Descriptions of of known vendors and devices ("products"). 61*7eb99bdaSLionel Sambuc */ 62*7eb99bdaSLionel Sambuc 63*7eb99bdaSLionel Sambuc #include <dev/pci/pcidevs_data.h> 64*7eb99bdaSLionel Sambuc 65*7eb99bdaSLionel Sambuc #ifndef _KERNEL 66*7eb99bdaSLionel Sambuc #include <string.h> 67*7eb99bdaSLionel Sambuc #endif 68*7eb99bdaSLionel Sambuc 69*7eb99bdaSLionel Sambuc #ifdef _KERNEL 70*7eb99bdaSLionel Sambuc static int pciverbose_modcmd(modcmd_t, void *); 71*7eb99bdaSLionel Sambuc 72*7eb99bdaSLionel Sambuc MODULE(MODULE_CLASS_MISC, pciverbose, "pci"); 73*7eb99bdaSLionel Sambuc 74*7eb99bdaSLionel Sambuc static int 75*7eb99bdaSLionel Sambuc pciverbose_modcmd(modcmd_t cmd, void *arg) 76*7eb99bdaSLionel Sambuc { 77*7eb99bdaSLionel Sambuc static const char *(*saved_findvendor)(pcireg_t); 78*7eb99bdaSLionel Sambuc static const char *(*saved_findproduct)(pcireg_t); 79*7eb99bdaSLionel Sambuc static const char *saved_unmatched; 80*7eb99bdaSLionel Sambuc 81*7eb99bdaSLionel Sambuc switch (cmd) { 82*7eb99bdaSLionel Sambuc case MODULE_CMD_INIT: 83*7eb99bdaSLionel Sambuc saved_findvendor = pci_findvendor; 84*7eb99bdaSLionel Sambuc saved_findproduct = pci_findproduct; 85*7eb99bdaSLionel Sambuc saved_unmatched = pci_unmatched; 86*7eb99bdaSLionel Sambuc pci_findvendor = pci_findvendor_real; 87*7eb99bdaSLionel Sambuc pci_findproduct = pci_findproduct_real; 88*7eb99bdaSLionel Sambuc pci_unmatched = "unmatched "; 89*7eb99bdaSLionel Sambuc pciverbose_loaded = 1; 90*7eb99bdaSLionel Sambuc return 0; 91*7eb99bdaSLionel Sambuc case MODULE_CMD_FINI: 92*7eb99bdaSLionel Sambuc pci_findvendor = saved_findvendor; 93*7eb99bdaSLionel Sambuc pci_findproduct = saved_findproduct; 94*7eb99bdaSLionel Sambuc pci_unmatched = saved_unmatched; 95*7eb99bdaSLionel Sambuc pciverbose_loaded = 0; 96*7eb99bdaSLionel Sambuc return 0; 97*7eb99bdaSLionel Sambuc default: 98*7eb99bdaSLionel Sambuc return ENOTTY; 99*7eb99bdaSLionel Sambuc } 100*7eb99bdaSLionel Sambuc } 101*7eb99bdaSLionel Sambuc #endif /* KERNEL */ 102*7eb99bdaSLionel Sambuc 103*7eb99bdaSLionel Sambuc static const char * 104*7eb99bdaSLionel Sambuc pci_untokenstring(const uint16_t *token, char *buf, size_t len) 105*7eb99bdaSLionel Sambuc { 106*7eb99bdaSLionel Sambuc char *cp = buf; 107*7eb99bdaSLionel Sambuc 108*7eb99bdaSLionel Sambuc buf[0] = '\0'; 109*7eb99bdaSLionel Sambuc for (; *token != 0; token++) { 110*7eb99bdaSLionel Sambuc cp = buf + strlcat(buf, pci_words + *token, len - 2); 111*7eb99bdaSLionel Sambuc cp[0] = ' '; 112*7eb99bdaSLionel Sambuc cp[1] = '\0'; 113*7eb99bdaSLionel Sambuc } 114*7eb99bdaSLionel Sambuc *cp = '\0'; 115*7eb99bdaSLionel Sambuc return cp != buf ? buf : NULL; 116*7eb99bdaSLionel Sambuc } 117*7eb99bdaSLionel Sambuc 118*7eb99bdaSLionel Sambuc const char * 119*7eb99bdaSLionel Sambuc pci_findvendor_real(pcireg_t id_reg) 120*7eb99bdaSLionel Sambuc { 121*7eb99bdaSLionel Sambuc static char buf[256]; 122*7eb99bdaSLionel Sambuc pci_vendor_id_t vendor = PCI_VENDOR(id_reg); 123*7eb99bdaSLionel Sambuc size_t n; 124*7eb99bdaSLionel Sambuc 125*7eb99bdaSLionel Sambuc for (n = 0; n < __arraycount(pci_vendors); n++) { 126*7eb99bdaSLionel Sambuc if (pci_vendors[n] == vendor) 127*7eb99bdaSLionel Sambuc return pci_untokenstring(&pci_vendors[n+1], buf, 128*7eb99bdaSLionel Sambuc sizeof(buf)); 129*7eb99bdaSLionel Sambuc 130*7eb99bdaSLionel Sambuc /* Skip Tokens */ 131*7eb99bdaSLionel Sambuc n++; 132*7eb99bdaSLionel Sambuc while (pci_vendors[n] != 0 && n < __arraycount(pci_vendors)) 133*7eb99bdaSLionel Sambuc n++; 134*7eb99bdaSLionel Sambuc } 135*7eb99bdaSLionel Sambuc return (NULL); 136*7eb99bdaSLionel Sambuc } 137*7eb99bdaSLionel Sambuc 138*7eb99bdaSLionel Sambuc const char * 139*7eb99bdaSLionel Sambuc pci_findproduct_real(pcireg_t id_reg) 140*7eb99bdaSLionel Sambuc { 141*7eb99bdaSLionel Sambuc static char buf[256]; 142*7eb99bdaSLionel Sambuc pci_vendor_id_t vendor = PCI_VENDOR(id_reg); 143*7eb99bdaSLionel Sambuc pci_product_id_t product = PCI_PRODUCT(id_reg); 144*7eb99bdaSLionel Sambuc size_t n; 145*7eb99bdaSLionel Sambuc 146*7eb99bdaSLionel Sambuc for (n = 0; n < __arraycount(pci_products); n++) { 147*7eb99bdaSLionel Sambuc if (pci_products[n] == vendor && pci_products[n+1] == product) 148*7eb99bdaSLionel Sambuc return pci_untokenstring(&pci_products[n+2], buf, 149*7eb99bdaSLionel Sambuc sizeof(buf)); 150*7eb99bdaSLionel Sambuc 151*7eb99bdaSLionel Sambuc /* Skip Tokens */ 152*7eb99bdaSLionel Sambuc n += 2; 153*7eb99bdaSLionel Sambuc while (pci_products[n] != 0 && n < __arraycount(pci_products)) 154*7eb99bdaSLionel Sambuc n++; 155*7eb99bdaSLionel Sambuc } 156*7eb99bdaSLionel Sambuc return (NULL); 157*7eb99bdaSLionel Sambuc } 158*7eb99bdaSLionel Sambuc 159