From: Martin Mares Date: Mon, 5 Jul 2004 15:41:26 +0000 (+0000) Subject: Merged more PCI Express updates. X-Git-Tag: v3.0.0~112 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=ec25b52dd43e5fc877f6a04e920ac862afe66b16;p=pciutils.git Merged more PCI Express updates. git-archimport-id: mj@ucw.cz--public/pciutils--main--2.2--patch-53 --- diff --git a/ChangeLog b/ChangeLog index 691e459..02b3a2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2004-07-05 Martin Mares + + * lspci.c (config_fetch): Wanted to merge Matthew's bug fix, but + ended up with rewriting the fetching mechanism to be fully dynamic, + but avoid reading config space registers not explicitly requested. + +2004-06-29 Matthew Wilcox + + * lspci.c: More work on PCI Express dumping. + + * lib/header.h: Updated PCI Express capability definitions. + + * lib/proc.c (proc_read): Removed bogus warning. + + * common.c (xrealloc): Introduced. + + * lspci.man: Added -xxxx. + 2004-06-27 Martin Mares * Released as 2.1.99-test6. diff --git a/README b/README index 9dd8dc6..44f836a 100644 --- a/README +++ b/README @@ -15,6 +15,7 @@ Some more things I intend to merge before the 2.2.0 release: o pcimodules and possibly other Linux module related stuff o New ID's from the pciids project + o Avoid calling show_ext_caps() for non-ext devices. ############################################################################ diff --git a/common.c b/common.c index a8d39d5..9181e4e 100644 --- a/common.c +++ b/common.c @@ -35,6 +35,15 @@ xmalloc(unsigned int howmuch) return p; } +void * +xrealloc(void *ptr, unsigned int howmuch) +{ + void *p = realloc(ptr, howmuch); + if (!p) + die("Unable to allocate %d bytes of memory", howmuch); + return p; +} + int parse_generic_option(int i, struct pci_access *pacc, char *optarg) { diff --git a/lib/header.h b/lib/header.h index 9d7643a..54b845d 100644 --- a/lib/header.h +++ b/lib/header.h @@ -695,7 +695,6 @@ #define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ #define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ #define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ -#define PCI_EXP_DEVCAP_READRQ 0x38000 /* Max_Read_Request_Size */ #define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ #define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ #define PCI_EXP_DEVCTL 0x8 /* Device Control */ @@ -703,12 +702,12 @@ #define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ #define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ #define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ -#define PCI_EXP_DEVCTL_URS 0x0010 /* Unsupported Request Severity */ +#define PCI_EXP_DEVCTL_RELAXED 0x0010 /* Enable Relaxed Ordering */ #define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ #define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ #define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ -#define PCI_EXP_DEVCTL_STOP 0x0800 /* Complete Pending Transactions */ +#define PCI_EXP_DEVCTL_NOSNOOP 0x0800 /* Enable No Snoop */ #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ #define PCI_EXP_DEVSTA 0xa /* Device Status */ #define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ @@ -718,12 +717,52 @@ #define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ #define PCI_EXP_LNKCAP 0xc /* Link Capabilities */ +#define PCI_EXP_LNKCAP_SPEED 0x0000f /* Maximum Link Speed */ +#define PCI_EXP_LNKCAP_WIDTH 0x003f0 /* Maximum Link Width */ +#define PCI_EXP_LNKCAP_ASPM 0x00c00 /* Active State Power Management */ +#define PCI_EXP_LNKCAP_L0S 0x07000 /* L0s Acceptable Latency */ +#define PCI_EXP_LNKCAP_L1 0x38000 /* L1 Acceptable Latency */ +#define PCI_EXP_LNKCAP_PORT 0xff000000 /* Port Number */ #define PCI_EXP_LNKCTL 0x10 /* Link Control */ +#define PCI_EXP_LNKCTL_ASPM 0x0003 /* ASPM Control */ +#define PCI_EXP_LNKCTL_RCB 0x0008 /* Read Completion Boundary */ +#define PCI_EXP_LNKCTL_DISABLE 0x0010 /* Link Disable */ +#define PCI_EXP_LNKCTL_RETRAIN 0x0020 /* Retrain Link */ +#define PCI_EXP_LNKCTL_CLOCK 0x0040 /* Common Clock Configuration */ +#define PCI_EXP_LNKCTL_XSYNCH 0x0080 /* Extended Synch */ #define PCI_EXP_LNKSTA 0x12 /* Link Status */ +#define PCI_EXP_LNKSTA_SPEED 0x000f /* Negotiated Link Speed */ +#define PCI_EXP_LNKSTA_WIDTH 0x03f0 /* Negotiated Link Width */ +#define PCI_EXP_LNKSTA_TR_ERR 0x0400 /* Training Error */ +#define PCI_EXP_LNKSTA_TRAIN 0x0800 /* Link Training */ +#define PCI_EXP_LNKSTA_SL_CLK 0x1000 /* Slot Clock Configuration */ #define PCI_EXP_SLTCAP 0x14 /* Slot Capabilities */ +#define PCI_EXP_SLTCAP_ATNB 0x0001 /* Attention Button Present */ +#define PCI_EXP_SLTCAP_PWRC 0x0002 /* Power Controller Present */ +#define PCI_EXP_SLTCAP_MRL 0x0004 /* MRL Sensor Present */ +#define PCI_EXP_SLTCAP_ATNI 0x0008 /* Attention Indicator Present */ +#define PCI_EXP_SLTCAP_PWRI 0x0010 /* Power Indicator Present */ +#define PCI_EXP_SLTCAP_HPS 0x0020 /* Hot-Plug Surprise */ +#define PCI_EXP_SLTCAP_HPC 0x0040 /* Hot-Plug Capable */ +#define PCI_EXP_SLTCAP_PWR_VAL 0x00007f80 /* Slot Power Limit Value */ +#define PCI_EXP_SLTCAP_PWR_SCL 0x00018000 /* Slot Power Limit Scale */ +#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */ #define PCI_EXP_SLTCTL 0x18 /* Slot Control */ +#define PCI_EXP_SLTCTL_ATNB 0x0001 /* Attention Button Pressed Enable */ +#define PCI_EXP_SLTCTL_PWRF 0x0002 /* Power Fault Detected Enable */ +#define PCI_EXP_SLTCTL_MRLS 0x0004 /* MRL Sensor Changed Enable */ +#define PCI_EXP_SLTCTL_PRSD 0x0008 /* Presence Detect Changed Enable */ +#define PCI_EXP_SLTCTL_CMDC 0x0010 /* Command Completed Interrupt Enable */ +#define PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */ +#define PCI_EXP_SLTCTL_ATNI 0x00C0 /* Attention Indicator Control */ +#define PCI_EXP_SLTCTL_PWRI 0x0300 /* Power Indicator Control */ +#define PCI_EXP_SLTCTL_PWRC 0x0400 /* Power Controller Control */ #define PCI_EXP_SLTSTA 0x1a /* Slot Status */ #define PCI_EXP_RTCTL 0x1c /* Root Control */ +#define PCI_EXP_RTCTL_SECEE 0x1 /* System Error on Correctable Error */ +#define PCI_EXP_RTCTL_SENFEE 0x1 /* System Error on Non-Fatal Error */ +#define PCI_EXP_RTCTL_SEFEE 0x1 /* System Error on Fatal Error */ +#define PCI_EXP_RTCTL_PMEIE 0x1 /* PME Interrupt Enable */ #define PCI_EXP_RTSTA 0x20 /* Root Status */ /* MSI-X */ diff --git a/lib/proc.c b/lib/proc.c index 9d02b41..ebc66e4 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -153,7 +153,7 @@ proc_read(struct pci_dev *d, int pos, byte *buf, int len) return 0; } else if (res != len) - d->access->warning("proc_read: tried to read %d bytes at %d, but got only %d", len, pos, res); + return 0; return 1; } diff --git a/lspci.c b/lspci.c index 6d89e91..dec904d 100644 --- a/lspci.c +++ b/lspci.c @@ -63,12 +63,31 @@ 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) { @@ -79,15 +98,16 @@ scan_device(struct pci_dev *p) d = xmalloc(sizeof(struct device)); bzero(d, sizeof(*d)); d->dev = p; - d->config_cnt = 64; + 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."); - d->config_cnt = 128; } 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); @@ -109,14 +129,6 @@ scan_devices(void) } } -static int -config_fetch(struct device *d, unsigned int pos, unsigned int len) -{ - if (pos + len < d->config_cnt) - return 1; - return pci_read_block(d->dev, pos, d->config + pos, len); -} - /* Config space accesses */ static inline byte @@ -921,16 +933,172 @@ static void show_debug(void) static float power_limit(int value, int scale) { - float scales[4] = { 1.0, 0.1, 0.01, 0.001 }; + static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 }; return value * scales[scale]; } -static void -show_express(struct device *d, int where, int cap) +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) @@ -942,16 +1110,18 @@ show_express(struct device *d, int where, int cap) 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 Bridge"); + printf("PCI/PCI-X Bridge"); break; default: printf("Unknown type"); @@ -960,28 +1130,20 @@ show_express(struct device *d, int where, int cap) if (verbose < 2) return; - t = get_conf_long(d, where + PCI_EXP_DEVCAP); - printf("\t\tMaxPayloadSizeSupported %d\n", 128 << (t & PCI_EXP_DEVCAP_PAYLOAD)); - printf("\t\tPhantomFunctions %d\n", 1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)); - printf("\t\tExtendedTags%c\n", FLAG(t, PCI_EXP_DEVCAP_EXT_TAG)); - printf("\t\tL0sLatency <%dns\n", 64 << ((t & PCI_EXP_DEVCAP_L0S) >> 6)); - printf("\t\tL1Latency <%dus\n", 1 << ((t & PCI_EXP_DEVCAP_L1) >> 9)); - if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END)) - printf("\t\tAtnBtn%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)); + size = 16; + if (slot) + size = 24; if (type == PCI_EXP_TYPE_ROOT_PORT) - printf("\t\tMaxReadRequestSizeSupported %d\n", 128 << ((t & PCI_EXP_DEVCAP_READRQ) >> 15)); - if (type == PCI_EXP_TYPE_UPSTREAM) - printf("\t\tSlotPowerLimit %f\n", - power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18, - (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26)); + size = 32; + if (!config_fetch(d, where + PCI_EXP_DEVCAP, size)) + return; - w = get_conf_word(d, where + PCI_EXP_DEVCTL); - printf("\t\tError Reporting: 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)); + 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 @@ -1016,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) { @@ -1081,6 +1312,7 @@ show_caps(struct device *d) where = next; } } + show_ext_caps(d); } static void diff --git a/lspci.man b/lspci.man index 58cfbd7..a5112d2 100644 --- a/lspci.man +++ b/lspci.man @@ -47,6 +47,9 @@ as several PCI devices when you try to read undefined portions of the config space (this behavior probably doesn't violate the PCI standard, but it's at least very stupid). .TP +.B -xxxx +Show hexadecimal dump of the extended PCI configuration space. +.TP .B -b Bus-centric view. Show all IRQ numbers and addresses as seen by the cards on the PCI bus instead of as seen by the kernel. diff --git a/pciutils.h b/pciutils.h index 31a4ce1..dcedbe6 100644 --- a/pciutils.h +++ b/pciutils.h @@ -19,6 +19,7 @@ void die(char *msg, ...) NONRET; void *xmalloc(unsigned int howmuch); +void *xrealloc(void *ptr, unsigned int howmuch); int parse_generic_option(int i, struct pci_access *pacc, char *optarg); #ifdef HAVE_PM_LINUX_PROC