Module Name:    src
Committed By:   msaitoh
Date:           Fri May 30 03:42:38 UTC 2014

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

Log Message:
- Add PCI-X capability stuff.
- remove extra ':' in pci_conf_print_pcie_cap()
- Add comments.


To generate a diff of this commit:
cvs rdiff -u -r1.121 -r1.122 src/sys/dev/pci/pci_subr.c
cvs rdiff -u -r1.93 -r1.94 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.121 src/sys/dev/pci/pci_subr.c:1.122
--- src/sys/dev/pci/pci_subr.c:1.121	Tue May 27 16:50:31 2014
+++ src/sys/dev/pci/pci_subr.c	Fri May 30 03:42:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_subr.c,v 1.121 2014/05/27 16:50:31 msaitoh Exp $	*/
+/*	$NetBSD: pci_subr.c,v 1.122 2014/05/30 03:42:38 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.121 2014/05/27 16:50:31 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.122 2014/05/30 03:42:38 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -1117,7 +1117,109 @@ pci_conf_print_msi_cap(const pcireg_t *r
 }
 
 /* XXX pci_conf_print_cpci_hostwap_cap */
-/* XXX pci_conf_print_pcix_cap */
+
+/*
+ * For both command register and status register.
+ * The argument "idx" is index number (0 to 7).
+ */
+static int
+pcix_split_trans(unsigned int idx)
+{
+	static int table[8] = {
+		1, 2, 3, 4, 8, 12, 16, 32
+	};
+
+	if (idx >= __arraycount(table))
+		return -1;
+	return table[idx];
+}
+
+static void
+pci_conf_print_pcix_cap(const pcireg_t *regs, int capoff)
+{
+	pcireg_t reg;
+	int isbridge;
+	int i;
+
+	isbridge = (PCI_HDRTYPE_TYPE(regs[o2i(PCI_BHLC_REG)])
+	    & PCI_HDRTYPE_PPB) != 0 ? 1 : 0;
+	printf("\n  PCI-X %s Capabilities Register\n",
+	    isbridge ? "Bridge" : "Non-bridge");
+
+	reg = regs[o2i(capoff)];
+	if (isbridge != 0) {
+		printf("    Secondary status register: 0x%04x\n",
+		    (reg & 0xffff0000) >> 16);
+		onoff("64bit device", reg, PCIX_STATUS_64BIT);
+		onoff("133MHz capable", reg, PCIX_STATUS_133);
+		onoff("Split completion discarded", reg, PCIX_STATUS_SPLDISC);
+		onoff("Unexpected split completion", reg, PCIX_STATUS_SPLUNEX);
+		onoff("Split completion overrun", reg, PCIX_BRIDGE_ST_SPLOVRN);
+		onoff("Split request delayed", reg, PCIX_BRIDGE_ST_SPLRQDL);
+		printf("      Secondary clock frequency: 0x%x\n",
+		    (reg & PCIX_BRIDGE_2NDST_CLKF)
+		    >> PCIX_BRIDGE_2NDST_CLKF_SHIFT);
+		printf("      Version: 0x%x\n",
+		    (reg & PCIX_BRIDGE_2NDST_VER_MASK)
+		    >> PCIX_BRIDGE_2NDST_VER_SHIFT);
+		onoff("266MHz capable", reg, PCIX_BRIDGE_ST_266);
+		onoff("533MHz capable", reg, PCIX_BRIDGE_ST_533);
+	} else {
+		printf("    Command register: 0x%04x\n",
+		    (reg & 0xffff0000) >> 16);
+		onoff("Data Parity Error Recovery", reg,
+		    PCIX_CMD_PERR_RECOVER);
+		onoff("Enable Relaxed Ordering", reg, PCIX_CMD_RELAXED_ORDER);
+		printf("      Maximum Burst Read Count: %u\n",
+		    PCIX_CMD_BYTECNT(reg));
+		printf("      Maximum Split Transactions: %d\n",
+		    pcix_split_trans((reg & PCIX_CMD_SPLTRANS_MASK)
+			>> PCIX_CMD_SPLTRANS_SHIFT));
+	}
+	reg = regs[o2i(capoff+PCIX_STATUS)]; /* Or PCIX_BRIDGE_PRI_STATUS */
+	printf("    %sStatus register: 0x%08x\n",
+	    isbridge ? "Bridge " : "", reg);
+	printf("      Function: %d\n", PCIX_STATUS_FN(reg));
+	printf("      Device: %d\n", PCIX_STATUS_DEV(reg));
+	printf("      Bus: %d\n", PCIX_STATUS_BUS(reg));
+	onoff("64bit device", reg, PCIX_STATUS_64BIT);
+	onoff("133MHz capable", reg, PCIX_STATUS_133);
+	onoff("Split completion discarded", reg, PCIX_STATUS_SPLDISC);
+	onoff("Unexpected split completion", reg, PCIX_STATUS_SPLUNEX);
+	if (isbridge != 0) {
+		onoff("Split completion overrun", reg, PCIX_BRIDGE_ST_SPLOVRN);
+		onoff("Split request delayed", reg, PCIX_BRIDGE_ST_SPLRQDL);
+	} else {
+		onoff2("Device Complexity", reg, PCIX_STATUS_DEVCPLX,
+		    "bridge device", "simple device");
+		printf("      Designed max memory read byte count: %d\n",
+		    512 << ((reg & PCIX_STATUS_MAXB_MASK)
+			>> PCIX_STATUS_MAXB_SHIFT));
+		printf("      Designed max outstanding split transaction: %d\n",
+		    pcix_split_trans((reg & PCIX_STATUS_MAXST_MASK)
+			>> PCIX_STATUS_MAXST_SHIFT));
+		printf("      MAX cumulative Read Size: %u\n",
+		    8 << ((reg & 0x1c000000) >> PCIX_STATUS_MAXRS_SHIFT));
+		onoff("Received split completion error", reg,
+		    PCIX_STATUS_SCERR);
+	}
+	onoff("266MHz capable", reg, PCIX_STATUS_266);
+	onoff("533MHz capable", reg, PCIX_STATUS_533);
+
+	if (isbridge == 0)
+		return;
+
+	/* Only for bridge */
+	for (i = 0; i < 2; i++) {
+		reg = regs[o2i(capoff+PCIX_BRIDGE_UP_STCR + (4 * i))];
+		printf("    %s split transaction control register: 0x%08x\n",
+		    (i == 0) ? "Upstream" : "Downstream", reg);
+		printf("      Capacity: %d\n", reg & PCIX_BRIDGE_STCAP);
+		printf("      Commitment Limit: %d\n",
+		    (reg & PCIX_BRIDGE_STCLIM) >> PCIX_BRIDGE_STCLIM_SHIFT);
+	}
+}
+
 /* XXX pci_conf_print_ldt_cap */
 /* XXX pci_conf_print_vendspec_cap */
 
@@ -1329,8 +1431,8 @@ pci_conf_print_pcie_cap(const pcireg_t *
 	pci_print_pcie_L0s_latency((reg & PCIE_DCAP_L0S_LATENCY) >> 6);
 	printf("      Endpoint L1 Acceptable Latency: ");
 	pci_print_pcie_L1_latency((reg & PCIE_DCAP_L1_LATENCY) >> 9);
-	onoff("Attention Button Present:", reg, PCIE_DCAP_ATTN_BUTTON);
-	onoff("Attention Indicator Present:", reg, PCIE_DCAP_ATTN_IND);
+	onoff("Attention Button Present", reg, PCIE_DCAP_ATTN_BUTTON);
+	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: %d\n",
@@ -1745,8 +1847,8 @@ pci_conf_print_caplist(
 {
 	int off;
 	pcireg_t rval;
-	int pcie_off = -1, pcipm_off = -1, msi_off = -1, vendspec_off = -1;
-	int msix_off = -1;
+	int pcie_off = -1, pcipm_off = -1, msi_off = -1, pcix_off = -1;
+	int vendspec_off = -1, msix_off = -1;
 	int debugport_off = -1, subsystem_off = -1, pciaf_off = -1;
 
 	for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
@@ -1784,6 +1886,7 @@ pci_conf_print_caplist(
 			printf("CompactPCI Hot-swapping");
 			break;
 		case PCI_CAP_PCIX:
+			pcix_off = off;
 			printf("PCI-X");
 			break;
 		case PCI_CAP_LDT:
@@ -1841,7 +1944,8 @@ pci_conf_print_caplist(
 	if (msi_off != -1)
 		pci_conf_print_msi_cap(regs, msi_off);
 	/* XXX CPCI_HOTSWAP */
-	/* XXX PCIX */
+	if (pcix_off != -1)
+		pci_conf_print_pcix_cap(regs, pcix_off);
 	/* XXX LDT */
 	if (vendspec_off != -1)
 		pci_conf_print_vendspec_cap(regs, vendspec_off);

Index: src/sys/dev/pci/pcireg.h
diff -u src/sys/dev/pci/pcireg.h:1.93 src/sys/dev/pci/pcireg.h:1.94
--- src/sys/dev/pci/pcireg.h:1.93	Tue May 27 16:26:15 2014
+++ src/sys/dev/pci/pcireg.h	Fri May 30 03:42:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcireg.h,v 1.93 2014/05/27 16:26:15 msaitoh Exp $	*/
+/*	$NetBSD: pcireg.h,v 1.94 2014/05/30 03:42:38 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1995, 1996, 1999, 2000
@@ -640,8 +640,14 @@ typedef u_int8_t pci_revision_t;
 /*
  * Capability ID: 0x07
  * PCI-X capability.
+ *
+ * PCI-X capability register has two different layouts. One is for bridge
+ * function. Another is for non-bridge functions.
  */
 
+
+/* For non-bridge functions */
+
 /*
  * Command. 16 bits at offset 2 (e.g. upper 16 bits of the first 32-bit
  * word at the capability; the lower 16 bits are the capability ID and
@@ -651,21 +657,24 @@ typedef u_int8_t pci_revision_t;
  * as 32-bit values, offset and shifted appropriately.  Make sure you perform
  * the appropriate R/M/W cycles!
  */
-#define PCIX_CMD			0x00
+#define PCIX_CMD		0x00
 #define PCIX_CMD_PERR_RECOVER	0x00010000
 #define PCIX_CMD_RELAXED_ORDER	0x00020000
 #define PCIX_CMD_BYTECNT_MASK	0x000c0000
 #define	PCIX_CMD_BYTECNT_SHIFT	18
-#define		PCIX_CMD_BCNT_512		0x00000000
-#define		PCIX_CMD_BCNT_1024		0x00040000
-#define		PCIX_CMD_BCNT_2048		0x00080000
-#define		PCIX_CMD_BCNT_4096		0x000c0000
+#define	PCIX_CMD_BYTECNT(reg)	\
+	(512 << (((reg) & PCIX_CMD_BYTECNT_MASK) >> PCIX_CMD_BYTECNT_SHIFT))
+#define		PCIX_CMD_BCNT_512	0x00000000
+#define		PCIX_CMD_BCNT_1024	0x00040000
+#define		PCIX_CMD_BCNT_2048	0x00080000
+#define		PCIX_CMD_BCNT_4096	0x000c0000
 #define PCIX_CMD_SPLTRANS_MASK	0x00700000
-#define		PCIX_CMD_SPLTRANS_1		0x00000000
-#define		PCIX_CMD_SPLTRANS_2		0x00100000
-#define		PCIX_CMD_SPLTRANS_3		0x00200000
-#define		PCIX_CMD_SPLTRANS_4		0x00300000
-#define		PCIX_CMD_SPLTRANS_8		0x00400000
+#define	PCIX_CMD_SPLTRANS_SHIFT	20
+#define		PCIX_CMD_SPLTRANS_1	0x00000000
+#define		PCIX_CMD_SPLTRANS_2	0x00100000
+#define		PCIX_CMD_SPLTRANS_3	0x00200000
+#define		PCIX_CMD_SPLTRANS_4	0x00300000
+#define		PCIX_CMD_SPLTRANS_8	0x00400000
 #define		PCIX_CMD_SPLTRANS_12	0x00500000
 #define		PCIX_CMD_SPLTRANS_16	0x00600000
 #define		PCIX_CMD_SPLTRANS_32	0x00700000
@@ -673,31 +682,40 @@ typedef u_int8_t pci_revision_t;
 /*
  * Status. 32 bits at offset 4.
  */
-#define PCIX_STATUS			0x04
-#define PCIX_STATUS_FN_MASK		0x00000007
+#define PCIX_STATUS		0x04
+#define PCIX_STATUS_FN_MASK	0x00000007
 #define PCIX_STATUS_DEV_MASK	0x000000f8
+#define PCIX_STATUS_DEV_SHIFT	3
 #define PCIX_STATUS_BUS_MASK	0x0000ff00
-#define PCIX_STATUS_64BIT		0x00010000
-#define PCIX_STATUS_133		0x00020000
-#define PCIX_STATUS_SPLDISC		0x00040000
-#define PCIX_STATUS_SPLUNEX		0x00080000
-#define PCIX_STATUS_DEVCPLX		0x00100000
-#define PCIX_STATUS_MAXB_MASK	0x00600000
+#define PCIX_STATUS_BUS_SHIFT	8
+#define PCIX_STATUS_FN(val)	((val) & PCIX_STATUS_FN_MASK)
+#define PCIX_STATUS_DEV(val)	\
+	(((val) & PCIX_STATUS_DEV_MASK) >> PCIX_STATUS_DEV_SHIFT)
+#define PCIX_STATUS_BUS(val)	\
+	(((val) & PCIX_STATUS_BUS_MASK) >> PCIX_STATUS_BUS_SHIFT)
+#define PCIX_STATUS_64BIT	0x00010000	/* 64bit device */
+#define PCIX_STATUS_133		0x00020000	/* 133MHz capable */
+#define PCIX_STATUS_SPLDISC	0x00040000	/* Split completion discarded*/
+#define PCIX_STATUS_SPLUNEX	0x00080000	/* Unexpected split complet. */
+#define PCIX_STATUS_DEVCPLX	0x00100000	/* Device Complexity */
+#define PCIX_STATUS_MAXB_MASK	0x00600000	/* MAX memory read Byte count*/
 #define	PCIX_STATUS_MAXB_SHIFT	21
 #define		PCIX_STATUS_MAXB_512	0x00000000
 #define		PCIX_STATUS_MAXB_1024	0x00200000
 #define		PCIX_STATUS_MAXB_2048	0x00400000
 #define		PCIX_STATUS_MAXB_4096	0x00600000
-#define PCIX_STATUS_MAXST_MASK	0x03800000
-#define		PCIX_STATUS_MAXST_1		0x00000000
-#define		PCIX_STATUS_MAXST_2		0x00800000
-#define		PCIX_STATUS_MAXST_3		0x01000000
-#define		PCIX_STATUS_MAXST_4		0x01800000
-#define		PCIX_STATUS_MAXST_8		0x02000000
+#define PCIX_STATUS_MAXST_MASK	0x03800000	/* MAX outstand. Split Trans.*/
+#define	PCIX_STATUS_MAXST_SHIFT	23
+#define		PCIX_STATUS_MAXST_1	0x00000000
+#define		PCIX_STATUS_MAXST_2	0x00800000
+#define		PCIX_STATUS_MAXST_3	0x01000000
+#define		PCIX_STATUS_MAXST_4	0x01800000
+#define		PCIX_STATUS_MAXST_8	0x02000000
 #define		PCIX_STATUS_MAXST_12	0x02800000
 #define		PCIX_STATUS_MAXST_16	0x03000000
 #define		PCIX_STATUS_MAXST_32	0x03800000
-#define PCIX_STATUS_MAXRS_MASK	0x1c000000
+#define PCIX_STATUS_MAXRS_MASK	0x1c000000	/* MAX cumulative Read Size */
+#define PCIX_STATUS_MAXRS_SHIFT	26
 #define		PCIX_STATUS_MAXRS_1K	0x00000000
 #define		PCIX_STATUS_MAXRS_2K	0x04000000
 #define		PCIX_STATUS_MAXRS_4K	0x08000000
@@ -706,7 +724,37 @@ typedef u_int8_t pci_revision_t;
 #define		PCIX_STATUS_MAXRS_32K	0x14000000
 #define		PCIX_STATUS_MAXRS_64K	0x18000000
 #define		PCIX_STATUS_MAXRS_128K	0x1c000000
-#define PCIX_STATUS_SCERR			0x20000000
+#define PCIX_STATUS_SCERR	0x20000000	/* rcv. Split Completion ERR.*/
+#define PCIX_STATUS_266		0x40000000	/* 266MHz capable */
+#define PCIX_STATUS_533		0x80000000	/* 533MHz capable */
+
+/* For bridge function */
+
+#define PCIX_BRIDGE_2ND_STATUS	0x00
+#define PCIX_BRIDGE_ST_64BIT	0x00010000	/* Same as PCIX_STATUS (nonb)*/
+#define PCIX_BRIDGE_ST_133	0x00020000	/* Same as PCIX_STATUS (nonb)*/
+#define PCIX_BRIDGE_ST_SPLDISC	0x00040000	/* Same as PCIX_STATUS (nonb)*/
+#define PCIX_BRIDGE_ST_SPLUNEX	0x00080000	/* Same as PCIX_STATUS (nonb)*/
+#define PCIX_BRIDGE_ST_SPLOVRN	0x00100000	/* Split completion overrun */
+#define PCIX_BRIDGE_ST_SPLRQDL	0x00200000	/* Split request delayed */
+#define PCIX_BRIDGE_2NDST_CLKF	0x03c00000	/* Secondary clock frequency */
+#define PCIX_BRIDGE_2NDST_CLKF_SHIFT 22
+#define PCIX_BRIDGE_2NDST_VER_MASK 0x30000000	/* Version */
+#define PCIX_BRIDGE_2NDST_VER_SHIFT 28
+#define PCIX_BRIDGE_ST_266	0x40000000	/* Same as PCIX_STATUS (nonb)*/
+#define PCIX_BRIDGE_ST_533	0x80000000	/* Same as PCIX_STATUS (nonb)*/
+
+#define PCIX_BRIDGE_PRI_STATUS	0x04
+/* Bit 0 to 15 are the same as PCIX_STATUS */
+/* Bit 16 to 21 are the same as PCIX_BRIDGE_2ND_STATUS */
+/* Bit 30 and 31 are the same as PCIX_BRIDGE_2ND_STATUS */
+
+#define PCIX_BRIDGE_UP_STCR	0x08 /* Upstream Split Transaction Control */
+#define PCIX_BRIDGE_DOWN_STCR	0x0c /* Downstream Split Transaction Control */
+/* The layouts of above two registers are the same */
+#define PCIX_BRIDGE_STCAP	0x0000ffff	/* Sp. Tr. Capacity */
+#define PCIX_BRIDGE_STCLIM	0xffff0000	/* Sp. Tr. Commitment Limit */
+#define PCIX_BRIDGE_STCLIM_SHIFT 16
 
 /*
  * Capability ID: 0x08

Reply via email to