Annotation of embedaddon/pciutils/lspci.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     The PCI Utilities -- List All PCI Devices
        !             3:  *
        !             4:  *     Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <string.h>
        !            11: #include <stdlib.h>
        !            12: #include <stdarg.h>
        !            13: 
        !            14: #include "lspci.h"
        !            15: 
        !            16: /* Options */
        !            17: 
        !            18: int verbose;                           /* Show detailed information */
        !            19: static int opt_hex;                    /* Show contents of config space as hexadecimal numbers */
        !            20: struct pci_filter filter;              /* Device filter */
        !            21: static int opt_tree;                   /* Show bus tree */
        !            22: static int opt_machine;                        /* Generate machine-readable output */
        !            23: static int opt_map_mode;               /* Bus mapping mode enabled */
        !            24: static int opt_domains;                        /* Show domain numbers (0=disabled, 1=auto-detected, 2=requested) */
        !            25: static int opt_kernel;                 /* Show kernel drivers */
        !            26: static int opt_query_dns;              /* Query the DNS (0=disabled, 1=enabled, 2=refresh cache) */
        !            27: static int opt_query_all;              /* Query the DNS for all entries */
        !            28: char *opt_pcimap;                      /* Override path to Linux modules.pcimap */
        !            29: 
        !            30: const char program_name[] = "lspci";
        !            31: 
        !            32: static char options[] = "nvbxs:d:ti:mgp:qkMDQ" GENERIC_OPTIONS ;
        !            33: 
        !            34: static char help_msg[] =
        !            35: "Usage: lspci [<switches>]\n"
        !            36: "\n"
        !            37: "Basic display modes:\n"
        !            38: "-mm\t\tProduce machine-readable output (single -m for an obsolete format)\n"
        !            39: "-t\t\tShow bus tree\n"
        !            40: "\n"
        !            41: "Display options:\n"
        !            42: "-v\t\tBe verbose (-vv for very verbose)\n"
        !            43: #ifdef PCI_OS_LINUX
        !            44: "-k\t\tShow kernel drivers handling each device\n"
        !            45: #endif
        !            46: "-x\t\tShow hex-dump of the standard part of the config space\n"
        !            47: "-xxx\t\tShow hex-dump of the whole config space (dangerous; root only)\n"
        !            48: "-xxxx\t\tShow hex-dump of the 4096-byte extended config space (root only)\n"
        !            49: "-b\t\tBus-centric view (addresses and IRQ's as seen by the bus)\n"
        !            50: "-D\t\tAlways show domain numbers\n"
        !            51: "\n"
        !            52: "Resolving of device ID's to names:\n"
        !            53: "-n\t\tShow numeric ID's\n"
        !            54: "-nn\t\tShow both textual and numeric ID's (names & numbers)\n"
        !            55: #ifdef PCI_USE_DNS
        !            56: "-q\t\tQuery the PCI ID database for unknown ID's via DNS\n"
        !            57: "-qq\t\tAs above, but re-query locally cached entries\n"
        !            58: "-Q\t\tQuery the PCI ID database for all ID's via DNS\n"
        !            59: #endif
        !            60: "\n"
        !            61: "Selection of devices:\n"
        !            62: "-s [[[[<domain>]:]<bus>]:][<slot>][.[<func>]]\tShow only devices in selected slots\n"
        !            63: "-d [<vendor>]:[<device>]\t\t\tShow only devices with specified ID's\n"
        !            64: "\n"
        !            65: "Other options:\n"
        !            66: "-i <file>\tUse specified ID database instead of %s\n"
        !            67: #ifdef PCI_OS_LINUX
        !            68: "-p <file>\tLook up kernel modules in a given file instead of default modules.pcimap\n"
        !            69: #endif
        !            70: "-M\t\tEnable `bus mapping' mode (dangerous; root only)\n"
        !            71: "\n"
        !            72: "PCI access options:\n"
        !            73: GENERIC_HELP
        !            74: ;
        !            75: 
        !            76: /*** Our view of the PCI bus ***/
        !            77: 
        !            78: struct pci_access *pacc;
        !            79: struct device *first_dev;
        !            80: static int seen_errors;
        !            81: 
        !            82: int
        !            83: config_fetch(struct device *d, unsigned int pos, unsigned int len)
        !            84: {
        !            85:   unsigned int end = pos+len;
        !            86:   int result;
        !            87: 
        !            88:   while (pos < d->config_bufsize && len && d->present[pos])
        !            89:     pos++, len--;
        !            90:   while (pos+len <= d->config_bufsize && len && d->present[pos+len-1])
        !            91:     len--;
        !            92:   if (!len)
        !            93:     return 1;
        !            94: 
        !            95:   if (end > d->config_bufsize)
        !            96:     {
        !            97:       int orig_size = d->config_bufsize;
        !            98:       while (end > d->config_bufsize)
        !            99:        d->config_bufsize *= 2;
        !           100:       d->config = xrealloc(d->config, d->config_bufsize);
        !           101:       d->present = xrealloc(d->present, d->config_bufsize);
        !           102:       memset(d->present + orig_size, 0, d->config_bufsize - orig_size);
        !           103:     }
        !           104:   result = pci_read_block(d->dev, pos, d->config + pos, len);
        !           105:   if (result)
        !           106:     memset(d->present + pos, 1, len);
        !           107:   return result;
        !           108: }
        !           109: 
        !           110: struct device *
        !           111: scan_device(struct pci_dev *p)
        !           112: {
        !           113:   struct device *d;
        !           114: 
        !           115:   if (p->domain && !opt_domains)
        !           116:     opt_domains = 1;
        !           117:   if (!pci_filter_match(&filter, p))
        !           118:     return NULL;
        !           119:   d = xmalloc(sizeof(struct device));
        !           120:   memset(d, 0, sizeof(*d));
        !           121:   d->dev = p;
        !           122:   d->config_cached = d->config_bufsize = 64;
        !           123:   d->config = xmalloc(64);
        !           124:   d->present = xmalloc(64);
        !           125:   memset(d->present, 1, 64);
        !           126:   if (!pci_read_block(p, 0, d->config, 64))
        !           127:     {
        !           128:       fprintf(stderr, "lspci: Unable to read the standard configuration space header of device %04x:%02x:%02x.%d\n",
        !           129:              p->domain, p->bus, p->dev, p->func);
        !           130:       seen_errors++;
        !           131:       return NULL;
        !           132:     }
        !           133:   if ((d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
        !           134:     {
        !           135:       /* For cardbus bridges, we need to fetch 64 bytes more to get the
        !           136:        * full standard header... */
        !           137:       if (config_fetch(d, 64, 64))
        !           138:        d->config_cached += 64;
        !           139:     }
        !           140:   pci_setup_cache(p, d->config, d->config_cached);
        !           141:   pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT);
        !           142:   return d;
        !           143: }
        !           144: 
        !           145: static void
        !           146: scan_devices(void)
        !           147: {
        !           148:   struct device *d;
        !           149:   struct pci_dev *p;
        !           150: 
        !           151:   pci_scan_bus(pacc);
        !           152:   for (p=pacc->devices; p; p=p->next)
        !           153:     if (d = scan_device(p))
        !           154:       {
        !           155:        d->next = first_dev;
        !           156:        first_dev = d;
        !           157:       }
        !           158: }
        !           159: 
        !           160: /*** Config space accesses ***/
        !           161: 
        !           162: static void
        !           163: check_conf_range(struct device *d, unsigned int pos, unsigned int len)
        !           164: {
        !           165:   while (len)
        !           166:     if (!d->present[pos])
        !           167:       die("Internal bug: Accessing non-read configuration byte at position %x", pos);
        !           168:     else
        !           169:       pos++, len--;
        !           170: }
        !           171: 
        !           172: byte
        !           173: get_conf_byte(struct device *d, unsigned int pos)
        !           174: {
        !           175:   check_conf_range(d, pos, 1);
        !           176:   return d->config[pos];
        !           177: }
        !           178: 
        !           179: word
        !           180: get_conf_word(struct device *d, unsigned int pos)
        !           181: {
        !           182:   check_conf_range(d, pos, 2);
        !           183:   return d->config[pos] | (d->config[pos+1] << 8);
        !           184: }
        !           185: 
        !           186: u32
        !           187: get_conf_long(struct device *d, unsigned int pos)
        !           188: {
        !           189:   check_conf_range(d, pos, 4);
        !           190:   return d->config[pos] |
        !           191:     (d->config[pos+1] << 8) |
        !           192:     (d->config[pos+2] << 16) |
        !           193:     (d->config[pos+3] << 24);
        !           194: }
        !           195: 
        !           196: /*** Sorting ***/
        !           197: 
        !           198: static int
        !           199: compare_them(const void *A, const void *B)
        !           200: {
        !           201:   const struct pci_dev *a = (*(const struct device **)A)->dev;
        !           202:   const struct pci_dev *b = (*(const struct device **)B)->dev;
        !           203: 
        !           204:   if (a->domain < b->domain)
        !           205:     return -1;
        !           206:   if (a->domain > b->domain)
        !           207:     return 1;
        !           208:   if (a->bus < b->bus)
        !           209:     return -1;
        !           210:   if (a->bus > b->bus)
        !           211:     return 1;
        !           212:   if (a->dev < b->dev)
        !           213:     return -1;
        !           214:   if (a->dev > b->dev)
        !           215:     return 1;
        !           216:   if (a->func < b->func)
        !           217:     return -1;
        !           218:   if (a->func > b->func)
        !           219:     return 1;
        !           220:   return 0;
        !           221: }
        !           222: 
        !           223: static void
        !           224: sort_them(void)
        !           225: {
        !           226:   struct device **index, **h, **last_dev;
        !           227:   int cnt;
        !           228:   struct device *d;
        !           229: 
        !           230:   cnt = 0;
        !           231:   for (d=first_dev; d; d=d->next)
        !           232:     cnt++;
        !           233:   h = index = alloca(sizeof(struct device *) * cnt);
        !           234:   for (d=first_dev; d; d=d->next)
        !           235:     *h++ = d;
        !           236:   qsort(index, cnt, sizeof(struct device *), compare_them);
        !           237:   last_dev = &first_dev;
        !           238:   h = index;
        !           239:   while (cnt--)
        !           240:     {
        !           241:       *last_dev = *h;
        !           242:       last_dev = &(*h)->next;
        !           243:       h++;
        !           244:     }
        !           245:   *last_dev = NULL;
        !           246: }
        !           247: 
        !           248: /*** Normal output ***/
        !           249: 
        !           250: static void
        !           251: show_slot_name(struct device *d)
        !           252: {
        !           253:   struct pci_dev *p = d->dev;
        !           254: 
        !           255:   if (!opt_machine ? opt_domains : (p->domain || opt_domains >= 2))
        !           256:     printf("%04x:", p->domain);
        !           257:   printf("%02x:%02x.%d", p->bus, p->dev, p->func);
        !           258: }
        !           259: 
        !           260: void
        !           261: get_subid(struct device *d, word *subvp, word *subdp)
        !           262: {
        !           263:   byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
        !           264: 
        !           265:   if (htype == PCI_HEADER_TYPE_NORMAL)
        !           266:     {
        !           267:       *subvp = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID);
        !           268:       *subdp = get_conf_word(d, PCI_SUBSYSTEM_ID);
        !           269:     }
        !           270:   else if (htype == PCI_HEADER_TYPE_CARDBUS && d->config_cached >= 128)
        !           271:     {
        !           272:       *subvp = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
        !           273:       *subdp = get_conf_word(d, PCI_CB_SUBSYSTEM_ID);
        !           274:     }
        !           275:   else
        !           276:     *subvp = *subdp = 0xffff;
        !           277: }
        !           278: 
        !           279: static void
        !           280: show_terse(struct device *d)
        !           281: {
        !           282:   int c;
        !           283:   struct pci_dev *p = d->dev;
        !           284:   char classbuf[128], devbuf[128];
        !           285: 
        !           286:   show_slot_name(d);
        !           287:   printf(" %s: %s",
        !           288:         pci_lookup_name(pacc, classbuf, sizeof(classbuf),
        !           289:                         PCI_LOOKUP_CLASS,
        !           290:                         p->device_class),
        !           291:         pci_lookup_name(pacc, devbuf, sizeof(devbuf),
        !           292:                         PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
        !           293:                         p->vendor_id, p->device_id));
        !           294:   if (c = get_conf_byte(d, PCI_REVISION_ID))
        !           295:     printf(" (rev %02x)", c);
        !           296:   if (verbose)
        !           297:     {
        !           298:       char *x;
        !           299:       c = get_conf_byte(d, PCI_CLASS_PROG);
        !           300:       x = pci_lookup_name(pacc, devbuf, sizeof(devbuf),
        !           301:                          PCI_LOOKUP_PROGIF | PCI_LOOKUP_NO_NUMBERS,
        !           302:                          p->device_class, c);
        !           303:       if (c || x)
        !           304:        {
        !           305:          printf(" (prog-if %02x", c);
        !           306:          if (x)
        !           307:            printf(" [%s]", x);
        !           308:          putchar(')');
        !           309:        }
        !           310:     }
        !           311:   putchar('\n');
        !           312: 
        !           313:   if (verbose || opt_kernel)
        !           314:     {
        !           315:       word subsys_v, subsys_d;
        !           316:       char ssnamebuf[256];
        !           317: 
        !           318:       get_subid(d, &subsys_v, &subsys_d);
        !           319:       if (subsys_v && subsys_v != 0xffff)
        !           320:        printf("\tSubsystem: %s\n",
        !           321:                pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
        !           322:                        PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
        !           323:                        p->vendor_id, p->device_id, subsys_v, subsys_d));
        !           324:     }
        !           325: }
        !           326: 
        !           327: /*** Verbose output ***/
        !           328: 
        !           329: static void
        !           330: show_size(pciaddr_t x)
        !           331: {
        !           332:   static const char suffix[][2] = { "", "K", "M", "G", "T" };
        !           333:   unsigned i;
        !           334:   if (!x)
        !           335:     return;
        !           336:   for (i = 0; i < (sizeof(suffix) / sizeof(*suffix) - 1); i++) {
        !           337:     if (x < 1024)
        !           338:       break;
        !           339:     x /= 1024;
        !           340:   }
        !           341:   printf(" [size=%u%s]", (unsigned)x, suffix[i]);
        !           342: }
        !           343: 
        !           344: static void
        !           345: show_bases(struct device *d, int cnt)
        !           346: {
        !           347:   struct pci_dev *p = d->dev;
        !           348:   word cmd = get_conf_word(d, PCI_COMMAND);
        !           349:   int i;
        !           350:   int virtual = 0;
        !           351: 
        !           352:   for (i=0; i<cnt; i++)
        !           353:     {
        !           354:       pciaddr_t pos = p->base_addr[i];
        !           355:       pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;
        !           356:       u32 flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
        !           357:       if (flg == 0xffffffff)
        !           358:        flg = 0;
        !           359:       if (!pos && !flg && !len)
        !           360:        continue;
        !           361:       if (verbose > 1)
        !           362:        printf("\tRegion %d: ", i);
        !           363:       else
        !           364:        putchar('\t');
        !           365:       if (pos && !flg)                 /* Reported by the OS, but not by the device */
        !           366:        {
        !           367:          printf("[virtual] ");
        !           368:          flg = pos;
        !           369:          virtual = 1;
        !           370:        }
        !           371:       if (flg & PCI_BASE_ADDRESS_SPACE_IO)
        !           372:        {
        !           373:          pciaddr_t a = pos & PCI_BASE_ADDRESS_IO_MASK;
        !           374:          printf("I/O ports at ");
        !           375:          if (a)
        !           376:            printf(PCIADDR_PORT_FMT, a);
        !           377:          else if (flg & PCI_BASE_ADDRESS_IO_MASK)
        !           378:            printf("<ignored>");
        !           379:          else
        !           380:            printf("<unassigned>");
        !           381:          if (!virtual && !(cmd & PCI_COMMAND_IO))
        !           382:            printf(" [disabled]");
        !           383:        }
        !           384:       else
        !           385:        {
        !           386:          int t = flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
        !           387:          pciaddr_t a = pos & PCI_ADDR_MEM_MASK;
        !           388:          int done = 0;
        !           389:          u32 z = 0;
        !           390: 
        !           391:          printf("Memory at ");
        !           392:          if (t == PCI_BASE_ADDRESS_MEM_TYPE_64)
        !           393:            {
        !           394:              if (i >= cnt - 1)
        !           395:                {
        !           396:                  printf("<invalid-64bit-slot>");
        !           397:                  done = 1;
        !           398:                }
        !           399:              else
        !           400:                {
        !           401:                  i++;
        !           402:                  z = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
        !           403:                }
        !           404:            }
        !           405:          if (!done)
        !           406:            {
        !           407:              if (a)
        !           408:                printf(PCIADDR_T_FMT, a);
        !           409:              else
        !           410:                printf(((flg & PCI_BASE_ADDRESS_MEM_MASK) || z) ? "<ignored>" : "<unassigned>");
        !           411:            }
        !           412:          printf(" (%s, %sprefetchable)",
        !           413:                 (t == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32-bit" :
        !           414:                 (t == PCI_BASE_ADDRESS_MEM_TYPE_64) ? "64-bit" :
        !           415:                 (t == PCI_BASE_ADDRESS_MEM_TYPE_1M) ? "low-1M" : "type 3",
        !           416:                 (flg & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-");
        !           417:          if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
        !           418:            printf(" [disabled]");
        !           419:        }
        !           420:       show_size(len);
        !           421:       putchar('\n');
        !           422:     }
        !           423: }
        !           424: 
        !           425: static void
        !           426: show_rom(struct device *d, int reg)
        !           427: {
        !           428:   struct pci_dev *p = d->dev;
        !           429:   pciaddr_t rom = p->rom_base_addr;
        !           430:   pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->rom_size : 0;
        !           431:   u32 flg = get_conf_long(d, reg);
        !           432:   word cmd = get_conf_word(d, PCI_COMMAND);
        !           433:   int virtual = 0;
        !           434: 
        !           435:   if (!rom && !flg && !len)
        !           436:     return;
        !           437:   putchar('\t');
        !           438:   if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK))
        !           439:     {
        !           440:       printf("[virtual] ");
        !           441:       flg = rom;
        !           442:       virtual = 1;
        !           443:     }
        !           444:   printf("Expansion ROM at ");
        !           445:   if (rom & PCI_ROM_ADDRESS_MASK)
        !           446:     printf(PCIADDR_T_FMT, rom & PCI_ROM_ADDRESS_MASK);
        !           447:   else if (flg & PCI_ROM_ADDRESS_MASK)
        !           448:     printf("<ignored>");
        !           449:   else
        !           450:     printf("<unassigned>");
        !           451:   if (!(flg & PCI_ROM_ADDRESS_ENABLE))
        !           452:     printf(" [disabled]");
        !           453:   else if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
        !           454:     printf(" [disabled by cmd]");
        !           455:   show_size(len);
        !           456:   putchar('\n');
        !           457: }
        !           458: 
        !           459: static void
        !           460: show_htype0(struct device *d)
        !           461: {
        !           462:   show_bases(d, 6);
        !           463:   show_rom(d, PCI_ROM_ADDRESS);
        !           464:   show_caps(d);
        !           465: }
        !           466: 
        !           467: static void
        !           468: show_htype1(struct device *d)
        !           469: {
        !           470:   u32 io_base = get_conf_byte(d, PCI_IO_BASE);
        !           471:   u32 io_limit = get_conf_byte(d, PCI_IO_LIMIT);
        !           472:   u32 io_type = io_base & PCI_IO_RANGE_TYPE_MASK;
        !           473:   u32 mem_base = get_conf_word(d, PCI_MEMORY_BASE);
        !           474:   u32 mem_limit = get_conf_word(d, PCI_MEMORY_LIMIT);
        !           475:   u32 mem_type = mem_base & PCI_MEMORY_RANGE_TYPE_MASK;
        !           476:   u32 pref_base = get_conf_word(d, PCI_PREF_MEMORY_BASE);
        !           477:   u32 pref_limit = get_conf_word(d, PCI_PREF_MEMORY_LIMIT);
        !           478:   u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK;
        !           479:   word sec_stat = get_conf_word(d, PCI_SEC_STATUS);
        !           480:   word brc = get_conf_word(d, PCI_BRIDGE_CONTROL);
        !           481:   int verb = verbose > 2;
        !           482: 
        !           483:   show_bases(d, 2);
        !           484:   printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n",
        !           485:         get_conf_byte(d, PCI_PRIMARY_BUS),
        !           486:         get_conf_byte(d, PCI_SECONDARY_BUS),
        !           487:         get_conf_byte(d, PCI_SUBORDINATE_BUS),
        !           488:         get_conf_byte(d, PCI_SEC_LATENCY_TIMER));
        !           489: 
        !           490:   if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) ||
        !           491:       (io_type != PCI_IO_RANGE_TYPE_16 && io_type != PCI_IO_RANGE_TYPE_32))
        !           492:     printf("\t!!! Unknown I/O range types %x/%x\n", io_base, io_limit);
        !           493:   else
        !           494:     {
        !           495:       io_base = (io_base & PCI_IO_RANGE_MASK) << 8;
        !           496:       io_limit = (io_limit & PCI_IO_RANGE_MASK) << 8;
        !           497:       if (io_type == PCI_IO_RANGE_TYPE_32)
        !           498:        {
        !           499:          io_base |= (get_conf_word(d, PCI_IO_BASE_UPPER16) << 16);
        !           500:          io_limit |= (get_conf_word(d, PCI_IO_LIMIT_UPPER16) << 16);
        !           501:        }
        !           502:       if (io_base <= io_limit || verb)
        !           503:        printf("\tI/O behind bridge: %08x-%08x\n", io_base, io_limit+0xfff);
        !           504:     }
        !           505: 
        !           506:   if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) ||
        !           507:       mem_type)
        !           508:     printf("\t!!! Unknown memory range types %x/%x\n", mem_base, mem_limit);
        !           509:   else
        !           510:     {
        !           511:       mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16;
        !           512:       mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16;
        !           513:       if (mem_base <= mem_limit || verb)
        !           514:        printf("\tMemory behind bridge: %08x-%08x\n", mem_base, mem_limit + 0xfffff);
        !           515:     }
        !           516: 
        !           517:   if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) ||
        !           518:       (pref_type != PCI_PREF_RANGE_TYPE_32 && pref_type != PCI_PREF_RANGE_TYPE_64))
        !           519:     printf("\t!!! Unknown prefetchable memory range types %x/%x\n", pref_base, pref_limit);
        !           520:   else
        !           521:     {
        !           522:       pref_base = (pref_base & PCI_PREF_RANGE_MASK) << 16;
        !           523:       pref_limit = (pref_limit & PCI_PREF_RANGE_MASK) << 16;
        !           524:       if (pref_base <= pref_limit || verb)
        !           525:        {
        !           526:          if (pref_type == PCI_PREF_RANGE_TYPE_32)
        !           527:            printf("\tPrefetchable memory behind bridge: %08x-%08x\n", pref_base, pref_limit + 0xfffff);
        !           528:          else
        !           529:            printf("\tPrefetchable memory behind bridge: %08x%08x-%08x%08x\n",
        !           530:                   get_conf_long(d, PCI_PREF_BASE_UPPER32),
        !           531:                   pref_base,
        !           532:                   get_conf_long(d, PCI_PREF_LIMIT_UPPER32),
        !           533:                   pref_limit + 0xfffff);
        !           534:        }
        !           535:     }
        !           536: 
        !           537:   if (verbose > 1)
        !           538:     printf("\tSecondary status: 66MHz%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c <SERR%c <PERR%c\n",
        !           539:             FLAG(sec_stat, PCI_STATUS_66MHZ),
        !           540:             FLAG(sec_stat, PCI_STATUS_FAST_BACK),
        !           541:             FLAG(sec_stat, PCI_STATUS_PARITY),
        !           542:             ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" :
        !           543:             ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" :
        !           544:             ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??",
        !           545:             FLAG(sec_stat, PCI_STATUS_SIG_TARGET_ABORT),
        !           546:             FLAG(sec_stat, PCI_STATUS_REC_TARGET_ABORT),
        !           547:             FLAG(sec_stat, PCI_STATUS_REC_MASTER_ABORT),
        !           548:             FLAG(sec_stat, PCI_STATUS_SIG_SYSTEM_ERROR),
        !           549:             FLAG(sec_stat, PCI_STATUS_DETECTED_PARITY));
        !           550: 
        !           551:   show_rom(d, PCI_ROM_ADDRESS1);
        !           552: 
        !           553:   if (verbose > 1)
        !           554:     {
        !           555:       printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c MAbort%c >Reset%c FastB2B%c\n",
        !           556:        FLAG(brc, PCI_BRIDGE_CTL_PARITY),
        !           557:        FLAG(brc, PCI_BRIDGE_CTL_SERR),
        !           558:        FLAG(brc, PCI_BRIDGE_CTL_NO_ISA),
        !           559:        FLAG(brc, PCI_BRIDGE_CTL_VGA),
        !           560:        FLAG(brc, PCI_BRIDGE_CTL_MASTER_ABORT),
        !           561:        FLAG(brc, PCI_BRIDGE_CTL_BUS_RESET),
        !           562:        FLAG(brc, PCI_BRIDGE_CTL_FAST_BACK));
        !           563:       printf("\t\tPriDiscTmr%c SecDiscTmr%c DiscTmrStat%c DiscTmrSERREn%c\n",
        !           564:        FLAG(brc, PCI_BRIDGE_CTL_PRI_DISCARD_TIMER),
        !           565:        FLAG(brc, PCI_BRIDGE_CTL_SEC_DISCARD_TIMER),
        !           566:        FLAG(brc, PCI_BRIDGE_CTL_DISCARD_TIMER_STATUS),
        !           567:        FLAG(brc, PCI_BRIDGE_CTL_DISCARD_TIMER_SERR_EN));
        !           568:     }
        !           569: 
        !           570:   show_caps(d);
        !           571: }
        !           572: 
        !           573: static void
        !           574: show_htype2(struct device *d)
        !           575: {
        !           576:   int i;
        !           577:   word cmd = get_conf_word(d, PCI_COMMAND);
        !           578:   word brc = get_conf_word(d, PCI_CB_BRIDGE_CONTROL);
        !           579:   word exca;
        !           580:   int verb = verbose > 2;
        !           581: 
        !           582:   show_bases(d, 1);
        !           583:   printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n",
        !           584:         get_conf_byte(d, PCI_CB_PRIMARY_BUS),
        !           585:         get_conf_byte(d, PCI_CB_CARD_BUS),
        !           586:         get_conf_byte(d, PCI_CB_SUBORDINATE_BUS),
        !           587:         get_conf_byte(d, PCI_CB_LATENCY_TIMER));
        !           588:   for (i=0; i<2; i++)
        !           589:     {
        !           590:       int p = 8*i;
        !           591:       u32 base = get_conf_long(d, PCI_CB_MEMORY_BASE_0 + p);
        !           592:       u32 limit = get_conf_long(d, PCI_CB_MEMORY_LIMIT_0 + p);
        !           593:       limit = limit + 0xfff;
        !           594:       if (base <= limit || verb)
        !           595:        printf("\tMemory window %d: %08x-%08x%s%s\n", i, base, limit,
        !           596:               (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]",
        !           597:               (brc & (PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 << i)) ? " (prefetchable)" : "");
        !           598:     }
        !           599:   for (i=0; i<2; i++)
        !           600:     {
        !           601:       int p = 8*i;
        !           602:       u32 base = get_conf_long(d, PCI_CB_IO_BASE_0 + p);
        !           603:       u32 limit = get_conf_long(d, PCI_CB_IO_LIMIT_0 + p);
        !           604:       if (!(base & PCI_IO_RANGE_TYPE_32))
        !           605:        {
        !           606:          base &= 0xffff;
        !           607:          limit &= 0xffff;
        !           608:        }
        !           609:       base &= PCI_CB_IO_RANGE_MASK;
        !           610:       limit = (limit & PCI_CB_IO_RANGE_MASK) + 3;
        !           611:       if (base <= limit || verb)
        !           612:        printf("\tI/O window %d: %08x-%08x%s\n", i, base, limit,
        !           613:               (cmd & PCI_COMMAND_IO) ? "" : " [disabled]");
        !           614:     }
        !           615: 
        !           616:   if (get_conf_word(d, PCI_CB_SEC_STATUS) & PCI_STATUS_SIG_SYSTEM_ERROR)
        !           617:     printf("\tSecondary status: SERR\n");
        !           618:   if (verbose > 1)
        !           619:     printf("\tBridgeCtl: Parity%c SERR%c ISA%c VGA%c MAbort%c >Reset%c 16bInt%c PostWrite%c\n",
        !           620:           FLAG(brc, PCI_CB_BRIDGE_CTL_PARITY),
        !           621:           FLAG(brc, PCI_CB_BRIDGE_CTL_SERR),
        !           622:           FLAG(brc, PCI_CB_BRIDGE_CTL_ISA),
        !           623:           FLAG(brc, PCI_CB_BRIDGE_CTL_VGA),
        !           624:           FLAG(brc, PCI_CB_BRIDGE_CTL_MASTER_ABORT),
        !           625:           FLAG(brc, PCI_CB_BRIDGE_CTL_CB_RESET),
        !           626:           FLAG(brc, PCI_CB_BRIDGE_CTL_16BIT_INT),
        !           627:           FLAG(brc, PCI_CB_BRIDGE_CTL_POST_WRITES));
        !           628: 
        !           629:   if (d->config_cached < 128)
        !           630:     {
        !           631:       printf("\t<access denied to the rest>\n");
        !           632:       return;
        !           633:     }
        !           634: 
        !           635:   exca = get_conf_word(d, PCI_CB_LEGACY_MODE_BASE);
        !           636:   if (exca)
        !           637:     printf("\t16-bit legacy interface ports at %04x\n", exca);
        !           638: }
        !           639: 
        !           640: static void
        !           641: show_verbose(struct device *d)
        !           642: {
        !           643:   struct pci_dev *p = d->dev;
        !           644:   word status = get_conf_word(d, PCI_STATUS);
        !           645:   word cmd = get_conf_word(d, PCI_COMMAND);
        !           646:   word class = p->device_class;
        !           647:   byte bist = get_conf_byte(d, PCI_BIST);
        !           648:   byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
        !           649:   byte latency = get_conf_byte(d, PCI_LATENCY_TIMER);
        !           650:   byte cache_line = get_conf_byte(d, PCI_CACHE_LINE_SIZE);
        !           651:   byte max_lat, min_gnt;
        !           652:   byte int_pin = get_conf_byte(d, PCI_INTERRUPT_PIN);
        !           653:   unsigned int irq = p->irq;
        !           654: 
        !           655:   show_terse(d);
        !           656: 
        !           657:   switch (htype)
        !           658:     {
        !           659:     case PCI_HEADER_TYPE_NORMAL:
        !           660:       if (class == PCI_CLASS_BRIDGE_PCI)
        !           661:        printf("\t!!! Invalid class %04x for header type %02x\n", class, htype);
        !           662:       max_lat = get_conf_byte(d, PCI_MAX_LAT);
        !           663:       min_gnt = get_conf_byte(d, PCI_MIN_GNT);
        !           664:       break;
        !           665:     case PCI_HEADER_TYPE_BRIDGE:
        !           666:       if ((class >> 8) != PCI_BASE_CLASS_BRIDGE)
        !           667:        printf("\t!!! Invalid class %04x for header type %02x\n", class, htype);
        !           668:       irq = int_pin = min_gnt = max_lat = 0;
        !           669:       break;
        !           670:     case PCI_HEADER_TYPE_CARDBUS:
        !           671:       if ((class >> 8) != PCI_BASE_CLASS_BRIDGE)
        !           672:        printf("\t!!! Invalid class %04x for header type %02x\n", class, htype);
        !           673:       min_gnt = max_lat = 0;
        !           674:       break;
        !           675:     default:
        !           676:       printf("\t!!! Unknown header type %02x\n", htype);
        !           677:       return;
        !           678:     }
        !           679: 
        !           680:   if (p->phy_slot)
        !           681:     printf("\tPhysical Slot: %s\n", p->phy_slot);
        !           682: 
        !           683:   if (verbose > 1)
        !           684:     {
        !           685:       printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n",
        !           686:             FLAG(cmd, PCI_COMMAND_IO),
        !           687:             FLAG(cmd, PCI_COMMAND_MEMORY),
        !           688:             FLAG(cmd, PCI_COMMAND_MASTER),
        !           689:             FLAG(cmd, PCI_COMMAND_SPECIAL),
        !           690:             FLAG(cmd, PCI_COMMAND_INVALIDATE),
        !           691:             FLAG(cmd, PCI_COMMAND_VGA_PALETTE),
        !           692:             FLAG(cmd, PCI_COMMAND_PARITY),
        !           693:             FLAG(cmd, PCI_COMMAND_WAIT),
        !           694:             FLAG(cmd, PCI_COMMAND_SERR),
        !           695:             FLAG(cmd, PCI_COMMAND_FAST_BACK),
        !           696:             FLAG(cmd, PCI_COMMAND_DISABLE_INTx));
        !           697:       printf("\tStatus: Cap%c 66MHz%c UDF%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c >SERR%c <PERR%c INTx%c\n",
        !           698:             FLAG(status, PCI_STATUS_CAP_LIST),
        !           699:             FLAG(status, PCI_STATUS_66MHZ),
        !           700:             FLAG(status, PCI_STATUS_UDF),
        !           701:             FLAG(status, PCI_STATUS_FAST_BACK),
        !           702:             FLAG(status, PCI_STATUS_PARITY),
        !           703:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" :
        !           704:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" :
        !           705:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??",
        !           706:             FLAG(status, PCI_STATUS_SIG_TARGET_ABORT),
        !           707:             FLAG(status, PCI_STATUS_REC_TARGET_ABORT),
        !           708:             FLAG(status, PCI_STATUS_REC_MASTER_ABORT),
        !           709:             FLAG(status, PCI_STATUS_SIG_SYSTEM_ERROR),
        !           710:             FLAG(status, PCI_STATUS_DETECTED_PARITY),
        !           711:             FLAG(status, PCI_STATUS_INTx));
        !           712:       if (cmd & PCI_COMMAND_MASTER)
        !           713:        {
        !           714:          printf("\tLatency: %d", latency);
        !           715:          if (min_gnt || max_lat)
        !           716:            {
        !           717:              printf(" (");
        !           718:              if (min_gnt)
        !           719:                printf("%dns min", min_gnt*250);
        !           720:              if (min_gnt && max_lat)
        !           721:                printf(", ");
        !           722:              if (max_lat)
        !           723:                printf("%dns max", max_lat*250);
        !           724:              putchar(')');
        !           725:            }
        !           726:          if (cache_line)
        !           727:            printf(", Cache Line Size: %d bytes", cache_line * 4);
        !           728:          putchar('\n');
        !           729:        }
        !           730:       if (int_pin || irq)
        !           731:        printf("\tInterrupt: pin %c routed to IRQ " PCIIRQ_FMT "\n",
        !           732:               (int_pin ? 'A' + int_pin - 1 : '?'), irq);
        !           733:     }
        !           734:   else
        !           735:     {
        !           736:       printf("\tFlags: ");
        !           737:       if (cmd & PCI_COMMAND_MASTER)
        !           738:        printf("bus master, ");
        !           739:       if (cmd & PCI_COMMAND_VGA_PALETTE)
        !           740:        printf("VGA palette snoop, ");
        !           741:       if (cmd & PCI_COMMAND_WAIT)
        !           742:        printf("stepping, ");
        !           743:       if (cmd & PCI_COMMAND_FAST_BACK)
        !           744:        printf("fast Back2Back, ");
        !           745:       if (status & PCI_STATUS_66MHZ)
        !           746:        printf("66MHz, ");
        !           747:       if (status & PCI_STATUS_UDF)
        !           748:        printf("user-definable features, ");
        !           749:       printf("%s devsel",
        !           750:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" :
        !           751:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" :
        !           752:             ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??");
        !           753:       if (cmd & PCI_COMMAND_MASTER)
        !           754:        printf(", latency %d", latency);
        !           755:       if (irq)
        !           756:        printf(", IRQ " PCIIRQ_FMT, irq);
        !           757:       putchar('\n');
        !           758:     }
        !           759: 
        !           760:   if (bist & PCI_BIST_CAPABLE)
        !           761:     {
        !           762:       if (bist & PCI_BIST_START)
        !           763:        printf("\tBIST is running\n");
        !           764:       else
        !           765:        printf("\tBIST result: %02x\n", bist & PCI_BIST_CODE_MASK);
        !           766:     }
        !           767: 
        !           768:   switch (htype)
        !           769:     {
        !           770:     case PCI_HEADER_TYPE_NORMAL:
        !           771:       show_htype0(d);
        !           772:       break;
        !           773:     case PCI_HEADER_TYPE_BRIDGE:
        !           774:       show_htype1(d);
        !           775:       break;
        !           776:     case PCI_HEADER_TYPE_CARDBUS:
        !           777:       show_htype2(d);
        !           778:       break;
        !           779:     }
        !           780: }
        !           781: 
        !           782: /*** Machine-readable dumps ***/
        !           783: 
        !           784: static void
        !           785: show_hex_dump(struct device *d)
        !           786: {
        !           787:   unsigned int i, cnt;
        !           788: 
        !           789:   cnt = d->config_cached;
        !           790:   if (opt_hex >= 3 && config_fetch(d, cnt, 256-cnt))
        !           791:     {
        !           792:       cnt = 256;
        !           793:       if (opt_hex >= 4 && config_fetch(d, 256, 4096-256))
        !           794:        cnt = 4096;
        !           795:     }
        !           796: 
        !           797:   for (i=0; i<cnt; i++)
        !           798:     {
        !           799:       if (! (i & 15))
        !           800:        printf("%02x:", i);
        !           801:       printf(" %02x", get_conf_byte(d, i));
        !           802:       if ((i & 15) == 15)
        !           803:        putchar('\n');
        !           804:     }
        !           805: }
        !           806: 
        !           807: static void
        !           808: print_shell_escaped(char *c)
        !           809: {
        !           810:   printf(" \"");
        !           811:   while (*c)
        !           812:     {
        !           813:       if (*c == '"' || *c == '\\')
        !           814:        putchar('\\');
        !           815:       putchar(*c++);
        !           816:     }
        !           817:   putchar('"');
        !           818: }
        !           819: 
        !           820: static void
        !           821: show_machine(struct device *d)
        !           822: {
        !           823:   struct pci_dev *p = d->dev;
        !           824:   int c;
        !           825:   word sv_id, sd_id;
        !           826:   char classbuf[128], vendbuf[128], devbuf[128], svbuf[128], sdbuf[128];
        !           827: 
        !           828:   get_subid(d, &sv_id, &sd_id);
        !           829: 
        !           830:   if (verbose)
        !           831:     {
        !           832:       printf((opt_machine >= 2) ? "Slot:\t" : "Device:\t");
        !           833:       show_slot_name(d);
        !           834:       putchar('\n');
        !           835:       printf("Class:\t%s\n",
        !           836:             pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class));
        !           837:       printf("Vendor:\t%s\n",
        !           838:             pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id));
        !           839:       printf("Device:\t%s\n",
        !           840:             pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id));
        !           841:       if (sv_id && sv_id != 0xffff)
        !           842:        {
        !           843:          printf("SVendor:\t%s\n",
        !           844:                 pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, sv_id));
        !           845:          printf("SDevice:\t%s\n",
        !           846:                 pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id));
        !           847:        }
        !           848:       if (p->phy_slot)
        !           849:        printf("PhySlot:\t%s\n", p->phy_slot);
        !           850:       if (c = get_conf_byte(d, PCI_REVISION_ID))
        !           851:        printf("Rev:\t%02x\n", c);
        !           852:       if (c = get_conf_byte(d, PCI_CLASS_PROG))
        !           853:        printf("ProgIf:\t%02x\n", c);
        !           854:       if (opt_kernel)
        !           855:        show_kernel_machine(d);
        !           856:     }
        !           857:   else
        !           858:     {
        !           859:       show_slot_name(d);
        !           860:       print_shell_escaped(pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class));
        !           861:       print_shell_escaped(pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id));
        !           862:       print_shell_escaped(pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id));
        !           863:       if (c = get_conf_byte(d, PCI_REVISION_ID))
        !           864:        printf(" -r%02x", c);
        !           865:       if (c = get_conf_byte(d, PCI_CLASS_PROG))
        !           866:        printf(" -p%02x", c);
        !           867:       if (sv_id && sv_id != 0xffff)
        !           868:        {
        !           869:          print_shell_escaped(pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, sv_id));
        !           870:          print_shell_escaped(pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id));
        !           871:        }
        !           872:       else
        !           873:        printf(" \"\" \"\"");
        !           874:       putchar('\n');
        !           875:     }
        !           876: }
        !           877: 
        !           878: /*** Main show function ***/
        !           879: 
        !           880: void
        !           881: show_device(struct device *d)
        !           882: {
        !           883:   if (opt_machine)
        !           884:     show_machine(d);
        !           885:   else
        !           886:     {
        !           887:       if (verbose)
        !           888:        show_verbose(d);
        !           889:       else
        !           890:        show_terse(d);
        !           891:       if (opt_kernel || verbose)
        !           892:        show_kernel(d);
        !           893:     }
        !           894:   if (opt_hex)
        !           895:     show_hex_dump(d);
        !           896:   if (verbose || opt_hex)
        !           897:     putchar('\n');
        !           898: }
        !           899: 
        !           900: static void
        !           901: show(void)
        !           902: {
        !           903:   struct device *d;
        !           904: 
        !           905:   for (d=first_dev; d; d=d->next)
        !           906:     show_device(d);
        !           907: }
        !           908: 
        !           909: /* Main */
        !           910: 
        !           911: int
        !           912: main(int argc, char **argv)
        !           913: {
        !           914:   int i;
        !           915:   char *msg;
        !           916: 
        !           917:   if (argc == 2 && !strcmp(argv[1], "--version"))
        !           918:     {
        !           919:       puts("lspci version " PCIUTILS_VERSION);
        !           920:       return 0;
        !           921:     }
        !           922: 
        !           923:   pacc = pci_alloc();
        !           924:   pacc->error = die;
        !           925:   pci_filter_init(pacc, &filter);
        !           926: 
        !           927:   while ((i = getopt(argc, argv, options)) != -1)
        !           928:     switch (i)
        !           929:       {
        !           930:       case 'n':
        !           931:        pacc->numeric_ids++;
        !           932:        break;
        !           933:       case 'v':
        !           934:        verbose++;
        !           935:        break;
        !           936:       case 'b':
        !           937:        pacc->buscentric = 1;
        !           938:        break;
        !           939:       case 's':
        !           940:        if (msg = pci_filter_parse_slot(&filter, optarg))
        !           941:          die("-s: %s", msg);
        !           942:        break;
        !           943:       case 'd':
        !           944:        if (msg = pci_filter_parse_id(&filter, optarg))
        !           945:          die("-d: %s", msg);
        !           946:        break;
        !           947:       case 'x':
        !           948:        opt_hex++;
        !           949:        break;
        !           950:       case 't':
        !           951:        opt_tree++;
        !           952:        break;
        !           953:       case 'i':
        !           954:         pci_set_name_list_path(pacc, optarg, 0);
        !           955:        break;
        !           956:       case 'm':
        !           957:        opt_machine++;
        !           958:        break;
        !           959:       case 'p':
        !           960:        opt_pcimap = optarg;
        !           961:        break;
        !           962: #ifdef PCI_OS_LINUX
        !           963:       case 'k':
        !           964:        opt_kernel++;
        !           965:        break;
        !           966: #endif
        !           967:       case 'M':
        !           968:        opt_map_mode++;
        !           969:        break;
        !           970:       case 'D':
        !           971:        opt_domains = 2;
        !           972:        break;
        !           973: #ifdef PCI_USE_DNS
        !           974:       case 'q':
        !           975:        opt_query_dns++;
        !           976:        break;
        !           977:       case 'Q':
        !           978:        opt_query_all = 1;
        !           979:        break;
        !           980: #else
        !           981:       case 'q':
        !           982:       case 'Q':
        !           983:        die("DNS queries are not available in this version");
        !           984: #endif
        !           985:       default:
        !           986:        if (parse_generic_option(i, pacc, optarg))
        !           987:          break;
        !           988:       bad:
        !           989:        fprintf(stderr, help_msg, pacc->id_file_name);
        !           990:        return 1;
        !           991:       }
        !           992:   if (optind < argc)
        !           993:     goto bad;
        !           994: 
        !           995:   if (opt_query_dns)
        !           996:     {
        !           997:       pacc->id_lookup_mode |= PCI_LOOKUP_NETWORK;
        !           998:       if (opt_query_dns > 1)
        !           999:        pacc->id_lookup_mode |= PCI_LOOKUP_REFRESH_CACHE;
        !          1000:     }
        !          1001:   if (opt_query_all)
        !          1002:     pacc->id_lookup_mode |= PCI_LOOKUP_NETWORK | PCI_LOOKUP_SKIP_LOCAL;
        !          1003: 
        !          1004:   pci_init(pacc);
        !          1005:   if (opt_map_mode)
        !          1006:     map_the_bus();
        !          1007:   else
        !          1008:     {
        !          1009:       scan_devices();
        !          1010:       sort_them();
        !          1011:       if (opt_tree)
        !          1012:        show_forest();
        !          1013:       else
        !          1014:        show();
        !          1015:     }
        !          1016:   pci_cleanup(pacc);
        !          1017: 
        !          1018:   return (seen_errors ? 2 : 0);
        !          1019: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>