diff mbox

pciutils: Add decode for Atomic Ops in lspci

Message ID 1482797232-13210-1-git-send-email-satananda.burla@caviumnetworks.com
State Not Applicable
Headers show

Commit Message

Satanand Burla Dec. 27, 2016, 12:07 a.m. UTC
This adds support for decoding Atomic Ops added in the following ECN
https://pcisig.com/sites/default/files/specification_documents/ECN_Atomic_Ops_080417.pdf

Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
---
 lib/header.h |  6 ++++++
 ls-caps.c    | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 66 insertions(+), 6 deletions(-)

Comments

Martin Mareš Dec. 27, 2016, 12:19 a.m. UTC | #1
Hi!

> This adds support for decoding Atomic Ops added in the following ECN
> https://pcisig.com/sites/default/files/specification_documents/ECN_Atomic_Ops_080417.pdf

In general, I would like to have Atomic Ops support in lspci,
but your patch has a couple of issues.

First of all, its coding style is inconsistent with the rest of the
code (and also with itself).

>  #define  PCI_EXP_DEV2_TIMEOUT_DIS	0x0010	/* Completion Timeout Disable Supported */
> +#define  PCI_EXP_DEV2_ATOMICOP_REQUESTER_EN	0x0040	/*AtomicOp RequesterEnable */
> +#define  PCI_EXP_DEV2_ATOMICOP_EGRESS_BLOCK	0x0080	/*AtomicOp Egress Blocking */

Coding style: comments.

> +static int
> +device_has_memory_space_bar(struct device *d)
> +{
> +  struct pci_dev *p = d->dev;
> +  int i,cnt = 0, found = 0;

Coding style: spaces.

> +  byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
> +
> +  switch (htype)
> +    {
> +    case PCI_HEADER_TYPE_NORMAL:
> +      cnt=6;
> +      break;
> +    case PCI_HEADER_TYPE_BRIDGE:
> +      cnt=2;
> +      break;
> +    case PCI_HEADER_TYPE_CARDBUS:
> +      cnt = 1;
> +      break;
> +    default:
> +      return 0;
> +    }
> +
> +  for (i=0; i<cnt; i++)
> +    {
> +      pciaddr_t pos = p->base_addr[i];
> +      pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;
> +      u32 flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
> +      if (flg == 0xffffffff)
> +        flg = 0;
> +      if (!pos && !flg && !len)
> +        continue;
> +      if ((flg & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
> +        {
> +          found = 1;
> +          break;
> +	 }
> +    }
> +  return found;
> +}

I do not understand why this is so complicated. Just ask pci_fill_info()
for PCI_FILL_BASES and use p->base_addr[]. No need to touch the config
registers, no need to switch on header type.

>  static void cap_express_dev2(struct device *d, int where, int type)
>  {
>    u32 l;
> @@ -973,9 +1013,18 @@ static void cap_express_dev2(struct device *d, int where, int type)
>  	FLAG(l, PCI_EXP_DEVCAP2_LTR),
>  	cap_express_devcap2_obff(PCI_EXP_DEVCAP2_OBFF(l)));
>    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");
> +    printf(" ARIFwd%c", FLAG(l, PCI_EXP_DEV2_ARI));
> +  printf("\n\t\t\t");
> +  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_UPSTREAM) ||
> +      (type == PCI_EXP_TYPE_DOWNSTREAM))

Coding style: superfluous parentheses.

> +    printf(" AtomicOP Routing%c", FLAG(l, PCI_EXP_DEVCAP2_ATOMICOP_ROUTING));
> +  if (type == PCI_EXP_TYPE_ROOT_PORT || device_has_memory_space_bar(d))
> +    {
> +      printf(" 32bit AtomicOP Completer%c", FLAG(l, PCI_EXP_DEVCAP2_32BIT_ATOMICOP_COMP));
> +      printf(" 64bit AtomicOP Completer%c", FLAG(l, PCI_EXP_DEVCAP2_64BIT_ATOMICOP_COMP));
> +      printf(" 128bit CAS Completer%c", FLAG(l, PCI_EXP_DEVCAP2_128BIT_CAS_COMP));
> +    }
> +  printf("\n");

This does not look good. It might write an empty line (if no condition
matches), it will write a space after a tab, and the output will be
hard to comprehend.

What about output like this?

	AtomicOPs: Routing+ 32bit+ 64bit- 128bitCAS-

>    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");
> +    printf(" ARIFwd%c", FLAG(w, PCI_EXP_DEV2_ARI));
> +  printf("\n\t\t\t");
> +  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ENDPOINT)
> +    printf(" AtomicOp Requester En%c", FLAG(w, PCI_EXP_DEV2_ATOMICOP_REQUESTER_EN));
> +  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_UPSTREAM) ||
> +      (type == PCI_EXP_TYPE_DOWNSTREAM))
> +    printf(" AtomicOP Egress Blocking%c", FLAG(l, PCI_EXP_DEV2_ATOMICOP_EGRESS_BLOCK));
> +  printf("\n");

Same here.

				Have a nice fortnight
diff mbox

Patch

diff --git a/lib/header.h b/lib/header.h
index a556638..9bf980d 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -859,7 +859,13 @@ 
 #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_ATOMICOP_REQUESTER_EN	0x0040	/*AtomicOp RequesterEnable */
+#define  PCI_EXP_DEV2_ATOMICOP_EGRESS_BLOCK	0x0080	/*AtomicOp Egress Blocking */
 #define  PCI_EXP_DEV2_ARI		0x0020	/* ARI Forwarding */
+#define  PCI_EXP_DEVCAP2_ATOMICOP_ROUTING	0x0040	/* AtomicOp Routing Supported */
+#define  PCI_EXP_DEVCAP2_32BIT_ATOMICOP_COMP	0x0080	/* 32bit AtomicOp Completer Supported */
+#define  PCI_EXP_DEVCAP2_64BIT_ATOMICOP_COMP	0x0100	/* 64bit AtomicOp Completer Supported */
+#define  PCI_EXP_DEVCAP2_128BIT_CAS_COMP	0x0200	/* 128bit CAS  Completer Supported */
 #define  PCI_EXP_DEV2_LTR		0x0400	/* LTR enabled */
 #define  PCI_EXP_DEV2_OBFF(x)		(((x) >> 13) & 3) /* OBFF enabled */
 #define PCI_EXP_DEVSTA2			0x2a	/* Device Status */
diff --git a/ls-caps.c b/ls-caps.c
index 7ff6c67..abed607 100644
--- a/ls-caps.c
+++ b/ls-caps.c
@@ -961,6 +961,46 @@  static const char *cap_express_devctl2_obff(int obff)
     }
 }
 
+static int
+device_has_memory_space_bar(struct device *d)
+{
+  struct pci_dev *p = d->dev;
+  int i,cnt = 0, found = 0;
+  byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
+
+  switch (htype)
+    {
+    case PCI_HEADER_TYPE_NORMAL:
+      cnt=6;
+      break;
+    case PCI_HEADER_TYPE_BRIDGE:
+      cnt=2;
+      break;
+    case PCI_HEADER_TYPE_CARDBUS:
+      cnt = 1;
+      break;
+    default:
+      return 0;
+    }
+
+  for (i=0; i<cnt; i++)
+    {
+      pciaddr_t pos = p->base_addr[i];
+      pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;
+      u32 flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
+      if (flg == 0xffffffff)
+        flg = 0;
+      if (!pos && !flg && !len)
+        continue;
+      if ((flg & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
+        {
+          found = 1;
+          break;
+	 }
+    }
+  return found;
+}
+
 static void cap_express_dev2(struct device *d, int where, int type)
 {
   u32 l;
@@ -973,9 +1013,18 @@  static void cap_express_dev2(struct device *d, int where, int type)
 	FLAG(l, PCI_EXP_DEVCAP2_LTR),
 	cap_express_devcap2_obff(PCI_EXP_DEVCAP2_OBFF(l)));
   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");
+    printf(" ARIFwd%c", FLAG(l, PCI_EXP_DEV2_ARI));
+  printf("\n\t\t\t");
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_UPSTREAM) ||
+      (type == PCI_EXP_TYPE_DOWNSTREAM))
+    printf(" AtomicOP Routing%c", FLAG(l, PCI_EXP_DEVCAP2_ATOMICOP_ROUTING));
+  if (type == PCI_EXP_TYPE_ROOT_PORT || device_has_memory_space_bar(d))
+    {
+      printf(" 32bit AtomicOP Completer%c", FLAG(l, PCI_EXP_DEVCAP2_32BIT_ATOMICOP_COMP));
+      printf(" 64bit AtomicOP Completer%c", FLAG(l, PCI_EXP_DEVCAP2_64BIT_ATOMICOP_COMP));
+      printf(" 128bit CAS Completer%c", FLAG(l, PCI_EXP_DEVCAP2_128BIT_CAS_COMP));
+    }
+  printf("\n");
 
   w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
   printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c, LTR%c, OBFF %s",
@@ -984,9 +1033,14 @@  static void cap_express_dev2(struct device *d, int where, int type)
 	FLAG(w, PCI_EXP_DEV2_LTR),
 	cap_express_devctl2_obff(PCI_EXP_DEV2_OBFF(w)));
   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");
+    printf(" ARIFwd%c", FLAG(w, PCI_EXP_DEV2_ARI));
+  printf("\n\t\t\t");
+  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ENDPOINT)
+    printf(" AtomicOp Requester En%c", FLAG(w, PCI_EXP_DEV2_ATOMICOP_REQUESTER_EN));
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_UPSTREAM) ||
+      (type == PCI_EXP_TYPE_DOWNSTREAM))
+    printf(" AtomicOP Egress Blocking%c", FLAG(l, PCI_EXP_DEV2_ATOMICOP_EGRESS_BLOCK));
+  printf("\n");
 }
 
 static const char *cap_express_link2_speed(int type)