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>