]> git.ipfire.org Git - thirdparty/pciutils.git/blob - ls-map.c
Sylixos port
[thirdparty/pciutils.git] / ls-map.c
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 }