]> mj.ucw.cz Git - pciutils.git/commitdiff
PCI Express Device, Link and Slot 2 capabilities support
authorZhao, Yu <yu.zhao@intel.com>
Thu, 3 Jul 2008 09:39:16 +0000 (17:39 +0800)
committerMartin Mares <mj@ucw.cz>
Tue, 26 Aug 2008 11:37:35 +0000 (13:37 +0200)
Signed-off-by: Yu Zhao <yu.zhao@intel.com>
lib/header.h |   22 +++++++
lspci.c      |  166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 186 insertions(+), 2 deletions(-)

lib/header.h
lspci.c

index a53eccceace7a73740e11e7ddc62af16cd58d47f..b92baadf479ad5bfb733f448207cfc21a5a57583 100644 (file)
 #define  PCI_EXP_RTSTA_PME_REQID   0x0000ffff /* PME Requester ID */
 #define  PCI_EXP_RTSTA_PME_STATUS  0x00010000 /* PME Status */
 #define  PCI_EXP_RTSTA_PME_PENDING 0x00020000 /* PME is Pending */
+#define PCI_EXP_DEVCAP2                        0x24    /* Device capabilities 2 */
+#define PCI_EXP_DEVCTL2                        0x28    /* Device Control */
+#define  PCI_EXP_DEV2_TIMEOUT_RANGE(x) ((x) & 0xf) /* Completion Timeout Ranges Supported */
+#define  PCI_EXP_DEV2_TIMEOUT_VALUE(x) ((x) & 0xf) /* Completion Timeout Value */
+#define  PCI_EXP_DEV2_TIMEOUT_DIS      0x0010  /* Completion Timeout Disable Supported */
+#define  PCI_EXP_DEV2_ARI              0x0020  /* ARI Forwarding */
+#define PCI_EXP_DEVSTA2                        0x2a    /* Device Status */
+#define PCI_EXP_LNKCAP2                        0x2c    /* Link Capabilities */
+#define PCI_EXP_LNKCTL2                        0x30    /* Link Control */
+#define  PCI_EXP_LNKCTL2_SPEED(x)      ((x) & 0xf) /* Target Link Speed */
+#define  PCI_EXP_LNKCTL2_CMPLNC                0x0010  /* Enter Compliance */
+#define  PCI_EXP_LNKCTL2_SPEED_DIS     0x0020  /* Hardware Autonomous Speed Disable */
+#define  PCI_EXP_LNKCTL2_DEEMPHASIS(x) (((x) >> 6) & 1) /* Selectable De-emphasis */
+#define  PCI_EXP_LNKCTL2_MARGIN(x)     (((x) >> 7) & 7) /* Transmit Margin */
+#define  PCI_EXP_LNKCTL2_MOD_CMPLNC    0x0400  /* Enter Modified Compliance */
+#define  PCI_EXP_LNKCTL2_CMPLNC_SOS    0x0800  /* Compliance SOS */
+#define  PCI_EXP_LNKCTL2_COM_DEEMPHASIS(x) (((x) >> 12) & 1) /* Compliance De-emphasis */
+#define PCI_EXP_LNKSTA2                        0x32    /* Link Status */
+#define  PCI_EXP_LINKSTA2_DEEMPHASIS(x)        ((x) & 1)       /* Current De-emphasis Level */
+#define PCI_EXP_SLTCAP2                        0x34    /* Slot Capabilities */
+#define PCI_EXP_SLTCTL2                        0x38    /* Slot Control */
+#define PCI_EXP_SLTSTA2                        0x3a    /* Slot Status */
 
 /* MSI-X */
 #define  PCI_MSIX_ENABLE       0x8000
diff --git a/lspci.c b/lspci.c
index 0515fcd6ad8d89c64bcc54fdf5d61da73163285b..1d3018a8445a4777edf54834843da4bd0ed1bf34 100644 (file)
--- a/lspci.c
+++ b/lspci.c
@@ -1038,8 +1038,6 @@ static void cap_express_dev(struct device *d, int where, int type)
        FLAG(w, PCI_EXP_DEVSTA_URD),
        FLAG(w, PCI_EXP_DEVSTA_AUXPD),
        FLAG(w, PCI_EXP_DEVSTA_TRPND));
-
-  /* FIXME: Second set of control/status registers is not supported yet. */
 }
 
 static char *link_speed(int speed)
@@ -1195,6 +1193,156 @@ static void cap_express_root(struct device *d, int where)
        FLAG(w, PCI_EXP_RTSTA_PME_PENDING));
 }
 
+static const char *cap_express_dev2_timeout_range(int type)
+{
+  /* Decode Completion Timeout Ranges. */
+  switch (type)
+    {
+      case 0:
+       return "Not Supported";
+      case 1:
+       return "Range A";
+      case 2:
+       return "Range B";
+      case 3:
+       return "Range AB";
+      case 6:
+       return "Range BC";
+      case 7:
+       return "Range ABC";
+      case 14:
+       return "Range BCD";
+      case 15:
+       return "Range ABCD";
+      default:
+       return "Unknown";
+    }
+}
+
+static const char *cap_express_dev2_timeout_value(int type)
+{
+  /* Decode Completion Timeout Value. */
+  switch (type)
+    {
+      case 0:
+       return "50us to 50ms";
+      case 1:
+       return "50us to 100us";
+      case 2:
+       return "1ms to 10ms";
+      case 5:
+       return "16ms to 55ms";
+      case 6:
+       return "65ms to 210ms";
+      case 9:
+       return "260ms to 900ms";
+      case 10:
+       return "1s to 3.5s";
+      case 13:
+       return "4s to 13s";
+      case 14:
+       return "17s to 64s";
+      default:
+       return "Unknown";
+    }
+}
+
+static void cap_express_dev2(struct device *d, int where, int type)
+{
+  u32 l;
+  u16 w;
+
+  l = get_conf_long(d, where + PCI_EXP_DEVCAP2);
+  printf("\t\tDevCap2: Completion Timeout: %s, TimeoutDis%c",
+       cap_express_dev2_timeout_range(PCI_EXP_DEV2_TIMEOUT_RANGE(l)),
+       FLAG(l, PCI_EXP_DEV2_TIMEOUT_DIS));
+  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
+    printf(" ARIFwd%c\n", FLAG(l, PCI_EXP_DEV2_ARI));
+  else
+    printf("\n");
+
+  w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
+  printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c",
+       cap_express_dev2_timeout_value(PCI_EXP_DEV2_TIMEOUT_VALUE(w)),
+       FLAG(w, PCI_EXP_DEV2_TIMEOUT_DIS));
+  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
+    printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEV2_ARI));
+  else
+    printf("\n");
+}
+
+static const char *cap_express_link2_speed(int type)
+{
+  switch (type)
+    {
+      case 0: /* hardwire to 0 means only the 2.5GT/s is supported */
+      case 1:
+       return "2.5GT/s";
+      case 2:
+       return "5GT/s";
+      default:
+       return "Unknown";
+    }
+}
+
+static const char *cap_express_link2_deemphasis(int type)
+{
+  switch (type)
+    {
+      case 0:
+       return "-6dB";
+      case 1:
+       return "-3.5dB";
+      default:
+       return "Unknown";
+    }
+}
+
+static const char *cap_express_link2_transmargin(int type)
+{
+  switch (type)
+    {
+      case 0:
+       return "Normal Operating Range";
+      case 1:
+       return "800-1200mV(full-swing)/400-700mV(half-swing)";
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+       return "200-400mV(full-swing)/100-200mV(half-swing)";
+      default:
+       return "Unknown";
+    }
+}
+
+static void cap_express_link2(struct device *d, int where, int type UNUSED)
+{
+  u16 w;
+
+  w = get_conf_word(d, where + PCI_EXP_LNKCTL2);
+  printf("\t\tLnkCtl2: Target Link Speed: %s, EnterCompliance%c SpeedDis%c, Selectable De-emphasis: %s\n"
+       "\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n"
+       "\t\t\t Compliance De-emphasis: %s\n",
+       cap_express_link2_speed(PCI_EXP_LNKCTL2_SPEED(w)),
+       FLAG(w, PCI_EXP_LNKCTL2_CMPLNC),
+       FLAG(w, PCI_EXP_LNKCTL2_SPEED_DIS),
+       cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)),
+       cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)),
+       FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC),
+       FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS),
+       cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
+
+  w = get_conf_word(d, where + PCI_EXP_LNKSTA2);
+  printf("\t\tLnkSta2: Current De-emphasis Level: %s\n",
+       cap_express_link2_deemphasis(PCI_EXP_LINKSTA2_DEEMPHASIS(w)));
+}
+
+static void cap_express_slot2(struct device *d UNUSED, int where UNUSED)
+{
+  /* No capabilities that require this field in PCIe rev2.0 spec. */
+}
+
 static void
 cap_express(struct device *d, int where, int cap)
 {
@@ -1257,6 +1405,20 @@ cap_express(struct device *d, int where, int cap)
     cap_express_slot(d, where);
   if (type == PCI_EXP_TYPE_ROOT_PORT)
     cap_express_root(d, where);
+
+  if ((cap & PCI_EXP_FLAGS_VERS) < 2)
+    return;
+
+  size = 16;
+  if (slot)
+    size = 24;
+  if (!config_fetch(d, where + PCI_EXP_DEVCAP2, size))
+    return;
+
+  cap_express_dev2(d, where, type);
+  cap_express_link2(d, where, type);
+  if (slot)
+    cap_express_slot2(d, where);
 }
 
 static void