root/dev/pci/pci_subr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pci_findvendor
  2. pci_findproduct
  3. pci_devinfo

    1 /*      $OpenBSD: pci_subr.c,v 1.21 2007/02/21 13:08:22 dlg Exp $       */
    2 /*      $NetBSD: pci_subr.c,v 1.19 1996/10/13 01:38:29 christos Exp $   */
    3 
    4 /*
    5  * Copyright (c) 1995, 1996 Christopher G. Demetriou.  All rights reserved.
    6  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Charles Hannum.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  * PCI autoconfiguration support functions.
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/device.h>
   41 
   42 #include <dev/pci/pcireg.h>
   43 #include <dev/pci/pcivar.h>
   44 #ifdef PCIVERBOSE
   45 #include <dev/pci/pcidevs.h>
   46 #include <dev/pci/pcidevs_data.h>
   47 #endif
   48 
   49 /*
   50  * Descriptions of known PCI classes and subclasses.
   51  *
   52  * Subclasses are described in the same way as classes, but have a
   53  * NULL subclass pointer.
   54  */
   55 struct pci_class {
   56         const char      *name;
   57         int             val;            /* as wide as pci_{,sub}class_t */
   58         const struct pci_class *subclasses;
   59 };
   60 
   61 const struct pci_class pci_subclass_prehistoric[] = {
   62         { "miscellaneous",      PCI_SUBCLASS_PREHISTORIC_MISC,          },
   63         { "VGA",                PCI_SUBCLASS_PREHISTORIC_VGA,           },
   64         { 0 }
   65 };
   66 
   67 const struct pci_class pci_subclass_mass_storage[] = {
   68         { "SCSI",               PCI_SUBCLASS_MASS_STORAGE_SCSI,         },
   69         { "IDE",                PCI_SUBCLASS_MASS_STORAGE_IDE,          },
   70         { "floppy",             PCI_SUBCLASS_MASS_STORAGE_FLOPPY,       },
   71         { "IPI",                PCI_SUBCLASS_MASS_STORAGE_IPI,          },
   72         { "RAID",               PCI_SUBCLASS_MASS_STORAGE_RAID,         },
   73         { "ATA",                PCI_SUBCLASS_MASS_STORAGE_ATA,          },
   74         { "SATA",               PCI_SUBCLASS_MASS_STORAGE_SATA,         },
   75         { "SAS",                PCI_SUBCLASS_MASS_STORAGE_SAS,          },
   76         { "miscellaneous",      PCI_SUBCLASS_MASS_STORAGE_MISC,         },
   77         { 0 },
   78 };
   79 
   80 const struct pci_class pci_subclass_network[] = {
   81         { "ethernet",           PCI_SUBCLASS_NETWORK_ETHERNET,          },
   82         { "token ring",         PCI_SUBCLASS_NETWORK_TOKENRING,         },
   83         { "FDDI",               PCI_SUBCLASS_NETWORK_FDDI,              },
   84         { "ATM",                PCI_SUBCLASS_NETWORK_ATM,               },
   85         { "ISDN",               PCI_SUBCLASS_NETWORK_ISDN,              },
   86         { "WorldFip",           PCI_SUBCLASS_NETWORK_WORLDFIP,          },
   87         { "PCMIG Multi Computing", PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP, },
   88         { "miscellaneous",      PCI_SUBCLASS_NETWORK_MISC,              },
   89         { 0 },
   90 };
   91 
   92 const struct pci_class pci_subclass_display[] = {
   93         { "VGA",                PCI_SUBCLASS_DISPLAY_VGA,               },
   94         { "XGA",                PCI_SUBCLASS_DISPLAY_XGA,               },
   95         { "3D",                 PCI_SUBCLASS_DISPLAY_3D,                },
   96         { "miscellaneous",      PCI_SUBCLASS_DISPLAY_MISC,              },
   97         { 0 },
   98 };
   99 
  100 const struct pci_class pci_subclass_multimedia[] = {
  101         { "video",              PCI_SUBCLASS_MULTIMEDIA_VIDEO,          },
  102         { "audio",              PCI_SUBCLASS_MULTIMEDIA_AUDIO,          },
  103         { "telephony",          PCI_SUBCLASS_MULTIMEDIA_TELEPHONY,      },
  104         { "hdaudio",            PCI_SUBCLASS_MULTIMEDIA_HDAUDIO,        },
  105         { "miscellaneous",      PCI_SUBCLASS_MULTIMEDIA_MISC,           },
  106         { 0 },
  107 };
  108 
  109 const struct pci_class pci_subclass_memory[] = {
  110         { "RAM",                PCI_SUBCLASS_MEMORY_RAM,                },
  111         { "flash",              PCI_SUBCLASS_MEMORY_FLASH,              },
  112         { "miscellaneous",      PCI_SUBCLASS_MEMORY_MISC,               },
  113         { 0 },
  114 };
  115 
  116 const struct pci_class pci_subclass_bridge[] = {
  117         { "host",               PCI_SUBCLASS_BRIDGE_HOST,               },
  118         { "ISA",                PCI_SUBCLASS_BRIDGE_ISA,                },
  119         { "EISA",               PCI_SUBCLASS_BRIDGE_EISA,               },
  120         { "MicroChannel",       PCI_SUBCLASS_BRIDGE_MC,                 },
  121         { "PCI",                PCI_SUBCLASS_BRIDGE_PCI,                },
  122         { "PCMCIA",             PCI_SUBCLASS_BRIDGE_PCMCIA,             },
  123         { "NuBus",              PCI_SUBCLASS_BRIDGE_NUBUS,              },
  124         { "CardBus",            PCI_SUBCLASS_BRIDGE_CARDBUS,            },
  125         { "RACEway",            PCI_SUBCLASS_BRIDGE_RACEWAY,            },
  126         { "Semi-transparent PCI", PCI_SUBCLASS_BRIDGE_STPCI,            },
  127         { "InfiniBand",         PCI_SUBCLASS_BRIDGE_INFINIBAND,         },
  128         { "miscellaneous",      PCI_SUBCLASS_BRIDGE_MISC,               },
  129         { 0 },
  130 };
  131 
  132 const struct pci_class pci_subclass_communications[] = {
  133         { "serial",             PCI_SUBCLASS_COMMUNICATIONS_SERIAL,     },
  134         { "parallel",           PCI_SUBCLASS_COMMUNICATIONS_PARALLEL,   },
  135         { "multi-port serial",  PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL,   },
  136         { "modem",              PCI_SUBCLASS_COMMUNICATIONS_MODEM,      },
  137         { "GPIB",               PCI_SUBCLASS_COMMUNICATIONS_GPIB,       },
  138         { "smartcard",          PCI_SUBCLASS_COMMUNICATIONS_SMARTCARD,  },
  139         { "miscellaneous",      PCI_SUBCLASS_COMMUNICATIONS_MISC,       },
  140         { 0 },
  141 };
  142 
  143 const struct pci_class pci_subclass_system[] = {
  144         { "interrupt",          PCI_SUBCLASS_SYSTEM_PIC,                },
  145         { "8237 DMA",           PCI_SUBCLASS_SYSTEM_DMA,                },
  146         { "8254 timer",         PCI_SUBCLASS_SYSTEM_TIMER,              },
  147         { "RTC",                PCI_SUBCLASS_SYSTEM_RTC,                },
  148         { "PCI Hot-Plug",       PCI_SUBCLASS_SYSTEM_PCIHOTPLUG,         },
  149         { "SD Host Controller", PCI_SUBCLASS_SYSTEM_SDHC,               },
  150         { "miscellaneous",      PCI_SUBCLASS_SYSTEM_MISC,               },
  151         { 0 },
  152 };
  153 
  154 const struct pci_class pci_subclass_input[] = {
  155         { "keyboard",           PCI_SUBCLASS_INPUT_KEYBOARD,            },
  156         { "digitizer",          PCI_SUBCLASS_INPUT_DIGITIZER,           },
  157         { "mouse",              PCI_SUBCLASS_INPUT_MOUSE,               },
  158         { "scanner",            PCI_SUBCLASS_INPUT_SCANNER,             },
  159         { "game port",          PCI_SUBCLASS_INPUT_GAMEPORT,            },
  160         { "miscellaneous",      PCI_SUBCLASS_INPUT_MISC,                },
  161         { 0 },
  162 };
  163 
  164 const struct pci_class pci_subclass_dock[] = {
  165         { "generic",            PCI_SUBCLASS_DOCK_GENERIC,              },
  166         { "miscellaneous",      PCI_SUBCLASS_DOCK_MISC,                 },
  167         { 0 },
  168 };
  169 
  170 const struct pci_class pci_subclass_processor[] = {
  171         { "386",                PCI_SUBCLASS_PROCESSOR_386,             },
  172         { "486",                PCI_SUBCLASS_PROCESSOR_486,             },
  173         { "Pentium",            PCI_SUBCLASS_PROCESSOR_PENTIUM,         },
  174         { "Alpha",              PCI_SUBCLASS_PROCESSOR_ALPHA,           },
  175         { "PowerPC",            PCI_SUBCLASS_PROCESSOR_POWERPC,         },
  176         { "MIPS",               PCI_SUBCLASS_PROCESSOR_MIPS,            },
  177         { "Co-processor",       PCI_SUBCLASS_PROCESSOR_COPROC,          },
  178         { 0 },
  179 };
  180 
  181 const struct pci_class pci_subclass_serialbus[] = {
  182         { "Firewire",           PCI_SUBCLASS_SERIALBUS_FIREWIRE,        },
  183         { "ACCESS.bus",         PCI_SUBCLASS_SERIALBUS_ACCESS,          },
  184         { "SSA",                PCI_SUBCLASS_SERIALBUS_SSA,             },
  185         { "USB",                PCI_SUBCLASS_SERIALBUS_USB,             },
  186         /* XXX Fiber Channel/_FIBRECHANNEL */
  187         { "Fiber Channel",      PCI_SUBCLASS_SERIALBUS_FIBER,           },
  188         { "SMBus",              PCI_SUBCLASS_SERIALBUS_SMBUS,           },
  189         { "InfiniBand",         PCI_SUBCLASS_SERIALBUS_INFINIBAND,      },
  190         { "IPMI",               PCI_SUBCLASS_SERIALBUS_IPMI,            },
  191         { "SERCOS",             PCI_SUBCLASS_SERIALBUS_SERCOS,          },
  192         { "CANbus",             PCI_SUBCLASS_SERIALBUS_CANBUS,          },
  193         { 0 },
  194 };
  195 
  196 const struct pci_class pci_subclass_wireless[] = {
  197         { "IrDA",               PCI_SUBCLASS_WIRELESS_IRDA,             },
  198         { "Consumer IR",        PCI_SUBCLASS_WIRELESS_CONSUMERIR,       },
  199         { "RF",                 PCI_SUBCLASS_WIRELESS_RF,               },
  200         { "bluetooth",          PCI_SUBCLASS_WIRELESS_BLUETOOTH,        },
  201         { "broadband",          PCI_SUBCLASS_WIRELESS_BROADBAND,        },
  202         { "802.11a (5 GHz)",    PCI_SUBCLASS_WIRELESS_802_11A,          },
  203         { "802.11b (2.4 GHz)",  PCI_SUBCLASS_WIRELESS_802_11B,          },
  204         { "miscellaneous",      PCI_SUBCLASS_WIRELESS_MISC,             },
  205         { 0 },
  206 };
  207 
  208 const struct pci_class pci_subclass_i2o[] = {
  209         { "standard",           PCI_SUBCLASS_I2O_STANDARD,              },
  210         { 0 },
  211 };
  212 
  213 const struct pci_class pci_subclass_satcom[] = {
  214         { "TV",                 PCI_SUBCLASS_SATCOM_TV,                 },
  215         { "audio",              PCI_SUBCLASS_SATCOM_AUDIO,              },
  216         { "voice",              PCI_SUBCLASS_SATCOM_VOICE,              },
  217         { "data",               PCI_SUBCLASS_SATCOM_DATA,               },
  218         { 0 },
  219 };
  220 
  221 const struct pci_class pci_subclass_crypto[] = {
  222         { "network/computing",  PCI_SUBCLASS_CRYPTO_NETCOMP,            },
  223         { "entertainment",      PCI_SUBCLASS_CRYPTO_ENTERTAINMENT,      },
  224         { "miscellaneous",      PCI_SUBCLASS_CRYPTO_MISC,               },
  225         { 0 },
  226 };
  227 
  228 const struct pci_class pci_subclass_dasp[] = {
  229         { "DPIO",               PCI_SUBCLASS_DASP_DPIO,                 },
  230         { "Time and Frequency", PCI_SUBCLASS_DASP_TIMEFREQ,             },
  231         { "synchronization",    PCI_SUBCLASS_DASP_SYNC,                 },
  232         { "management",         PCI_SUBCLASS_DASP_MGMT,                 },
  233         { "miscellaneous",      PCI_SUBCLASS_DASP_MISC,                 },
  234         { 0 },
  235 };
  236 
  237 const struct pci_class pci_class[] = {
  238         { "prehistoric",        PCI_CLASS_PREHISTORIC,
  239             pci_subclass_prehistoric,                           },
  240         { "mass storage",       PCI_CLASS_MASS_STORAGE,
  241             pci_subclass_mass_storage,                          },
  242         { "network",            PCI_CLASS_NETWORK,
  243             pci_subclass_network,                               },
  244         { "display",            PCI_CLASS_DISPLAY,
  245             pci_subclass_display,                               },
  246         { "multimedia",         PCI_CLASS_MULTIMEDIA,
  247             pci_subclass_multimedia,                            },
  248         { "memory",             PCI_CLASS_MEMORY,
  249             pci_subclass_memory,                                },
  250         { "bridge",             PCI_CLASS_BRIDGE,
  251             pci_subclass_bridge,                                },
  252         { "communications",     PCI_CLASS_COMMUNICATIONS,
  253             pci_subclass_communications,                        },
  254         { "system",             PCI_CLASS_SYSTEM,
  255             pci_subclass_system,                                },
  256         { "input",              PCI_CLASS_INPUT,
  257             pci_subclass_input,                                 },
  258         { "dock",               PCI_CLASS_DOCK,
  259             pci_subclass_dock,                                  },
  260         { "processor",          PCI_CLASS_PROCESSOR,
  261             pci_subclass_processor,                             },
  262         { "serial bus",         PCI_CLASS_SERIALBUS,
  263             pci_subclass_serialbus,                             },
  264         { "wireless",           PCI_CLASS_WIRELESS,
  265             pci_subclass_wireless,                              },
  266         { "I2O",                PCI_CLASS_I2O,
  267             pci_subclass_i2o,                                   },
  268         { "satellite comm",     PCI_CLASS_SATCOM,
  269             pci_subclass_satcom,                                },
  270         { "crypto",             PCI_CLASS_CRYPTO,
  271             pci_subclass_crypto,                                },
  272         { "DASP",               PCI_CLASS_DASP,
  273             pci_subclass_dasp,                                  },
  274         { "undefined",          PCI_CLASS_UNDEFINED,
  275             0,                                                  },
  276         { 0 },
  277 };
  278 
  279 const char *
  280 pci_findvendor(pcireg_t id_reg)
  281 {
  282 #ifdef PCIVERBOSE
  283         pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
  284         const struct pci_known_vendor *kdp;
  285 
  286         kdp = pci_known_vendors;
  287         while (kdp->vendorname != NULL) {       /* all have vendor name */
  288                 if (kdp->vendor == vendor)
  289                         break;
  290                 kdp++;
  291         }
  292         return (kdp->vendorname);
  293 #else
  294         return (NULL);
  295 #endif
  296 }
  297 
  298 const char *
  299 pci_findproduct(pcireg_t id_reg)
  300 {
  301 #ifdef PCIVERBOSE
  302         pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
  303         pci_product_id_t product = PCI_PRODUCT(id_reg);
  304         const struct pci_known_product *pkp;
  305 
  306         pkp = pci_known_products;
  307         while (pkp->productname != NULL) {      /* all have product name */
  308                 if (pkp->vendor == vendor && pkp->product == product)
  309                         break;
  310                 pkp++;
  311         }
  312         return (pkp->productname);
  313 #else
  314         return NULL;
  315 #endif
  316 }
  317 
  318 void
  319 pci_devinfo(pcireg_t id_reg, pcireg_t class_reg, int showclass, char *cp,
  320             size_t cp_max)
  321 {
  322         pci_vendor_id_t vendor;
  323         pci_product_id_t product;
  324         pci_class_t class;
  325         pci_subclass_t subclass;
  326         pci_interface_t interface;
  327         pci_revision_t revision;
  328         const char *vendor_namep = NULL, *product_namep = NULL;
  329         const struct pci_class *classp, *subclassp;
  330         size_t cp_len = 0;
  331 #ifdef PCIVERBOSE
  332         const char *unmatched = "unknown ";
  333 #else
  334         const char *unmatched = "";
  335 #endif
  336 
  337         vendor = PCI_VENDOR(id_reg);
  338         product = PCI_PRODUCT(id_reg);
  339 
  340         class = PCI_CLASS(class_reg);
  341         subclass = PCI_SUBCLASS(class_reg);
  342         interface = PCI_INTERFACE(class_reg);
  343         revision = PCI_REVISION(class_reg);
  344 
  345 #ifdef PCIVERBOSE
  346         vendor_namep = pci_findvendor(id_reg);
  347         if (vendor_namep != NULL)
  348                 product_namep = pci_findproduct(id_reg);
  349 #endif /* PCIVERBOSE */
  350 
  351         classp = pci_class;
  352         while (classp->name != NULL) {
  353                 if (class == classp->val)
  354                         break;
  355                 classp++;
  356         }
  357 
  358         subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
  359         while (subclassp && subclassp->name != NULL) {
  360                 if (subclass == subclassp->val)
  361                         break;
  362                 subclassp++;
  363         }
  364 
  365         if (vendor_namep == NULL)
  366                 snprintf(cp, cp_max, "%svendor 0x%04x product 0x%04x",
  367                     unmatched, vendor, product);
  368         else if (product_namep != NULL)
  369                 snprintf(cp, cp_max, "\"%s %s\"", vendor_namep, product_namep);
  370         else
  371                 snprintf(cp, cp_max, "vendor \"%s\", unknown product 0x%04x",
  372                     vendor_namep, product);
  373         if (showclass && product_namep == NULL) {
  374                 strlcat(cp, " (", cp_max);
  375                 cp_len = strlen(cp);
  376                 if (classp->name == NULL)
  377                         snprintf(cp + cp_len, cp_max - cp_len,
  378                             "unknown class 0x%02x, subclass 0x%02x",
  379                             class, subclass);
  380                 else if (subclassp == NULL || subclassp->name == NULL)
  381                         snprintf(cp + cp_len, cp_max - cp_len,
  382                             "class %s unknown subclass 0x%02x", classp->name,
  383                             subclass);
  384                 else
  385                         snprintf(cp + cp_len, cp_max - cp_len,
  386                             "class %s subclass %s", classp->name,
  387                             subclassp->name);
  388 #if 0 /* not very useful */
  389                 cp_len = strlen(cp);
  390                 snprintf(cp + cp_len, cp_max - cp_len,
  391                     ", interface 0x%02x", interface);
  392 #endif
  393                 cp_len = strlen(cp);
  394                 snprintf(cp + cp_len, cp_max - cp_len,
  395                     ", rev 0x%02x)", revision);
  396         } else {
  397                 cp_len = strlen(cp);
  398                 snprintf(cp + cp_len, cp_max - cp_len, " rev 0x%02x",
  399                     revision);
  400         }
  401 }

/* [<][>][^][v][top][bottom][index][help] */