Module Name:    src
Committed By:   msaitoh
Date:           Mon May 22 04:21:20 UTC 2017

Modified Files:
        src/sys/dev/pci: pci_subr.c

Log Message:
- The Captured Slot Power Limit value is only for device which has upsteam
   port.
- The following three registers are the same encoding, so use the same
  function:
   - the Captured Slot Power Limit in the Device Capability register of PICe
     capability.
   - the Slot Power Limit in Slot Capability register of PCIe capability.
   - the Base Power and Data Scale in the Data Register of Power Budgeting
     capability.
- Fix the alternative encoding check of power limit as document. Add check if
  scale equals to 0.


To generate a diff of this commit:
cvs rdiff -u -r1.180 -r1.181 src/sys/dev/pci/pci_subr.c

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.180 src/sys/dev/pci/pci_subr.c:1.181
--- src/sys/dev/pci/pci_subr.c:1.180	Tue May  9 11:17:07 2017
+++ src/sys/dev/pci/pci_subr.c	Mon May 22 04:21:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_subr.c,v 1.180 2017/05/09 11:17:07 msaitoh Exp $	*/
+/*	$NetBSD: pci_subr.c,v 1.181 2017/05/22 04:21:20 msaitoh 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.180 2017/05/09 11:17:07 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.181 2017/05/22 04:21:20 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v
 #endif
 
 static int pci_conf_find_cap(const pcireg_t *, int, unsigned int, int *);
+static void pci_conf_print_pcie_power(uint8_t, unsigned int);
 
 /*
  * Descriptions of known PCI classes and subclasses.
@@ -1651,6 +1652,7 @@ pci_conf_print_pcie_cap(const pcireg_t *
 	bool check_link = true;
 	bool check_slot = false;
 	bool check_rootport = false;
+	bool check_upstreamport = false;
 	unsigned int pciever;
 	unsigned int i;
 
@@ -1664,9 +1666,11 @@ pci_conf_print_pcie_cap(const pcireg_t *
 	switch ((reg & 0x00f00000) >> 20) {
 	case PCIE_XCAP_TYPE_PCIE_DEV:	/* 0x0 */
 		printf("PCI Express Endpoint device\n");
+		check_upstreamport = true;
 		break;
 	case PCIE_XCAP_TYPE_PCI_DEV:	/* 0x1 */
 		printf("Legacy PCI Express Endpoint device\n");
+		check_upstreamport = true;
 		break;
 	case PCIE_XCAP_TYPE_ROOT:	/* 0x4 */
 		printf("Root Port of PCI Express Root Complex\n");
@@ -1675,6 +1679,7 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		break;
 	case PCIE_XCAP_TYPE_UP:		/* 0x5 */
 		printf("Upstream Port of PCI Express Switch\n");
+		check_upstreamport = true;
 		break;
 	case PCIE_XCAP_TYPE_DOWN:	/* 0x6 */
 		printf("Downstream Port of PCI Express Switch\n");
@@ -1683,9 +1688,11 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		break;
 	case PCIE_XCAP_TYPE_PCIE2PCI:	/* 0x7 */
 		printf("PCI Express to PCI/PCI-X Bridge\n");
+		check_upstreamport = true;
 		break;
 	case PCIE_XCAP_TYPE_PCI2PCIE:	/* 0x8 */
 		printf("PCI/PCI-X to PCI Express Bridge\n");
+		/* Upstream port is not PCIe */
 		check_slot = true;
 		break;
 	case PCIE_XCAP_TYPE_ROOT_INTEP:	/* 0x9 */
@@ -1735,10 +1742,12 @@ pci_conf_print_pcie_cap(const pcireg_t *
 	onoff("Attention Indicator Present", reg, PCIE_DCAP_ATTN_IND);
 	onoff("Power Indicator Present", reg, PCIE_DCAP_PWR_IND);
 	onoff("Role-Based Error Report", reg, PCIE_DCAP_ROLE_ERR_RPT);
-	printf("      Captured Slot Power Limit Value: %u\n",
-	    (unsigned int)__SHIFTOUT(reg, PCIE_DCAP_SLOT_PWR_LIM_VAL));
-	printf("      Captured Slot Power Limit Scale: %u\n",
-	    (unsigned int)__SHIFTOUT(reg, PCIE_DCAP_SLOT_PWR_LIM_SCALE));
+	if (check_upstreamport) {
+		printf("      Captured Slot Power Limit: ");
+		pci_conf_print_pcie_power(
+			__SHIFTOUT(reg, PCIE_DCAP_SLOT_PWR_LIM_VAL),
+			__SHIFTOUT(reg, PCIE_DCAP_SLOT_PWR_LIM_SCALE));
+	}
 	onoff("Function-Level Reset Capability", reg, PCIE_DCAP_FLR);
 
 	/* Device Control Register */
@@ -1882,10 +1891,9 @@ pci_conf_print_pcie_cap(const pcireg_t *
 		onoff("Power Indicator Present", reg, PCIE_SLCAP_PIP);
 		onoff("Hot-Plug Surprise", reg, PCIE_SLCAP_HPS);
 		onoff("Hot-Plug Capable", reg, PCIE_SLCAP_HPC);
-		printf("      Slot Power Limit Value: %d\n",
-		    (unsigned int)(reg & PCIE_SLCAP_SPLV) >> 7);
-		printf("      Slot Power Limit Scale: %d\n",
-		    (unsigned int)(reg & PCIE_SLCAP_SPLS) >> 15);
+		printf("      Slot Power Limit Value: ");
+		pci_conf_print_pcie_power(__SHIFTOUT(reg, PCIE_SLCAP_SPLV),
+		    __SHIFTOUT(reg, PCIE_SLCAP_SPLS));
 		onoff("Electromechanical Interlock Present", reg,
 		    PCIE_SLCAP_EIP);
 		onoff("No Command Completed Support", reg, PCIE_SLCAP_NCCS);
@@ -2700,40 +2708,47 @@ pci_conf_print_vc_cap(const pcireg_t *re
 		    "  VC", varbsel, varbsize);
 }
 
+/*
+ * Print Power limit. This encoding is the same among the following registers:
+ *  - The Captured Slot Power Limit in the PCIe Device Capability Register.
+ *  - The Slot Power Limit in the PCIe Slot Capability Register.
+ *  - The Base Power in the Data register of Power Budgeting capability.
+ */
 static void
-pci_conf_print_pwrbdgt_base_power(uint8_t base, unsigned int scale)
+pci_conf_print_pcie_power(uint8_t base, unsigned int scale)
 {
-	if (base <= 0xef) {
-		unsigned int sdiv = 1;
-		for (unsigned int i = scale; i > 0; i--)
-			sdiv *= 10;
+	unsigned int sdiv = 1;
 
-		printf("%u", base / sdiv);
+	if ((scale == 0) && (base > 0xef)) {
+		const char *s;
 
-		if (scale != 0) {
-			printf(".%u", base % sdiv);
+		switch (base) {
+		case 0xf0:
+			s = "239W < x <= 250W";
+			break;
+		case 0xf1:
+			s = "250W < x <= 275W";
+			break;
+		case 0xf2:
+			s = "275W < x <= 300W";
+			break;
+		default:
+			s = "reserved for above 300W";
+			break;
 		}
-		printf ("W\n");
-		return;
+		printf("%s\n", s);
 	}
 
-	const char *s;
+	for (unsigned int i = scale; i > 0; i--)
+		sdiv *= 10;
 
-	switch (base) {
-	case 0xf0:
-		s = "239W < x <= 250W";
-		break;
-	case 0xf1:
-		s = "250W < x <= 275W";
-		break;
-	case 0xf2:
-		s = "275W < x <= 300W";
-		break;
-	default:
-		s = "reserved for above 300W";
-		break;
+	printf("%u", base / sdiv);
+
+	if (scale != 0) {
+		printf(".%u", base % sdiv);
 	}
-	printf("%s\n", s);
+	printf ("W\n");
+	return;
 }
 
 static const char *
@@ -2782,7 +2797,6 @@ static void
 pci_conf_print_pwrbdgt_cap(const pcireg_t *regs, int capoff, int extcapoff)
 {
 	pcireg_t reg;
-	unsigned int scale;
 
 	printf("\n  Power Budgeting\n");
 
@@ -2791,9 +2805,10 @@ pci_conf_print_pwrbdgt_cap(const pcireg_
 
 	reg = regs[o2i(extcapoff + PCI_PWRBDGT_DATA)];
 	printf("    Data register: 0x%08x\n", reg);
-	scale = __SHIFTOUT(reg, PCI_PWRBDGT_DATA_SCALE);
 	printf("      Base Power: ");
-	pci_conf_print_pwrbdgt_base_power((uint8_t)reg, scale);
+	pci_conf_print_pcie_power(
+	    __SHIFTOUT(reg, PCI_PWRBDGT_DATA_BASEPWR),
+	    __SHIFTOUT(reg, PCI_PWRBDGT_DATA_SCALE));
 	printf("      PM Sub State: 0x%hhx\n",
 	    (uint8_t)__SHIFTOUT(reg, PCI_PWRBDGT_PM_SUBSTAT));
 	printf("      PM State: D%u\n",

Reply via email to