Module Name:    src
Committed By:   martin
Date:           Tue Jul  4 14:35:21 UTC 2017

Modified Files:
        src/sys/dev/pci [netbsd-8]: pci_subr.c pcireg.h

Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #80):
        sys/dev/pci/pci_subr.c: revision 1.184
        sys/dev/pci/pci_subr.c: revision 1.185
        sys/dev/pci/pci_subr.c: revision 1.186
        sys/dev/pci/pci_subr.c: revision 1.187
        sys/dev/pci/pci_subr.c: revision 1.188
        sys/dev/pci/pci_subr.c: revision 1.189
        sys/dev/pci/pcireg.h: revision 1.131
 Add missing return to print the Slot Power Limit Value correctly.
 Fix to print the following bit fields correctly.
  -  Supported Link Speeds Vector in LCAP2
  -  Lower SKP OS Generation Supported Speed Vector  in LCAP2
  -  Lower SKP OS Reception Supported Speed Vector in LCAP2
  -  Enable Lower SKP OS Generation Vector in LCTL3
Note that the above bitfields start from 0 and the follwing bitfields start
from 1:
  -  Maximum Link Speed in LCAP
  -  Current Link Speed in LCSR
  -  Target Link Speed in LCSR2
 For the Target Link Speed in LCSR2, 0 is allowed for a device which supports
2.5GT/s only (and this check also works for devices which compliant to
versions of the base specification prior to 3.0.
Tested with BCM5709:
-      Target Link Speed: unknown value (0)
+      Target Link Speed: 2.5GT/s
 For Attention Indicator Control bit and Power Indicator Control bit, it's
allowed to be a read only value 0 if corresponding capability register bit
is 0.
 Fix a bug that LTR's latency in L1 PM Substates capability and Latency
Tolerance Reporting capability isn't printed correctly.
Fix printf format/argument.


To generate a diff of this commit:
cvs rdiff -u -r1.183 -r1.183.2.1 src/sys/dev/pci/pci_subr.c
cvs rdiff -u -r1.130 -r1.130.2.1 src/sys/dev/pci/pcireg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/pci_subr.c
diff -u src/sys/dev/pci/pci_subr.c:1.183 src/sys/dev/pci/pci_subr.c:1.183.2.1
--- src/sys/dev/pci/pci_subr.c:1.183	Mon May 29 07:09:20 2017
+++ src/sys/dev/pci/pci_subr.c	Tue Jul  4 14:35:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_subr.c,v 1.183 2017/05/29 07:09:20 msaitoh Exp $	*/
+/*	$NetBSD: pci_subr.c,v 1.183.2.1 2017/07/04 14:35:21 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183 2017/05/29 07:09:20 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183.2.1 2017/07/04 14:35:21 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -1606,18 +1606,39 @@ pci_print_pcie_compl_timeout(uint32_t va
 	}
 }
 
-static const char * const pcie_linkspeeds[] = {"2.5", "2.5", "5.0", "8.0"};
+static const char * const pcie_linkspeeds[] = {"2.5", "5.0", "8.0"};
 
+/*
+ * Print link speed. This function is used for the following register bits:
+ *   Maximum Link Speed in LCAP
+ *   Current Link Speed in LCSR
+ *   Target Link Speed in LCSR2
+ * All of above bitfield's values start from 1.
+ * For LCSR2, 0 is allowed for a device which supports 2.5GT/s only (and
+ * this check also works for devices which compliant to versions of the base
+ * specification prior to 3.0.
+ */
 static void
-pci_print_pcie_linkspeed(pcireg_t val)
+pci_print_pcie_linkspeed(int regnum, pcireg_t val)
 {
 
-	if (val > __arraycount(pcie_linkspeeds))
+	if ((regnum == PCIE_LCSR2) && (val == 0))
+		printf("2.5GT/s\n");
+	else if ((val < 1) || (val > __arraycount(pcie_linkspeeds)))
 		printf("unknown value (%u)\n", val);
 	else
-		printf("%sGT/s\n", pcie_linkspeeds[val]);
+		printf("%sGT/s\n", pcie_linkspeeds[val - 1]);
 }
 
+/*
+ * Print link speed "vector".
+ * This function is used for the following register bits:
+ *   Supported Link Speeds Vector in LCAP2
+ *   Lower SKP OS Generation Supported Speed Vector  in LCAP2
+ *   Lower SKP OS Reception Supported Speed Vector in LCAP2
+ *   Enable Lower SKP OS Generation Vector in LCTL3
+ * All of above bitfield's values start from 0.
+ */
 static void
 pci_print_pcie_linkspeedvector(pcireg_t val)
 {
@@ -1788,7 +1809,7 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		reg = regs[o2i(capoff + PCIE_LCAP)];
 		printf("    Link Capabilities Register: 0x%08x\n", reg);
 		printf("      Maximum Link Speed: ");
-		pci_print_pcie_linkspeed(reg & PCIE_LCAP_MAX_SPEED);
+		pci_print_pcie_linkspeed(PCIE_LCAP, reg & PCIE_LCAP_MAX_SPEED);
 		printf("      Maximum Link Width: x%u lanes\n",
 		    (unsigned int)__SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH));
 		printf("      Active State PM Support: ");
@@ -1871,7 +1892,8 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		reg = regs[o2i(capoff + PCIE_LCSR)];
 		printf("    Link Status Register: 0x%04x\n", reg >> 16);
 		printf("      Negotiated Link Speed: ");
-		pci_print_pcie_linkspeed(__SHIFTOUT(reg, PCIE_LCSR_LINKSPEED));
+		pci_print_pcie_linkspeed(PCIE_LCSR,
+		    __SHIFTOUT(reg, PCIE_LCSR_LINKSPEED));
 		printf("      Negotiated Link Width: x%u lanes\n",
 		    (unsigned int)__SHIFTOUT(reg, PCIE_LCSR_NLW));
 		onoff("Training Error", reg, PCIE_LCSR_LINKTRAIN_ERR);
@@ -1885,8 +1907,10 @@ pci_conf_print_pcie_cap(const pcireg_t *
 	}
 
 	if (check_slot == true) {
+		pcireg_t slcap;
+		
 		/* Slot Capability Register */
-		reg = regs[o2i(capoff + PCIE_SLCAP)];
+		slcap = reg = regs[o2i(capoff + PCIE_SLCAP)];
 		printf("    Slot Capability Register: 0x%08x\n", reg);
 		onoff("Attention Button Present", reg, PCIE_SLCAP_ABP);
 		onoff("Power Controller Present", reg, PCIE_SLCAP_PCP);
@@ -1914,35 +1938,44 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		onoff("Command Completed Interrupt Enabled", reg,
 		    PCIE_SLCSR_CCE);
 		onoff("Hot-Plug Interrupt Enabled", reg, PCIE_SLCSR_HPE);
-		printf("      Attention Indicator Control: ");
-		switch ((reg & PCIE_SLCSR_AIC) >> 6) {
-		case 0x0:
-			printf("reserved\n");
-			break;
-		case PCIE_SLCSR_IND_ON:
-			printf("on\n");
-			break;
-		case PCIE_SLCSR_IND_BLINK:
-			printf("blink\n");
-			break;
-		case PCIE_SLCSR_IND_OFF:
-			printf("off\n");
-			break;
+		/*
+		 * For Attention Indicator Control and Power Indicator Control,
+		 * it's allowed to be a read only value 0 if corresponding
+		 * capability register bit is 0.
+		 */
+		if (slcap & PCIE_SLCAP_AIP) {
+			printf("      Attention Indicator Control: ");
+			switch ((reg & PCIE_SLCSR_AIC) >> 6) {
+			case 0x0:
+				printf("reserved\n");
+				break;
+			case PCIE_SLCSR_IND_ON:
+				printf("on\n");
+				break;
+			case PCIE_SLCSR_IND_BLINK:
+				printf("blink\n");
+				break;
+			case PCIE_SLCSR_IND_OFF:
+				printf("off\n");
+				break;
+			}
 		}
-		printf("      Power Indicator Control: ");
-		switch ((reg & PCIE_SLCSR_PIC) >> 8) {
-		case 0x0:
-			printf("reserved\n");
-			break;
-		case PCIE_SLCSR_IND_ON:
-			printf("on\n");
-			break;
-		case PCIE_SLCSR_IND_BLINK:
-			printf("blink\n");
-			break;
-		case PCIE_SLCSR_IND_OFF:
-			printf("off\n");
-			break;
+		if (slcap & PCIE_SLCAP_PIP) {
+			printf("      Power Indicator Control: ");
+			switch ((reg & PCIE_SLCSR_PIC) >> 8) {
+			case 0x0:
+				printf("reserved\n");
+				break;
+			case PCIE_SLCSR_IND_ON:
+				printf("on\n");
+				break;
+			case PCIE_SLCSR_IND_BLINK:
+				printf("blink\n");
+				break;
+			case PCIE_SLCSR_IND_OFF:
+				printf("off\n");
+				break;
+			}
 		}
 		printf("      Power Controller Control: Power %s\n",
 		    reg & PCIE_SLCSR_PCC ? "off" : "on");
@@ -2151,10 +2184,11 @@ pci_conf_print_pcie_cap(const pcireg_t *
 
 		/* Link Control 2 */
 		reg = regs[o2i(capoff + PCIE_LCSR2)];
+		/* If the vector is 0, LCAP2 is not implemented */
 		printf("    Link Control 2: 0x%04x\n", reg & 0xffff);
 		printf("      Target Link Speed: ");
-		pci_print_pcie_linkspeed(__SHIFTOUT(reg,
-			PCIE_LCSR2_TGT_LSPEED));
+		pci_print_pcie_linkspeed(PCIE_LCSR2,
+		    __SHIFTOUT(reg, PCIE_LCSR2_TGT_LSPEED));
 		onoff("Enter Compliance Enabled", reg, PCIE_LCSR2_ENT_COMPL);
 		onoff("HW Autonomous Speed Disabled", reg,
 		    PCIE_LCSR2_HW_AS_DIS);
@@ -2741,6 +2775,7 @@ pci_conf_print_pcie_power(uint8_t base, 
 			break;
 		}
 		printf("%s\n", s);
+		return;
 	}
 
 	for (unsigned int i = scale; i > 0; i--)
@@ -3468,18 +3503,15 @@ pci_conf_print_ltr_cap(const pcireg_t *r
 	pcireg_t reg;
 
 	printf("\n  Latency Tolerance Reporting\n");
-	reg = regs[o2i(extcapoff + PCI_LTR_MAXSNOOPLAT)] & 0xffff;
-	printf("    Max Snoop Latency Register: 0x%04x\n", reg);
-	printf("      Max Snoop LatencyValue: %u\n",
-	    (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_VAL));
-	printf("      Max Snoop LatencyScale: %uns\n",
-	    PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_SCALE)));
-	reg = regs[o2i(extcapoff + PCI_LTR_MAXNOSNOOPLAT)] >> 16;
-	printf("    Max No-Snoop Latency Register: 0x%04x\n", reg);
-	printf("      Max No-Snoop LatencyValue: %u\n",
-	    (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_VAL));
-	printf("      Max No-Snoop LatencyScale: %uns\n",
-	    PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_SCALE)));
+	reg = regs[o2i(extcapoff + PCI_LTR_MAXSNOOPLAT)];
+	printf("    Max Snoop Latency Register: 0x%04x\n", reg & 0xffff);
+	printf("      Max Snoop Latency: %juns\n",
+	    (uintmax_t)(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_VAL)
+	    * PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_SCALE))));
+	printf("    Max No-Snoop Latency Register: 0x%04x\n", reg >> 16);
+	printf("      Max No-Snoop Latency: %juns\n",
+	    (uintmax_t)(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_VAL)
+	    * PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_SCALE))));
 }
 
 static void

Index: src/sys/dev/pci/pcireg.h
diff -u src/sys/dev/pci/pcireg.h:1.130 src/sys/dev/pci/pcireg.h:1.130.2.1
--- src/sys/dev/pci/pcireg.h:1.130	Mon May 29 07:09:20 2017
+++ src/sys/dev/pci/pcireg.h	Tue Jul  4 14:35:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcireg.h,v 1.130 2017/05/29 07:09:20 msaitoh Exp $	*/
+/*	$NetBSD: pcireg.h,v 1.130.2.1 2017/07/04 14:35:21 martin Exp $	*/
 
 /*
  * Copyright (c) 1995, 1996, 1999, 2000
@@ -1877,7 +1877,7 @@ struct pci_rom {
 #define	PCI_LTR_MAXNOSNOOPLAT	0x04	/* Max No-Snoop Latency */
 #define	PCI_LTR_MAXNOSNOOPLAT_VAL __BITS(25, 16) /* Max No-Snoop LatencyValue*/
 #define	PCI_LTR_MAXNOSNOOPLAT_SCALE __BITS(28, 26) /*Max NoSnoop LatencyScale*/
-#define	PCI_LTR_SCALETONS(x) ((32 << (x)) / 32)
+#define	PCI_LTR_SCALETONS(x) (1 << ((x) * 5))
 
 /*
  * Extended capability ID: 0x0019

Reply via email to