add more spacing
[personal-kdebase.git] / apps / kinfocenter / pci / kpci.cpp
blob0bed0a732e16ebbcb3f208a29c887ae6b396eeb9
1 /* Retrieve information about PCI subsystem through libpci library from
2 pciutils package. This should be possible on Linux, BSD and AIX.
4 This code is based on example.c, lspci.c and pci.ids from pciutils.
6 Device classes, subclasses and programming interfaces are hardcoded
7 here, since there are only few of them, and they are important and
8 should their names be translated.
10 Author: Konrad Rzepecki <hannibal@megapolis.pl>
12 #include "kpci_private.h"
14 //extern "C" is needed to proper linking with libpci
15 extern "C" {
16 #include <pci/pci.h>
18 #include <unistd.h>
19 #include <sys/types.h> //getuid
20 #include <ctype.h> //isxdigit
21 #include <string.h> //memcpy
22 #include <QTreeWidget>
23 #include <QTreeWidgetItem>
24 #include <QFile>
26 static const QString& getNameById(const id2name *const table, int id) {
27 for (int i=0;; i++) {
28 if ((table[i].id==id)||(table[i].id==-1)) {
29 return table[i].name;
30 }//if
31 }//while
32 }//getNameById
34 static const QString& getNameBy2Id(const id3name *const table, int id, int id2) {
35 for (int i=0;; i++) {
36 if (((table[i].id==id)&&(table[i].id2==id2))|| ((table[i].id==id)&&(table[i].id2==-1))|| (table[i].id==-1)) {
37 return table[i].name;
38 }//if
39 }//while
40 }//getNameBy2Id
42 static const QString& getNameBy3Id(const id4name *const table, int id, int id2, int id3) {
43 for (int i=0;; i++) {
44 if (((table[i].id==id)&&(table[i].id2==id2)&&(table[i].id3==id3))|| ((table[i].id==id)&&(table[i].id2==id2)&&(table[i].id3==-1))|| ((table[i].id==id)&&(table[i].id2==-1))|| (table[i].id==-1)) {
45 return table[i].name;
46 }//if
47 }//while
48 }//getNameBy3Id
50 static QTreeWidgetItem* create(QTreeWidgetItem* parent, const QString& title, const QString& value) {
51 QStringList list;
52 list << title << value;
53 return new QTreeWidgetItem(parent, list);
56 static QTreeWidgetItem* createTitle(QTreeWidgetItem* parent, const QString& title) {
57 QStringList list;
58 list << title;
59 return new QTreeWidgetItem(parent, list);
62 static QTreeWidgetItem* addDeviceClass(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
63 QString value;
64 QTreeWidgetItem *localAfter=NULL;
65 after=create(parent, i18n("Device Class"), getNameById(devClass, info->devClass)+value.sprintf(" (0x%02X)", info->devClass));
66 after=create(parent, i18n("Device Subclass"), getNameBy2Id(devSubclass, info->devClass, info->devSubClass)+value.sprintf(" (0x%02X)", info->devSubClass));
67 after=create(parent, i18n("Device Programming Interface"), getNameBy3Id(devInterface, info->devClass, info->devSubClass, info->devProgIface)+value.sprintf(" (0x%02X)", info->devProgIface));
68 if ((info->devClass==0x01)&&(info->devSubClass==0x01)) { //programming interface for IDE
69 localAfter=create(after, i18n("Master IDE Device"), (info->progIdeMaster ? i18n(strYes) : i18n(strNo)));
70 localAfter=create(after, i18n("Secondary programmable indicator"), (info->progSecProgInd ? i18n(strYes) : i18n(strNo)));
71 localAfter=create(after, i18n("Secondary operating mode"), (info->progSecOperMode ? i18n(strYes) : i18n(strNo)));
72 localAfter=create(after, i18n("Primary programmable indicator"), (info->progPriProgInd ? i18n(strYes) : i18n(strNo)));
73 localAfter=create(after, i18n("Primary operating mode"), (info->progPriOperMode ? i18n(strYes) : i18n(strNo)));
74 }//if
75 return after;
76 }//addDeviceClass
78 static QTreeWidgetItem* addVendor(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_access *PCIAccess) {
79 char nameBuffer[NAME_BUFFER_SIZE];
80 QString line, value, topname;
81 short int subvendor=0, subdevice=0;
82 bool isVendor=false, isDevice=false, isSub=false;
84 memset((void*)nameBuffer, 0, NAME_BUFFER_SIZE);
85 if (info->headerType==PCI_HEADER_TYPE_CARDBUS) {
86 subvendor=info->cbSubVendor;
87 subdevice=info->cbSubDevice;
88 }//if
89 else {
90 subvendor=info->subVendor;
91 subdevice=info->subDevice;
92 }//else
94 //WARNING all pci_lookup_name calls should have 4 extra args for compatibility with older pcilib !
95 if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, info->vendor, 0, 0, 0)!=NULL) {
96 // line.setAscii(nameBuffer); //not work, workaround below
97 line = QString::fromAscii(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, info->vendor, 0, 0, 0));
98 if (line.contains("Unknown")==0) {
99 isVendor=true;
100 topname=line;
101 after=create(parent, i18n("Vendor"), line+value.sprintf(" (0x%04X)", info->vendor));
102 if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE, info->vendor, info->device, 0, 0)!=NULL) {
103 // line.setAscii(nameBuffer); //not work, workaround below
104 line = QString::fromAscii(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE, info->vendor, info->device, 0, 0));
105 if (line.contains("Unknown")==0) {
106 isDevice=true;
107 topname+=QString(" ")+line;
108 after=create(parent, i18n("Device"), line+value.sprintf(" (0x%04X)", info->device));
109 if (info->headerType==PCI_HEADER_TYPE_BRIDGE) {
110 isSub=true;
111 }//if
112 else if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE|PCI_LOOKUP_SUBSYSTEM, info->vendor, info->device, subvendor, subdevice)!=NULL) {
113 // line.setAscii(nameBuffer); //not work, workaround below
114 line = QString::fromAscii(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE|PCI_LOOKUP_SUBSYSTEM, info->vendor, info->device, subvendor, subdevice));
115 if (line.contains("Unknown")==0) {
116 isSub=true;
117 after=create(parent, i18n("Subsystem"), line+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice));
118 }//if
119 }//eliif
120 }//if
121 }//iif
122 }//if
123 }//if
124 if (!isVendor) {
125 after=create(parent, i18n("Vendor"), i18n(strUnknown)+value.sprintf(" (0x%04X)", info->vendor));
126 if (!isDevice) {
127 after=create(parent, i18n("Device"), i18n(strUnknown)+value.sprintf(" (0x%04X)", info->device));
128 }//if
129 topname=i18n(strUnknown);
130 }//if
131 if ((!isSub)&&(info->headerType!=PCI_HEADER_TYPE_BRIDGE)) { //if entire subsytem was not found, search at least for subvendor
132 if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, subvendor, 0, 0, 0)!=NULL) {
133 // line.setAscii(nameBuffer); //not work, workaround below
134 line = QString::fromAscii(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, subvendor, 0, 0, 0));
135 if (line.contains("Unknown")==0) {
136 after=create(parent, i18n("Subsystem"), line+i18n(" - device:")+value.sprintf(" 0x%04X (0x%04X:0x%04X)", subdevice, subvendor, subdevice));
137 }//if
138 else {
139 after=create(parent, i18n("Subsystem"), i18n(strUnknown)+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice));
140 }//else
141 }//if
142 else {
143 after=create(parent, i18n("Subsystem"), i18n(strUnknown)+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice));
144 }//else
145 }//if
146 parent->setText(1, topname);
147 return after;
148 }//addVendor
150 static QTreeWidgetItem* addInterrupt(QTreeWidgetItem *parent, QTreeWidgetItem *after, int irq, int pin) {
151 QTreeWidgetItem *localAfter=NULL;
152 QString value;
153 if ((irq!=0)||(pin!=0)) {
154 after=createTitle(parent, i18n("Interrupt"));
155 localAfter=create(after, i18n("IRQ"), value.sprintf("%i", irq));
156 localAfter=create(after, i18n("Pin"), value.sprintf("%c", (pin==0 ? '?' : 'A'-1+pin)));
157 }//if
158 return after;
159 }//addInterrupt
161 static QTreeWidgetItem* addControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
162 QTreeWidgetItem *localAfter=NULL;
163 QString value;
164 after=create(parent, i18n("Control"), value.sprintf("0x%04X", info->command));
165 localAfter=create(after, i18n("Response in I/O space"), (info->comIo ? i18n(strEnabled) : i18n(strDisabled)));
166 localAfter=create(after, i18n("Response in memory space"), (info->comMemory ? i18n(strEnabled) : i18n(strDisabled)));
167 localAfter=create(after, i18n("Bus mastering"), (info->comMaster ? i18n(strEnabled) : i18n(strDisabled)));
168 localAfter=create(after, i18n("Response to special cycles"), (info->comSpecial ? i18n(strEnabled) : i18n(strDisabled)));
169 localAfter=create(after, i18n("Memory write and invalidate"), (info->comInvalidate ? i18n(strEnabled) : i18n(strDisabled)));
170 localAfter=create(after, i18n("Palette snooping"), (info->comVgaPalette ? i18n(strEnabled) : i18n(strDisabled)));
171 localAfter=create(after, i18n("Parity checking"), (info->comParity ? i18n(strEnabled) : i18n(strDisabled)));
172 localAfter=create(after, i18n("Address/data stepping"), (info->comWait ? i18n(strEnabled) : i18n(strDisabled)));
173 localAfter=create(after, i18n("System error"), (info->comSerr ? i18n(strEnabled) : i18n(strDisabled)));
174 localAfter=create(after, i18n("Back-to-back writes"), (info->comFastBack ? i18n(strEnabled) : i18n(strDisabled)));
175 localAfter=create(after, i18n("Interrupt"), (info->comInterrupt ? i18n(strDisabled) : i18n(strEnabled))); //reverse order is intentional
176 return after;
177 }//addControl
179 static QTreeWidgetItem* addStatus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
180 QTreeWidgetItem *localAfter=NULL;
181 QString value;
182 after=create(parent, i18n("Status"), value.sprintf("0x%04X", info->status));
183 localAfter=create(after, i18n("Interrupt status"), (info->statCapList ? i18n(strEnabled) : i18n(strDisabled)));
184 localAfter=create(after, i18n("Capability list"), (info->statCapList ? i18n(strYes) : i18n(strNo)));
185 localAfter=create(after, i18n("66 MHz PCI 2.1 bus"), (info->stat66MHz ? i18n(strYes) : i18n(strNo)));
186 localAfter=create(after, i18n("User-definable features"), (info->statUdf ? i18n(strYes) : i18n(strNo)));
187 localAfter=create(after, i18n("Accept fast back-to-back"), (info->statFastBack ? i18n(strYes) : i18n(strNo)));
188 localAfter=create(after, i18n("Data parity error"), (info->statParity ? i18n(strYes) : i18n(strNo)));
189 localAfter=create(after, i18n("Device selection timing"), getNameById(devSel, info->statDevsel));
190 localAfter=create(after, i18n("Signaled target abort"), (info->statSigTargetAbort ? i18n(strYes) : i18n(strNo)));
191 localAfter=create(after, i18n("Received target abort"), (info->statRecTargetAbort ? i18n(strYes) : i18n(strNo)));
192 localAfter=create(after, i18n("Received master abort"), (info->statRecMasterAbort ? i18n(strYes) : i18n(strNo)));
193 localAfter=create(after, i18n("Signaled system error"), (info->statSigSystemError ? i18n(strYes) : i18n(strNo)));
194 localAfter=create(after, i18n("Parity error"), (info->statDetectedParity ? i18n(strYes) : i18n(strNo)));
195 return after;
196 }//addStatus
198 static QTreeWidgetItem* addLatency(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
199 QTreeWidgetItem *localAfter=NULL;
200 QString value;
201 after=create(parent, i18n("Latency"), value.sprintf("%u", info->latencyTimer));
202 if (info->headerType==PCI_HEADER_TYPE_NORMAL) {
203 if (info->minGnt==0) {
204 localAfter=create(after, i18n("MIN_GNT"), i18n("No major requirements (0x00)"));
205 }//if
206 else {
207 localAfter=create(after, i18n("MIN_GNT"), value.sprintf("%u ns (0x%02X)", info->minGnt*250, info->minGnt));
208 }//else
209 if (info->maxLat==0) {
210 localAfter=create(after, i18n("MAX_LAT"), i18n("No major requirements (0x00)"));
211 }//if
212 else {
213 localAfter=create(after, i18n("MAX_LAT"), value.sprintf("%u ns (0x%02X)", info->maxLat*250, info->maxLat));
214 }//else
215 }//if
216 return after;
217 }//addLatency
219 static QTreeWidgetItem* addHeaderType(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
220 QTreeWidgetItem *localAfter=NULL;
221 QString value;
222 after=create(parent, i18n("Header"),value.sprintf("0x%02X",info->headerTypeFull));
223 localAfter=create(after, i18n("Type"),getNameById(headerType,info->headerType)+value.sprintf(" (0x%02X)",info->headerType));
224 localAfter=create(after, i18n("Multifunctional"),(info->multifunctional?i18n(strYes):i18n(strNo)));
225 return after;
226 }//addHeaderType
228 static QTreeWidgetItem* addBist(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
229 QTreeWidgetItem *localAfter=NULL;
230 QString value;
231 after=create(parent, i18n("Build-in self test"), value.sprintf("0x%02X", info->bist));
232 localAfter=create(after, i18n("BIST Capable"), (info->bistCapable ? i18n(strYes) : i18n(strNo)));
233 if (info->bistCapable==1) {
234 localAfter=create(after, i18n("BIST Start"), (info->bistStart ? i18n(strYes) : i18n(strNo)));
235 localAfter=create(after, i18n("Completion code"), value.sprintf("0x%01X", info->bistCode));
236 }//if
237 return after;
238 }//addBist
240 static QTreeWidgetItem* addSize(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciaddr_t size) {
241 if (size<0x400) {
242 after=create(parent, i18n("Size"), QString("%1 B").arg(static_cast<unsigned long>(size)));
243 }//if
244 else if (size<0x100000) {
245 after=create(parent, i18n("Size"), QString("%1 kiB").arg(static_cast<unsigned long>(size/0x400)));
246 }//elif
247 else if (size<0x40000000) {
248 after=create(parent, i18n("Size"), QString("%1 MiB").arg(static_cast<unsigned long>(size/0x100000)));
249 }//elif
251 #ifdef HAVE_PCIADDR_T64
253 else if (size<0x10000000000LL) {
254 after=create(parent, i18n("Size"),QString("%1 GiB").arg(static_cast<unsigned long>(size/0x40000000)));
255 }//elif
256 else if (size<0x4000000000000LL) {
257 after=create(parent, i18n("Size"),QString("%1 PiB").arg(static_cast<unsigned long>(size/0x10000000000LL)));
258 }//elif
259 else if (size<0x1000000000000000LL) {
260 after=create(parent, i18n("Size"),QString("%1 EiB").arg(static_cast<unsigned long>(size/0x4000000000000LL)));
261 }//elif
263 #else //HAVE_PCIADDR_T64
264 else {
265 after=create(parent, i18n("Size"), QString("%1 GiB").arg(static_cast<unsigned long>(size/0x40000000)));
266 }//else
268 #endif //HAVE_PCIADDR_T64
269 return after;
270 }//addSize
272 static QTreeWidgetItem* addMapping(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_dev* PCIDevice) {
273 QTreeWidgetItem *localAfter=NULL;
274 QTreeWidgetItem *topLocalAfter=NULL;
275 QString value;
276 bool is64b=false;
277 after=createTitle(parent, i18n("Address mappings"));
278 for (int i=0; i<6; i++) {
279 if (((info->headerType==PCI_HEADER_TYPE_BRIDGE)&&(i>1))||((info->headerType==PCI_HEADER_TYPE_CARDBUS)&&(i>0))) {
280 break;
281 }//if
282 if (is64b) { //skip one range
283 continue;
284 }//if
285 topLocalAfter=createTitle(after, i18n("Mapping %1", i));
286 localAfter=create(topLocalAfter, i18n("Space"), (info->mapping[i].baseAddressMap ? i18n("I/O") : i18n("Memory")));
287 if (info->mapping[i].baseAddressMap==0) { //memory only
288 localAfter=create(topLocalAfter, i18n("Type"), getNameById(mappingType, info->mapping[i].baseAddressType));
289 localAfter=create(topLocalAfter, i18n("Prefetchable"), (info->mapping[i].baseAddressPref ? i18n(strYes) : i18n(strNo)));
290 }//if
291 if (is64b) { //there is no long long support in Qt so we need compose value
292 topLocalAfter->setText(1, value.sprintf("0x%08X%08X", info->mapping[i+1].baseAddress, info->mapping[i].baseAddress));
293 if (info->mapping[i+1].baseAddress==0) { //no top 4 bytes
294 if ((info->mapping[i].baseAddress&(~(info->mapping[i].baseAddressMap ? 0x3 : 0xF)))==0) { //no address at all
295 localAfter=create(topLocalAfter, i18n("Address"), i18n("Unassigned"));
296 localAfter=create(topLocalAfter, i18n("Size"), i18n("Unassigned"));
297 }//if
298 else {
299 localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X", (info->mapping[i].baseAddress&(~(info->mapping[i].baseAddressMap ? 0x3 : 0xF)))));
300 localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]);
301 }//else
302 }//if
303 else {
304 localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X%08X", info->mapping[i+1].baseAddress, (~(info->mapping[i].baseAddress&(info->mapping[i].baseAddressMap ? 0x3 : 0xF)))));
305 localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]);
306 }//else
307 }//if
308 else {
309 topLocalAfter->setText(1, value.sprintf("0x%08X", info->mapping[i].baseAddress));
310 if ((info->mapping[i].baseAddress&(~(info->mapping[i].baseAddressMap ? 0x3 : 0xF)))==0) { //no address at all
311 localAfter=create(topLocalAfter, i18n("Address"), i18n("Unassigned"));
312 localAfter=create(topLocalAfter, i18n("Size"), i18n("Unassigned"));
313 }//if
314 else {
315 localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X", (info->mapping[i].baseAddress&(~(info->mapping[i].baseAddressMap ? 0x3 : 0xF)))));
316 localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]);
317 }//else
318 }//else
319 }//for
320 return after;
321 }//addMapping
323 static QTreeWidgetItem* addBus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
324 QTreeWidgetItem *localAfter=NULL;
325 QString value;
326 if (info->headerType==PCI_HEADER_TYPE_BRIDGE) {
327 after=createTitle(parent, i18n("Bus"));
328 localAfter=create(after, i18n("Primary bus number"), value.sprintf("0x%02X", info->primaryBus));
329 localAfter=create(after, i18n("Secondary bus number"), value.sprintf("0x%02X", info->secondaryBus));
330 localAfter=create(after, i18n("Subordinate bus number"), value.sprintf("0x%02X", info->subordinateBus));
331 localAfter=create(after, i18n("Secondary latency timer"), value.sprintf("0x%02X", info->secLatencyTimer));
332 }//if
333 else if (info->headerType==PCI_HEADER_TYPE_CARDBUS) { //should be checked
334 after=createTitle(parent, i18n("Bus"));
335 localAfter=create(after, i18n("Primary bus number"), value.sprintf("0x%02X", info->cbPrimaryBus));
336 localAfter=create(after, i18n("CardBus number"), value.sprintf("0x%02X", info->cbCardBus));
337 localAfter=create(after, i18n("Subordinate bus number"), value.sprintf("0x%02X", info->cbSubordinateBus));
338 localAfter=create(after, i18n("CardBus latency timer"), value.sprintf("0x%02X", info->cbLatencyTimer));
339 }//elif
340 return after;
341 }//addBus
343 static QTreeWidgetItem* addSecStatus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
344 QTreeWidgetItem *localAfter=NULL;
345 QString value;
346 if (info->headerType==PCI_HEADER_TYPE_BRIDGE) {
347 after=create(parent, i18n("Secondary status"), value.sprintf("0x%04X", info->secStatus));
348 localAfter=create(after, i18n("Interrupt status"),(info->secStatCapList?i18n(strEnabled):i18n(strDisabled)));
349 localAfter=create(after, i18n("Capability list"),(info->secStatCapList?i18n(strYes):i18n(strNo)));
350 localAfter=create(after, i18n("66 MHz PCI 2.1 bus"),(info->secStat66MHz?i18n(strYes):i18n(strNo)));
351 localAfter=create(after, i18n("User-definable features"),(info->secStatUdf?i18n(strYes):i18n(strNo)));
352 localAfter=create(after, i18n("Accept fast back-to-back"),(info->secStatFastBack?i18n(strYes):i18n(strNo)));
353 localAfter=create(after, i18n("Data parity error"),(info->secStatParity?i18n(strYes):i18n(strNo)));
354 localAfter=create(after, i18n("Device selection timing"),getNameById(devSel,info->secStatDevsel));
355 localAfter=create(after, i18n("Signaled target abort"),(info->secStatSigTargetAbort?i18n(strYes):i18n(strNo)));
356 localAfter=create(after, i18n("Received target abort"),(info->secStatRecTargetAbort?i18n(strYes):i18n(strNo)));
357 localAfter=create(after, i18n("Received master abort"),(info->secStatRecMasterAbort?i18n(strYes):i18n(strNo)));
358 localAfter=create(after, i18n("Signaled system error"),(info->secStatSigSystemError?i18n(strYes):i18n(strNo)));
359 localAfter=create(after, i18n("Parity error"),(info->secStatDetectedParity?i18n(strYes):i18n(strNo)));
360 }//if
361 else if (info->headerType==PCI_HEADER_TYPE_CARDBUS) { //should be checked
362 after=create(parent,i18n("Secondary status"),value.sprintf("0x%04X",info->cbSecStatus));
363 localAfter=create(after, i18n("Interrupt status"),(info->cbSecStatCapList?i18n(strEnabled):i18n(strDisabled)));
364 localAfter=create(after, i18n("Capability list"),(info->cbSecStatCapList?i18n(strYes):i18n(strNo)));
365 localAfter=create(after, i18n("66 MHz PCI 2.1 bus"),(info->cbSecStat66MHz?i18n(strYes):i18n(strNo)));
366 localAfter=create(after, i18n("User-definable features"),(info->cbSecStatUdf?i18n(strYes):i18n(strNo)));
367 localAfter=create(after, i18n("Accept fast back-to-back"),(info->cbSecStatFastBack?i18n(strYes):i18n(strNo)));
368 localAfter=create(after, i18n("Data parity error"),(info->cbSecStatParity?i18n(strYes):i18n(strNo)));
369 localAfter=create(after, i18n("Device selection timing"),getNameById(devSel,info->cbSecStatDevsel));
370 localAfter=create(after, i18n("Signaled target abort"),(info->cbSecStatSigTargetAbort?i18n(strYes):i18n(strNo)));
371 localAfter=create(after, i18n("Received target abort"),(info->cbSecStatRecTargetAbort?i18n(strYes):i18n(strNo)));
372 localAfter=create(after, i18n("Received master abort"),(info->cbSecStatRecMasterAbort?i18n(strYes):i18n(strNo)));
373 localAfter=create(after, i18n("Signaled system error"),(info->cbSecStatSigSystemError?i18n(strYes):i18n(strNo)));
374 localAfter=create(after, i18n("Parity error"),(info->cbSecStatDetectedParity?i18n(strYes):i18n(strNo)));
375 }//elif
376 return after;
377 }//addSecStatus
379 static QTreeWidgetItem* addBridgeBehind(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
380 QTreeWidgetItem *localAfter=NULL;
381 QString value;
382 if (info->headerType==PCI_HEADER_TYPE_BRIDGE) {
383 after=createTitle(parent, i18n("I/O behind bridge"));
384 localAfter=create(after, i18n("32-bit"),(info->ioBaseType?i18n(strYes):i18n(strNo)));
385 if (info->ioBaseType==0) {
386 localAfter=create(after, i18n("Base"),value.sprintf("0x%04X",info->ioBase&0xFFF0));
387 localAfter=create(after, i18n("Limit"),value.sprintf("0x%04X",info->ioLimit|0x0F));
388 }//if
389 else {
390 localAfter=create(after, i18n("Base"),value.sprintf("0x%04X%04X",info->ioBaseUpper16,info->ioBase&0xFFF0));
391 localAfter=create(after, i18n("Limit"),value.sprintf("0x%04X%04X",info->ioLimitUpper16,info->ioLimit|0x0F));
392 }//else
393 after=createTitle(parent, i18n("Memory behind bridge"));
394 localAfter=create(after, i18n("Base"),value.sprintf("0x%08X",(info->memoryBase<<16)&0xFFFFFFF0));
395 localAfter=create(after, i18n("Limit"),value.sprintf("0x%08X",(info->memoryLimit<<16)|0x0FFFFF));
396 after=createTitle(parent, i18n("Prefetchable memory behind bridge"));
397 localAfter=create(after, i18n("64-bit"),(info->ioBaseType?i18n(strYes):i18n(strNo)));
398 if (info->ioBaseType==0) {
399 localAfter=create(after, i18n("Base"),value.sprintf("0x%08X",(info->prefMemoryBase<<16)&0xFFFFFFF0));
400 localAfter=create(after, i18n("Limit"),value.sprintf("0x%08X",(info->prefMemoryLimit<<16)|0x0FFFFF));
401 }//if
402 else {
403 localAfter=create(after, i18n("Base"),value.sprintf("0x%08X%08X",info->prefBaseUpper32,(info->prefMemoryBase<<16)&0xFFFFFFF0));
404 localAfter=create(after, i18n("Limit"),value.sprintf("0x%0x8X%08X",info->prefLimitUpper32,(info->prefMemoryLimit<<16)|0x0FFFFF));
405 }//else
406 }//if
407 return after;
408 }//addBridgeBechind
410 static QTreeWidgetItem* addBridgeControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
411 QTreeWidgetItem *localAfter=NULL;
412 QString value;
413 if (info->headerType==PCI_HEADER_TYPE_BRIDGE) {
414 after=create(parent, i18n("Bridge control"),value.sprintf("0x%04X",info->bridgeControl));
415 localAfter=create(after, i18n("Secondary parity checking"),(info->bridgeControlParity?i18n(strEnabled):i18n(strDisabled)));
416 localAfter=create(after, i18n("Secondary system error"),(info->bridgeControlSerr?i18n(strEnabled):i18n(strDisabled)));
417 localAfter=create(after, i18n("ISA ports forwarding"),(info->bridgeControlIsa?i18n(strDisabled):i18n(strEnabled))); //reverse order is intentional
418 localAfter=create(after, i18n("VGA forwarding"),(info->bridgeControlVga?i18n(strEnabled):i18n(strDisabled)));
419 localAfter=create(after, i18n("Master abort"),(info->bridgeControlMasterAbort?i18n(strEnabled):i18n(strDisabled)));
420 localAfter=create(after, i18n("Secondary bus reset"),(info->bridgeControlBusReset?i18n(strYes):i18n(strNo)));
421 localAfter=create(after, i18n("Secondary back-to-back writes"),(info->bridgeControlFastBack?i18n(strEnabled):i18n(strDisabled)));
422 localAfter=create(after, i18n("Primary discard timer counts"),(info->bridgeControlPriDisTim?i18n("2e10 PCI clocks"):i18n("2e15 PCI clocks")));
423 localAfter=create(after, i18n("Secondary discard timer counts"),(info->bridgeControlSecDisTim?i18n("2e10 PCI clocks"):i18n("2e15 PCI clocks")));
424 localAfter=create(after, i18n("Discard timer error"),(info->bridgeControlDisTimStat?i18n(strYes):i18n(strNo)));
425 localAfter=create(after, i18n("Discard timer system error"),(info->bridgeControlDisTimeSerr?i18n(strEnabled):i18n(strDisabled)));
426 }//if
427 return after;
428 }//addBridgeControl
430 static QTreeWidgetItem* addRom(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_dev* PCIDevice) {
431 QTreeWidgetItem *localAfter=NULL;
432 QString value;
433 if ((info->headerType==PCI_HEADER_TYPE_NORMAL)||(info->headerType==PCI_HEADER_TYPE_BRIDGE)) {
434 after=createTitle(parent, i18n("Expansion ROM"));
435 localAfter=create(after, i18n("Status"),(info->romEnabled?i18n(strEnabled):i18n(strDisabled)));
436 if (PCIDevice->rom_base_addr==0) { //no address at all
437 localAfter=create(after, i18n("Address"),i18n("Unassigned"));
438 localAfter=create(after, i18n("Size"),i18n("Unassigned"));
439 }//if
440 else {
441 localAfter=create(after, i18n("Address"),value.sprintf("0x%X",static_cast<unsigned>(PCIDevice->rom_base_addr)));
442 localAfter=addSize(after, localAfter, PCIDevice->rom_size);
443 }//else
444 }//if
445 return after;
446 }//addRom
448 static QTreeWidgetItem* addCardbusResource(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
449 QTreeWidgetItem *localAfter=NULL;
450 QTreeWidgetItem *topLocalAfter=NULL;
451 QString value;
452 int pref=0;
453 if (info->headerType==PCI_HEADER_TYPE_CARDBUS) {
454 after=createTitle(parent, i18n("Memory windows"));
455 for (int i=0; i<2; i++) {
456 pref=(i ? info->cbControlPref1 : info->cbControlPref0);
457 topLocalAfter=createTitle(after, i18n("Window %1", i));
458 localAfter=create(topLocalAfter, i18n("Prefetchable"),(pref?i18n(strYes):i18n(strNo)));
459 localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%08X",info->cbMemory[i].cbMemoryBase));
460 localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%08X",info->cbMemory[i].cbMemoryLimit));
461 }//for
462 after=createTitle(parent, i18n("I/O windows"));
463 for (int i=0; i<2; i++) {
464 topLocalAfter=createTitle(after, i18n("Window %1", i));
465 localAfter=create(topLocalAfter, i18n("Type"),(info->cbIo[i].cbIoBaseType?i18n("32-bit"):i18n("16-bit")));
466 if (info->cbIo[i].cbIoBaseType==1) {
467 localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%08X",info->cbIo[i].cbIoBase&0xFFFFFFFC));
468 localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%08X",info->cbIo[i].cbIoLimit|0x03));
469 }//if
470 else {
471 localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%04X",info->cbIo[i].cbIoBase&0xFFFC));
472 localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%04X",(info->cbIo[i].cbIoLimit&0xFFFF)|0x03));
473 }//else
474 }//for
475 after=create(parent, i18n("16-bit legacy interface ports"),value.sprintf("0x%04X",info->cbLegacyModeBase));
476 }//if
477 return after;
478 }//addCardbusResource
480 static QTreeWidgetItem* addCardbusControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
481 QTreeWidgetItem *localAfter=NULL;
482 QString value;
483 if (info->headerType==PCI_HEADER_TYPE_CARDBUS) {
484 after=create(parent, i18n("CardBus control"),value.sprintf("0x%04X",info->cbControl));
485 localAfter=create(after, i18n("Secondary parity checking"),(info->cbControlParity?i18n(strEnabled):i18n(strDisabled)));
486 localAfter=create(after, i18n("Secondary system error"),(info->cbControlSerr?i18n(strEnabled):i18n(strDisabled)));
487 localAfter=create(after, i18n("ISA ports forwarding"),(info->cbControlIsa?i18n(strDisabled):i18n(strEnabled))); //reverse order is intentional
488 localAfter=create(after, i18n("VGA forwarding"),(info->cbControlVga?i18n(strEnabled):i18n(strDisabled)));
489 localAfter=create(after, i18n("Master abort"),(info->cbControlMasterAbort?i18n(strEnabled):i18n(strDisabled)));
490 localAfter=create(after, i18n("Interrupts for 16-bit cards"),(info->cbControl16Int?i18n(strEnabled):i18n(strDisabled)));
491 localAfter=create(after, i18n("Window 0 prefetchable memory"),(info->cbControlPref0?i18n(strEnabled):i18n(strDisabled)));
492 localAfter=create(after, i18n("Window 1 prefetchable memory"),(info->cbControlPref1?i18n(strEnabled):i18n(strDisabled)));
493 localAfter=create(after, i18n("Post writes"),(info->cbControlPostWrites?i18n(strEnabled):i18n(strDisabled)));
494 }//if
495 return after;
496 }//addCardbusControl
498 static QTreeWidgetItem* addRaw(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
499 QTreeWidgetItem *localAfter=NULL;
500 QString value, temp;
501 after=createTitle(parent, i18n("Raw PCI config space"));
502 for (int i=0; i<(getuid()==0 ? 16 : 4); i++) {
503 for (int j=0; j<16; j++) {
504 if (j!=0) {
505 value+=temp.sprintf(" %02X", info->raw[i*16+j]);
506 }//if
507 else {
508 value.sprintf("%02X", info->raw[i*16+j]);
509 }//if
510 }//for
511 localAfter=create(after, temp.sprintf("0x%02X:",i*16),value);
512 }//for
513 return after;
514 }//addRaw
516 static QTreeWidgetItem* addCapsPm(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) {
517 QTreeWidgetItem *localAfter=NULL;
518 QTreeWidgetItem *subLocalAfter=NULL;
519 QString value;
520 pmInfo infoPm;
521 if ((offset+2+sizeof(pmInfo))<256) {
522 memcpy(reinterpret_cast<void*>(&infoPm.raw[0]), reinterpret_cast<void*>(&info->raw[offset+2]), sizeof(pmInfo));
523 after=create(parent, i18n("Capabilities"),value.sprintf("0x%04X",infoPm.caps));
524 localAfter=create(after, i18n("Version"),QString::number(infoPm.capsVer));
525 localAfter=create(after, i18n("Clock required for PME generation"),(infoPm.capsClock?i18n(strYes):i18n(strNo)));
526 localAfter=create(after, i18n("Device-specific initialization required"),(infoPm.capsDsi?i18n(strYes):i18n(strNo)));
527 localAfter=create(after, i18n("Maximum auxiliary current required in D3 cold"),getNameById(auxCur,infoPm.capsAuxCur));
528 localAfter=create(after, i18n("D1 support"),(infoPm.capsD1Supp?i18n(strEnabled):i18n(strDisabled)));
529 localAfter=create(after, i18n("D2 support"),(infoPm.capsD2Supp?i18n(strEnabled):i18n(strDisabled)));
530 localAfter=createTitle(after, i18n("Power management events"));
531 subLocalAfter=create(localAfter, i18n("D0"),(infoPm.capsPmeD0?i18n(strEnabled):i18n(strDisabled)));
532 subLocalAfter=create(localAfter, i18n("D1"),(infoPm.capsPmeD1?i18n(strEnabled):i18n(strDisabled)));
533 subLocalAfter=create(localAfter, i18n("D2"),(infoPm.capsPmeD2?i18n(strEnabled):i18n(strDisabled)));
534 subLocalAfter=create(localAfter, i18n("D3 hot"),(infoPm.capsPmeD3hot?i18n(strEnabled):i18n(strDisabled)));
535 subLocalAfter=create(localAfter, i18n("D3 cold"),(infoPm.capsPmeD3cold?i18n(strEnabled):i18n(strDisabled)));
536 localAfter=NULL;
537 after=create(parent, i18n("Status"),value.sprintf("0x%04X",infoPm.status));
538 localAfter=create(after, i18n("Power state"),getNameById(powerState,infoPm.statPower));
539 localAfter=create(after, i18n("Power management"),(infoPm.statPme?i18n(strEnabled):i18n(strDisabled)));
540 localAfter=create(after, i18n("Data select"),QString::number(infoPm.statDataSelect));
541 localAfter=create(after, i18n("Data scale"),QString::number(infoPm.statDataScale));
542 localAfter=create(after, i18n("Power management status"),(infoPm.statPmeStat?i18n(strEnabled):i18n(strDisabled)));
543 if ((info->devClass==0x06)&&(info->devSubClass==0x04)) { //PCI bridge
544 subLocalAfter=NULL;
545 localAfter=create(after, i18n("Bridge status"),value.sprintf("0x%02X",infoPm.statusBridge));
546 subLocalAfter=create(localAfter, i18n("Secondary bus state in D3 hot"),(infoPm.statBridgeBx?i18n("B2"):i18n("B3")));
547 subLocalAfter=create(localAfter, i18n("Secondary bus power & clock control"),(infoPm.statBridgeClock?i18n(strEnabled):i18n(strDisabled)));
548 }//if
549 }//if
550 after=create(parent, i18n("Data"),value.sprintf("0x%02X",infoPm.data));
551 return after;
552 }//addCapsPm
554 static QTreeWidgetItem* addCapsAgp(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) {
555 QTreeWidgetItem *localAfter=NULL;
556 QString value;
557 agpInfo infoAgp;
558 int i, cycleSize;
559 if ((offset+2+sizeof(agpInfo))<256) {
560 memcpy(reinterpret_cast<void*>(&infoAgp.raw[0]), reinterpret_cast<void*>(&info->raw[offset+2]), sizeof(agpInfo));
561 // after=create(parent, i18n("Revision"),value.sprintf("%i.%i",infoAgp.revMaior,infoAgp.revMinor));
562 after=create(parent, i18n("Revision"),QString("%1.%2").arg(infoAgp.revMaior).arg(infoAgp.revMinor));
563 after=create(parent, i18n("Status"),value.sprintf("0x%08X",infoAgp.status));
564 localAfter=create(after, i18n("Rate"),getNameById(agpRate,infoAgp.statusEnhRate));
565 localAfter=create(after, i18n("AGP 3.0 mode"),(infoAgp.statusMode?i18n(strEnabled):i18n(strDisabled)));
566 localAfter=create(after, i18n("Fast Writes"),(infoAgp.statusFastWrite?i18n(strEnabled):i18n(strDisabled)));
567 localAfter=create(after, i18n("Address over 4 GiB"),(infoAgp.statusOver4gb?i18n(strEnabled):i18n(strDisabled)));
568 if (infoAgp.statusMode==1) {
569 localAfter=create(after, i18n("Translation of host processor access"),(infoAgp.statusHtrans?i18n(strDisabled):i18n(strEnabled))); //reverse order is intentional
570 localAfter=create(after, i18n("64-bit GART"),(infoAgp.statusGart64b?i18n(strEnabled):i18n(strDisabled)));
571 localAfter=create(after, i18n("Cache Coherency"),(infoAgp.statusItaCoh?i18n(strEnabled):i18n(strDisabled)));
572 }//if
573 localAfter=create(after, i18n("Side-band addressing"),(infoAgp.statusSba?i18n(strEnabled):i18n(strDisabled)));
574 if (infoAgp.statusMode==1) {
575 localAfter=create(after, i18n("Calibrating cycle"),getNameById(calCycle,infoAgp.statusCalCycle));
576 for (i=0, cycleSize=1; i<(infoAgp.statusOptReqSize+4); i++) {
577 cycleSize*=2;
578 }//for
579 localAfter=create(after, i18n("Optimum asynchronous request size"),value.sprintf("%i (0x%02X)",cycleSize,infoAgp.statusOptReqSize));
580 localAfter=create(after, i18n("Isochronous transactions"),(infoAgp.statusIsochSupp?i18n(strEnabled):i18n(strDisabled)));
581 }//if
582 localAfter=create(after, i18n("Maximum number of AGP command"),value.sprintf("%i (0x%02X)",infoAgp.statusReq+1,infoAgp.statusReq));
583 localAfter=NULL;
584 after=create(parent, i18n("Configuration"),value.sprintf("0x%08X",infoAgp.config));
585 localAfter=create(after, i18n("Rate"),getNameById(agpRate,infoAgp.configEnhRate));
586 localAfter=create(after, i18n("Fast Writes"),(infoAgp.configFastWrite?i18n(strEnabled):i18n(strDisabled)));
587 if (infoAgp.statusMode==1) {
588 localAfter=create(after, i18n("Address over 4 GiB"),(infoAgp.configOver4gb?i18n(strEnabled):i18n(strDisabled)));
589 localAfter=create(after, i18n("64-bit GART"),(infoAgp.configGart64b?i18n(strEnabled):i18n(strDisabled)));
590 }//if
591 localAfter=create(after, i18n("AGP"),(infoAgp.configAgp?i18n(strEnabled):i18n(strDisabled)));
592 localAfter=create(after, i18n("Side-band addressing"),(infoAgp.configSba?i18n(strEnabled):i18n(strDisabled)));
593 if (infoAgp.statusMode==1) {
594 localAfter=create(after, i18n("Calibrating cycle"),getNameById(calCycle,infoAgp.configCalCycle));
595 for (i=0, cycleSize=1; i<(infoAgp.configOptReqSize+4); i++) {
596 cycleSize*=2;
597 }//for
598 localAfter=create(after, i18n("Optimum asynchronous request size"),value.sprintf("%i (0x%02X)",cycleSize,infoAgp.configOptReqSize));
599 }//if
600 localAfter=create(after, i18n("Maximum number of AGP command"),value.sprintf("%i (0x%02X)",infoAgp.configReq+1,infoAgp.configReq));
601 }//if
602 return after;
603 }//addCapsAgp
605 static QTreeWidgetItem* addCapsVpd(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) {
606 QString value;
607 vpdInfo infoVpd;
608 if ((offset+2+sizeof(vpdInfo))<256) {
609 memcpy(reinterpret_cast<void*>(&infoVpd.raw[0]), reinterpret_cast<void*>(&info->raw[offset+2]), sizeof(vpdInfo));
610 after=create(parent, i18n("Data address"),value.sprintf("0x%04X",infoVpd.vpdAddress));
611 after=create(parent, i18n("Transfer completed"),(infoVpd.vpdTransfer?i18n(strYes):i18n(strNo)));
612 after=create(parent, i18n("Data"),value.sprintf("0x%08X",infoVpd.vpdData));
613 }//if
614 return after;
615 }//addCapsVpd
617 static QTreeWidgetItem* addCapsMsi(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) {
618 QTreeWidgetItem *localAfter=NULL;
619 QString value;
620 msiInfo infoMsi;
621 int size=10;
622 if ((offset+4)<256) { //copy control only (for now)
623 memcpy(reinterpret_cast<void*>(&infoMsi.raw[0]), reinterpret_cast<void*>(&info->raw[offset+2]), 2);
624 after=create(parent, i18n("Message control"),value.sprintf("0x%04X",infoMsi.msiControl));
625 localAfter=create(after, i18n("Message signaled interrupts"),(infoMsi.msiEnable?i18n(strEnabled):i18n(strDisabled)));
626 localAfter=create(after, i18n("Multiple message capable"),getNameById(multipleMessage,infoMsi.msiMmCapable));
627 localAfter=create(after, i18n("Multiple message enable"),getNameById(multipleMessage,infoMsi.msiMmEnable));
628 localAfter=create(after, i18n("64-bit address"),(infoMsi.msi64bit?i18n(strEnabled):i18n(strDisabled)));
629 localAfter=create(after, i18n("Per vector masking"),(infoMsi.msiPerVector?i18n(strEnabled):i18n(strDisabled)));
630 size+=(infoMsi.msi64bit ? 4 : 0)+(infoMsi.msiPerVector ? 8 : 0);
631 if ((offset+size)<256) { //copy all MSI data
632 memcpy(reinterpret_cast<void*>(&infoMsi.raw[0]), reinterpret_cast<void*>(&info->raw[offset+size]), 2);
633 if (infoMsi.msi64bit==1) {
634 after=create(parent, i18n("Address"),value.sprintf("0x%08X%08X",infoMsi.msiUpperAddress,infoMsi.msiAddress));
635 after=create(parent, i18n("Data"),value.sprintf("0x%04X",infoMsi.msiData64));
636 if (infoMsi.msiPerVector==1) {
637 after=create(parent, i18n("Mask"),value.sprintf("0x%08X",infoMsi.msiMask64));
638 after=create(parent, i18n("Pending"),value.sprintf("0x%08X",infoMsi.msiPending64));
639 }//if
640 }//if
641 else {
642 after=create(parent, i18n("Address"),value.sprintf("0x%08X",infoMsi.msiAddress));
643 after=create(parent, i18n("Data"),value.sprintf("0x%04X",infoMsi.msiData));
644 if (infoMsi.msiPerVector==1) {
645 after=create(parent, i18n("Mask"),value.sprintf("0x%08X",infoMsi.msiMask));
646 after=create(parent, i18n("Pending"),value.sprintf("0x%08X",infoMsi.msiPending));
647 }//if
648 }//else
649 }//if
650 }//if
651 return after;
652 }//addCapsMsi
654 static QTreeWidgetItem* addCapsVendor(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) {
655 QString value, temp;
656 after=create(parent, i18n("Length"),value.sprintf("0x%02X",info->raw[offset+2]));
657 if ((offset+3)<256) { //check partial size
658 if (info->raw[offset+2]<=2) {
659 after=create(parent, i18n("Data"),i18n("None"));
660 }//if
661 else {
662 if ((offset+info->raw[offset+2])<256) { //check full size
663 for (int i=3; i<(info->raw[offset+2]); i++) {
664 if (i!=3) {
665 value+=temp.sprintf(" 0x%02X", info->raw[offset+i]);
666 }//if
667 else {
668 value.sprintf("0x%02X", info->raw[offset+i]);
669 }//if
670 }//for
671 after=create(parent, i18n("Data"),value);
672 }//if
673 }//else
674 }//if
675 return after;
676 }//addCapsVendor
678 static QTreeWidgetItem* addCaps(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) {
679 QTreeWidgetItem *localAfter=NULL;
680 QTreeWidgetItem *topLocalAfter=NULL;
681 QString value;
682 unsigned char offset;
683 if ((info->headerType==PCI_HEADER_TYPE_NORMAL)||(info->headerType==PCI_HEADER_TYPE_BRIDGE)) {
684 if ((info->capabilityList!=0)&&(info->statCapList!=0)) {
685 after=create(parent, i18n("Capabilities"),value.sprintf("0x%02X",info->capabilityList));
686 if (getuid()==0) {
687 for (offset=info->capabilityList; offset!=0; offset=info->raw[offset+1]) {
688 topLocalAfter=create(after, getNameById(capNames,info->raw[offset]),value.sprintf("0x%02X",info->raw[offset]));
689 localAfter=create(topLocalAfter, i18n("Next"),(info->raw[offset+1]==0?i18n("0x00 (None)"):value.sprintf("0x%02X",info->raw[offset+1])));
690 switch (info->raw[offset]) {
691 case 0x01: //Power Managemet
692 addCapsPm(topLocalAfter, localAfter, info, offset);
693 break;
694 case 0x02: //AGP
695 addCapsAgp(topLocalAfter, localAfter, info, offset);
696 break;
697 case 0x03: //VPD
698 addCapsVpd(topLocalAfter, localAfter, info, offset);
699 break;
700 case 0x05: //MSI
701 addCapsMsi(topLocalAfter, localAfter, info, offset);
702 break;
703 case 0x09: //vendor specific
704 addCapsVendor(topLocalAfter, localAfter, info, offset);
705 break;
706 default:
707 break;
708 }//switch
709 }//for
710 }//if
711 else {
712 topLocalAfter=createTitle(after, i18n("Root only"));
713 }//else
714 }//if
715 else {
716 after=create(parent, i18n("Capabilities"),i18n("0x00 (None)"));
717 }//else
718 }//if
719 return after;
720 }//addCaps
722 bool GetInfo_PCIUtils(QTreeWidget* tree) {
724 QStringList headers;
725 headers << i18n("Information") << i18n("Value");
726 tree->setHeaderLabels(headers);
727 tree->setRootIsDecorated(true);
729 pci_access *PCIAccess=NULL;
730 pci_dev *PCIDevice=NULL;
732 //init libpci
733 PCIAccess=pci_alloc();
734 if (PCIAccess==NULL) {
735 return false;
736 }//if
738 pci_init(PCIAccess);
739 pci_scan_bus(PCIAccess);
741 QTreeWidgetItem *DeviceName=NULL, *after=NULL;
742 QString value;
743 pciInfo info;
745 //proces all devices
746 for (PCIDevice=PCIAccess->devices; PCIDevice; PCIDevice=PCIDevice->next) {
747 //get PCI data
748 pci_fill_info(PCIDevice, PCI_FILL_IDENT|PCI_FILL_IRQ|PCI_FILL_BASES|PCI_FILL_ROM_BASE|PCI_FILL_SIZES);
749 if (getuid()==0) {
750 pci_read_block(PCIDevice, 0, info.raw, 256);
751 }//if
752 else {
753 pci_read_block(PCIDevice, 0, info.raw, 64);
754 }//else
756 QStringList deviceList;
757 deviceList << value.sprintf("%02X:%02X.%d", PCIDevice->bus, PCIDevice->dev, PCIDevice->func);
758 //create device tree
759 DeviceName=new QTreeWidgetItem(tree, deviceList);
760 //adding class, subclass and programming interface info
761 after=addDeviceClass(DeviceName, NULL, &info);
763 //adding revision
764 after=create(DeviceName, i18n("Revision"), value.sprintf("0x%02X", info.revision));
765 //adding vendor, device, and subvendor/sudevice info
766 after=addVendor(DeviceName, after, &info, PCIAccess);
767 //adding control
768 after=addControl(DeviceName, after, &info);
769 //adding status
770 after=addStatus(DeviceName, after, &info);
772 //adding cache line size
773 after=create(DeviceName, i18n("Cache line size"), value.sprintf("0x%02X", info.cacheLineSize));
774 //adding latency
775 after=addLatency(DeviceName, after, &info);
776 //adding header type
777 after=addHeaderType(DeviceName, after, &info);
778 //adding BIST
779 after=addBist(DeviceName, after, &info);
780 //adding address mapping
781 after=addMapping(DeviceName, after, &info, PCIDevice);
782 //adding bus info
783 after=addBus(DeviceName, after, &info);
784 //adding secondary status
785 after=addSecStatus(DeviceName, after, &info);
786 //adding resourece behind bridge
787 after=addBridgeBehind(DeviceName, after, &info);
788 //adding bridge control
789 after=addBridgeControl(DeviceName, after, &info);
790 //adding cardbus resource
791 after=addCardbusResource(DeviceName, after, &info);
792 //adding cardbus control
793 after=addCardbusControl(DeviceName, after, &info);
794 //adding ROM
795 after=addRom(DeviceName, after, &info, PCIDevice);
796 //adding capabilities
797 after=addCaps(DeviceName, after, &info);
799 //adding interrupt info (IRQ, pin)
800 after=addInterrupt(DeviceName, after, PCIDevice->irq, info.interruptPin); //PCI data have wrong IRQ ?!?
801 //add raw PCI config data
802 after=addRaw(DeviceName, after, &info);
803 }//for
805 pci_cleanup(PCIAccess);
806 return true;
807 } //GetInfo_PCIUtils