[BACK]Return to pci_subr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci

Annotation of src/sys/dev/pci/pci_subr.c, Revision 1.13

1.13    ! cgd         1: /*     $NetBSD: pci_subr.c,v 1.12 1995/08/16 04:54:50 cgd Exp $        */
1.3       cgd         2:
1.1       mycroft     3: /*
1.13    ! cgd         4:  * Copyright (c) 1995, 1996 Christopher G. Demetriou.  All rights reserved.
1.1       mycroft     5:  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Charles Hannum.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
1.10      cgd        34:  * PCI autoconfiguration support functions.
1.1       mycroft    35:  */
                     36:
                     37: #include <sys/param.h>
1.10      cgd        38: #include <sys/systm.h>
1.1       mycroft    39: #include <sys/device.h>
                     40:
1.10      cgd        41: #include <dev/pci/pcireg.h>
1.7       cgd        42: #include <dev/pci/pcivar.h>
1.10      cgd        43: #ifdef PCIVERBOSE
                     44: #include <dev/pci/pcidevs.h>
                     45: #endif
1.1       mycroft    46:
                     47: int
                     48: pciprint(aux, pci)
                     49:        void *aux;
                     50:        char *pci;
                     51: {
                     52:        register struct pci_attach_args *pa = aux;
                     53:
1.6       mycroft    54:        printf(" bus %d device %d", pa->pa_bus, pa->pa_device);
                     55:        return (UNCONF);
                     56: }
                     57:
                     58: int
                     59: pcisubmatch(parent, match, aux)
                     60:        struct device *parent;
                     61:        void *match, *aux;
                     62: {
                     63:        struct cfdata *cf = match;
                     64:        struct pci_attach_args *pa = aux;
                     65:
                     66:        if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != pa->pa_bus)
                     67:                return 0;
                     68:        if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != pa->pa_device)
                     69:                return 0;
                     70:        return ((*cf->cf_driver->cd_match)(parent, match, aux));
1.1       mycroft    71: }
                     72:
1.8       cgd        73: /*
                     74:  * Try to find and attach the PCI device at the give bus and device number.
                     75:  * Return 1 if successful, 0 if unsuccessful.
                     76:  */
                     77: int
                     78: pci_attach_subdev(pcidev, bus, device)
1.10      cgd        79:        struct device *pcidev;
                     80:        int bus, device;
1.1       mycroft    81: {
1.8       cgd        82:        pcitag_t tag;
                     83:        pcireg_t id, class;
                     84:        struct pci_attach_args pa;
                     85:        struct cfdata *cf;
1.10      cgd        86:        int supported;
                     87:        char devinfo[256];
1.8       cgd        88:
                     89:        tag = pci_make_tag(bus, device, 0);
                     90:        id = pci_conf_read(tag, PCI_ID_REG);
                     91:        if (id == 0 || id == 0xffffffff)
                     92:                return (0);
                     93:        class = pci_conf_read(tag, PCI_CLASS_REG);
                     94:
                     95:        pa.pa_bus = bus;
                     96:        pa.pa_device = device;
                     97:        pa.pa_tag = tag;
                     98:        pa.pa_id = id;
                     99:        pa.pa_class = class;
                    100:
1.10      cgd       101: #if defined(PCIVERBOSE) && 0 /* _too_ verbose */
                    102:        pci_devinfo(id, class, devinfo, NULL);
                    103:        printf("%s bus %d device %d: %s\n", pcidev->dv_xname, bus,
                    104:            device, devinfo);
                    105: #endif /* _too_ verbose */
                    106:
1.8       cgd       107:        if ((cf = config_search(pcisubmatch, pcidev, &pa)) != NULL)
                    108:                config_attach(pcidev, cf, &pa, pciprint);
                    109:        else {
1.13    ! cgd       110:                pci_devinfo(id, class, 1, devinfo);
        !           111:                printf("%s bus %d device %d: %s not configured\n",
        !           112:                    pcidev->dv_xname, bus, device, devinfo);
1.8       cgd       113:                return (0);
                    114:        }
1.1       mycroft   115:
1.8       cgd       116:        return (1);
1.10      cgd       117: }
                    118:
                    119: /*
                    120:  * Descriptions of known PCI classes and subclasses.
                    121:  *
                    122:  * Subclasses are described in the same way as classes, but have a
                    123:  * NULL subclass pointer.
                    124:  */
                    125: struct pci_class {
                    126:        char            *name;
                    127:        int             val;            /* as wide as pci_{,sub}class_t */
                    128:        struct pci_class *subclasses;
                    129: };
                    130:
                    131: struct pci_class pci_subclass_prehistoric[] = {
                    132:        { "miscellaneous",      PCI_SUBCLASS_PREHISTORIC_MISC,          },
                    133:        { "VGA",                PCI_SUBCLASS_PREHISTORIC_VGA,           },
                    134:        { 0 }
                    135: };
                    136:
                    137: struct pci_class pci_subclass_mass_storage[] = {
                    138:        { "SCSI",               PCI_SUBCLASS_MASS_STORAGE_SCSI,         },
                    139:        { "IDE",                PCI_SUBCLASS_MASS_STORAGE_IDE,          },
                    140:        { "floppy",             PCI_SUBCLASS_MASS_STORAGE_FLOPPY,       },
                    141:        { "IPI",                PCI_SUBCLASS_MASS_STORAGE_IPI,          },
                    142:        { "miscellaneous",      PCI_SUBCLASS_MASS_STORAGE_MISC,         },
                    143:        { 0 },
                    144: };
                    145:
                    146: struct pci_class pci_subclass_network[] = {
                    147:        { "ethernet",           PCI_SUBCLASS_NETWORK_ETHERNET,          },
                    148:        { "token ring",         PCI_SUBCLASS_NETWORK_TOKENRING,         },
                    149:        { "FDDI",               PCI_SUBCLASS_NETWORK_FDDI,              },
                    150:        { "miscellaneous",      PCI_SUBCLASS_NETWORK_MISC,              },
                    151:        { 0 },
                    152: };
                    153:
                    154: struct pci_class pci_subclass_display[] = {
                    155:        { "VGA",                PCI_SUBCLASS_DISPLAY_VGA,               },
                    156:        { "XGA",                PCI_SUBCLASS_DISPLAY_XGA,               },
                    157:        { "miscellaneous",      PCI_SUBCLASS_DISPLAY_MISC,              },
                    158:        { 0 },
                    159: };
                    160:
                    161: struct pci_class pci_subclass_multimedia[] = {
                    162:        { "video",              PCI_SUBCLASS_MULTIMEDIA_VIDEO,          },
                    163:        { "audio",              PCI_SUBCLASS_MULTIMEDIA_AUDIO,          },
                    164:        { "miscellaneous",      PCI_SUBCLASS_MULTIMEDIA_MISC,           },
                    165:        { 0 },
                    166: };
                    167:
                    168: struct pci_class pci_subclass_memory[] = {
                    169:        { "RAM",                PCI_SUBCLASS_MEMORY_RAM,                },
                    170:        { "flash",              PCI_SUBCLASS_MEMORY_FLASH,              },
                    171:        { "miscellaneous",      PCI_SUBCLASS_MEMORY_MISC,               },
                    172:        { 0 },
                    173: };
                    174:
                    175: struct pci_class pci_subclass_bridge[] = {
                    176:        { "host",               PCI_SUBCLASS_BRIDGE_HOST,               },
                    177:        { "ISA",                PCI_SUBCLASS_BRIDGE_ISA,                },
                    178:        { "EISA",               PCI_SUBCLASS_BRIDGE_EISA,               },
                    179:        { "MicroChannel",       PCI_SUBCLASS_BRIDGE_MC,                 },
                    180:        { "PCI",                PCI_SUBCLASS_BRIDGE_PCI,                },
                    181:        { "PCMCIA",             PCI_SUBCLASS_BRIDGE_PCMCIA,             },
                    182:        { "miscellaneous",      PCI_SUBCLASS_BRIDGE_MISC,               },
                    183:        { 0 },
                    184: };
                    185:
                    186: struct pci_class pci_class[] = {
                    187:        { "prehistoric",        PCI_CLASS_PREHISTORIC,
                    188:            pci_subclass_prehistoric,                           },
                    189:        { "mass storage",       PCI_CLASS_MASS_STORAGE,
                    190:            pci_subclass_mass_storage,                          },
                    191:        { "network",            PCI_CLASS_NETWORK,
                    192:            pci_subclass_network,                               },
                    193:        { "display",            PCI_CLASS_DISPLAY,
1.11      cgd       194:            pci_subclass_display,                               },
1.10      cgd       195:        { "multimedia",         PCI_CLASS_MULTIMEDIA,
                    196:            pci_subclass_multimedia,                            },
                    197:        { "memory",             PCI_CLASS_MEMORY,
                    198:            pci_subclass_memory,                                },
                    199:        { "bridge",             PCI_CLASS_BRIDGE,
                    200:            pci_subclass_bridge,                                },
                    201:        { "undefined",          PCI_CLASS_UNDEFINED,
                    202:            0,                                                  },
                    203:        { 0 },
                    204: };
                    205:
                    206: #ifdef PCIVERBOSE
                    207: /*
                    208:  * Descriptions of of known vendors and devices ("products").
                    209:  */
                    210: struct pci_knowndev {
                    211:        pci_vendor_id_t         vendor;
                    212:        pci_product_id_t        product;
                    213:        int                     flags;
                    214:        char                    *vendorname, *productname;
                    215: };
1.13    ! cgd       216: #define        PCI_KNOWNDEV_NOPROD     0x01            /* match on vendor only */
1.10      cgd       217:
                    218: #include <dev/pci/pcidevs_data.h>
                    219: #endif /* PCIVERBOSE */
                    220:
                    221: void
1.13    ! cgd       222: pci_devinfo(id_reg, class_reg, showclass, cp)
1.10      cgd       223:        pcireg_t id_reg, class_reg;
1.13    ! cgd       224:        int showclass;
1.10      cgd       225:        char *cp;
                    226: {
                    227:        pci_vendor_id_t vendor;
                    228:        pci_product_id_t product;
                    229:        pci_class_t class;
                    230:        pci_subclass_t subclass;
                    231:        pci_interface_t interface;
                    232:        pci_revision_t revision;
                    233:        char *vendor_namep, *product_namep;
                    234:        struct pci_class *classp, *subclassp;
                    235: #ifdef PCIVERBOSE
                    236:        struct pci_knowndev *kdp;
                    237: #endif
                    238:
                    239:        vendor = PCI_VENDOR(id_reg);
                    240:        product = PCI_PRODUCT(id_reg);
                    241:
                    242:        class = PCI_CLASS(class_reg);
                    243:        subclass = PCI_SUBCLASS(class_reg);
                    244:        interface = PCI_INTERFACE(class_reg);
                    245:        revision = PCI_REVISION(class_reg);
                    246:
                    247: #ifdef PCIVERBOSE
                    248:        kdp = pci_knowndevs;
                    249:         while (kdp->vendorname != NULL) {      /* all have vendor name */
                    250:                 if (kdp->vendor == vendor && (kdp->product == product ||
                    251:                    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0))
                    252:                         break;
                    253:                kdp++;
                    254:        }
1.13    ! cgd       255:         if (kdp->vendorname == NULL)
1.10      cgd       256:                vendor_namep = product_namep = NULL;
1.13    ! cgd       257:        else {
1.10      cgd       258:                vendor_namep = kdp->vendorname;
                    259:                product_namep = (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0 ?
                    260:                    kdp->productname : NULL;
                    261:         }
                    262: #else /* PCIVERBOSE */
                    263:        vendor_namep = product_namep = NULL;
                    264: #endif /* PCIVERBOSE */
                    265:
                    266:        classp = pci_class;
                    267:        while (classp->name != NULL) {
                    268:                if (class == classp->val)
                    269:                        break;
                    270:                classp++;
                    271:        }
                    272:
                    273:        subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
                    274:        while (subclassp && subclassp->name != NULL) {
                    275:                if (subclass == subclassp->val)
                    276:                        break;
                    277:                subclassp++;
                    278:        }
                    279:
                    280:        if (vendor_namep == NULL)
                    281:                cp += sprintf(cp, "unknown vendor/product: 0x%04x/0x%04x",
                    282:                    vendor, product);
                    283:        else if (product_namep != NULL)
                    284:                cp += sprintf(cp, "%s %s", vendor_namep, product_namep);
                    285:        else
                    286:                cp += sprintf(cp, "vendor: %s, unknown product: 0x%x",
                    287:                    vendor_namep, product);
1.13    ! cgd       288:        if (showclass) {
        !           289:                cp += sprintf(cp, " (");
        !           290:                if (classp->name == NULL)
        !           291:                        cp += sprintf(cp,
        !           292:                            "unknown class/subclass: 0x%02x/0x%02x",
        !           293:                            class, subclass);
        !           294:                else {
        !           295:                        cp += sprintf(cp, "class: %s, ", classp->name);
        !           296:                        if (subclassp == NULL || subclassp->name == NULL)
        !           297:                                cp += sprintf(cp, "unknown subclass: 0x%02x",
        !           298:                                    subclass);
        !           299:                        else
        !           300:                                cp += sprintf(cp, "subclass: %s",
        !           301:                                    subclassp->name);
        !           302:                }
1.10      cgd       303: #if 0 /* not very useful */
1.13    ! cgd       304:                cp += sprintf(cp, ", interface: 0x%02x", interface);
1.10      cgd       305: #endif
1.13    ! cgd       306:                cp += sprintf(cp, ", revision: 0x%02x)", revision);
        !           307:        }
1.1       mycroft   308: }

CVSweb <webmaster@jp.NetBSD.org>