Annotation of embedaddon/pciutils/ls-map.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     The PCI Utilities -- Bus Mapping Mode
                      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: 
                     13: #include "lspci.h"
                     14: 
                     15: struct bus_bridge {
                     16:   struct bus_bridge *next;
                     17:   byte this, dev, func, first, last, bug;
                     18: };
                     19: 
                     20: struct bus_info {
                     21:   byte exists;
                     22:   byte guestbook;
                     23:   struct bus_bridge *bridges, *via;
                     24: };
                     25: 
                     26: static struct bus_info *bus_info;
                     27: 
                     28: static void
                     29: map_bridge(struct bus_info *bi, struct device *d, int np, int ns, int nl)
                     30: {
                     31:   struct bus_bridge *b = xmalloc(sizeof(struct bus_bridge));
                     32:   struct pci_dev *p = d->dev;
                     33: 
                     34:   b->next = bi->bridges;
                     35:   bi->bridges = b;
                     36:   b->this = get_conf_byte(d, np);
                     37:   b->dev = p->dev;
                     38:   b->func = p->func;
                     39:   b->first = get_conf_byte(d, ns);
                     40:   b->last = get_conf_byte(d, nl);
                     41:   printf("## %02x.%02x:%d is a bridge from %02x to %02x-%02x\n",
                     42:         p->bus, p->dev, p->func, b->this, b->first, b->last);
                     43:   if (b->this != p->bus)
                     44:     printf("!!! Bridge points to invalid primary bus.\n");
                     45:   if (b->first > b->last)
                     46:     {
                     47:       printf("!!! Bridge points to invalid bus range.\n");
                     48:       b->last = b->first;
                     49:     }
                     50: }
                     51: 
                     52: static void
                     53: do_map_bus(int bus)
                     54: {
                     55:   int dev, func;
                     56:   int verbose = pacc->debugging;
                     57:   struct bus_info *bi = bus_info + bus;
                     58:   struct device *d;
                     59: 
                     60:   if (verbose)
                     61:     printf("Mapping bus %02x\n", bus);
                     62:   for (dev = 0; dev < 32; dev++)
                     63:     if (filter.slot < 0 || filter.slot == dev)
                     64:       {
                     65:        int func_limit = 1;
                     66:        for (func = 0; func < func_limit; func++)
                     67:          if (filter.func < 0 || filter.func == func)
                     68:            {
                     69:              /* XXX: Bus mapping supports only domain 0 */
                     70:              struct pci_dev *p = pci_get_dev(pacc, 0, bus, dev, func);
                     71:              u16 vendor = pci_read_word(p, PCI_VENDOR_ID);
                     72:              if (vendor && vendor != 0xffff)
                     73:                {
                     74:                  if (!func && (pci_read_byte(p, PCI_HEADER_TYPE) & 0x80))
                     75:                    func_limit = 8;
                     76:                  if (verbose)
                     77:                    printf("Discovered device %02x:%02x.%d\n", bus, dev, func);
                     78:                  bi->exists = 1;
                     79:                  if (d = scan_device(p))
                     80:                    {
                     81:                      show_device(d);
                     82:                      switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
                     83:                        {
                     84:                        case PCI_HEADER_TYPE_BRIDGE:
                     85:                          map_bridge(bi, d, PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS);
                     86:                          break;
                     87:                        case PCI_HEADER_TYPE_CARDBUS:
                     88:                          map_bridge(bi, d, PCI_CB_PRIMARY_BUS, PCI_CB_CARD_BUS, PCI_CB_SUBORDINATE_BUS);
                     89:                          break;
                     90:                        }
                     91:                      free(d);
                     92:                    }
                     93:                  else if (verbose)
                     94:                    printf("But it was filtered out.\n");
                     95:                }
                     96:              pci_free_dev(p);
                     97:            }
                     98:       }
                     99: }
                    100: 
                    101: static void
                    102: do_map_bridges(int bus, int min, int max)
                    103: {
                    104:   struct bus_info *bi = bus_info + bus;
                    105:   struct bus_bridge *b;
                    106: 
                    107:   bi->guestbook = 1;
                    108:   for (b=bi->bridges; b; b=b->next)
                    109:     {
                    110:       if (bus_info[b->first].guestbook)
                    111:        b->bug = 1;
                    112:       else if (b->first < min || b->last > max)
                    113:        b->bug = 2;
                    114:       else
                    115:        {
                    116:          bus_info[b->first].via = b;
                    117:          do_map_bridges(b->first, b->first, b->last);
                    118:        }
                    119:     }
                    120: }
                    121: 
                    122: static void
                    123: map_bridges(void)
                    124: {
                    125:   int i;
                    126: 
                    127:   printf("\nSummary of buses:\n\n");
                    128:   for (i=0; i<256; i++)
                    129:     if (bus_info[i].exists && !bus_info[i].guestbook)
                    130:       do_map_bridges(i, 0, 255);
                    131:   for (i=0; i<256; i++)
                    132:     {
                    133:       struct bus_info *bi = bus_info + i;
                    134:       struct bus_bridge *b = bi->via;
                    135: 
                    136:       if (bi->exists)
                    137:        {
                    138:          printf("%02x: ", i);
                    139:          if (b)
                    140:            printf("Entered via %02x:%02x.%d\n", b->this, b->dev, b->func);
                    141:          else if (!i)
                    142:            printf("Primary host bus\n");
                    143:          else
                    144:            printf("Secondary host bus (?)\n");
                    145:        }
                    146:       for (b=bi->bridges; b; b=b->next)
                    147:        {
                    148:          printf("\t%02x.%d Bridge to %02x-%02x", b->dev, b->func, b->first, b->last);
                    149:          switch (b->bug)
                    150:            {
                    151:            case 1:
                    152:              printf(" <overlap bug>");
                    153:              break;
                    154:            case 2:
                    155:              printf(" <crossing bug>");
                    156:              break;
                    157:            }
                    158:          putchar('\n');
                    159:        }
                    160:     }
                    161: }
                    162: 
                    163: void
                    164: map_the_bus(void)
                    165: {
                    166:   if (pacc->method == PCI_ACCESS_PROC_BUS_PCI ||
                    167:       pacc->method == PCI_ACCESS_SYS_BUS_PCI ||
                    168:       pacc->method == PCI_ACCESS_DUMP)
                    169:     printf("WARNING: Bus mapping can be reliable only with direct hardware access enabled.\n\n");
                    170:   bus_info = xmalloc(sizeof(struct bus_info) * 256);
                    171:   memset(bus_info, 0, sizeof(struct bus_info) * 256);
                    172:   if (filter.bus >= 0)
                    173:     do_map_bus(filter.bus);
                    174:   else
                    175:     {
                    176:       int bus;
                    177:       for (bus=0; bus<256; bus++)
                    178:        do_map_bus(bus);
                    179:     }
                    180:   map_bridges();
                    181: }

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