linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] lspci: support for CCIX DVSEC
@ 2019-06-27 14:43 Jonathan Cameron
  2019-06-27 14:43 ` [RFC PATCH 1/2] lspci: CCIX DVSEC initial support Jonathan Cameron
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Jonathan Cameron @ 2019-06-27 14:43 UTC (permalink / raw)
  To: linux-pci, Martin Mareš
  Cc: bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm,
	Jonathan Cameron

This series adds support for near complete interpretation of CCIX DVSEC.
Most of the CCIX base 1.0 specification is covered, but a few minor
elements are not currently printed (some of the timeouts and credit
types). That can be rectified in a future version or follow up patch
and isn't necessary for this discussion.

CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
It is flexible in allowed interconnect topologies, but is overlayed
on top of a traditional PCIe tree.  Note that CCIX physical devices
may turn up in a number of different locations in the PCIe tree.

The topology configuration and physical layer controls and description
are presented using PCIe DVSEC structures defined in the CCIX 1.0
base specification.  These use the unique ID granted by the PCISIG.
Note that, whilst it looks like a Vendor ID for this usecase it is
not one and can only be used to identify DVSEC and related CCIX protocol
messages.

So why an RFC?
* Are the lspci maintainers happy to have the tool include support for
  PCI configuration structures that are defined in other standards?
* Is the general approach and code structure appropriate?
* It's a lot of description so chances are some of it isn't in a format
  consistent with the rest of lspci!

The patch set includes and example that was manually created to exercise
much of the parser.  We also have qemu patches to emulate more complex
topologies if anyone wants to experiment.

https://patchwork.kernel.org/cover/11015357/

Example output from lspci -t -F ccix-specex1 -s 03:00.0

03:00.0 Class 0700: Device 19ec:0003 (prog-if 01)
	Subsystem: Device 19ec:0007
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 32 bytes
	Interrupt: pin A routed to IRQ 255
	Region 0: Memory at e0000000 (64-bit, non-prefetchable)
	Region 2: Memory at e4000000 (64-bit, non-prefetchable)
	Region 4: [virtual] Memory at 80000000000 (64-bit, prefetchable)
	Capabilities: [40] Power Management version 3
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [48] MSI: Enable- Count=1/4 Maskable- 64bit+
		Address: 0000000000000000  Data: 0000
	Capabilities: [60] MSI-X: Enable- Count=32 Masked-
		Vector table: BAR=3 offset=00000000
		PBA: BAR=2 offset=00008fe0
	Capabilities: [70] Express (v2) Endpoint, MSI 00
		DevCap:	MaxPayload 1024 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
			ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000W
		DevCtl:	CorrErr+ NonFatalErr+ FatalErr+ UnsupReq-
			RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
			MaxPayload 128 bytes, MaxReadReq 512 bytes
		DevSta:	CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
		LnkCap:	Port #0, Speed 8GT/s, Width x8, ASPM not supported
			ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
		LnkCtl:	ASPM Disabled; RCB 128 bytes Disabled- CommClk-
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 8GT/s (ok), Width x8 (ok)
			TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
		DevCap2: Completion Timeout: Range BC, TimeoutDis+, NROPrPrP-, LTR-
			 10BitTagComp-, 10BitTagReq-, OBFF Not Supported, ExtFmt-, EETLPPrefix-
			 EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
			 FRS-, TPHComp-, ExtTPHComp-
		DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
			 AtomicOpsCtl: ReqEn-
		LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
			 Compliance De-emphasis: -6dB
		LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+, EqualizationPhase1+
			 EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
	Capabilities: [100 v1] Advanced Error Reporting
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
		AERCap:	First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
		HeaderLog: 00000000 00000000 00000000 00000000
	Capabilities: [1c0 v1] Secondary PCI Express
		LnkCtl3: LnkEquIntrruptEn-, PerformEqu-
		LaneErrStat: 0
	Capabilities: [1f0 v1] Virtual Channel
		Caps:	LPEVC=0 RefClk=100ns PATEntryBits=1
		Arb:	Fixed- WRR32- WRR64- WRR128-
		Ctrl:	ArbSelect=Fixed
		Status:	InProgress-
		Port Arbitration Table [500] <?>
		VC0:	Caps:	PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
			Arb:	Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
			Ctrl:	Enable+ ID=0 ArbSelect=Fixed TC/VC=7f
			Status:	NegoPending- InProgress-
		VC1:	Caps:	PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
			Arb:	Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
			Ctrl:	Enable+ ID=1 ArbSelect=Fixed TC/VC=80
			Status:	NegoPending- InProgress-
	Capabilities: [380 v1] Address Translation Service (ATS)
		ATSCap:	Invalidate Queue Depth: 00
		ATSCtl:	Enable-, Smallest Translation Unit: 00
	Capabilities: [600 v0] Designated Vendor-Specific <>
		Vendor:1e2c Version:0
		<CCIX Transport 600>
			TranCap:	ESM+ SR/LR RecalOnrC- CalTime: 500us QuickEqTime: 200ms/208ms
			ESMRateCap:	2.5 GT/s 5 GT/s 8 GT/s 16 GT/s 20 GT/s 25 GT/s 
			ESMStatus:	25 GT/s Cal+
			ESMCtl:		ESM0: 16 GT/s ESM1: 25 GT/s ESM+ ESMCompliance- LR
					ExtEqPhase2TimeOut: 400 ms / 408 ms  ExtEqPhase3TimeOut: 600 ms / 608 ms 
					QuickEqTimeout: Unknown
			ESMEqCtl 20GT/s:	Lane #00: Trans Presets US: 0x1 DS: 0x2
						Lane #01: Trans Presets US: 0x2 DS: 0x3
						Lane #02: Trans Presets US: 0x1 DS: 0x2
						Lane #03: Trans Presets US: 0x2 DS: 0x3
						Lane #04: Trans Presets US: 0x2 DS: 0x3
						Lane #05: Trans Presets US: 0x1 DS: 0x2
						Lane #06: Trans Presets US: 0x2 DS: 0x3
						Lane #07: Trans Presets US: 0x1 DS: 0x2
						Lane #08: Trans Presets US: 0x1 DS: 0x2
						Lane #09: Trans Presets US: 0x2 DS: 0x3
						Lane #10: Trans Presets US: 0x1 DS: 0x2
						Lane #11: Trans Presets US: 0x2 DS: 0x3
						Lane #12: Trans Presets US: 0x2 DS: 0x3
						Lane #13: Trans Presets US: 0x1 DS: 0x2
						Lane #14: Trans Presets US: 0x2 DS: 0x3
						Lane #15: Trans Presets US: 0x1 DS: 0x2

			ESMEqCtl 25GT/s:	Lane #00: Trans Presets US: 0x4 DS: 0x5
						Lane #01: Trans Presets US: 0x5 DS: 0x6
						Lane #02: Trans Presets US: 0x4 DS: 0x5
						Lane #03: Trans Presets US: 0x5 DS: 0x6
						Lane #04: Trans Presets US: 0x5 DS: 0x6
						Lane #05: Trans Presets US: 0x4 DS: 0x5
						Lane #06: Trans Presets US: 0x5 DS: 0x6
						Lane #07: Trans Presets US: 0x4 DS: 0x5
						Lane #08: Trans Presets US: 0x4 DS: 0x5
						Lane #09: Trans Presets US: 0x5 DS: 0x6
						Lane #10: Trans Presets US: 0x4 DS: 0x5
						Lane #11: Trans Presets US: 0x5 DS: 0x6
						Lane #12: Trans Presets US: 0x5 DS: 0x6
						Lane #13: Trans Presets US: 0x4 DS: 0x5
						Lane #14: Trans Presets US: 0x5 DS: 0x6
						Lane #15: Trans Presets US: 0x4 DS: 0x5
				TLCap: OptTLP+ VCResCapInd: 1
				TLCtl: OptTLP+ LengthCheck+
	Capabilities: [644 v0] Designated Vendor-Specific <>
		Vendor:1e2c Version:0
		<CCIX Protocol 644 7bc>
			CCIX Cap [680 v0] Common
				CommonCap:	DevID: 3 StructVer: 0 DevMultiPort- PrimaryPort
				CommonCap2:	Rdy+ PartialCache- PortAgg- 128B- MultiHop- SamAlign- SWPort- 
						AddrWidth: 48 bit, DataRdyTime: 16 * 32^7
				PER [d00]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
					Component:	Link
					Address:	[0x0000000100000000], MaskLen: 3
					MemErr:	FRU:		3
						MemType:	NonVolatile
						Operation:	Scrub
						ErrorType:	SingleSymbolChipKillECC
						Chan:		2
						Module:		3
						Bank:		4
						Device:		5
						Row:		6
						Column:		7
						Rank:		8
						BitPos:		1
						ChipID:		9
						MemPoolType:	Unspecified
						VenSpecLen:	0
			CCIX Cap [6a0 v0] Port
				PortCap:	Port #0 Rdy+ OptTLP+ P2PForward- Links: 1 PSAMNum: 0 
				PortCap2:	Agg Mask 0x0
				PortCap3:	FW Mask 0x0
			CCIX Cap [6b4 v0] Link
				LinkCap:	Rdy+ SharedCredits- MsgPack- NoCompAck- MaxPktSize: 128B 
				LinkSendCap:	MaxMemReq: 16, MaxSnpReq: 16, MaxDatReq: 32
				LinkRcvCap:	MaxMemReq: 16, MaxSnpReq: 16, MaxDatReq: 32
				MiscCap:	MaxMiscReqSend: 16, MaxMiscReqRcv 16
			CCIX Cap [6d0 v0] Request Agent
				RACapStat:	DiscRdyStat+ CacheFlushStat-
			CCIX Ctl [800] Common
				CommCtl1:	DeviceEnable+ PrimaryPortEnable+ Mesh- PortAgg-
						IDMTableValid+ RSAMTableValid+ HSAMTableValid- SWPort-
						ErrorAgent: 0, DevID: 2
				CommCtl2:	PartialCache- 128B- AddrWidth: 48 bit
				DevErrCtl:	Enable+
			CCIX Ctl [820] Port
				PortCntrl:	Enable+ OptTLP+ LinksEnabled: 33, PSAMNum: 0
				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
				ErrCtlSta2:	SevLogMask: 0x00, SevPERMsgMask: 0x00
				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
				SourceTransportID: 02:00.0
				PER [da0]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
					Component:	Port
					Address:	[0x0000000002000000], MaskLen: 0
					PortErr:
						Operation:	Command
						PortErrType:	Generic
						CCIX Message:	Unspecified
			CCIX Ctl [840] Link
				Link#00 [844]
				LinkCtl:	Enable+ CreditSnd+ MsgPack- NoCmpAck- MaxPktSize: 128B 
						RA-to-HA
				MaxCredit:	Mem: 0016, Snoop: 0016, Data 0016, Misc 0000
				MinCredit:	Mem: 0008, Snoop: 0008, Data 0008, Misc 0000
				DestBDF:	01:00.0
				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
				ErrCtlSta2:	SevLogMask: 0x01, SevPERMsgMask: 0x00
				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
				PER [d80]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
					Component:	Link
					Address:	[0x0000000002000000], MaskLen: 3
					LinkErr:
						OperationType:	Read
						ErrorType:	CreditOverflow
						LinkID:		3
						LinkCreditType:	4
						CCIX Message:	Unspecified
			CCIX Ctl [960] Request Agent
				RACtl:	ID: 01, Enable+ SnpRespEnable- CacheFlush- CacheEnable-
				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
				ErrCtlSta2:	SevLogMask: 0x00, SevPERMsgMask: 0x00
				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
				PER [d40]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
					Component:	RA
					Address:	[0x0000000100000000], MaskLen: 3
					CacheErr:
						CacheType:	Data
						OperationType:	Prefetch
						CacheError:	Data
						Level:		4
						Set:		5
						Way:		6
						InstanceID:	1
			CCIX IDM Table [c00]
				#00: Port#00 Link#00
				#02: Local
			CCIX RSAM Table [b00]
				#00: Enable+ Port#00 NumAgg: 01	[0x0000000000000000:0x0002000000000000]
				#01: Enable- Local		[0x0000000000000000:0x0000000000000000]
				#02: Enable- Local		[0x0000000000000000:0x0000000000000000]
				#03: Enable- Local		[0x0000000000000000:0x0000000000000000]
				#04: Enable- Local		[0x0000000000000000:0x0000000000000000]

The following grants the 'pciutils' project trademark usage of
CCIX tradmark where relevant.

This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
you and other parties that are paticipating (the "participants") in the
pciutils with the understanding that the participants will use CCIX's
name and trademark only when this patch is used in association with the
pciutils project.

CCIX is also distributing this patch to these participants with the
understanding that if any portion of the CCIX specification will be
used or referenced in the pciutils project, the participants will not modify
the cited portion of the CCIX specification and will give CCIX propery
copyright attribution by including the following copyright notice with
the cited part of the CCIX specification:
"© 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."

Jonathan Cameron (2):
  CCIX DVSEC initial support
  DVSEC Add an example from the ccix spec.

 Makefile           |    2 +-
 lib/header.h       |    2 +
 ls-ccix.c          | 1364 ++++++++++++++++++++++++++++++++++++++++++++
 ls-ecaps.c         |   28 +-
 lspci.h            |    4 +
 tests/ccix-specex1 |  661 +++++++++++++++++++++
 6 files changed, 2059 insertions(+), 2 deletions(-)
 create mode 100644 ls-ccix.c
 create mode 100644 tests/ccix-specex1

-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC PATCH 1/2] lspci: CCIX DVSEC initial support
  2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
@ 2019-06-27 14:43 ` Jonathan Cameron
  2020-01-22  9:48   ` Martin Mareš
  2019-06-27 14:43 ` [RFC PATCH 2/2] lspci: DVSEC Add an example from the ccix spec Jonathan Cameron
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2019-06-27 14:43 UTC (permalink / raw)
  To: linux-pci, Martin Mareš
  Cc: bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm,
	Jonathan Cameron

The CCIX Base Specification 1.0, www.ccixconsortium.org
describes the PCI DVSEC based configuration space for
CCIX elements and topology.

This patch:
1. Introduces into ls-ecap the ability to call parsers for
   the Designated Vendor-Specific Extended Capablity (DVSEC)
   elements. These may be defined by a particular vendor, or
   as in this case, a consoritium with appropriate unique ID
   issued by the PCI SIG.
2. Parsing of CCIX Transport Layer DVSEC.  This is straight
   forward for devices supporting only PCI defined speeds,
   with a lot more information on devices that also support the
   20GT/s and 25GT/s extended speeds defined in the CCIX spec.
3. Parsing of CCIX Protocol Layer DVSEC. This defines the system
   topology along with agent specific elements.
   * Common Device Capabilities and Control
   * Address and ID routing tables.
   * Protocol Agent Capabilities and Controls.
   * CCIX Protocol Layer Port Capabilities and Controls.
   * CCIX Protocol Layer Link Capabilities and Controls.
   * Protocol Error Controls and Records as needed for RAS
     handling.

The support is fairly complete but for this initial version some
minor elements are not yet reported.

Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 Makefile     |    2 +-
 lib/header.h |    2 +
 ls-ccix.c    | 1364 ++++++++++++++++++++++++++++++++++++++++++++++++++
 ls-ecaps.c   |   28 +-
 lspci.h      |    4 +
 5 files changed, 1398 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index ff51be1..17c9cb2 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ force:
 lib/config.h lib/config.mk:
 	cd lib && ./configure
 
-lspci: lspci.o ls-vpd.o ls-caps.o ls-caps-vendor.o ls-ecaps.o ls-kernel.o ls-tree.o ls-map.o common.o lib/$(PCILIB)
+lspci: lspci.o ls-vpd.o ls-caps.o ls-caps-vendor.o ls-ecaps.o ls-ccix.o ls-kernel.o ls-tree.o ls-map.o common.o lib/$(PCILIB)
 setpci: setpci.o common.o lib/$(PCILIB)
 
 LSPCIINC=lspci.h pciutils.h $(PCIINC)
diff --git a/lib/header.h b/lib/header.h
index bfdcc80..c790821 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -1354,6 +1354,8 @@
 
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_VENDOR_ID_COMPAQ		0x0e11
+/* Note that this is a PCISIG Issued Unique Value rather than a Vendor ID */
+#define PCI_VENDOR_ID_CCIX              0x1e2c
 
 /* I/O resource flags, compatible with <include/linux/ioport.h> */
 
diff --git a/ls-ccix.c b/ls-ccix.c
new file mode 100644
index 0000000..c9f156e
--- /dev/null
+++ b/ls-ccix.c
@@ -0,0 +1,1364 @@
+/*
+ *	The PCI Utilities -- Show CCIX Capabilities
+ *
+ *	Copyright (c) 2018 Jonathan Cameron <Jonathan.Cameron@huawei.com>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lspci.h"
+
+#define ARRAY_SIZE(x) sizeof(x)/sizeof(*(x))
+
+struct ccix_state {
+  int portagg_capable:1;
+  int sw_portal_capable:1;
+  int forwarding:1;
+  u32 dev_error_log_offset;
+  u32 idm_table_offset;
+  u32 sr_table_offset;
+  u32 hsam_table_offset;
+  u32 hsam_table_size;
+  u32 rsam_table_offset;
+  u32 rsam_table_size;
+  u32 links;
+  int ra_found, ra_ctl_found;
+  u32 ha_num_ids[64];
+  u32 ha_num_pools[64];
+  int ha_found, ha_ctl_found;
+  u32 sa_num_pools[64];
+  int sa_found, sa_ctl_found;
+  u32 psamnum;
+  u32 port_error_offset;
+  u32 link_error_offset;
+  u32 sa_error_offset[64];
+  u32 ra_error_offset[64];
+  u32 ha_error_offset[64];
+};
+
+/* Where is not always aligned, hence use byte reads */
+static void
+ccix_vendor_error(struct device *d, int where)
+{
+  u8 buff, buff2;
+  u16 len;
+
+  buff = get_conf_byte(d, where);
+  buff2 = get_conf_byte(d, where + 1);
+  len = (u16)buff2 << 8 | buff;
+  printf("\t\t\t\t\t\tVenSpecLen:\t%u\n", len);
+}
+
+/*
+ * Note used both for mem pool definition in which it
+ * is only 3 bits and for memory errors in which it is
+ * a byte with vendor defined upper half.
+ */
+static const char * ccix_sub_mem_types[8] = {
+  "NotSpecified", "SRAM", "DDR", "NVDIMM-F",
+  "NVDIMM-N", "HBM", "FLASH", "Unknown"
+};
+
+static const char * ccix_operation_type[11] = {
+  "GenericUndetermined", "GenericRead", "GenericWrite",
+  "DataRead", "DataWrite", "InstructionFetch", "Prefetch",
+  "Eviction", "Snooping", "Snooped", "Management",
+};
+
+static void
+ccix_memory_error(struct device *d, int where)
+{
+  static const char * memory_type[] = {
+    "Other/NonSpec", "ROM", "Volatile", "NonVolatile", "Device",
+  };
+  static const char * memory_error_type[] = {
+    "Unknown", "NoError", "SingleBitECC", "MultiBitECC",
+    "SingleSymbolChipKillECC", "MultiSymbolChipKillECC",
+    "MasterAbort", "TargetAbort", "ParityError", "WatchDog",
+    "InvalidAddr", "MirrorBroken", "MemorySparing", "Scrub",
+    "PhysicalMemMapOutEvent",
+  };
+  static const char * memory_operation[] = {
+    "Generic", "Read", "Write", NULL, "Scrub",
+  };
+  u32 buff, valbits;
+  u8 value;
+
+  valbits = get_conf_long(d, where);
+  buff = get_conf_long(d, where + 0x4);
+
+  printf("\t\t\t\t\tMemErr:\t");
+  if ((buff & 0xff) == 255)
+    printf("Internal\n");
+  else
+    printf("FRU:\t\t%u\n", buff & 0xff);
+
+  /*
+   * Note we ignore the error message length as it provides no
+   * useful information not conveyed in other ways.
+   */
+  printf("\t\t\t\t\t\tMemType:\t");
+  buff = get_conf_long(d, where + 0x8);
+  if (valbits & 0x01) {
+    value = buff & 0xff;
+    if (value >= 0x80)
+      printf("Vendor 0x%x\n", value);
+    else
+      printf("%s\n", value >= ARRAY_SIZE(memory_type) ?
+	     "Unknown": memory_type[value]);
+  } else
+    printf("Unspecifcied\n");
+
+  printf("\t\t\t\t\t\tOperation:\t");
+  if (valbits & 0x02) {
+    value = (buff >> 8) & 0xff;
+    switch (value) {
+    case 0 ... 2:
+    case 4:
+      printf("%s\n", memory_operation[value]);
+      break;
+    default: printf("Unknown\n"); break;
+    }
+  } else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tErrorType:\t");
+  if (valbits & 0x04) {
+    value = (buff >> 16) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(memory_error_type) ?
+	   "Unknown" : memory_error_type[value]);
+  } else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tChan:\t\t");
+  if (valbits & 0x08)
+    printf("%u\n", (buff >> 24) & 0xff);
+  else
+    printf("Unspecified\n");
+
+  buff = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\t\t\tModule:\t\t");
+  if (valbits & 0x1000)
+    printf("%u\n", buff & 0xffff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tBank:\t\t");
+  if (valbits & 0x10)
+    printf("%u\n", (buff >> 16) & 0xffff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tDevice:\t\t");
+  if (valbits & 0x20)
+    printf("%u\n", get_conf_long(d, where + 0x10));
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tRow:\t\t");
+  if (valbits & 0x40)
+    printf("%u\n", get_conf_long(d, where + 0x14));
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tColumn:\t\t");
+  if (valbits & 0x80)
+    printf("%u\n", get_conf_long(d, where + 0x18));
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tRank:\t\t");
+  if (valbits & 0x100)
+    printf("%u\n", get_conf_long(d, where + 0x1c));
+  else
+    printf("Unspecified\n");
+
+  buff = get_conf_long(d, where + 0x20);
+  printf("\t\t\t\t\t\tBitPos:\t\t");
+  if (valbits & 0x200)
+    printf("%u\n", buff & 0xff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tChipID:\t\t");
+  if (valbits & 0x400)
+    printf("%u\n", (buff >> 8) & 0xff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tMemPoolType:\t");
+  if (valbits & 0x2000) {
+    value = (buff >> 16) & 0xff;
+    if (value >= 0x80)
+      printf("Vendor 0x%x\n", value);
+    else {
+      printf("%s\n", value >= ARRAY_SIZE(ccix_sub_mem_types) ?
+	     "Unknown": ccix_sub_mem_types[value]);
+    }
+  } else
+    printf("Unspecified\n");
+
+  if (valbits & 0x800)
+    ccix_vendor_error(d, where + 0x23);
+}
+
+static void
+ccix_cache_error(struct device *d, int where)
+{
+  u32 buff, buff2, valbits;
+  u8 value;
+  static const char * ccix_cache_type[4] = {
+    "Instruction", "Data", "Unified", "SnoopFilterDirectory"
+  };
+  static const char * ccix_cache_error_type[6] = {
+    "Data", "Tag", "Timeout", "Hang", "DataLost", "InvalidAddr",
+  };
+
+  valbits = get_conf_long(d, where);
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\t\tCacheErr:\n");
+  printf("\t\t\t\t\t\tCacheType:\t");
+  if (valbits & 0x01) {
+    value = (buff >> 16) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(ccix_cache_type) ?
+	   "Unknown": ccix_cache_type[value]);
+  } else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tOperationType:\t");
+  if (valbits & 0x2) {
+    value = (buff >> 24) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(ccix_operation_type) ?
+	   "Unknown" : ccix_operation_type[value]);
+  } else
+    printf("Unspecified\n");
+  buff = get_conf_long(d, where + 0x8);
+  printf("\t\t\t\t\t\tCacheError:\t");
+  if (valbits & 0x4) {
+    value = buff & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(ccix_cache_error_type) ?
+	   "Unknown" : ccix_cache_error_type[value]);
+  } else 
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tLevel:\t\t");
+  if (valbits & 0x8)
+    printf("%u\n", (buff >> 8) & 0xff);
+  else
+    printf("Unspecified\n");
+
+  buff2 = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\t\t\tSet:\t\t");
+  if (valbits & 0x10)
+    printf("%u\n", (buff >> 16) & 0xffff | ((buff2 & 0xffff) << 16));
+  else
+    printf("Unspecified\n");
+
+  buff = buff2;
+  buff2 = get_conf_long(d, where + 0x10);
+  printf("\t\t\t\t\t\tWay:\t\t");
+  if (valbits & 0x20)
+    printf("%u\n", (buff >> 16) & 0xffff | ((buff2 & 0xffff) << 16));
+  else
+    printf("Unspecified\n");
+
+  buff = buff2;
+  printf("\t\t\t\t\t\tInstanceID:\t");
+  if (valbits & 0x40)
+    printf("%u\n", (buff >> 16) & 0xff);
+  else
+    printf("Unspecified\n");
+
+  if (valbits & 0x80)
+    ccix_vendor_error(d, where + 0x14);
+}
+static void
+ccix_atc_error(struct device *d, int where)
+{
+  u32 buff, valbits;
+  u8 value;
+
+  valbits = get_conf_long(d, where);
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\t\tATCErr:\n");
+  printf("\t\t\t\t\t\tOperationType:\t");
+  if (valbits & 0x1) {
+    value = (buff >> 16) & 0xff;
+    switch (value) {
+    case 0 ... 10:
+      printf("%s\n", ccix_operation_type[value]);
+      break;
+    default:
+      printf("Unknown\n");
+      break;
+    }
+  } else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tInstanceID:\t");
+  if (valbits & 0x02)
+    printf("%u\n", buff >> 24);
+  else
+    printf("Unspecified\n");
+
+  if (valbits & 0x04)
+    ccix_vendor_error(d, where + 0x0c);
+}
+
+static void
+ccix_port_error(struct device *d, int where)
+{
+  static const char * port_op_type[] = {
+    "Command", "Read", "Write"
+  };
+  static const char * port_error_type[8] = {
+    "Generic", "BusParrity", "NoBDF", "AddrInval",
+    "IDInval", "Timeout", "Hang", "EgressBlk"
+  };
+  u32 buff, valbits;
+  u8 value;
+
+  buff = get_conf_long(d, where);
+  valbits = buff & 0xf;
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\t\tPortErr:\n");
+  printf("\t\t\t\t\t\tOperation:\t");
+  if (valbits & 0x1) {
+    value = (buff >> 16) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(port_op_type) ?
+	   "Unknown" : port_op_type[value]);
+  } else {
+    printf("Unspecified\n");
+  }
+
+  printf("\t\t\t\t\t\tPortErrType:\t");
+  if (valbits & 0x2) {
+    value = (buff >> 24) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(port_error_type) ?
+	   "Unknown" : port_error_type[value]);
+  } else {
+    printf("Unspecified\n");
+  }
+
+  /* We could report the raw CCIX message header if present */
+  printf("\t\t\t\t\t\tCCIX Message:\t"); 
+  if (valbits & 0x04)
+    printf("Present\n");
+  else
+    printf("Unspecified\n");
+
+  if (valbits & 0x08)
+    ccix_vendor_error(d, where + 0x28);
+}
+
+static void
+ccix_link_error(struct device *d, int where)
+{
+  u32 buff, valbits;
+  u8 value;
+  const char * link_op_types[3] = {
+    "Command", "Read", "Write",
+  };
+  const char * link_error_types[5] = {
+    "Generic", "CreditUnderflow", "CreditOverflow",
+    "UnusableCreditReceived", "CreditTimeout"
+  };
+
+  valbits = get_conf_long(d, where);
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\t\tLinkErr:\n");
+  printf("\t\t\t\t\t\tOperationType:\t");
+  if (valbits & 0x1) {
+    value = (buff >> 16) & 0xff;
+    printf("%s\n", value >= ARRAY_SIZE(link_op_types) ?
+	   "Unknown" : link_op_types[value]);
+  } else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tErrorType:\t");
+  if (valbits & 0x02) {
+    value = buff >> 24;
+    printf("%s\n", value >= ARRAY_SIZE(link_error_types) ?
+	   "Unknown" : link_error_types[value]);
+  } else
+    printf("Unspecified\n");
+
+  buff = get_conf_long(d, where + 0x8);
+  printf("\t\t\t\t\t\tLinkID:\t\t");
+  if (valbits & 0x04)
+    printf("%u\n", buff & 0xff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tLinkCreditType:\t");
+  if (valbits & 0x08)
+    printf("%u\n", (buff >> 8) & 0xff);
+  else
+    printf("Unspecified\n");
+
+  printf("\t\t\t\t\t\tCCIX Message:\t");
+  if (valbits & 0x10)
+    printf("Present\n");
+  else
+    printf("Unspecified\n");
+
+  if (valbits & 0x20)
+    ccix_vendor_error(d, where + 0x2c);
+}
+
+static void
+ccix_agent_error(struct device *d, int where)
+{
+  u32 valbits;
+
+  valbits = get_conf_long(d, where);
+  printf("\t\t\t\t\tInterErr:\n");
+  if (valbits & 0x01)
+    ccix_vendor_error(d, where + 0x8);
+}
+
+/* Does it make sense to do these in lspci? */
+static void
+ccix_error_log(struct device *d, int where)
+{
+  u32 buff, buff2;
+  u8 value;
+  u8 error_type;
+  int vendor_specific;
+
+  static const char * ccix_element[5] = {
+    "RA", "HA", "SA", "Port", "Link"
+  };
+
+  buff = get_conf_long(d, where);
+
+  printf("\t\t\t\tPER [%03x]:\tLogVersion: %u, ME%c ",
+	 where, buff & 0xff, FLAG(buff, 0x8000));
+  buff = get_conf_long(d, where + 0x4);
+  printf("SevUE%c SevNoComm%c SevDegraded%c SevDeferred%c\n",
+	 FLAG(buff, 0x10000), FLAG(buff, 0x20000),
+	 FLAG(buff, 0x40000), FLAG(buff, 0x80000));
+  printf("\t\t\t\t\tComponent:\t");
+  value = (buff >> 12) & 0xf;
+  printf("%s\n", value >= ARRAY_SIZE(ccix_element) ?
+	 "Unknown" : ccix_element[value]);
+  error_type = (buff >> 24) & 0x7;
+  vendor_specific = (buff >> 31) & 0x1;
+  printf("\t\t\t\t\tAddress:\t");
+  if ((buff >> 30) & 0x1) {
+    buff = get_conf_long(d, where + 0x8);
+    buff2 = get_conf_long(d, where + 0xc);
+    printf("[0x%016lx], ", (u64)buff2 << 32 | (buff & 0xfffffffc));
+    buff = get_conf_long(d, where + 0x10);
+    printf("MaskLen: %u\n", buff & 0x3f);
+  } else
+    printf("NotValid\n");
+
+  if (!vendor_specific) {
+    switch(error_type) {
+    case 0:
+      ccix_memory_error(d, where + 0x14);
+      break;
+    case 1:
+      ccix_cache_error(d, where + 0x14);
+      break;
+    case 2:
+      ccix_atc_error(d, where + 0x14);
+      break;
+    case 3:
+      ccix_port_error(d, where + 0x14);
+      break;
+    case 4:
+      ccix_link_error(d, where + 0x14);
+      break;
+    case 5:
+      ccix_agent_error(d, where + 0x14);
+      break;
+    default:
+      printf("\t\t\t\t\tUnknownErr:\n");
+      break;
+    }
+  } else {
+    printf("\t\t\t\t\tVendorSpecific\n");
+  }
+}
+
+static void
+ccix_mem_pool(struct device *d, int where, int i)
+{
+  u32 buff, buff2;
+  u64 pool_size;
+  static const char * ccix_mem_types[8] = {
+    "Other", "Expansion", "Hole", "ROM",
+    "Volatile", "Non-Volatile", "Device", "Unknown"
+  };
+  static const char * ccix_mem_attr[8] = {
+    "Device", "Unknown", "Unknown", "Unknown",
+    "Non-Cacheable", "Cacheable", "Unknown", "Unknown"
+  };
+  static const char * ccix_mem_ext_attr[8] = {
+    "System", "Private", "Unknown", "Unknown",
+    "Unknown", "Unknown", "Unknown", "Unknown"
+  };
+
+  buff = get_conf_long(d, where);
+  printf("\t\t\t\tPool #%u:\tReady%c ", i, FLAG(buff, 0x1));
+  printf("%s/%s/%s/%s\n",
+	 ccix_mem_types[(buff >> 1) & 0x7],
+	 ccix_sub_mem_types[(buff >> 4) & 0x7],
+	 ccix_mem_attr[(buff >> 8) & 0x7],
+	 ccix_mem_ext_attr[(buff >> 11) & 0x7]);
+  printf("\t\t\t\t\t\tNon4GBAligned%c\n", FLAG(buff, 0x80));
+
+  buff2 = get_conf_long(d, where + 0x4);
+  pool_size = (((u64)buff2 << 16 | ((buff >> 16) & 0xffff)) + 1) * 65536;
+  printf("\t\t\t\t\t\tSize: ");
+  if (pool_size & 0x3ff == 0)
+    printf("%lu B", pool_size);
+  else {
+    if (pool_size & 0xfffff)
+      printf("%lu kB", pool_size >> 10);
+    else {
+      if (pool_size & 0x3fffffff)
+	printf("%lu MB", pool_size >> 20);
+      else {
+	if (pool_size & 0xffffffffff)
+	  printf("%lu GB", pool_size >> 30);
+	else
+	  printf("%lu TB", pool_size >> 40);
+      }
+    }
+  }
+  printf("\n");
+}
+
+static void
+ccix_bat(struct device *d, int where, int i)
+{
+  u32 buff;
+
+  buff = get_conf_long(d, where);
+  printf("\t\t\t\tPool #%u:\tValid%c ", i, FLAG(buff, 0x1));
+  buff = get_conf_long(d, where + 0x4);
+  printf("BaseAddr: [0x%016lx]\n", (u64)buff << 32);
+}
+
+static void
+ccix_error_ctl_stat(struct device *d, int where, int *error)
+{
+  u32 buff;
+
+  buff = get_conf_long(d, where);
+  printf("\t\t\t\tErrCtlSta1:\tCurrent: ");
+  switch (buff & 0x3) {
+  case 0:
+    printf("No error, ");
+    *error = 0;
+    break;
+  case 1:
+    printf("Error pending, ");
+    *error = 1;
+    break;
+  case 2:
+    printf("Invalid, ");
+    *error = 0;
+    break;
+  case 3:
+    printf("Error pending / PER Sent, ");
+    *error = 1;
+    break;
+  }
+  printf("LogDisable%c PERMsgDisable%c\n", FLAG(buff, 0x2), FLAG(buff, 0x4));
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tErrCtlSta2:\tSevLogMask: 0x%02x, SevPERMsgMask: 0x%02x\n",
+	 buff & 0x3f, (buff >> 8) & 0x3f);
+  printf("\t\t\t\tTypeMaskR/L:\tMem%c/%c Cache%c/%c ATC%c/%c Port%c/%c Agent%c/%c\n",
+	 FLAG(buff, 0x0010000), FLAG(buff, 0x0020000),
+	 FLAG(buff, 0x0040000), FLAG(buff, 0x0080000),
+	 FLAG(buff, 0x0100000), FLAG(buff, 0x0200000),
+	 FLAG(buff, 0x0400000), FLAG(buff, 0x0800000),
+	 FLAG(buff, 0x1000000), FLAG(buff, 0x2000000));
+}
+
+static void
+ccix_sa_cap(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+  unsigned i;
+
+  buff = get_conf_long(d, where + 0x4);
+  state->sa_num_pools[state->sa_found] = (buff >> 4) & 0x3f;
+  printf("\t\t\t\tSACapStat:\tDiscRdyStat%c MemPoolRdy%c NumMemPool: %u\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x80000000), (buff >> 4) & 0x3f);
+  state->sa_error_offset[state->sa_found] = get_conf_long(d, where + 0x8) >> 20;
+  for (i = 0; i < state->sa_num_pools[state->sa_found]; i++)
+    ccix_mem_pool(d, where + 0x0c + i * 8, i);
+
+  state->sa_found++;
+}
+
+static void
+ccix_sa_ctl(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+  unsigned i;
+  int num_sbat, error;
+
+  buff = get_conf_long(d, where + 0x4);
+  num_sbat = (buff >> 4) & 0x3f;
+  printf("\t\t\t\tSACtl:\tEnable%c SAID: %02u, NumSBATEnable: %02u\n",
+	 FLAG(buff, 0x1), (buff >> 26) & 0x3f, num_sbat);
+
+  ccix_error_ctl_stat(d, where + 0x8, &error);
+  if (error && state->sa_error_offset[state->sa_ctl_found])
+    ccix_error_log(d, state->sa_error_offset[state->sa_ctl_found]);
+
+  for (i = 0; i < state->sa_num_pools[state->sa_ctl_found]; i++)
+    ccix_bat(d, where + 0x10 + 8 * i, i);
+  state->sa_ctl_found++;
+}
+
+static void
+ccix_ra_cap(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tRACapStat:\tDiscRdyStat%c CacheFlushStat%c\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x80000000));
+  state->ra_error_offset[state->ra_found] = get_conf_long(d, where + 0x8) >> 20;
+
+  state->ra_found++;
+}
+
+static void
+ccix_ra_ctl(struct device *d, int where, struct ccix_state *state UNUSED)
+{
+  u32 buff;
+  int error;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tRACtl:\tID: %02u, Enable%c SnpRespEnable%c CacheFlush%c CacheEnable%c\n",
+	 (buff >> 26) & 0x3f, FLAG(buff, 0x1), FLAG(buff, 0x2),
+	 FLAG(buff, 0x4000), FLAG(buff, 0x8000));
+
+  ccix_error_ctl_stat(d, where + 0x8, &error);
+  if (error && state->ra_error_offset[state->ra_ctl_found])
+    ccix_error_log(d, state->ra_error_offset[state->ra_ctl_found]);
+
+  state->ra_ctl_found++;
+}
+
+static void
+ccix_ha_cap(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+  unsigned i;
+
+  buff = get_conf_long(d, where + 0x4);
+  state->ha_num_ids[state->ha_found] = ((buff >> 1) & 0x3f) + 1;
+
+  printf("\t\t\t\tHACapStat:\tDiscRdyStat%c MemPoolRdy%c MemExp%c NumHAID: %u, NumMemPool: %u\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x80000000), FLAG(buff, 0x10000),
+	 ((buff >> 1) & 0x3f) + 1, (buff >> 8) & 0x3f);
+  state->ha_num_pools[state->ha_found] = (buff >> 8) & 0x3f;
+
+  state->ha_error_offset[state->ha_found] = get_conf_long(d, where + 0x8) >> 20;
+
+  for (i = 0; i < state->ha_num_pools[state->ha_found]; i++)
+    ccix_mem_pool(d, where + 0xc + i * 8, i);
+
+  state->ha_found++;
+}
+
+static void
+ccix_ha_ctl(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff, buff2;
+  int error;
+  unsigned i, j;
+  unsigned hbat_start = 0x18 + ((state->ha_num_ids[state->ha_ctl_found] - 1) / 4 + 1) * 4;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tHACtl:\tEnable%c MemExpEnable%c HBatEnabled: %u\n", FLAG(buff, 0x1),
+	 FLAG(buff, 0x10000), (buff >> 8) & 0x3f);
+
+  buff = get_conf_long(d, where + 0x8);
+  buff2 = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\tRAIDV:\t0x%016lx\n", ((u64)buff2 << 32) | buff);
+  ccix_error_ctl_stat(d, where + 0x10, &error);
+
+  if (error && state->ha_error_offset[state->ha_ctl_found])
+    ccix_error_log(d, state->ha_error_offset[state->ha_ctl_found]);
+
+  for (i = 0; i <= (state->ha_num_ids[state->ha_ctl_found] - 1) / 4; i++) {
+    buff = get_conf_long(d, where + 0x18 + i * 4);
+    for(j = 0; j < 4; j++) {
+      if (i * 4 + j < state->ha_num_ids[state->ha_ctl_found])
+	printf("\t\t\t\tHA #%02u:\tID: %02u\n", i * 4 + j,
+	       (buff >> (8 * j) & 0x3f));
+    }
+  }
+
+  for (i = 0; i < state->ha_num_pools[state->ha_ctl_found]; i++)
+    ccix_bat(d, where + hbat_start + 8 * i, i);
+
+  state->ha_ctl_found++;
+}
+
+static void
+ccix_link_cap(struct device *d, int where,
+	      struct ccix_state *state UNUSED)
+{
+  u32 buff;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tLinkCap:\tRdy%c SharedCredits%c MsgPack%c NoCompAck%c ",
+	 FLAG(buff, 0x1), FLAG(buff, 0x2), FLAG(buff, 0x4), FLAG(buff, 0x8));
+  printf("MaxPktSize: ");
+  switch (buff >> 7 & 0x7) {
+  case 0: printf("128B "); break;
+  case 1: printf("256B "); break;
+  case 2: printf("512B "); break;
+  default: printf("Unknown "); break;
+  };
+  printf("\n");
+
+  buff = get_conf_long(d, where + 0x8);
+  printf("\t\t\t\tLinkSendCap:\tMaxMemReq: %u, MaxSnpReq: %u, MaxDatReq: %u\n",
+	 buff & 0x3f, (buff >> 10) & 0x3f, (buff >> 20) & 0x3f);
+
+  buff = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\tLinkRcvCap:\tMaxMemReq: %u, MaxSnpReq: %u, MaxDatReq: %u\n",
+	 buff & 0x3f, (buff >> 10) & 0x3f, (buff >> 20) & 0x3f);
+
+  buff = get_conf_long(d, where + 0x10);
+  printf("\t\t\t\tMiscCap:\tMaxMiscReqSend: %u, MaxMiscReqRcv %u\n",
+	 buff & 0x3f, (buff >> 10) & 0x3f);
+  state->link_error_offset = get_conf_long(d, where + 0x14) >> 20;
+}
+
+static void
+ccix_link_ctl(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff, buff2;
+  unsigned int i;
+  int error;
+  u16 BDF;
+  int link_len = state->forwarding ? 8 * 4 : 6 * 4;
+
+  for (i = 0; i < state->links; i++) {
+    printf("\t\t\t\tLink#%02u [%x]\n", i, where + i * link_len + 0x4);
+
+    buff = get_conf_long(d, where + i * link_len + 0x4);
+    printf("\t\t\t\tLinkCtl:\tEnable%c CreditSnd%c MsgPack%c NoCmpAck%c ",
+	   FLAG(buff, 0x1), FLAG(buff, 0x2), FLAG(buff, 0x4), FLAG(buff, 0x40));
+    printf("MaxPktSize: ");
+    switch (buff >> 7 & 0x7) {
+    case 0: printf("128B "); break;
+    case 1: printf("256B "); break;
+    case 2: printf("512B "); break;
+    default: printf("Unknown "); break;
+    };
+    printf("\n");
+    printf("\t\t\t\t\t\t");
+    if ((buff >> 10) & 0x1)
+      printf("HA-to-SA\n");
+    else
+      printf("RA-to-HA\n");
+
+    buff = get_conf_long(d, where + i * link_len + 0x8);
+    /* Print misc credits along with others */
+    buff2 = get_conf_long(d, where + i * link_len + 0x10);
+    printf("\t\t\t\tMaxCredit:\tMem: %04u, Snoop: %04u, Data %04u, Misc %04u\n",
+	   buff & 0x3ff, (buff >> 10) & 0x3ff, (buff >> 20) & 0x3ff,
+	   buff2 & 0x3ff);
+
+    buff = get_conf_long(d, where + i * link_len + 0xc);
+    printf("\t\t\t\tMinCredit:\tMem: %04u, Snoop: %04u, Data %04u, Misc %04u\n",
+	   buff & 0x3ff, (buff >> 10) & 0x3ff, (buff >> 20) & 0x3ff,
+	   (buff2 >> 10) & 0x3ff);
+
+    if (state->forwarding) {
+      buff = get_conf_long(d, where + i * link_len + 0x20);
+      buff2 = get_conf_long(d, where + i * link_len + 0x24);
+      printf("\t\t\t\tBcastFwd:\t0x%016lx\n", (u64)buff2 << 32 | buff);
+    }
+
+    /*
+     * Transport ID map - comes after the control block, but eiaer to follow here
+     * where it is associated with the link's other information
+     */
+    buff = get_conf_long(d, where + state->links * link_len + 0x4 + 4 * i);
+    BDF = buff & 0xffff;
+    printf("\t\t\t\tDestBDF:\t%02x:%02x.%d\n",
+	   BDF >> 8, (BDF >> 3) & 0x1f, BDF & 0x7);
+
+    ccix_error_ctl_stat(d, where + i * link_len + 0x14, &error);
+    if (error && state->link_error_offset)
+      ccix_error_log(d, state->link_error_offset);
+  }
+}
+
+static void
+ccix_port_cap(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tPortCap:\t");
+  printf("Port #%u Rdy%c OptTLP%c P2PForward%c ", buff >> 27,
+	 FLAG(buff, 0x1), FLAG(buff, 0x2), FLAG(buff, 0x10));
+  state->links = (buff >> 7) & 0x3f;
+  state->forwarding = (buff >> 4);
+  printf("Links: %u ", state->links);
+  state->psamnum = (buff >> 13) & 0x3f;
+  printf("PSAMNum: %u ", state->psamnum);
+  printf("\n");
+
+  buff = get_conf_long(d, where + 0x8);
+  printf("\t\t\t\tPortCap2:\tAgg Mask 0x%x\n", buff & 0xff);
+
+  buff = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\tPortCap3:\tFW Mask 0x%x\n", buff & 0xff);
+
+  buff = get_conf_long(d, where + 0x10);
+  state->port_error_offset = buff >> 20;
+}
+
+static void
+ccix_port_ctl(struct device *d, int where,
+	      struct ccix_state *state UNUSED)
+{
+  u32 buff;
+  u32 psamnum;
+  u32 i;
+  int error = 0;
+  u16 BDF;
+
+  buff = get_conf_long(d, where + 0x4);
+  psamnum =  (buff >> 13) & 0x3f;
+  printf("\t\t\t\tPortCntrl:\tEnable%c OptTLP%c LinksEnabled: %u, PSAMNum: %u\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x2), (buff >> 7) & 0x3f, psamnum);
+
+  ccix_error_ctl_stat(d, where + 0x8, &error);
+  buff = get_conf_long(d, where + 0x10);
+  BDF = buff & 0xffff;
+  printf("\t\t\t\tSourceTransportID: %02x:%02x.%d\n",
+	 BDF >> 8, (BDF >> 3) & 0x1f, BDF & 0x7);
+
+  for (i = 0; i < state->psamnum; i++) {
+    buff = get_conf_long(d, where + 0x14 + 12 * i);
+    printf("\t\t\t\tPSamEntry%02u: Valid%c Link%02u ", i,
+	   FLAG(buff, 0x1), (buff >> 9) & 0x3f);
+    if (buff & (1 << 15))
+      printf("HA-to-SA ");
+    else
+      printf("RA-to-HA ");
+    printf("[0x%016lx-0x%016lx]\n",
+	   (uint64_t)get_conf_long(d, where + 0x14 + 12 * i + 4) << 32,
+	   (uint64_t)get_conf_long(d, where + 0x14 + 12 * i + 8) << 32);
+  }
+  if (error && state->port_error_offset)
+    ccix_error_log(d, state->port_error_offset);
+}
+
+static void
+ccix_common_cap(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff;
+  int mesh_capable = 0;
+  u64 sw_portal_size;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tCommonCap:\t");
+  printf("DevID: %u ", (buff >> 24) & 0xff);
+  printf("StructVer: %u ", (buff >> 22) & 0x3);
+  if (buff & 0x1) {
+    printf("MultiPort+ ");
+    if (buff & 0x4) {
+      printf("Mesh+ ");
+      mesh_capable = 1;
+    }
+    else
+      printf("Mesh- ");
+  } else
+    printf("DevMultiPort- ");
+  if (buff & 0x2) {
+    printf("PrimaryPort\n");
+
+    buff = get_conf_long(d, where + 0x8);
+    printf("\t\t\t\tCommonCap2:\tRdy%c PartialCache%c PortAgg%c 128B%c MultiHop%c SamAlign%c ",
+	   FLAG(buff, 0x1), FLAG(buff, 0x2), FLAG(buff, 0x4),
+	   FLAG(buff, 0x8), FLAG(buff, 0x80), FLAG(buff, 0x200));
+    state->portagg_capable = (buff >> 3) & 0x1;
+    if (buff & (1 << 8)) {
+      printf("SWPort+ ");
+      state->sw_portal_capable = 1;
+    }
+    else
+      printf("SWPort- ");
+    printf("\n");
+
+    printf("\t\t\t\t\t\tAddrWidth: ");
+    switch ((buff >> 4) & 0x7) {
+    case 0x0: printf("48 bit, "); break;
+    case 0x1: printf("52 bit, "); break;
+    case 0x2: printf("56 bit, "); break;
+    case 0x3: printf("60 bit, "); break;
+    case 0x4: printf("64 bit, "); break;
+    default: printf("unknown, "); break;
+    }
+    printf("DataRdyTime: %u * 32^%u\n",
+	   (buff >> 19) & 0x3f, (buff >> 28) & 0x7);
+    if (state->sw_portal_capable) {
+      buff = get_conf_long(d, where + 0x20 + mesh_capable ? 4 : 0);
+      sw_portal_size = (u64)buff * 65636;;
+      printf("\t\t\t\t\t\tSWPortalSize: ");
+      if (sw_portal_size & 0x3ff)
+	printf("%lu B", sw_portal_size);
+      else {
+	if (sw_portal_size & 0xfffff)
+	  printf("%lu kB", sw_portal_size >> 10);
+	else {
+	  if (sw_portal_size & 0x3fffffff)
+	    printf("%lu MB", sw_portal_size >> 20);
+	  else {
+	    if (sw_portal_size & 0xffffffffff)
+	      printf("%lu GB", sw_portal_size >> 30);
+	    else
+	      printf("%lu TB", sw_portal_size >> 40);
+	  }
+	}
+      }
+      printf("\n");
+    }
+    state->dev_error_log_offset = get_conf_long(d, where + 0x10) >> 20;
+    state->idm_table_offset = get_conf_long(d, where + 0x14) >> 20;
+    buff = get_conf_long(d, where + 0x18);
+    state->rsam_table_offset = buff >> 20;
+    state->rsam_table_size = buff & 0xfff;
+    buff = get_conf_long(d, where + 0x1c);
+    state->hsam_table_offset = buff >> 20;
+    state->hsam_table_size = buff & 0xfff;
+    if (mesh_capable)
+      state->sr_table_offset = get_conf_long(d, where + 0x20) >> 20;
+  }
+  else
+    printf("SecondaryPort\n");
+
+  if (state->dev_error_log_offset)
+   ccix_error_log(d, state->dev_error_log_offset);
+}
+
+static void
+ccix_common_ctl(struct device *d, int where, struct ccix_state *state)
+{
+  u32 buff, buff2;
+  int offset = 0;
+
+  buff = get_conf_long(d, where + 0x4);
+  printf("\t\t\t\tCommCtl1:\tDeviceEnable%c PrimaryPortEnable%c Mesh%c PortAgg%c\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x2), FLAG(buff, 0x4), FLAG(buff, 0x10));
+  printf("\t\t\t\t\t\tIDMTableValid%c RSAMTableValid%c HSAMTableValid%c SWPort%c\n",
+	 FLAG(buff, 0x20), FLAG(buff, 0x40),
+	 FLAG(buff, 0x80), FLAG(buff, 0x100));
+  printf("\t\t\t\t\t\tErrorAgent: %u, DevID: %u\n",
+	 (buff >> 16) & 0x3f, (buff >> 24) & 0xff);
+
+  buff = get_conf_long(d, where + 0x8);
+  printf("\t\t\t\tCommCtl2:\tPartialCache%c 128B%c ",
+	 FLAG(buff, 0x2), FLAG(buff, 0x8));
+  printf("AddrWidth: ");
+  switch ((buff >> 4) & 0x7) {
+  case 0x0: printf("48 bit\n"); break;
+  case 0x1: printf("52 bit\n"); break;
+  case 0x2: printf("56 bit\n"); break;
+  case 0x3: printf("60 bit\n"); break;
+  case 0x4: printf("64 bit\n"); break;
+  default: printf("unknown\n "); break;
+  }
+
+  buff = get_conf_long(d, where + 0xc);
+  printf("\t\t\t\tDevErrCtl:\tEnable%c\n", FLAG(buff, 0x1));
+  if ((state->forwarding && !state->ha_found &&
+       !state->ra_found && state->portagg_capable) ||
+      (!state->forwarding && state->portagg_capable &&
+       state->ha_found && !state->ra_found)) {
+    buff = get_conf_long(d, where + 0x10);
+    buff2 = get_conf_long(d, where + 0x14);
+    printf("\t\t\t\tSnpRqHM:\tHashMask: 0x%016lx\n",
+	   ((u64)buff2 << 32) | (buff & 0xffffffc0));
+
+    offset += 8;
+  }
+  if (state->sw_portal_capable) {
+    buff = get_conf_long(d, where + 0x10 + offset);
+    printf("\t\t\t\tSWPortal:\tBaseAddress = [0x%016lx]\n",
+	   (u64)buff << 32);
+  }
+}
+
+static void
+ccix_sam_entry(struct device *d, unsigned int index, int where)
+{
+  u32 buff, buff2;
+  buff = get_conf_long(d, where);
+  printf("\t\t\t\t#%02u: Enable%c ", index, FLAG(buff, 0x1));
+  if (buff & 0x2) {
+    printf("Port#%02u ", (buff >> 4) & 0xf);
+    printf("NumAgg: %02u\t", ((buff >> 10) & 0xf) + 1);
+  } else
+    printf("Local\t\t");
+
+  buff = get_conf_long(d, where + 0x4);
+  buff2 = get_conf_long(d, where + 0x8);
+  printf("[0x%016lx:0x%016lx]\n", ((u64)buff) << 32, ((u64)buff2) << 32);
+}
+
+static void
+ccix_protocol_dvsec(struct device *d, int where, int len)
+{
+  struct ccix_handler {
+    const char * name;
+    void (*cap_handler)(struct device *d, int where, struct ccix_state *state);
+    void (*ctl_handler)(struct device *d, int where, struct ccix_state *state);
+  };
+  static const struct ccix_handler ccix_handlers[11] = {
+    [0x0] = { "General", NULL, NULL, },
+    [0x1] = { "Unexpcted TL DVSEC", NULL, NULL, },
+    [0x2] = { "Unexpected PRL DVSEC", NULL, NULL, },
+    [0x3] = { "Common", ccix_common_cap, ccix_common_ctl, },
+    [0x4] = { "Port", ccix_port_cap, ccix_port_ctl, },
+    [0x5] = { "Link", ccix_link_cap, ccix_link_ctl, },
+    [0x6] = { "Home Agent", ccix_ha_cap, ccix_ha_ctl, },
+    [0x7] = { "Unknown", NULL, NULL, },
+    [0x8] = { "Request Agent", ccix_ra_cap, ccix_ra_ctl, },
+    [0x9] = { "Unknown", NULL, NULL, },
+    [0xa] = { "Slave Agent", ccix_sa_cap, ccix_sa_ctl, },
+  };
+
+  int i;
+  u32 buff, buff2;
+  u32 guid[4];
+  u32 cap_stat_offset;
+  u32 cnt_offset;
+  u32 sam_entry_offset;
+  u16 element;
+  u16 guid_offset;
+  struct ccix_state state = {};
+
+  printf("Protocol %x %x>\n", where, len);
+
+  buff = get_conf_long(d, where + 0x8);
+  guid_offset = buff >> 20;
+  if (!config_fetch(d, where + 0xc, len - 0xc))
+    return;
+
+  buff = get_conf_long(d, where + 0xc);
+  cap_stat_offset = (buff >> 20) & 0xfff;
+
+  buff = get_conf_long(d, where + 16);
+  cnt_offset = (buff >> 20) & 0xfff;
+
+  while (cap_stat_offset) {
+    buff = get_conf_long(d, cap_stat_offset);
+    element = buff & 0xffff;
+    printf("\t\t\tCCIX Cap [%x v%u] ", cap_stat_offset, (buff >> 16) & 0xf);
+    if (element >= sizeof(ccix_handlers) / sizeof(ccix_handlers[0])) {
+      printf("Unknown\n");
+    } else {
+      printf("%s\n", ccix_handlers[buff & 0xffff].name);
+      if (ccix_handlers[buff & 0xffff].cap_handler)
+	ccix_handlers[buff & 0xffff].cap_handler(d, cap_stat_offset, &state);
+      cap_stat_offset = buff >> 20;
+    }
+  }
+
+  while (cnt_offset) {
+    buff = get_conf_long(d, cnt_offset);
+    printf("\t\t\tCCIX Ctl [%x] ", cnt_offset);
+    element = buff & 0xfff;
+    if (element >= sizeof(ccix_handlers) / sizeof(ccix_handlers[0])) {
+      printf("Unknown\n");
+    } else {
+      printf("%s\n", ccix_handlers[buff & 0xffff].name);
+      if (ccix_handlers[buff & 0xffff].ctl_handler)
+	ccix_handlers[buff & 0xffff].ctl_handler(d, cnt_offset, &state);
+    }
+    cnt_offset = buff >> 20;
+  }
+
+  if (guid_offset) {
+    buff = get_conf_long(d, guid_offset + 16);
+    printf("\t\t\tCCIX CCID OVERRIDE [%x v%d]\n", guid_offset, buff & 0xf);
+    guid[0] = get_conf_long(d, guid_offset);
+    guid[1] = get_conf_long(d, guid_offset + 4);
+    guid[2] = get_conf_long(d, guid_offset + 8);
+    guid[3] = get_conf_long(d, guid_offset + 12);
+    
+    if ((guid[0] != 0xc3cb993b) ||
+	(guid[1] != 0x02c4436f) ||
+	(guid[2] != 0x9b68d271) ||
+	(guid[3] != 0xf2e8ca31)) {
+      printf("\t\t\t\t Invalid GUID\n");
+    } else {
+      printf("\t\t\t\t OverrideCCID:\t%04x\n", buff >> 16);
+    }
+  }
+
+  if (state.idm_table_offset) {
+    printf("\t\t\tCCIX IDM Table [%x]\n", state.idm_table_offset);
+    /* Only print valid entries */
+    for (i = 0; i < 64; i++) {
+      buff = get_conf_long(d, state.idm_table_offset + i * 4);
+      if ((buff & 0x1) == 0)
+	continue;
+      printf("\t\t\t\t#%02u: ", i);
+      if (buff & 0x02) {
+	printf("Port#%02u ", (buff >> 4) & 0xf);
+	if ((buff >> 10) & 0xf)
+	  printf("NumAgg: %02u, ", ((buff >> 10) & 0xf) + 1);
+	printf("Link#%02u", (buff >> 15) & 0x3f);
+      } else {
+	printf("Local");
+      }
+      printf("\n");
+    }
+  }
+  if (state.sr_table_offset) {
+    printf("\t\t\tCCIX SR Table [%x]\n", state.sr_table_offset);
+    /* Only print valid entries */
+    for (i = 0; i < 64; i++) {
+      buff = get_conf_long(d, state.sr_table_offset + i * 4);
+      if ((buff & 0x1) == 0)
+	continue;
+      printf("\t\t\t\t#%02u: ", i);
+      if (buff & 0x02) {
+	printf("Port#%02u ", (buff >> 4) & 0xf);
+	if ((buff >> 10) & 0xf)
+	  printf("NumAgg: %02u, ", ((buff >> 10) & 0xf) + 1);
+	printf("Link#%02u", (buff >> 15) & 0x3f);
+      } else {
+	printf("Local");
+      }
+      printf("\n");
+    }
+  }
+
+  if (state.rsam_table_offset) {
+    printf("\t\t\tCCIX RSAM Table [%x]\n", state.rsam_table_offset);
+    /* relies on the hash mask only have 2 DW if present*/
+    for (sam_entry_offset = 0; sam_entry_offset < state.rsam_table_size;
+	 sam_entry_offset += 0xc)
+      ccix_sam_entry(d, sam_entry_offset / 12,
+		     state.rsam_table_offset + sam_entry_offset);
+    /* Potential Hash mask here */
+    if (state.portagg_capable) {
+      buff = get_conf_long(d, state.rsam_table_offset + state.rsam_table_size - 0x8);
+      buff2 = get_conf_long(d, state.rsam_table_offset + state.rsam_table_size - 0x4);
+      printf("\t\t\t\tHashMask: 0x%016lx\n",
+	     ((u64)buff2 << 32) | (buff & 0xffffffc0));
+    }
+  }
+
+  if (state.hsam_table_offset) {
+    printf("\t\t\tCCIX HSAM Table [%x]\n", state.hsam_table_offset);
+    for (sam_entry_offset = 0; sam_entry_offset < state.hsam_table_size;
+	 sam_entry_offset += 0xc)
+      ccix_sam_entry(d, sam_entry_offset / 12,
+		     state.hsam_table_offset + sam_entry_offset);
+    /* Potential Hash mask here */
+    if (state.portagg_capable) {
+      buff = get_conf_long(d, state.hsam_table_offset + state.hsam_table_size - 0x8);
+      buff2 = get_conf_long(d, state.hsam_table_offset + state.hsam_table_size - 0x4);
+      printf("\t\t\t\tHashMask: 0x%016lx\n",
+	     ((u64)buff2 << 32) | (buff & 0xffffffc0));
+    }
+  }
+}
+
+static void
+ccix_transport_dvsec(struct device *d, int where, int len)
+{
+  u32 buff;
+  int i, j;
+
+  static const char *cal_times[8] = {
+    "10us", "50us", "100us", "500us",
+    "1ms", "5ms", "10ms", "50ms"};
+
+  static const char *quick_eq_times[] = {
+    "<NotSupp>",
+    "8ms/16ms",
+    "24ms/32ms",
+    "50ms/58ms",
+    "100ms/108ms",
+    "200ms/208ms",
+  };
+
+  static const char *ext_eq_phase_timeout[] = {
+    "24 ms / 32 ms ",
+    "50 ms / 58 ms ",
+    "100 ms / 108 ms ",
+    "200 ms / 208 ms ",
+    "400 ms / 408 ms ",
+    "600 ms / 608 ms ",
+  };
+
+  static const char *reach[4] = {
+    "SR", "LR", "SR/LR", "Unknown",
+  };
+
+  printf("Transport %x>\n", where);
+  /* CCIX v1.0 specification has a fixed length Transport DVSEC with 17DW */
+  if (len < 17 * 4) {
+    printf("\t\t\t\t<incomplete>\n");
+    return;
+  }
+  if (!config_fetch(d, where + 0xc, len - 0xc)) {
+    printf("\t\t\t<ureadable>\n");
+    return;
+  }
+  buff = get_conf_long(d, where + 0x8) >> 16;
+  printf("\t\t\tTranCap:\t");
+  if (buff & 1) {
+    printf("ESM+ %s RecalOnrC%c CalTime: %s QuickEqTime: %s\n",
+	   reach[(buff >> 1) & 0x3], FLAG(buff, 0x8),
+	   cal_times[(buff >> 4) & 0x7],
+	   ((buff >> 8) & 0x7) >= ARRAY_SIZE(quick_eq_times) ?
+	   "Unknown" : quick_eq_times[(buff >> 8) & 0x7]);
+
+    buff = get_conf_long(d, where + 0xc);
+    printf("\t\t\tESMRateCap:\t");
+    if (buff & (1 << 0))
+      printf("2.5 GT/s ");
+    if (buff & (1 << 1))
+      printf("5 GT/s ");
+    if (buff & (1 << 2))
+      printf("8 GT/s ");
+    if (buff & (1 << 5))
+      printf("16 GT/s ");
+    if (buff & (1 << 9))
+      printf("20 GT/s ");
+    if (buff & (1 << 14))
+      printf("25 GT/s ");
+    printf("\n");
+
+    buff = get_conf_long(d, where + 0x14);
+    printf("\t\t\tESMStatus:\t");
+    switch(buff & 0x7f) {
+    case 0: printf("Inactive "); break;
+    case 1: printf("2.5 GT/s "); break;
+    case 2: printf("5 GT/s "); break;
+    case 3: printf("8 GT/s "); break;
+    case 6: printf("16 GT/s "); break;
+    case 10: printf("20 GT/s "); break;
+    case 15: printf("25 GT/s "); break;
+    default:
+      printf("Unknown ");
+      break;
+    }
+    printf("Cal%c\n", FLAG(buff, 0x80));
+
+    buff = get_conf_long(d, where + 0x18);
+    printf("\t\t\tESMCtl:\t\tESM0: ");
+    switch(buff & 0x7f) {
+    case 0: printf("No speed "); break;
+    case 3: printf("8 GT/s "); break;
+    case 6: printf("16 GT/s "); break;
+    default:
+      printf("Unknown ");
+      break;
+    }
+    printf("ESM1: ");
+    switch((buff >> 8) & 0x7f) {
+    case 0: printf("No speed "); break;
+    case 6: printf("16 GT/s "); break;
+    case 10: printf("20 GT/s "); break;
+    case 15: printf("25 GT/s "); break;
+    default:
+      printf("Unknown ");
+      break;
+    }
+    printf("ESM%c ESMCompliance%c ", FLAG(buff, 0x8000), FLAG(buff, 0x80000));
+    if (buff & (1 << 24))
+      printf("LR\n");
+    else
+      printf("SR\n");
+    printf("\t\t\t\t\tExtEqPhase2TimeOut: %s ExtEqPhase3TimeOut: %s\n",
+	   ext_eq_phase_timeout[(buff >> 16) & 0x7],
+	   ext_eq_phase_timeout[(buff >> 20) & 0x7]);
+    printf("\t\t\t\t\tQuickEqTimeout: %s",
+	   (buff >> 26) & 0x7 > ARRAY_SIZE(quick_eq_times) ?
+	   "Unknown" : quick_eq_times[(buff >> 26) & 0x7]);
+
+    /* Equivalent values in Secondary PCI Express Ext Cap */
+    printf("\n\t\t\tESMEqCtl 20GT/s:\t");
+    for (i = 0; i < 4; i++) {
+      buff = get_conf_long(d, where + 0x1c + i * 4);
+      for (j = 0; j < 4; j++) {
+	      if (i | j)
+		printf("\t\t\t\t\t\t");
+	      printf("Lane #%02u: ", i * 4 + j);
+	      printf("Trans Presets US: 0x%x DS: 0x%x\n",
+		     (buff >> (8 * j)) & 0x7,
+		     (buff >> (8 *j + 4)) & 0x7);
+      }
+    }
+    printf("\n\t\t\tESMEqCtl 25GT/s:\t");
+    for (i = 0; i < 4; i++) {
+      buff = get_conf_long(d, where + 0x2c + i * 4);
+      for (j = 0; j < 4; j++) {
+	      if (i | j)
+		printf("\t\t\t\t\t\t");
+	      printf("Lane #%02u: Trans Presets US: 0x%x DS: 0x%x\n",
+		     i * 4 + j, (buff >> (8 * j)) & 0x7,
+		     (buff >> (8 *j + 4)) & 0x7);
+      }
+    }
+  }
+  else
+    printf("ESM- \n");
+
+  buff = get_conf_long(d, where + 0x3c);
+  printf("\t\t\tTLCap:\t\tOptTLP%c VCResCapInd: %u\n",
+	 FLAG(buff, 0x1), (buff >> 8) & 0x7);
+
+  buff = get_conf_long(d, where + 0x40);
+  printf("\t\t\tTLCtl:\t\tOptTLP%c LengthCheck%c\n",
+	 FLAG(buff, 0x1), FLAG(buff, 0x2));
+}
+
+void
+cap_ccix(struct device *d, int where)
+{
+  u32 buff;
+  u32 len;
+
+  /* First two DW have already been fetched to identify the DVSEC VID */
+  if (!config_fetch(d, where + 0x8, 4)) {
+    printf("\t\t<unreadable>\n");
+    return;
+  }
+
+  printf("\t\t<CCIX ");
+  buff = get_conf_long(d, where + 0x4);
+  len = buff >> 20;
+
+  buff = get_conf_long(d, where + 0x8);
+  switch(buff & 0xFF) {
+  case 1:
+    ccix_transport_dvsec(d, where, len);
+    break;
+  case 2:
+    ccix_protocol_dvsec(d, where, len);
+    break;
+  default:
+    printf("\t\t\t<UNKNOWN>\n");
+    break;
+  }
+}
diff --git a/ls-ecaps.c b/ls-ecaps.c
index 4417cd9..85c6084 100644
--- a/ls-ecaps.c
+++ b/ls-ecaps.c
@@ -797,6 +797,32 @@ cap_ptm(struct device *d, int where)
     }
 }
 
+static void
+cap_dvsec(struct device *d, int where)
+{
+  u32 buff;
+
+  printf("Designated Vendor-Specific <>\n");
+
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + 4, 4)) {
+      printf("\t\t<unreadable>\n");
+      return;
+    }
+    buff = get_conf_long(d, where + 4);
+    printf("\t\tVendor:%4x Version:%u\n", buff & 0xFFFF, (buff >> 16) & 0xF);
+    switch (buff & 0xffff) {
+    case PCI_VENDOR_ID_CCIX:
+      cap_ccix(d, where);
+      break;
+    default:
+      printf("\t\t<UNKNOWN VENDOR %4x %4x>\n", buff & 0xFFFF, PCI_VENDOR_ID_CCIX );
+      break;
+    }
+}
+
 void
 show_ext_caps(struct device *d, int type)
 {
@@ -924,7 +950,7 @@ show_ext_caps(struct device *d, int type)
 	    printf("Readiness Time Reporting <?>\n");
 	    break;
 	  case PCI_EXT_CAP_ID_DVSEC:
-	    printf("Designated Vendor-Specific <?>\n");
+	    cap_dvsec(d, where);
 	    break;
 	  case PCI_EXT_CAP_ID_VF_REBAR:
 	    printf("VF Resizable BAR <?>\n");
diff --git a/lspci.h b/lspci.h
index fefee52..94efebd 100644
--- a/lspci.h
+++ b/lspci.h
@@ -75,6 +75,10 @@ void show_caps(struct device *d, int where);
 
 void show_ext_caps(struct device *d, int type);
 
+/* ls-ccix.c */
+
+void cap_ccix(struct device *d, int where);
+
 /* ls-caps-vendor.c */
 
 void show_vendor_caps(struct device *d, int where, int cap);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 2/2] lspci: DVSEC Add an example from the ccix spec.
  2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
  2019-06-27 14:43 ` [RFC PATCH 1/2] lspci: CCIX DVSEC initial support Jonathan Cameron
@ 2019-06-27 14:43 ` Jonathan Cameron
  2019-07-02 21:28 ` [RFC PATCH 0/2] lspci: support for CCIX DVSEC Bjorn Helgaas
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2019-06-27 14:43 UTC (permalink / raw)
  To: linux-pci, Martin Mareš
  Cc: bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm,
	Jonathan Cameron

This example has 3 devices, the switch is not included.
The final device is reporting a large set of errors.

Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 tests/ccix-specex1 | 661 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 661 insertions(+)

diff --git a/tests/ccix-specex1 b/tests/ccix-specex1
new file mode 100644
index 0000000..f650297
--- /dev/null
+++ b/tests/ccix-specex1
@@ -0,0 +1,661 @@
+01:00.0 Class 0700: Device 19ec:0001
+00: ec 19 01 00 07 00 10 00 00 01 00 07 08 00 00 00
+10: 04 00 00 e0 00 00 00 00 04 00 00 e4 00 00 00 00
+20: 0c 00 00 00 00 08 00 00 00 00 00 00 ec 19 07 00
+30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00
+40: 01 48 03 00 08 00 00 00 05 60 84 00 00 00 00 00
+50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+60: 11 70 1f 00 02 80 00 00 e2 8f 00 00 00 00 00 00
+70: 10 00 02 00 23 80 00 00 17 29 00 00 83 f0 43 00
+80: 08 00 83 10 00 00 00 00 00 00 00 00 00 00 00 00
+90: 00 00 00 00 16 00 00 00 00 00 00 00 0e 00 00 00
+a0: 03 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00
+b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+100: 01 00 01 1c 00 00 00 00 00 00 40 00 30 20 46 00
+110: 00 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00
+120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+140: 10 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+150: 00 00 00 00 00 00 01 00 00 00 00 00 53 05 00 00
+160: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1c0: 19 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1f0: 02 00 01 38 01 00 00 00 00 00 00 31 00 00 00 00
+200: 00 00 00 00 7f 00 00 80 00 00 00 00 00 00 00 00
+210: 80 00 00 81 00 00 00 00 00 00 00 00 00 00 00 00
+220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+380: 0f 00 01 60 20 00 00 00 00 00 00 00 00 00 00 00
+390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+600: 23 00 40 64 2c 1e 40 04 01 00 35 05 27 42 00 00
+610: 00 00 00 00 8f 00 00 00 06 8f 54 15 21 32 21 32
+620: 32 21 32 21 21 32 21 32 32 21 32 21 54 65 54 65
+630: 65 54 65 54 54 65 54 65 65 54 65 54 01 01 00 00
+640: 03 00 00 00 23 00 00 00 2c 1e c0 6b 02 00 00 00
+650: 00 01 00 68 00 01 00 80 00 00 00 00 00 00 00 00
+660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+680: 03 00 00 6a 03 00 00 13 01 00 80 70 00 00 00 00
+690: 00 00 00 00 00 00 00 c0 3c 00 00 00 2c 00 00 b0
+6a0: 04 00 40 6b 03 41 00 00 00 00 00 00 00 00 00 00
+6b0: 00 00 00 d8 05 00 00 6d 21 40 00 02 10 40 00 02
+6c0: 10 40 00 02 10 40 00 00 00 00 00 f0 00 00 00 00
+6d0: 06 00 00 00 01 02 01 80 20 00 00 08 29 05 ff ff
+6e0: ff 00 00 00 03 05 ff ff ff 00 00 00 00 00 00 00
+6f0: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+800: 03 00 00 82 a3 00 00 01 00 00 00 00 01 00 00 00
+810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+820: 04 00 00 8b 03 21 00 00 00 00 00 00 00 00 00 00
+830: 00 01 00 00 01 80 00 00 00 01 00 00 00 02 00 00
+840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8b0: 05 00 00 96 03 04 00 00 10 40 00 01 08 20 80 00
+8c0: 10 20 00 00 00 00 00 00 00 00 00 00 03 00 00 00
+8d0: 10 40 00 01 08 20 80 00 10 20 00 00 00 00 00 00
+8e0: 00 00 00 00 00 02 00 00 08 02 00 00 00 00 00 00
+8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+960: 06 00 00 00 01 02 01 00 04 00 00 00 00 00 00 00
+970: 08 00 00 97 00 00 00 04 00 00 00 00 01 00 00 00
+980: 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
+990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+aa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b00: 03 00 00 00 00 01 00 00 00 00 02 00 00 00 00 00
+b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c00: 11 00 00 00 03 80 00 00 03 00 00 00 00 00 00 00
+c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d00: 01 f8 00 00 01 00 05 54 00 00 00 00 00 00 00 00
+d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+02:00.0 Class 0700: Device 19ec:0002
+00: ec 19 02 09 07 00 10 00 00 01 00 07 08 00 00 00
+10: 04 00 00 e0 00 00 00 00 04 00 00 e4 00 00 00 00
+20: 0c 00 00 00 00 08 00 00 00 00 00 00 ec 19 07 00
+30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00
+40: 01 48 03 00 08 00 00 00 05 60 84 00 00 00 00 00
+50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+60: 11 70 1f 00 02 80 00 00 e2 8f 00 00 00 00 00 00
+70: 10 00 02 00 23 80 00 00 17 29 00 00 83 f0 43 00
+80: 08 00 83 10 00 00 00 00 00 00 00 00 00 00 00 00
+90: 00 00 00 00 16 00 00 00 00 00 00 00 0e 00 00 00
+a0: 03 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00
+b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+100: 01 00 01 1c 00 00 00 00 00 00 40 00 30 20 46 00
+110: 00 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00
+120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+140: 10 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+150: 00 00 00 00 00 00 01 00 00 00 00 00 53 05 00 00
+160: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1c0: 19 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1f0: 02 00 01 38 01 00 00 00 00 00 00 31 00 00 00 00
+200: 00 00 00 00 7f 00 00 80 00 00 00 00 00 00 00 00
+210: 80 00 00 81 00 00 00 00 00 00 00 00 00 00 00 00
+220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+380: 0f 00 01 60 20 00 00 00 00 00 00 00 00 00 00 00
+390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+600: 23 00 40 64 2c 1e 40 04 01 00 35 05 27 42 00 00
+610: 00 00 00 00 8f 00 00 00 06 8f 54 15 21 32 21 32
+620: 32 21 32 21 21 32 21 32 32 21 32 21 54 65 54 65
+630: 65 54 65 54 54 65 54 65 65 54 65 54 01 01 00 00
+640: 03 00 00 00 23 00 00 00 2c 1e c0 6b 02 00 00 00
+650: 00 01 00 68 00 01 00 80 00 00 00 00 00 00 00 00
+660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+680: 03 00 00 6a 02 00 00 02 01 00 80 70 00 00 00 00
+690: 00 00 00 00 00 00 00 c0 3c 00 00 00 00 00 00 00
+6a0: 04 00 40 6b 83 00 00 00 00 00 00 00 00 00 00 00
+6b0: 00 00 00 d8 05 00 00 6d 21 40 00 02 10 40 00 02
+6c0: 10 40 00 02 10 40 00 00 00 00 00 f0 00 00 00 00
+6d0: 0a 00 00 00 11 00 01 80 20 00 00 08 03 05 ff ff
+6e0: ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+800: 03 00 00 82 a3 00 00 02 00 00 00 00 01 00 00 00
+810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+820: 04 00 00 8b 83 10 00 00 00 00 00 00 00 00 00 00
+830: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8b0: 05 00 00 96 03 04 00 00 10 40 00 01 08 20 80 00
+8c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
+8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+960: 0a 00 00 00 11 00 01 04 04 00 00 00 00 00 00 00
+970: 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00
+980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+aa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c00: 03 00 00 00 11 80 00 00 00 00 00 00 00 00 00 00
+c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d00: 01 f8 00 00 01 00 05 54 00 00 00 00 00 00 00 00
+d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+03:00.0 Class 0700: Device 19ec:0003
+00: ec 19 03 00 07 00 10 00 00 01 00 07 08 00 00 00
+10: 04 00 00 e0 00 00 00 00 04 00 00 e4 00 00 00 00
+20: 0c 00 00 00 00 08 00 00 00 00 00 00 ec 19 07 00
+30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00
+40: 01 48 03 00 08 00 00 00 05 60 84 00 00 00 00 00
+50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+60: 11 70 1f 00 03 00 00 00 e2 8f 00 00 00 00 00 00
+70: 10 00 02 00 23 80 00 00 17 29 00 00 83 f0 43 00
+80: 08 00 83 10 00 00 00 00 00 00 00 00 00 00 00 00
+90: 00 00 00 00 16 00 00 00 00 00 00 00 0e 00 00 00
+a0: 03 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00
+b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+100: 01 00 01 1c 00 00 00 00 00 00 40 00 30 20 46 00
+110: 00 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00
+120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+140: 10 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+150: 00 00 00 00 00 00 01 00 00 00 00 00 53 05 00 00
+160: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1c0: 19 00 01 1f 00 00 00 00 00 00 00 00 00 00 00 00
+1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1f0: 02 00 01 38 01 00 00 00 00 00 00 31 00 00 00 00
+200: 00 00 00 00 7f 00 00 80 00 00 00 00 00 00 00 00
+210: 80 00 00 81 00 00 00 00 00 00 00 00 00 00 00 00
+220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+380: 0f 00 01 60 20 00 00 00 00 00 00 00 00 00 00 00
+390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+600: 23 00 40 64 2c 1e 40 04 01 00 35 05 27 42 00 00
+610: 00 00 00 00 8f 00 00 00 06 8f 54 15 21 32 21 32
+620: 32 21 32 21 21 32 21 32 32 21 32 21 54 65 54 65
+630: 65 54 65 54 54 65 54 65 65 54 65 54 01 01 00 00
+640: 03 00 00 00 23 00 00 00 2c 1e c0 7b 02 00 00 00
+650: 00 01 00 68 00 01 00 80 00 00 00 00 00 00 00 00
+660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+680: 03 00 00 6a 02 00 00 03 01 00 80 70 00 00 00 00
+690: 00 00 00 d0 00 00 00 c0 3c 00 00 b0 00 00 00 00
+6a0: 04 00 40 6b 83 00 00 00 00 00 00 00 00 00 00 00
+6b0: 00 00 00 da 05 00 00 6d 21 40 00 02 10 40 00 02
+6c0: 10 40 00 02 10 40 00 00 00 00 00 d8 00 00 00 00
+6d0: 08 00 00 00 01 00 00 00 00 00 00 d4 00 00 00 00
+6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+800: 03 00 00 82 63 00 00 02 00 00 00 00 01 00 00 00
+810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+820: 04 00 00 84 83 10 00 00 01 00 00 00 00 00 00 00
+830: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+840: 05 00 00 96 03 00 00 00 10 40 00 01 08 20 80 00
+850: 00 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00
+860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+960: 08 00 00 00 11 00 01 04 01 00 00 00 00 00 00 00
+970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+aa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b00: 03 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00
+b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c00: 03 00 00 00 00 00 00 00 11 80 00 00 00 00 00 00
+c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d00: 01 84 00 00 00 40 08 40 00 00 00 00 01 00 00 00
+d10: 03 00 00 00 ff 1f 00 00 03 00 00 00 03 04 04 02
+d20: 03 00 04 00 05 00 00 00 06 00 00 00 07 00 00 00
+d30: 08 00 00 00 01 09 04 00 00 00 00 00 00 00 00 00
+d40: 01 84 00 00 00 00 08 41 00 00 00 00 01 00 00 00
+d50: 03 00 00 00 7f 00 00 00 02 00 01 06 00 04 05 00
+d60: 00 00 06 00 00 00 01 00 00 00 00 00 00 00 00 00
+d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d80: 01 84 00 00 00 40 08 44 00 00 00 02 00 00 00 00
+d90: 03 00 00 00 0f 00 00 00 00 00 01 02 03 04 00 00
+da0: 01 84 00 00 00 30 08 43 00 00 00 02 00 00 00 00
+db0: 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00
+dc0: 01 84 00 00 00 30 08 44 00 00 00 02 00 00 00 00
+dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+de0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+df0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/2] lspci: support for CCIX DVSEC
  2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
  2019-06-27 14:43 ` [RFC PATCH 1/2] lspci: CCIX DVSEC initial support Jonathan Cameron
  2019-06-27 14:43 ` [RFC PATCH 2/2] lspci: DVSEC Add an example from the ccix spec Jonathan Cameron
@ 2019-07-02 21:28 ` Bjorn Helgaas
  2019-07-03  7:18   ` Jonathan Cameron
  2019-08-06 11:16 ` Jonathan Cameron
  2020-01-22  9:42 ` Martin Mareš
  4 siblings, 1 reply; 9+ messages in thread
From: Bjorn Helgaas @ 2019-07-02 21:28 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-pci, Martin Mareš,
	Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

On Thu, Jun 27, 2019 at 10:43:53PM +0800, Jonathan Cameron wrote:
> This series adds support for near complete interpretation of CCIX DVSEC.
> Most of the CCIX base 1.0 specification is covered, but a few minor
> elements are not currently printed (some of the timeouts and credit
> types). That can be rectified in a future version or follow up patch
> and isn't necessary for this discussion.
> 
> CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
> It is flexible in allowed interconnect topologies, but is overlayed
> on top of a traditional PCIe tree.  Note that CCIX physical devices
> may turn up in a number of different locations in the PCIe tree.
> 
> The topology configuration and physical layer controls and description
> are presented using PCIe DVSEC structures defined in the CCIX 1.0
> base specification.  These use the unique ID granted by the PCISIG.
> Note that, whilst it looks like a Vendor ID for this usecase it is
> not one and can only be used to identify DVSEC and related CCIX protocol
> messages.
> 
> So why an RFC?
> * Are the lspci maintainers happy to have the tool include support for
>   PCI configuration structures that are defined in other standards?
> * Is the general approach and code structure appropriate?
> * It's a lot of description so chances are some of it isn't in a format
>   consistent with the rest of lspci!
> 
> The patch set includes and example that was manually created to exercise
> much of the parser.  We also have qemu patches to emulate more complex
> topologies if anyone wants to experiment.
> 
> https://patchwork.kernel.org/cover/11015357/
> 
> Example output from lspci -t -F ccix-specex1 -s 03:00.0
> 
> 03:00.0 Class 0700: Device 19ec:0003 (prog-if 01)
> ...

> 	Capabilities: [600 v0] Designated Vendor-Specific <>
> 		Vendor:1e2c Version:0
> 		<CCIX Transport 600>
> 			TranCap:	ESM+ SR/LR RecalOnrC- CalTime: 500us QuickEqTime: 200ms/208ms
> 			ESMRateCap:	2.5 GT/s 5 GT/s 8 GT/s 16 GT/s 20 GT/s 25 GT/s 
> 			ESMStatus:	25 GT/s Cal+
> 			ESMCtl:		ESM0: 16 GT/s ESM1: 25 GT/s ESM+ ESMCompliance- LR
> 					ExtEqPhase2TimeOut: 400 ms / 408 ms  ExtEqPhase3TimeOut: 600 ms / 608 ms 
> 					QuickEqTimeout: Unknown
> 			ESMEqCtl 20GT/s:	Lane #00: Trans Presets US: 0x1 DS: 0x2

It's a minor annoyance that all these lines are longer than 80 columns.  I
know there are existing things in lspci that are wider, which are also
slightly annoying.  But you're adding a TON of them and there's a bunch of
whitespace at the beginning of each line :)

> The following grants the 'pciutils' project trademark usage of
> CCIX tradmark where relevant.
> 
> This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
> you and other parties that are paticipating (the "participants") in the
> pciutils with the understanding that the participants will use CCIX's
> name and trademark only when this patch is used in association with the
> pciutils project.
> 
> CCIX is also distributing this patch to these participants with the
> understanding that if any portion of the CCIX specification will be
> used or referenced in the pciutils project, the participants will not modify
> the cited portion of the CCIX specification and will give CCIX propery
> copyright attribution by including the following copyright notice with
> the cited part of the CCIX specification:
> "© 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."

s/tradmark/trademark/
s/paticipating/participating/
s/propery/proper/

I guess "will not modify the cited portion" just means people will
quote it accurately?  It seems obvious that people proposing changes
to pciutils can't really modify the CCIX spec.

The above all sounds a little onerous and I doubt I would sign up to
it because I'd be afraid to mention "CCIX" in an email and I'm pretty
sure I'd forget to add the copyright notice somewhere.  But
fortunately that's up to Martin, not me.

> Jonathan Cameron (2):
>   CCIX DVSEC initial support
>   DVSEC Add an example from the ccix spec.

s/ccix/CCIX/ so they match.  No period necessary in subject line.

I don't maintain pciutils, but I like to have subject lines match in
grammatical style.  One of the above is a sentence and the other is not.
Maybe:

  Add CCIX DVSEC decoding support
  Add DVSEC example from CCIX spec

Bjorn

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/2] lspci: support for CCIX DVSEC
  2019-07-02 21:28 ` [RFC PATCH 0/2] lspci: support for CCIX DVSEC Bjorn Helgaas
@ 2019-07-03  7:18   ` Jonathan Cameron
  0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2019-07-03  7:18 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, Martin =?GB18030?B?TWFyZYEwlDg=?=,
	Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GB18030", Size: 6559 bytes --]

Hi Bjorn,

Thanks for taking a look.

On Tue, 2 Jul 2019 16:28:29 -0500
Bjorn Helgaas <helgaas@kernel.org> wrote:

> On Thu, Jun 27, 2019 at 10:43:53PM +0800, Jonathan Cameron wrote:
> > This series adds support for near complete interpretation of CCIX DVSEC.
> > Most of the CCIX base 1.0 specification is covered, but a few minor
> > elements are not currently printed (some of the timeouts and credit
> > types). That can be rectified in a future version or follow up patch
> > and isn't necessary for this discussion.
> > 
> > CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
> > It is flexible in allowed interconnect topologies, but is overlayed
> > on top of a traditional PCIe tree.  Note that CCIX physical devices
> > may turn up in a number of different locations in the PCIe tree.
> > 
> > The topology configuration and physical layer controls and description
> > are presented using PCIe DVSEC structures defined in the CCIX 1.0
> > base specification.  These use the unique ID granted by the PCISIG.
> > Note that, whilst it looks like a Vendor ID for this usecase it is
> > not one and can only be used to identify DVSEC and related CCIX protocol
> > messages.
> > 
> > So why an RFC?
> > * Are the lspci maintainers happy to have the tool include support for
> >   PCI configuration structures that are defined in other standards?
> > * Is the general approach and code structure appropriate?
> > * It's a lot of description so chances are some of it isn't in a format
> >   consistent with the rest of lspci!
> > 
> > The patch set includes and example that was manually created to exercise
> > much of the parser.  We also have qemu patches to emulate more complex
> > topologies if anyone wants to experiment.
> > 
> > https://patchwork.kernel.org/cover/11015357/
> > 
> > Example output from lspci -t -F ccix-specex1 -s 03:00.0
> > 
> > 03:00.0 Class 0700: Device 19ec:0003 (prog-if 01)
> > ...  
> 
> > 	Capabilities: [600 v0] Designated Vendor-Specific <>
> > 		Vendor:1e2c Version:0
> > 		<CCIX Transport 600>
> > 			TranCap:	ESM+ SR/LR RecalOnrC- CalTime: 500us QuickEqTime: 200ms/208ms
> > 			ESMRateCap:	2.5 GT/s 5 GT/s 8 GT/s 16 GT/s 20 GT/s 25 GT/s 
> > 			ESMStatus:	25 GT/s Cal+
> > 			ESMCtl:		ESM0: 16 GT/s ESM1: 25 GT/s ESM+ ESMCompliance- LR
> > 					ExtEqPhase2TimeOut: 400 ms / 408 ms  ExtEqPhase3TimeOut: 600 ms / 608 ms 
> > 					QuickEqTimeout: Unknown
> > 			ESMEqCtl 20GT/s:	Lane #00: Trans Presets US: 0x1 DS: 0x2  
> 
> It's a minor annoyance that all these lines are longer than 80 columns.  I
> know there are existing things in lspci that are wider, which are also
> slightly annoying.  But you're adding a TON of them and there's a bunch of
> whitespace at the beginning of each line :)

I agree entirely, but not sure what to do about it whilst fitting in
the style that lscpi already has.

We could:
1. Wrap where possible, but leave the same deep indents.  That would get rid
   of some of the long lines but still leave an excessive seeming amount
   of indentation.
2. Reduce the indent, perhaps by not having the separate layer for
   which DVSEC it is.

	Capabilities: [600 v0] DVSEC: CCIX - Transport Layer

The second 600 is redundant anyway.

I'm not sure if that potentially overloads things too much as hard
to know what future DVSECs will be defined with really long names.

> 
> > The following grants the 'pciutils' project trademark usage of
> > CCIX tradmark where relevant.
> > 
> > This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
> > you and other parties that are paticipating (the "participants") in the
> > pciutils with the understanding that the participants will use CCIX's
> > name and trademark only when this patch is used in association with the
> > pciutils project.
> > 
> > CCIX is also distributing this patch to these participants with the
> > understanding that if any portion of the CCIX specification will be
> > used or referenced in the pciutils project, the participants will not modify
> > the cited portion of the CCIX specification and will give CCIX propery
> > copyright attribution by including the following copyright notice with
> > the cited part of the CCIX specification:
> > "0„8 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."  
> 
> s/tradmark/trademark/
> s/paticipating/participating/
> s/propery/proper/

Gah. That's what I get for copy typing that stuff between two machines rather
than figuring out the games to get it from one to the other.
Sorry about that!

> 
> I guess "will not modify the cited portion" just means people will
> quote it accurately?  It seems obvious that people proposing changes
> to pciutils can't really modify the CCIX spec.

True enough. Note this stuff only applies if a section of the spec is
actually quoted.  As I understand it, things like field names etc
are covered by fair use.  Note that this whole series doesn't have
such a copyright notice, because I don't believe there are any
quotations from the specification in here.

> 
> The above all sounds a little onerous and I doubt I would sign up to
> it because I'd be afraid to mention "CCIX" in an email and I'm pretty
> sure I'd forget to add the copyright notice somewhere.  But
> fortunately that's up to Martin, not me.

The whole thing is a bit unfortunate, but the intent on the copyright stuff is
that any substantial quotes from any spec should have that anyway.  The
real aim is the trademark grant bit. I gather that's all about showing
you are actively maintaining your trademark (granting it's use with particular
scope counts).

As a non lawyer I'm certainly not a good source on this, but as I understand
it there is no problem in using it to describe a CCIX device etc, but that
it only gets dodgy if it becomes part of a 'product' name or similar.

It is also worth noting that anything using PCI-SIG terms is also under
a trademark policy...
http://pcisig.com/sites/default/files/newsroom_attachments/Trademark_and_Logo_Usage_Guidelines_updated_112206.pdf

That's probably not a can of worms to open though (it makes a scary
read)

> 
> > Jonathan Cameron (2):
> >   CCIX DVSEC initial support
> >   DVSEC Add an example from the ccix spec.  
> 
> s/ccix/CCIX/ so they match.  No period necessary in subject line.
> 
> I don't maintain pciutils, but I like to have subject lines match in
> grammatical style.  One of the above is a sentence and the other is not.
> Maybe:
> 
>   Add CCIX DVSEC decoding support
>   Add DVSEC example from CCIX spec

I'll tidy them up for V2. Thanks!
> 
> Bjorn



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/2] lspci: support for CCIX DVSEC
  2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
                   ` (2 preceding siblings ...)
  2019-07-02 21:28 ` [RFC PATCH 0/2] lspci: support for CCIX DVSEC Bjorn Helgaas
@ 2019-08-06 11:16 ` Jonathan Cameron
  2020-01-22  9:42 ` Martin Mareš
  4 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2019-08-06 11:16 UTC (permalink / raw)
  To: linux-pci, Martin Mareš
  Cc: bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

Heads up for the curious: 

Evaluation version of the CCIX 1.0a base specification now available,
(though there is a form to complete and license agreement)..

https://www.ccixconsortium.com/ccix-library/download-form/

I'll hopefully get v2 of this patch set out in the next few weeks.

Thanks,

Jonathan


On Thu, 27 Jun 2019 22:43:53 +0800
Jonathan Cameron <Jonathan.Cameron@huawei.com> wrote:

> This series adds support for near complete interpretation of CCIX DVSEC.
> Most of the CCIX base 1.0 specification is covered, but a few minor
> elements are not currently printed (some of the timeouts and credit
> types). That can be rectified in a future version or follow up patch
> and isn't necessary for this discussion.
> 
> CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
> It is flexible in allowed interconnect topologies, but is overlayed
> on top of a traditional PCIe tree.  Note that CCIX physical devices
> may turn up in a number of different locations in the PCIe tree.
> 
> The topology configuration and physical layer controls and description
> are presented using PCIe DVSEC structures defined in the CCIX 1.0
> base specification.  These use the unique ID granted by the PCISIG.
> Note that, whilst it looks like a Vendor ID for this usecase it is
> not one and can only be used to identify DVSEC and related CCIX protocol
> messages.
> 
> So why an RFC?
> * Are the lspci maintainers happy to have the tool include support for
>   PCI configuration structures that are defined in other standards?
> * Is the general approach and code structure appropriate?
> * It's a lot of description so chances are some of it isn't in a format
>   consistent with the rest of lspci!
> 
> The patch set includes and example that was manually created to exercise
> much of the parser.  We also have qemu patches to emulate more complex
> topologies if anyone wants to experiment.
> 
> https://patchwork.kernel.org/cover/11015357/
> 
> Example output from lspci -t -F ccix-specex1 -s 03:00.0
> 
> 03:00.0 Class 0700: Device 19ec:0003 (prog-if 01)
> 	Subsystem: Device 19ec:0007
> 	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
> 	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> 	Latency: 0, Cache Line Size: 32 bytes
> 	Interrupt: pin A routed to IRQ 255
> 	Region 0: Memory at e0000000 (64-bit, non-prefetchable)
> 	Region 2: Memory at e4000000 (64-bit, non-prefetchable)
> 	Region 4: [virtual] Memory at 80000000000 (64-bit, prefetchable)
> 	Capabilities: [40] Power Management version 3
> 		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
> 		Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
> 	Capabilities: [48] MSI: Enable- Count=1/4 Maskable- 64bit+
> 		Address: 0000000000000000  Data: 0000
> 	Capabilities: [60] MSI-X: Enable- Count=32 Masked-
> 		Vector table: BAR=3 offset=00000000
> 		PBA: BAR=2 offset=00008fe0
> 	Capabilities: [70] Express (v2) Endpoint, MSI 00
> 		DevCap:	MaxPayload 1024 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
> 			ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000W
> 		DevCtl:	CorrErr+ NonFatalErr+ FatalErr+ UnsupReq-
> 			RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
> 			MaxPayload 128 bytes, MaxReadReq 512 bytes
> 		DevSta:	CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
> 		LnkCap:	Port #0, Speed 8GT/s, Width x8, ASPM not supported
> 			ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
> 		LnkCtl:	ASPM Disabled; RCB 128 bytes Disabled- CommClk-
> 			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> 		LnkSta:	Speed 8GT/s (ok), Width x8 (ok)
> 			TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
> 		DevCap2: Completion Timeout: Range BC, TimeoutDis+, NROPrPrP-, LTR-
> 			 10BitTagComp-, 10BitTagReq-, OBFF Not Supported, ExtFmt-, EETLPPrefix-
> 			 EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
> 			 FRS-, TPHComp-, ExtTPHComp-
> 		DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
> 			 AtomicOpsCtl: ReqEn-
> 		LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
> 			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
> 			 Compliance De-emphasis: -6dB
> 		LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+, EqualizationPhase1+
> 			 EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
> 	Capabilities: [100 v1] Advanced Error Reporting
> 		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> 		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> 		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
> 		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
> 		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
> 		AERCap:	First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
> 			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
> 		HeaderLog: 00000000 00000000 00000000 00000000
> 	Capabilities: [1c0 v1] Secondary PCI Express
> 		LnkCtl3: LnkEquIntrruptEn-, PerformEqu-
> 		LaneErrStat: 0
> 	Capabilities: [1f0 v1] Virtual Channel
> 		Caps:	LPEVC=0 RefClk=100ns PATEntryBits=1
> 		Arb:	Fixed- WRR32- WRR64- WRR128-
> 		Ctrl:	ArbSelect=Fixed
> 		Status:	InProgress-
> 		Port Arbitration Table [500] <?>
> 		VC0:	Caps:	PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
> 			Arb:	Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
> 			Ctrl:	Enable+ ID=0 ArbSelect=Fixed TC/VC=7f
> 			Status:	NegoPending- InProgress-
> 		VC1:	Caps:	PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
> 			Arb:	Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
> 			Ctrl:	Enable+ ID=1 ArbSelect=Fixed TC/VC=80
> 			Status:	NegoPending- InProgress-
> 	Capabilities: [380 v1] Address Translation Service (ATS)
> 		ATSCap:	Invalidate Queue Depth: 00
> 		ATSCtl:	Enable-, Smallest Translation Unit: 00
> 	Capabilities: [600 v0] Designated Vendor-Specific <>
> 		Vendor:1e2c Version:0
> 		<CCIX Transport 600>
> 			TranCap:	ESM+ SR/LR RecalOnrC- CalTime: 500us QuickEqTime: 200ms/208ms
> 			ESMRateCap:	2.5 GT/s 5 GT/s 8 GT/s 16 GT/s 20 GT/s 25 GT/s 
> 			ESMStatus:	25 GT/s Cal+
> 			ESMCtl:		ESM0: 16 GT/s ESM1: 25 GT/s ESM+ ESMCompliance- LR
> 					ExtEqPhase2TimeOut: 400 ms / 408 ms  ExtEqPhase3TimeOut: 600 ms / 608 ms 
> 					QuickEqTimeout: Unknown
> 			ESMEqCtl 20GT/s:	Lane #00: Trans Presets US: 0x1 DS: 0x2
> 						Lane #01: Trans Presets US: 0x2 DS: 0x3
> 						Lane #02: Trans Presets US: 0x1 DS: 0x2
> 						Lane #03: Trans Presets US: 0x2 DS: 0x3
> 						Lane #04: Trans Presets US: 0x2 DS: 0x3
> 						Lane #05: Trans Presets US: 0x1 DS: 0x2
> 						Lane #06: Trans Presets US: 0x2 DS: 0x3
> 						Lane #07: Trans Presets US: 0x1 DS: 0x2
> 						Lane #08: Trans Presets US: 0x1 DS: 0x2
> 						Lane #09: Trans Presets US: 0x2 DS: 0x3
> 						Lane #10: Trans Presets US: 0x1 DS: 0x2
> 						Lane #11: Trans Presets US: 0x2 DS: 0x3
> 						Lane #12: Trans Presets US: 0x2 DS: 0x3
> 						Lane #13: Trans Presets US: 0x1 DS: 0x2
> 						Lane #14: Trans Presets US: 0x2 DS: 0x3
> 						Lane #15: Trans Presets US: 0x1 DS: 0x2
> 
> 			ESMEqCtl 25GT/s:	Lane #00: Trans Presets US: 0x4 DS: 0x5
> 						Lane #01: Trans Presets US: 0x5 DS: 0x6
> 						Lane #02: Trans Presets US: 0x4 DS: 0x5
> 						Lane #03: Trans Presets US: 0x5 DS: 0x6
> 						Lane #04: Trans Presets US: 0x5 DS: 0x6
> 						Lane #05: Trans Presets US: 0x4 DS: 0x5
> 						Lane #06: Trans Presets US: 0x5 DS: 0x6
> 						Lane #07: Trans Presets US: 0x4 DS: 0x5
> 						Lane #08: Trans Presets US: 0x4 DS: 0x5
> 						Lane #09: Trans Presets US: 0x5 DS: 0x6
> 						Lane #10: Trans Presets US: 0x4 DS: 0x5
> 						Lane #11: Trans Presets US: 0x5 DS: 0x6
> 						Lane #12: Trans Presets US: 0x5 DS: 0x6
> 						Lane #13: Trans Presets US: 0x4 DS: 0x5
> 						Lane #14: Trans Presets US: 0x5 DS: 0x6
> 						Lane #15: Trans Presets US: 0x4 DS: 0x5
> 				TLCap: OptTLP+ VCResCapInd: 1
> 				TLCtl: OptTLP+ LengthCheck+
> 	Capabilities: [644 v0] Designated Vendor-Specific <>
> 		Vendor:1e2c Version:0
> 		<CCIX Protocol 644 7bc>
> 			CCIX Cap [680 v0] Common
> 				CommonCap:	DevID: 3 StructVer: 0 DevMultiPort- PrimaryPort
> 				CommonCap2:	Rdy+ PartialCache- PortAgg- 128B- MultiHop- SamAlign- SWPort- 
> 						AddrWidth: 48 bit, DataRdyTime: 16 * 32^7
> 				PER [d00]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
> 					Component:	Link
> 					Address:	[0x0000000100000000], MaskLen: 3
> 					MemErr:	FRU:		3
> 						MemType:	NonVolatile
> 						Operation:	Scrub
> 						ErrorType:	SingleSymbolChipKillECC
> 						Chan:		2
> 						Module:		3
> 						Bank:		4
> 						Device:		5
> 						Row:		6
> 						Column:		7
> 						Rank:		8
> 						BitPos:		1
> 						ChipID:		9
> 						MemPoolType:	Unspecified
> 						VenSpecLen:	0
> 			CCIX Cap [6a0 v0] Port
> 				PortCap:	Port #0 Rdy+ OptTLP+ P2PForward- Links: 1 PSAMNum: 0 
> 				PortCap2:	Agg Mask 0x0
> 				PortCap3:	FW Mask 0x0
> 			CCIX Cap [6b4 v0] Link
> 				LinkCap:	Rdy+ SharedCredits- MsgPack- NoCompAck- MaxPktSize: 128B 
> 				LinkSendCap:	MaxMemReq: 16, MaxSnpReq: 16, MaxDatReq: 32
> 				LinkRcvCap:	MaxMemReq: 16, MaxSnpReq: 16, MaxDatReq: 32
> 				MiscCap:	MaxMiscReqSend: 16, MaxMiscReqRcv 16
> 			CCIX Cap [6d0 v0] Request Agent
> 				RACapStat:	DiscRdyStat+ CacheFlushStat-
> 			CCIX Ctl [800] Common
> 				CommCtl1:	DeviceEnable+ PrimaryPortEnable+ Mesh- PortAgg-
> 						IDMTableValid+ RSAMTableValid+ HSAMTableValid- SWPort-
> 						ErrorAgent: 0, DevID: 2
> 				CommCtl2:	PartialCache- 128B- AddrWidth: 48 bit
> 				DevErrCtl:	Enable+
> 			CCIX Ctl [820] Port
> 				PortCntrl:	Enable+ OptTLP+ LinksEnabled: 33, PSAMNum: 0
> 				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
> 				ErrCtlSta2:	SevLogMask: 0x00, SevPERMsgMask: 0x00
> 				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
> 				SourceTransportID: 02:00.0
> 				PER [da0]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
> 					Component:	Port
> 					Address:	[0x0000000002000000], MaskLen: 0
> 					PortErr:
> 						Operation:	Command
> 						PortErrType:	Generic
> 						CCIX Message:	Unspecified
> 			CCIX Ctl [840] Link
> 				Link#00 [844]
> 				LinkCtl:	Enable+ CreditSnd+ MsgPack- NoCmpAck- MaxPktSize: 128B 
> 						RA-to-HA
> 				MaxCredit:	Mem: 0016, Snoop: 0016, Data 0016, Misc 0000
> 				MinCredit:	Mem: 0008, Snoop: 0008, Data 0008, Misc 0000
> 				DestBDF:	01:00.0
> 				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
> 				ErrCtlSta2:	SevLogMask: 0x01, SevPERMsgMask: 0x00
> 				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
> 				PER [d80]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
> 					Component:	Link
> 					Address:	[0x0000000002000000], MaskLen: 3
> 					LinkErr:
> 						OperationType:	Read
> 						ErrorType:	CreditOverflow
> 						LinkID:		3
> 						LinkCreditType:	4
> 						CCIX Message:	Unspecified
> 			CCIX Ctl [960] Request Agent
> 				RACtl:	ID: 01, Enable+ SnpRespEnable- CacheFlush- CacheEnable-
> 				ErrCtlSta1:	Current: Error pending, LogDisable- PERMsgDisable-
> 				ErrCtlSta2:	SevLogMask: 0x00, SevPERMsgMask: 0x00
> 				TypeMaskR/L:	Mem-/- Cache-/- ATC-/- Port-/- Agent-/-
> 				PER [d40]:	LogVersion: 1, ME+ SevUE- SevNoComm- SevDegraded- SevDeferred+
> 					Component:	RA
> 					Address:	[0x0000000100000000], MaskLen: 3
> 					CacheErr:
> 						CacheType:	Data
> 						OperationType:	Prefetch
> 						CacheError:	Data
> 						Level:		4
> 						Set:		5
> 						Way:		6
> 						InstanceID:	1
> 			CCIX IDM Table [c00]
> 				#00: Port#00 Link#00
> 				#02: Local
> 			CCIX RSAM Table [b00]
> 				#00: Enable+ Port#00 NumAgg: 01	[0x0000000000000000:0x0002000000000000]
> 				#01: Enable- Local		[0x0000000000000000:0x0000000000000000]
> 				#02: Enable- Local		[0x0000000000000000:0x0000000000000000]
> 				#03: Enable- Local		[0x0000000000000000:0x0000000000000000]
> 				#04: Enable- Local		[0x0000000000000000:0x0000000000000000]
> 
> The following grants the 'pciutils' project trademark usage of
> CCIX tradmark where relevant.
> 
> This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
> you and other parties that are paticipating (the "participants") in the
> pciutils with the understanding that the participants will use CCIX's
> name and trademark only when this patch is used in association with the
> pciutils project.
> 
> CCIX is also distributing this patch to these participants with the
> understanding that if any portion of the CCIX specification will be
> used or referenced in the pciutils project, the participants will not modify
> the cited portion of the CCIX specification and will give CCIX propery
> copyright attribution by including the following copyright notice with
> the cited part of the CCIX specification:
> "© 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."
> 
> Jonathan Cameron (2):
>   CCIX DVSEC initial support
>   DVSEC Add an example from the ccix spec.
> 
>  Makefile           |    2 +-
>  lib/header.h       |    2 +
>  ls-ccix.c          | 1364 ++++++++++++++++++++++++++++++++++++++++++++
>  ls-ecaps.c         |   28 +-
>  lspci.h            |    4 +
>  tests/ccix-specex1 |  661 +++++++++++++++++++++
>  6 files changed, 2059 insertions(+), 2 deletions(-)
>  create mode 100644 ls-ccix.c
>  create mode 100644 tests/ccix-specex1
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/2] lspci: support for CCIX DVSEC
  2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
                   ` (3 preceding siblings ...)
  2019-08-06 11:16 ` Jonathan Cameron
@ 2020-01-22  9:42 ` Martin Mareš
  2020-01-27 11:48   ` Jonathan Cameron
  4 siblings, 1 reply; 9+ messages in thread
From: Martin Mareš @ 2020-01-22  9:42 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-pci, bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

Hello!

> This series adds support for near complete interpretation of CCIX DVSEC.
> Most of the CCIX base 1.0 specification is covered, but a few minor
> elements are not currently printed (some of the timeouts and credit
> types). That can be rectified in a future version or follow up patch
> and isn't necessary for this discussion.
> 
> CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
> It is flexible in allowed interconnect topologies, but is overlayed
> on top of a traditional PCIe tree.  Note that CCIX physical devices
> may turn up in a number of different locations in the PCIe tree.
> 
> The topology configuration and physical layer controls and description
> are presented using PCIe DVSEC structures defined in the CCIX 1.0
> base specification.  These use the unique ID granted by the PCISIG.
> Note that, whilst it looks like a Vendor ID for this usecase it is
> not one and can only be used to identify DVSEC and related CCIX protocol
> messages.
> 
> So why an RFC?
> * Are the lspci maintainers happy to have the tool include support for
>   PCI configuration structures that are defined in other standards?
> * Is the general approach and code structure appropriate?
> * It's a lot of description so chances are some of it isn't in a format
>   consistent with the rest of lspci!

I am very happy to include parsers of vendor-specific capabilities.

The general approach is fine, but please bring the source code closer
to the coding style of the rest of pciutils.

> The following grants the 'pciutils' project trademark usage of
> CCIX tradmark where relevant.
> 
> This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
> you and other parties that are paticipating (the "participants") in the
> pciutils with the understanding that the participants will use CCIX's
> name and trademark only when this patch is used in association with the
> pciutils project.

I suspect that this is not compatible with the GPL. Everybody is allowed
to use portions of pciutils in other GPLed projects. So the trademark usage
right should be granted to use in the contributed code, regardless of whether
it is currently in the pciutils project, or any other project.

> CCIX is also distributing this patch to these participants with the
> understanding that if any portion of the CCIX specification will be
> used or referenced in the pciutils project, the participants will not modify
> the cited portion of the CCIX specification and will give CCIX propery
> copyright attribution by including the following copyright notice with
> the cited part of the CCIX specification:
> "© 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."

Are there any citations affected by this in your patch? You only refer to data
structures defined by the specification, but this is factual information which
cannot be copyrighted (but IANAL).

I am strongly opposed to adding more copyright notices to the pciutils
besides the GPL.

				Have a nice fortnight
-- 
Martin `MJ' Mareš                        <mj@ucw.cz>   http://mj.ucw.cz/
United Computer Wizards, Prague, Czech Republic, Europe, Earth, Universe
hAS ANYONE SEEN MY cAPSLOCK KEY?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 1/2] lspci: CCIX DVSEC initial support
  2019-06-27 14:43 ` [RFC PATCH 1/2] lspci: CCIX DVSEC initial support Jonathan Cameron
@ 2020-01-22  9:48   ` Martin Mareš
  0 siblings, 0 replies; 9+ messages in thread
From: Martin Mareš @ 2020-01-22  9:48 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-pci, bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

Hello!

A couple of remarks to the code:

> +#define ARRAY_SIZE(x) sizeof(x)/sizeof(*(x))

This can be useful in other parts, too, so please move it to pciutils.h.

> +struct ccix_state {
> +  int portagg_capable:1;
> +  int sw_portal_capable:1;
> +  int forwarding:1;

Please avoid bit fields. There is no need to save data size at the expense
of increasing code size.

> +static const char * ccix_sub_mem_types[8] = {

This should be "static const char * const ccix_sub_mem_types[8]".

> +  printf("\t\t\t\t\tMemErr:\t");

Could you please try decreasing the overall amount of indent to make
the output narrower?

> +    switch (value) {
> +    case 0 ... 2:

Please avoid GCC extensions.

> +static void
> +cap_dvsec(struct device *d, int where)
> +{
> +  u32 buff;
> +
> +  printf("Designated Vendor-Specific <>\n");
> +
> +  if (verbose < 2)
> +    return;

The "<>" does not make much sense now :)

If verbose < 2, I would print

	Designated Vendor-Specific: vendor XXXX, version NNN

> +    buff = get_conf_long(d, where + 4);
> +    printf("\t\tVendor:%4x Version:%u\n", buff & 0xFFFF, (buff >> 16) & 0xF);
> +    switch (buff & 0xffff) {

Maybe read two 16-bit numbers instead?

				Have a nice fortnight
-- 
Martin `MJ' Mareš                        <mj@ucw.cz>   http://mj.ucw.cz/
United Computer Wizards, Prague, Czech Republic, Europe, Earth, Universe
"Snow falling on Perl. White noise covering line noise. Hides all the bugs too." -- J. Putnam

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/2] lspci: support for CCIX DVSEC
  2020-01-22  9:42 ` Martin Mareš
@ 2020-01-27 11:48   ` Jonathan Cameron
  0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2020-01-27 11:48 UTC (permalink / raw)
  To: Martin Mareš
  Cc: linux-pci, bhelgaas, Lorenzo Pieralisi, jcm, nariman.poushin, linuxarm

On Wed, 22 Jan 2020 10:42:21 +0100
Martin Mareš <mj@ucw.cz> wrote:

> Hello!
> 
> > This series adds support for near complete interpretation of CCIX DVSEC.
> > Most of the CCIX base 1.0 specification is covered, but a few minor
> > elements are not currently printed (some of the timeouts and credit
> > types). That can be rectified in a future version or follow up patch
> > and isn't necessary for this discussion.
> > 
> > CCIX (www.ccixconsortium.org) is a coherent interconnect specification.
> > It is flexible in allowed interconnect topologies, but is overlayed
> > on top of a traditional PCIe tree.  Note that CCIX physical devices
> > may turn up in a number of different locations in the PCIe tree.
> > 
> > The topology configuration and physical layer controls and description
> > are presented using PCIe DVSEC structures defined in the CCIX 1.0
> > base specification.  These use the unique ID granted by the PCISIG.
> > Note that, whilst it looks like a Vendor ID for this usecase it is
> > not one and can only be used to identify DVSEC and related CCIX protocol
> > messages.
> > 
> > So why an RFC?
> > * Are the lspci maintainers happy to have the tool include support for
> >   PCI configuration structures that are defined in other standards?
> > * Is the general approach and code structure appropriate?
> > * It's a lot of description so chances are some of it isn't in a format
> >   consistent with the rest of lspci!  
> 
> I am very happy to include parsers of vendor-specific capabilities.

Great.

> 
> The general approach is fine, but please bring the source code closer
> to the coding style of the rest of pciutils.

Will do - though may take me a while to get back to this one.

> 
> > The following grants the 'pciutils' project trademark usage of
> > CCIX tradmark where relevant.
> > 
> > This patch is being distributed by the CCIX Consortium, Inc. (CCIX) to
> > you and other parties that are paticipating (the "participants") in the
> > pciutils with the understanding that the participants will use CCIX's
> > name and trademark only when this patch is used in association with the
> > pciutils project.  
> 
> I suspect that this is not compatible with the GPL. Everybody is allowed
> to use portions of pciutils in other GPLed projects. So the trademark usage
> right should be granted to use in the contributed code, regardless of whether
> it is currently in the pciutils project, or any other project.

I'll keep clear of the interesting legal argument around that one.
Good news is that the CCIX consortium has agreed to more standard statement
on trademark ownership only.  No right limitations in the new version, just
statements of fact.

As I understand it, using the CCIX to mean CCIX is never a trademark violation
anyway, it's only when composites are created from it that we might run into
issues.  That's true whatever the text here says and is equally true of PCI for
example if they should ever decide to enforce their trademarks.

> 
> > CCIX is also distributing this patch to these participants with the
> > understanding that if any portion of the CCIX specification will be
> > used or referenced in the pciutils project, the participants will not modify
> > the cited portion of the CCIX specification and will give CCIX propery
> > copyright attribution by including the following copyright notice with
> > the cited part of the CCIX specification:
> > "© 2019 CCIX CONSORTIUM, INC. ALL RIGHTS RESERVED."  
> 
> Are there any citations affected by this in your patch? You only refer to data
> structures defined by the specification, but this is factual information which
> cannot be copyrighted (but IANAL).

I never got a clear answer on this from our legal (was exploring other
alternatives if we couldn't get the CCIX consortium requirements relaxed).
My understanding was the same as yours, but it became unnecessary with
confirmation that the CCIX consortium legal had relaxed their requirements
anyway.

> 
> I am strongly opposed to adding more copyright notices to the pciutils
> besides the GPL.
> 
> 				Have a nice fortnight

I'll fix the legal stuff in the next version. We got that changed after
push back from various other bits of the open source community.  Just took
a while due to some other complexities that I won't go into but you might
be able to guess given who I work for ;)

Was very helpful indeed to get feedback of the form you've given as it
forced the issue nicely.  I should have posted a note to this thread to
say that was changing, sorry for wasting your time.

Thanks!

Jonathan




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-01-27 11:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27 14:43 [RFC PATCH 0/2] lspci: support for CCIX DVSEC Jonathan Cameron
2019-06-27 14:43 ` [RFC PATCH 1/2] lspci: CCIX DVSEC initial support Jonathan Cameron
2020-01-22  9:48   ` Martin Mareš
2019-06-27 14:43 ` [RFC PATCH 2/2] lspci: DVSEC Add an example from the ccix spec Jonathan Cameron
2019-07-02 21:28 ` [RFC PATCH 0/2] lspci: support for CCIX DVSEC Bjorn Helgaas
2019-07-03  7:18   ` Jonathan Cameron
2019-08-06 11:16 ` Jonathan Cameron
2020-01-22  9:42 ` Martin Mareš
2020-01-27 11:48   ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).