[BACK]Return to pci_subr.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/pci_subr.c, Revision 1.1

1.1     ! nbrk        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: }

CVSweb