]> git.ipfire.org Git - thirdparty/pciutils.git/blobdiff - ls-caps.c
ls-ecaps: Correct the link state reporting
[thirdparty/pciutils.git] / ls-caps.c
index 91acb59982ac2a32baafe9b81b584d5fdc004655..65e92e687591ef84092a9f84e57ec814d6fd5a44 100644 (file)
--- a/ls-caps.c
+++ b/ls-caps.c
@@ -3,7 +3,9 @@
  *
  *     Copyright (c) 1997--2018 Martin Mares <mj@ucw.cz>
  *
- *     Can be freely distributed and used under the terms of the GNU GPL.
+ *     Can be freely distributed and used under the terms of the GNU GPL v2+.
+ *
+ *     SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include <stdio.h>
@@ -44,8 +46,8 @@ cap_pm(struct device *d, int where, int cap)
   b = get_conf_byte(d, where + PCI_PM_PPB_EXTENSIONS);
   if (b)
     printf("\t\tBridge: PM%c B3%c\n",
-          FLAG(t, PCI_PM_BPCC_ENABLE),
-          FLAG(~t, PCI_PM_PPB_B2_B3));
+          FLAG(b, PCI_PM_BPCC_ENABLE),
+          FLAG(~b, PCI_PM_PPB_B2_B3));
 }
 
 static void
@@ -578,7 +580,7 @@ cap_ht(struct device *d, int where, int cmd)
            break;
          offl = get_conf_long(d, where + PCI_HT_MSIM_ADDR_LO);
          offh = get_conf_long(d, where + PCI_HT_MSIM_ADDR_HI);
-         printf("\t\tMapping Address Base: %016llx\n", ((unsigned long long)offh << 32) | (offl & ~0xfffff));
+         printf("\t\tMapping Address Base: %016" PCI_U64_FMT_X "\n", ((u64)offh << 32) | (offl & ~0xfffff));
        }
       break;
     case PCI_HT_CMD_TYP_DR:
@@ -659,18 +661,16 @@ static int exp_downstream_port(int type)
 static void show_power_limit(int value, int scale)
 {
   static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
-  static const int scale0_values[3] = { 250, 275, 300 };
 
-  if (scale == 0 && value >= 0xF0)
+  if (scale == 0 && value == 0xFF)
     {
-      /* F3h to FFh = Reserved for Slot Power Limit values above 300 W */
-      if (value >= 0xF3)
-        {
-          printf(">300W");
-          return;
-        }
-      value = scale0_values[value - 0xF0];
+      printf(">600W");
+      return;
     }
+
+  if (scale == 0 && value >= 0xF0 && value <= 0xFE)
+    value = 250 + 25 * (value - 0xF0);
+
   printf("%gW", value * scales[scale]);
 }
 
@@ -717,6 +717,7 @@ static void cap_express_dev(struct device *d, int where, int type)
       printf(" SlotPowerLimit ");
       show_power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18, (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26);
     }
+  printf(" TEE-IO%c", FLAG(t, PCI_EXP_DEVCAP_TEE_IO));
   printf("\n");
 
   w = get_conf_word(d, where + PCI_EXP_DEVCTL);
@@ -771,13 +772,16 @@ static char *link_speed(int speed)
     }
 }
 
-static char *link_compare(int sta, int cap)
+static char *link_compare(int type, int sta, int cap)
 {
-  if (sta < cap)
-    return "downgraded";
   if (sta > cap)
-    return "strange";
-  return "ok";
+    return " (overdriven)";
+  if (sta == cap)
+    return "";
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_DOWNSTREAM) ||
+      (type == PCI_EXP_TYPE_PCIE_BRIDGE))
+    return "";
+  return " (downgraded)";
 }
 
 static char *aspm_support(int code)
@@ -838,7 +842,7 @@ static void cap_express_link(struct device *d, int where, int type)
   if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) ||
       (type == PCI_EXP_TYPE_LEG_END) || (type == PCI_EXP_TYPE_PCI_BRIDGE))
     printf(" RCB %d bytes,", w & PCI_EXP_LNKCTL_RCB ? 128 : 64);
-  printf(" Disabled%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
+  printf(" LnkDisable%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
        FLAG(w, PCI_EXP_LNKCTL_DISABLE),
        FLAG(w, PCI_EXP_LNKCTL_CLOCK),
        FLAG(w, PCI_EXP_LNKCTL_XSYNCH),
@@ -850,11 +854,11 @@ static void cap_express_link(struct device *d, int where, int type)
   w = get_conf_word(d, where + PCI_EXP_LNKSTA);
   sta_speed = w & PCI_EXP_LNKSTA_SPEED;
   sta_width = (w & PCI_EXP_LNKSTA_WIDTH) >> 4;
-  printf("\t\tLnkSta:\tSpeed %s (%s), Width x%d (%s)\n",
+  printf("\t\tLnkSta:\tSpeed %s%s, Width x%d%s\n",
        link_speed(sta_speed),
-       link_compare(sta_speed, cap_speed),
+       link_compare(type, sta_speed, cap_speed),
        sta_width,
-       link_compare(sta_width, cap_width));
+       link_compare(type, sta_width, cap_width));
   printf("\t\t\tTrErr%c Train%c SlotClk%c DLActive%c BWMgmt%c ABWMgmt%c\n",
        FLAG(w, PCI_EXP_LNKSTA_TR_ERR),
        FLAG(w, PCI_EXP_LNKSTA_TRAIN),
@@ -1082,7 +1086,7 @@ device_has_memory_space_bar(struct device *d)
   int i, found = 0;
 
   for (i=0; i<6; i++)
-    if (p->base_addr[i] && p->size[i])
+    if (p->base_addr[i] || p->size[i])
       {
         if (!(p->base_addr[i] & PCI_BASE_ADDRESS_SPACE_IO))
           {
@@ -1150,12 +1154,9 @@ static void cap_express_dev2(struct device *d, int where, int type)
     }
 
   w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
-  printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c LTR%c 10BitTagReq%c OBFF %s,",
+  printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c",
        cap_express_dev2_timeout_value(PCI_EXP_DEVCTL2_TIMEOUT_VALUE(w)),
-       FLAG(w, PCI_EXP_DEVCTL2_TIMEOUT_DIS),
-       FLAG(w, PCI_EXP_DEVCTL2_LTR),
-       FLAG(w, PCI_EXP_DEVCTL2_10BIT_TAG_REQ),
-       cap_express_devctl2_obff(PCI_EXP_DEVCTL2_OBFF(w)));
+       FLAG(w, PCI_EXP_DEVCTL2_TIMEOUT_DIS));
   if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
     printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEVCTL2_ARI));
   else
@@ -1173,6 +1174,15 @@ static void cap_express_dev2(struct device *d, int where, int type)
         printf(" EgressBlck%c", FLAG(w, PCI_EXP_DEVCTL2_ATOMICOP_EGRESS_BLOCK));
       printf("\n");
     }
+  printf("\t\t\t IDOReq%c IDOCompl%c LTR%c EmergencyPowerReductionReq%c\n",
+       FLAG(w, PCI_EXP_DEVCTL2_IDO_REQ_EN),
+       FLAG(w, PCI_EXP_DEVCTL2_IDO_CMP_EN),
+       FLAG(w, PCI_EXP_DEVCTL2_LTR),
+       FLAG(w, PCI_EXP_DEVCTL2_EPR_REQ));
+  printf("\t\t\t 10BitTagReq%c OBFF %s, EETLPPrefixBlk%c\n",
+       FLAG(w, PCI_EXP_DEVCTL2_10BIT_TAG_REQ),
+       cap_express_devctl2_obff(PCI_EXP_DEVCTL2_OBFF(w)),
+       FLAG(w, PCI_EXP_DEVCTL2_EE_TLP_BLK));
 }
 
 static const char *cap_express_link2_speed_cap(int vector)
@@ -1182,8 +1192,10 @@ static const char *cap_express_link2_speed_cap(int vector)
    * permitted to skip support for any data rates between 2.5GT/s and the
    * highest supported rate.
    */
-  if (vector & 0x60)
+  if (vector & 0x40)
     return "RsvdP";
+  if (vector & 0x20)
+    return "2.5-64GT/s";
   if (vector & 0x10)
     return "2.5-32GT/s";
   if (vector & 0x08)
@@ -1427,7 +1439,7 @@ cap_express(struct device *d, int where, int cap)
     default:
       printf("Unknown type %d", type);
   }
-  printf(", MSI %02x\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9);
+  printf(", IntMsgNum %d\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9);
   if (verbose < 2)
     return type;