X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lspci.c;h=dec904d4ccbdc5c840e5633197fae904c4cecb30;hb=ec25b52dd43e5fc877f6a04e920ac862afe66b16;hp=5d1a0fc1176c7c31d8580ae3ab696065b237bde3;hpb=138c0385ee743a772df323d12096b82201d0fc17;p=pciutils.git diff --git a/lspci.c b/lspci.c index 5d1a0fc..dec904d 100644 --- a/lspci.c +++ b/lspci.c @@ -34,6 +34,7 @@ Usage: lspci []\n\ -b\t\tBus-centric view (PCI addresses and IRQ's instead of those seen by the CPU)\n\ -x\t\tShow hex-dump of the standard portion of config space\n\ -xxx\t\tShow hex-dump of the whole config space (dangerous; root only)\n\ +-xxxx\t\tShow hex-dump of the 4096-byte extended config space (root only)\n\ -s [[[[]:]]:][][.[]]\tShow only devices in selected slots\n\ -d []:[]\tShow only selected devices\n\ -t\t\tShow bus tree\n\ @@ -62,16 +63,34 @@ static struct pci_access *pacc; struct device { struct device *next; struct pci_dev *dev; - unsigned int config_cnt; - byte config[256]; + unsigned int config_cnt, config_bufsize; + byte *config; }; static struct device *first_dev; +static int +config_fetch(struct device *d, unsigned int pos, unsigned int len) +{ + unsigned int end = pos+len; + int result; + if (end <= d->config_cnt) + return 1; + if (end > d->config_bufsize) + { + while (end > d->config_bufsize) + d->config_bufsize *= 2; + d->config = xrealloc(d->config, d->config_bufsize); + } + result = pci_read_block(d->dev, pos, d->config + pos, len); + if (result && pos == d->config_cnt) + d->config_cnt = end; + return result; +} + static struct device * scan_device(struct pci_dev *p) { - int how_much = (show_hex > 2) ? 256 : 64; struct device *d; if (!pci_filter_match(&filter, p)) @@ -79,16 +98,17 @@ scan_device(struct pci_dev *p) d = xmalloc(sizeof(struct device)); bzero(d, sizeof(*d)); d->dev = p; - if (!pci_read_block(p, 0, d->config, how_much)) - die("Unable to read %d bytes of configuration space.", how_much); - if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS) + d->config_cnt = d->config_bufsize = 64; + d->config = xmalloc(64); + if (!pci_read_block(p, 0, d->config, 64)) + die("Unable to read the configuration space header."); + if ((d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS) { - /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */ - if (!pci_read_block(p, 64, d->config+64, 64)) + /* For cardbus bridges, we need to fetch 64 bytes more to get the + * full standard header... */ + if (!config_fetch(d, 64, 64)) die("Unable to read cardbus bridge extension data."); - how_much = 128; } - d->config_cnt = how_much; pci_setup_cache(p, d->config, d->config_cnt); pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); return d; @@ -109,26 +129,6 @@ scan_devices(void) } } -static int -check_root(void) -{ - static int is_root = -1; - - if (is_root < 0) - is_root = !geteuid(); - return is_root; -} - -static int -config_fetch(struct device *d, unsigned int pos, unsigned int len) -{ - if (pos + len < d->config_cnt) - return 1; - if (pacc->method != PCI_ACCESS_DUMP && !check_root()) - return 0; - return pci_read_block(d->dev, pos, d->config + pos, len); -} - /* Config space accesses */ static inline byte @@ -404,8 +404,7 @@ format_agp_rate(int rate, char *buf, int agp3) { if (c != buf) *c++ = ','; - *c++ = 'x'; - *c++ = '0' + (1 << (i + 2*agp3)); + c += sprintf(c, "x%d", 1 << (i + 2*agp3)); } if (c != buf) *c = 0; @@ -417,7 +416,7 @@ static void show_agp(struct device *d, int where, int cap) { u32 t; - char rate[8]; + char rate[16]; int ver, rev; int agp3 = 0; @@ -554,6 +553,324 @@ show_pcix(struct device *d, int where) } } +static inline char * +ht_link_width(unsigned width) +{ + static char * const widths[8] = { "8bit", "16bit", "[2]", "32bit", "2bit", "4bit", "[6]", "N/C" }; + return widths[width]; +} + +static inline char * +ht_link_freq(unsigned freq) +{ + static char * const freqs[16] = { "200MHz", "300MHz", "400MHz", "500MHz", "600MHz", "800MHz", "1.0GHz", "1.2GHz", + "1.4GHz", "1.6GHz", "[a]", "[b]", "[c]", "[d]", "[e]", "Vend" }; + return freqs[freq]; +} + +static void +show_ht_pri(struct device *d, int where, int cmd) +{ + u16 lctr0, lcnf0, lctr1, lcnf1, eh; + u8 rid, lfrer0, lfcap0, ftr, lfrer1, lfcap1, mbu, mlu, bn; + + printf("HyperTransport: Slave or Primary Interface\n"); + if (verbose < 2) + return; + + printf("\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c DUL%c\n", + (cmd & PCI_HT_PRI_CMD_BUID), + (cmd & PCI_HT_PRI_CMD_UC) >> 5, + FLAG(cmd, PCI_HT_PRI_CMD_MH), + FLAG(cmd, PCI_HT_PRI_CMD_DD), + FLAG(cmd, PCI_HT_PRI_CMD_DUL)); + if (!config_fetch(d, where + PCI_HT_PRI_LCTR0, PCI_HT_PRI_SIZEOF - PCI_HT_PRI_LCTR0)) + return; + lctr0 = get_conf_word(d, where + PCI_HT_PRI_LCTR0); + printf("\t\tLink Control 0: CFlE%c CST%c CFE%c > 8, + FLAG(lctr0, PCI_HT_LCTR_ISOCEN), + FLAG(lctr0, PCI_HT_LCTR_LSEN), + FLAG(lctr0, PCI_HT_LCTR_EXTCTL), + FLAG(lctr0, PCI_HT_LCTR_64B)); + lcnf0 = get_conf_word(d, where + PCI_HT_PRI_LCNF0); + printf("\t\tLink Config 0: MLWI=%s DwFcIn%c MLWO=%s DwFcOut%c LWI=%s DwFcInEn%c LWO=%s DwFcOutEn%c\n", + ht_link_width(lcnf0 & PCI_HT_LCNF_MLWI), + FLAG(lcnf0, PCI_HT_LCNF_DFI), + ht_link_width((lcnf0 & PCI_HT_LCNF_MLWO) >> 4), + FLAG(lcnf0, PCI_HT_LCNF_DFO), + ht_link_width((lcnf0 & PCI_HT_LCNF_LWI) >> 8), + FLAG(lcnf0, PCI_HT_LCNF_DFIE), + ht_link_width((lcnf0 & PCI_HT_LCNF_LWO) >> 12), + FLAG(lcnf0, PCI_HT_LCNF_DFOE)); + lctr1 = get_conf_word(d, where + PCI_HT_PRI_LCTR1); + printf("\t\tLink Control 1: CFlE%c CST%c CFE%c > 8, + FLAG(lctr1, PCI_HT_LCTR_ISOCEN), + FLAG(lctr1, PCI_HT_LCTR_LSEN), + FLAG(lctr1, PCI_HT_LCTR_EXTCTL), + FLAG(lctr1, PCI_HT_LCTR_64B)); + lcnf1 = get_conf_word(d, where + PCI_HT_PRI_LCNF1); + printf("\t\tLink Config 1: MLWI=%s DwFcIn%c MLWO=%s DwFcOut%c LWI=%s DwFcInEn%c LWO=%s DwFcOutEn%c\n", + ht_link_width(lcnf1 & PCI_HT_LCNF_MLWI), + FLAG(lcnf1, PCI_HT_LCNF_DFI), + ht_link_width((lcnf1 & PCI_HT_LCNF_MLWO) >> 4), + FLAG(lcnf1, PCI_HT_LCNF_DFO), + ht_link_width((lcnf1 & PCI_HT_LCNF_LWI) >> 8), + FLAG(lcnf1, PCI_HT_LCNF_DFIE), + ht_link_width((lcnf1 & PCI_HT_LCNF_LWO) >> 12), + FLAG(lcnf1, PCI_HT_LCNF_DFOE)); + rid = get_conf_byte(d, where + PCI_HT_PRI_RID); + printf("\t\tRevision ID: %u.%02u\n", + (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN)); + lfrer0 = get_conf_byte(d, where + PCI_HT_PRI_LFRER0); + printf("\t\tLink Frequency 0: %s\n", ht_link_freq(lfrer0 & PCI_HT_LFRER_FREQ)); + printf("\t\tLink Error 0: > 2, + FLAG(cmd, PCI_HT_SEC_CMD_CS), + FLAG(cmd, PCI_HT_SEC_CMD_HH), + FLAG(cmd, PCI_HT_SEC_CMD_AS), + FLAG(cmd, PCI_HT_SEC_CMD_HIECE), + FLAG(cmd, PCI_HT_SEC_CMD_DUL)); + if (!config_fetch(d, where + PCI_HT_SEC_LCTR, PCI_HT_SEC_SIZEOF - PCI_HT_SEC_LCTR)) + return; + lctr = get_conf_word(d, where + PCI_HT_SEC_LCTR); + printf("\t\tLink Control: CFlE%c CST%c CFE%c > 8, + FLAG(lctr, PCI_HT_LCTR_ISOCEN), + FLAG(lctr, PCI_HT_LCTR_LSEN), + FLAG(lctr, PCI_HT_LCTR_EXTCTL), + FLAG(lctr, PCI_HT_LCTR_64B)); + lcnf = get_conf_word(d, where + PCI_HT_SEC_LCNF); + printf("\t\tLink Config: MLWI=%s DwFcIn%c MLWO=%s DwFcOut%c LWI=%s DwFcInEn%c LWO=%s DwFcOutEn%c\n", + ht_link_width(lcnf & PCI_HT_LCNF_MLWI), + FLAG(lcnf, PCI_HT_LCNF_DFI), + ht_link_width((lcnf & PCI_HT_LCNF_MLWO) >> 4), + FLAG(lcnf, PCI_HT_LCNF_DFO), + ht_link_width((lcnf & PCI_HT_LCNF_LWI) >> 8), + FLAG(lcnf, PCI_HT_LCNF_DFIE), + ht_link_width((lcnf & PCI_HT_LCNF_LWO) >> 12), + FLAG(lcnf, PCI_HT_LCNF_DFOE)); + rid = get_conf_byte(d, where + PCI_HT_SEC_RID); + printf("\t\tRevision ID: %u.%02u\n", + (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN)); + lfrer = get_conf_byte(d, where + PCI_HT_SEC_LFRER); + printf("\t\tLink Frequency: %s\n", ht_link_freq(lfrer & PCI_HT_LFRER_FREQ)); + printf("\t\tLink Error: > 5, (cmd & PCI_HT_RID_MIN)); + break; + case PCI_HT_CMD_TYP_UIDC: + printf("HyperTransport: UnitID Clumping\n"); + break; + case PCI_HT_CMD_TYP_ECSA: + printf("HyperTransport: Extended Configuration Space Access\n"); + break; + case PCI_HT_CMD_TYP_AM: + printf("HyperTransport: Address Mapping\n"); + break; + case PCI_HT_CMD_TYP_MSIM: + printf("HyperTransport: MSI Mapping\n"); + break; + case PCI_HT_CMD_TYP_DR: + printf("HyperTransport: DirectRoute\n"); + break; + case PCI_HT_CMD_TYP_VCS: + printf("HyperTransport: VCSet\n"); + break; + case PCI_HT_CMD_TYP_RM: + printf("HyperTransport: Retry Mode\n"); + break; + case PCI_HT_CMD_TYP_X86: + printf("HyperTransport: X86 (reserved)\n"); + break; + default: + printf("HyperTransport: #%02x\n", type >> 11); + } +} + static void show_rom(struct device *d) { @@ -604,6 +921,251 @@ show_msi(struct device *d, int where, int cap) printf("%08x Data: %04x\n", t, w); } +static void show_vendor(void) +{ + printf("Vendor Specific Information\n"); +} + +static void show_debug(void) +{ + printf("Debug port\n"); +} + +static float power_limit(int value, int scale) +{ + static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 }; + return value * scales[scale]; +} + +static const char *latency_l0s(int value) +{ + static const char *latencies[] = { "<64ns", "<128ns", "<256ns", "<512ns", "<1us", "<2us", "<4us", "unlimited" }; + return latencies[value]; +} + +static const char *latency_l1(int value) +{ + static const char *latencies[] = { "<1us", "<2us", "<4us", "<8us", "<16us", "<32us", "<64us", "unlimited" }; + return latencies[value]; +} + +static void show_express_dev(struct device *d, int where, int type) +{ + u32 t; + u16 w; + + t = get_conf_long(d, where + PCI_EXP_DEVCAP); + printf("\t\tDevice: Supported: MaxPayload %d bytes, PhantFunc %d, ExtTag%c\n", + 128 << (t & PCI_EXP_DEVCAP_PAYLOAD), + (1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)) - 1, + FLAG(t, PCI_EXP_DEVCAP_EXT_TAG)); + printf("\t\tDevice: Latency L0s %s, L1 %s\n", + latency_l0s((t & PCI_EXP_DEVCAP_L0S) >> 6), + latency_l1((t & PCI_EXP_DEVCAP_L1) >> 9)); + if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END) || + (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE)) + printf("\t\tDevice: AtnBtn%c AtnInd%c PwrInd%c\n", + FLAG(t, PCI_EXP_DEVCAP_ATN_BUT), + FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND)); + if (type == PCI_EXP_TYPE_UPSTREAM) + printf("\t\tDevice: SlotPowerLimit %f\n", + power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18, + (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26)); + + w = get_conf_word(d, where + PCI_EXP_DEVCTL); + printf("\t\tDevice: Errors: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n", + FLAG(w, PCI_EXP_DEVCTL_CERE), + FLAG(w, PCI_EXP_DEVCTL_NFERE), + FLAG(w, PCI_EXP_DEVCTL_FERE), + FLAG(w, PCI_EXP_DEVCTL_URRE)); + printf("\t\tDevice: RlxdOrd%c ExtTag%c PhantFunc%c AuxPwr%c NoSnoop%c\n", + FLAG(w, PCI_EXP_DEVCTL_RELAXED), + FLAG(w, PCI_EXP_DEVCTL_EXT_TAG), + FLAG(w, PCI_EXP_DEVCTL_PHANTOM), + FLAG(w, PCI_EXP_DEVCTL_AUX_PME), + FLAG(w, PCI_EXP_DEVCTL_NOSNOOP)); + printf("\t\tDevice: MaxPayload %d bytes, MaxReadReq %d bytes\n", + 128 << ((w & PCI_EXP_DEVCTL_PAYLOAD) >> 5), + 128 << ((w & PCI_EXP_DEVCTL_READRQ) >> 12)); +} + +static char *link_speed(int speed) +{ + switch (speed) + { + case 1: + return "2.5Gb/s"; + default: + return "unknown"; + } +} + +static char *aspm_support(int code) +{ + switch (code) + { + case 1: + return "L0s"; + case 3: + return "L0s L1"; + default: + return "unknown"; + } +} + +static const char *aspm_enabled(int code) +{ + static const char *desc[] = { "Disabled", "L0s Enabled", "L1 Enabled", "L0s L1 Enabled" }; + return desc[code]; +} + +static void show_express_link(struct device *d, int where, int type) +{ + u32 t; + u16 w; + + t = get_conf_long(d, where + PCI_EXP_LNKCAP); + printf("\t\tLink: Supported Speed %s, Width x%d, ASPM %s, Port %d\n", + link_speed(t & PCI_EXP_LNKCAP_SPEED), (t & PCI_EXP_LNKCAP_WIDTH) >> 4, + aspm_support((t & PCI_EXP_LNKCAP_ASPM) >> 10), + t >> 24); + printf("\t\tLink: Latency L0s %s, L1 %s\n", + latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12), + latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15)); + w = get_conf_word(d, where + PCI_EXP_LNKCTL); + printf("\t\tLink: ASPM %s", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM)); + if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) || + (type == PCI_EXP_TYPE_LEG_END)) + printf(" RCB %d bytes", w & PCI_EXP_LNKCTL_RCB ? 128 : 64); + if (w & PCI_EXP_LNKCTL_DISABLE) + printf(" Disabled"); + printf(" CommClk%c ExtSynch%c\n", FLAG(w, PCI_EXP_LNKCTL_CLOCK), + FLAG(w, PCI_EXP_LNKCTL_XSYNCH)); + w = get_conf_word(d, where + PCI_EXP_LNKSTA); + printf("\t\tLink: Speed %s, Width x%d\n", + link_speed(t & PCI_EXP_LNKSTA_SPEED), (t & PCI_EXP_LNKSTA_WIDTH) >> 4); +} + +static const char *indicator(int code) +{ + static const char *names[] = { "Unknown", "On", "Blink", "Off" }; + return names[code]; +} + +static void show_express_slot(struct device *d, int where) +{ + u32 t; + u16 w; + + t = get_conf_long(d, where + PCI_EXP_SLTCAP); + printf("\t\tSlot: AtnBtn%c PwrCtrl%c MRL%c AtnInd%c PwrInd%c HotPlug%c Surpise%c\n", + FLAG(t, PCI_EXP_SLTCAP_ATNB), + FLAG(t, PCI_EXP_SLTCAP_PWRC), + FLAG(t, PCI_EXP_SLTCAP_MRL), + FLAG(t, PCI_EXP_SLTCAP_ATNI), + FLAG(t, PCI_EXP_SLTCAP_PWRI), + FLAG(t, PCI_EXP_SLTCAP_HPC), + FLAG(t, PCI_EXP_SLTCAP_HPS)); + printf("\t\tSlot: Number %d, PowerLimit %f\n", t >> 19, + power_limit((t & PCI_EXP_SLTCAP_PWR_VAL) >> 7, + (t & PCI_EXP_SLTCAP_PWR_SCL) >> 15)); + w = get_conf_word(d, where + PCI_EXP_SLTCTL); + printf("\t\tSlot: Enabled AtnBtn%c PwrFlt%c MRL%c PresDet%c CmdCplt%c HPIrq%c\n", + FLAG(w, PCI_EXP_SLTCTL_ATNB), + FLAG(w, PCI_EXP_SLTCTL_PWRF), + FLAG(w, PCI_EXP_SLTCTL_MRLS), + FLAG(w, PCI_EXP_SLTCTL_PRSD), + FLAG(w, PCI_EXP_SLTCTL_CMDC), + FLAG(w, PCI_EXP_SLTCTL_HPIE)); + printf("\t\tSlot: AttnInd %s, PwrInd %s, Power%c\n", + indicator((w & PCI_EXP_SLTCTL_ATNI) >> 6), + indicator((w & PCI_EXP_SLTCTL_PWRI) >> 8), + FLAG(w, w & PCI_EXP_SLTCTL_PWRC)); +} + +static void show_express_root(struct device *d, int where) +{ + u16 w = get_conf_word(d, where + PCI_EXP_RTCTL); + printf("\t\tRoot: Correctable%c Non-Fatal%c Fatal%c PME%c\n", + FLAG(w, PCI_EXP_RTCTL_SECEE), + FLAG(w, PCI_EXP_RTCTL_SENFEE), + FLAG(w, PCI_EXP_RTCTL_SEFEE), + FLAG(w, PCI_EXP_RTCTL_PMEIE)); +} + +static void +show_express(struct device *d, int where, int cap) +{ + int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4; + int size; + int slot = 0; + + printf("Express "); + switch (type) + { + case PCI_EXP_TYPE_ENDPOINT: + printf("Endpoint"); + break; + case PCI_EXP_TYPE_LEG_END: + printf("Legacy Endpoint"); + break; + case PCI_EXP_TYPE_ROOT_PORT: + slot = cap & PCI_EXP_FLAGS_SLOT; + printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT)); + break; + case PCI_EXP_TYPE_UPSTREAM: + printf("Upstream Port"); + break; + case PCI_EXP_TYPE_DOWNSTREAM: + slot = cap & PCI_EXP_FLAGS_SLOT; + printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT)); + break; + case PCI_EXP_TYPE_PCI_BRIDGE: + printf("PCI/PCI-X Bridge"); + break; + default: + printf("Unknown type"); + } + printf(" IRQ %d\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9); + if (verbose < 2) + return; + + size = 16; + if (slot) + size = 24; + if (type == PCI_EXP_TYPE_ROOT_PORT) + size = 32; + if (!config_fetch(d, where + PCI_EXP_DEVCAP, size)) + return; + + show_express_dev(d, where, type); + show_express_link(d, where, type); + if (slot) + show_express_slot(d, where); + if (type == PCI_EXP_TYPE_ROOT_PORT) + show_express_root(d, where); +} + +static void +show_msix(struct device *d, int where, int cap) +{ + u32 off; + + printf("MSI-X: Enable%c Mask%c TabSize=%d\n", + FLAG(cap, PCI_MSIX_ENABLE), + FLAG(cap, PCI_MSIX_MASK), + (cap & PCI_MSIX_TABSIZE) + 1); + if (verbose < 2 || !config_fetch(d, where + PCI_MSIX_TABLE, 8)) + return; + + off = get_conf_long(d, where + PCI_MSIX_TABLE); + printf("\t\tVector table: BAR=%d offset=%08x\n", + off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR); + off = get_conf_long(d, where + PCI_MSIX_PBA); + printf("\t\tPBA: BAR=%d offset=%08x\n", + off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR); +} + static void show_slotid(int cap) { @@ -616,6 +1178,75 @@ show_slotid(int cap) chs); } +static void +show_aer(struct device *d, int where) +{ + printf("Advanced Error Reporting\n"); +} + +static void +show_vc(struct device *d, int where) +{ + printf("Virtual Channel\n"); +} + +static void +show_dsn(struct device *d, int where) +{ + u32 t1, t2; + if (!config_fetch(d, where + 4, 8)) + return; + t1 = get_conf_long(d, where + 4); + t2 = get_conf_long(d, where + 8); + printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", + t1 & 0xff, (t1 >> 8) & 0xff, (t1 >> 16) & 0xff, t1 >> 24, + t2 & 0xff, (t2 >> 8) & 0xff, (t2 >> 16) & 0xff, t2 >> 24); +} + +static void +show_pb(struct device *d, int where) +{ + printf("Power Budgeting\n"); +} + +static void +show_ext_caps(struct device *d) +{ + int where = 0x100; + do + { + u32 header; + int id; + + if (!config_fetch(d, where, 4)) + break; + header = get_conf_long(d, where); + if (!header) + break; + id = header & 0xffff; + printf("\tCapabilities: [%03x] ", where); + switch (id) + { + case PCI_EXT_CAP_ID_AER: + show_aer(d, where); + break; + case PCI_EXT_CAP_ID_VC: + show_vc(d, where); + break; + case PCI_EXT_CAP_ID_DSN: + show_dsn(d, where); + break; + case PCI_EXT_CAP_ID_PB: + show_pb(d, where); + break; + default: + printf("Unknown (%d)\n", id); + break; + } + where = header >> 20; + } while (where); +} + static void show_caps(struct device *d) { @@ -660,12 +1291,28 @@ show_caps(struct device *d) case PCI_CAP_ID_PCIX: show_pcix(d, where); break; + case PCI_CAP_ID_HT: + show_ht(d, where, cap); + break; + case PCI_CAP_ID_VNDR: + show_vendor(); + break; + case PCI_CAP_ID_DBG: + show_debug(); + break; + case PCI_CAP_ID_EXP: + show_express(d, where, cap); + break; + case PCI_CAP_ID_MSIX: + show_msix(d, where, cap); + break; default: printf("#%02x [%04x]\n", id, cap); } where = next; } } + show_ext_caps(d); } static void @@ -747,7 +1394,7 @@ show_htype1(struct device *d) } if (verbose > 1) - printf("\tSecondary status: 66Mhz%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c SERR%c TAbort%c > 8) != PCI_BASE_CLASS_BRIDGE) printf("\t!!! Invalid class %04x for header type %02x\n", class, htype); irq = int_pin = min_gnt = max_lat = 0; subsys_v = subsys_d = 0; @@ -986,9 +1633,17 @@ show_verbose(struct device *d) static void show_hex_dump(struct device *d) { - unsigned int i; + unsigned int i, cnt; - for(i=0; iconfig_cnt; i++) + cnt = d->config_cnt; + if (show_hex >= 3 && config_fetch(d, cnt, 256-cnt)) + { + cnt = 256; + if (show_hex >= 4 && config_fetch(d, 256, 4096-256)) + cnt = 4096; + } + + for(i=0; imethod == PCI_ACCESS_PROC_BUS_PCI || pacc->method == PCI_ACCESS_DUMP) printf("WARNING: Bus mapping can be reliable only with direct hardware access enabled.\n\n"); - else if (!check_root()) - die("Only root can map the bus."); bus_info = xmalloc(sizeof(struct bus_info) * 256); bzero(bus_info, sizeof(struct bus_info) * 256); if (filter.bus >= 0)