From 71aeac6364db0d0386be9df6927c1468414719ad Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Mon, 25 May 2020 12:26:07 +0200 Subject: [PATCH] lspci: Generelized decoding of DVSEC extended capability We decode the DVSEC capability header first. If we recognize the vendor and ID (and the length is at least the minimum we need), we call a specific function to interpret the rest of the capability. --- ls-ecaps.c | 58 +++++++++++++++--------------------------------------- 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/ls-ecaps.c b/ls-ecaps.c index fca1921..e0c0e1a 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -1,7 +1,7 @@ /* * The PCI Utilities -- Show Extended Capabilities * - * Copyright (c) 1997--2010 Martin Mares + * Copyright (c) 1997--2020 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -635,11 +635,11 @@ cap_rclink(struct device *d, int where) } static void -cap_cxl(struct device *d, int where) +cap_dvsec_cxl(struct device *d, int where) { u16 l; - printf("CXL Designated Vendor-Specific:\n"); + printf(": CXL\n"); if (verbose < 2) return; @@ -661,51 +661,28 @@ cap_cxl(struct device *d, int where) printf("\t\tCXLSta:\tViral%c\n", FLAG(l, PCI_CXL_STATUS_VIRAL)); } -static int -is_cxl_cap(struct device *d, int where) -{ - u32 hdr; - u16 w; - - if (!config_fetch(d, where + PCI_DVSEC_HEADER1, 8)) - return 0; - - /* Check for supported Vendor */ - hdr = get_conf_long(d, where + PCI_DVSEC_HEADER1); - w = BITS(hdr, 0, 16); - if (w != PCI_VENDOR_ID_INTEL) - return 0; - - /* Check for Designated Vendor-Specific ID */ - hdr = get_conf_long(d, where + PCI_DVSEC_HEADER2); - w = BITS(hdr, 0, 16); - if (w == PCI_DVSEC_INTEL_CXL) - return 1; - - return 0; -} - static void cap_dvsec(struct device *d, int where) { - u32 hdr; - - printf("Designated Vendor-Specific:\n"); + printf("Designated Vendor-Specific: "); if (!config_fetch(d, where + PCI_DVSEC_HEADER1, 8)) { printf("\n"); return; } - hdr = get_conf_long(d, where + PCI_DVSEC_HEADER1); - printf("\t\tDVSEC Vendor ID=%04x Rev=%d Len=%03x \n", - BITS(hdr, 0, 16), - BITS(hdr, 16, 4), - BITS(hdr, 20, 12)); + u32 hdr = get_conf_long(d, where + PCI_DVSEC_HEADER1); + u16 vendor = BITS(hdr, 0, 16); + byte rev = BITS(hdr, 16, 4); + u16 len = BITS(hdr, 20, 12); - hdr = get_conf_long(d, where + PCI_DVSEC_HEADER2); - printf("\t\tDVSEC ID=%04x \n", - BITS(hdr, 0, 16)); + u16 id = get_conf_long(d, where + PCI_DVSEC_HEADER2); + + printf("Vendor=%04x ID=%04x Rev=%d Len=%d", vendor, id, rev, len); + if (vendor == PCI_VENDOR_ID_INTEL && id == PCI_DVSEC_INTEL_CXL && len >= 16) + cap_dvsec_cxl(d, where); + else + printf(" \n"); } static void @@ -998,10 +975,7 @@ show_ext_caps(struct device *d, int type) printf("Readiness Time Reporting \n"); break; case PCI_EXT_CAP_ID_DVSEC: - if (is_cxl_cap(d, where)) - cap_cxl(d, where); - else - cap_dvsec(d, where); + cap_dvsec(d, where); break; case PCI_EXT_CAP_ID_VF_REBAR: printf("VF Resizable BAR \n"); -- 2.39.5