NetBSD Problem Report #4249

Received: (qmail 24362 invoked from network); 9 Oct 1997 20:00:29 -0000
Message-Id: <199710091959.OAA06640@clouseau.arl.wustl.edu>
Date: Thu, 9 Oct 1997 14:59:35 -0500 (CDT)
From: "Zubin D. Dittia" <zubin@clouseau.arl.wustl.edu>
Reply-To: zubin@clouseau.arl.wustl.edu
To: gnats-bugs@gnats.netbsd.org
Subject: PCI config space dump routine, useful for debugging
X-Send-Pr-Version: 3.95

>Number:         4249
>Category:       kern
>Synopsis:       feature useful for debugging PCI device drivers
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 09 13:05:02 +0000 1997
>Closed-Date:    Tue Apr 14 21:21:55 +0000 1998
>Last-Modified:  Tue Apr 14 21:22:20 +0000 1998
>Originator:     Zubin D. Dittia
>Release:        NetBSD-1.2E
>Organization:
Washington University in St. Louis

Zubin D. Dittia					zubin@dworkin.wustl.edu
Campus Box 1045, Washington Univ.,		Tel: +1-(314)-935-4163
1 Brookings Dr., St. Louis, MO 63130, USA.	Fax: +1-(314)-935-7302
>Environment:
i386 NetBSD GENERIC

>Description:
	I have added a function pci_conf_print() to the PCI support
	routines in dev/pci/pci_subr.c, which prints out details
	of all the PCI configuration registers found on a card.
	It should be called when debugging the card/driver, from
	the driver's attach routine.  It can be compiled out when
	not debugging.

	I tested the routine on a few cards and it works fine.
>How-To-Repeat:

>Fix:
	I am enclosing the concatenated output from "diff -c" for the
	three modified files (dev/pci/pci_subr.c, dev/pci/pcireg.h,
	and dev/pci/pcivar.h) below.


*** /a/pain/current/src/sys/dev/pci/pci_subr.c	Tue Jun  3 22:49:26 1997
--- pci_subr.c	Thu Oct  9 14:51:43 1997
***************
*** 1,6 ****
--- 1,7 ----
  /*	$NetBSD: pci_subr.c,v 1.20 1997/03/19 19:38:46 cgd Exp $	*/

  /*
+  * Copyright (c) 1997, Zubin D. Dittia.  All rights reserved.
   * Copyright (c) 1995, 1996 Christopher G. Demetriou.  All rights reserved.
   * Copyright (c) 1994 Charles Hannum.  All rights reserved.
   *
***************
*** 301,304 ****
--- 302,466 ----
  			cp += sprintf(cp, ", revision 0x%02x", revision);
  		cp += sprintf(cp, ")");
  	}
+ }
+ 
+ /*
+  * Print out most of the PCI configuration registers.  Typically used
+  * in a device attach routine like this:
+  *	#ifdef MYDEV_DEBUG
+  *	printf("%s: ", sc->sc_dev.dv_xname);
+  *	pci_conf_print(pa->pa_pc, pa->pa_tag);
+  *	#endif MYDEV_DEBUG
+  */
+ void
+ pci_conf_print(pc, tag)
+ 	pci_chipset_tag_t	pc;
+ 	pcitag_t		tag;
+ {
+ 	int			rval;
+ #ifdef PCIVERBOSE
+ 	struct pci_knowndev	*kdp;
+ #endif PCIVERBOSE
+ 	struct pci_class	*classp, *subclassp;
+ 	const char		*on_str = "ON",
+ 				*off_str = "OFF";
+ 
+ 	printf("PCI configuration registers:\n");
+ 
+ 	rval = pci_conf_read(pc, tag, PCI_ID_REG);
+ #ifndef PCIVERBOSE
+ 	printf("  Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
+ 	printf("  Device ID: 0x%04x\n", PCI_PRODUCT(rval));
+ #else
+ 	for (kdp = pci_knowndevs; kdp->vendorname != NULL; kdp++) {
+ 		if (kdp->vendor == PCI_VENDOR(rval) &&
+ 		    (kdp->product == PCI_PRODUCT(rval) ||
+ 		    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0)) {
+ 			break;
+ 		}
+ 	}
+ 	if (kdp->vendorname != NULL)
+ 		printf("  Vendor Name: %s\n", kdp->vendorname);
+ 	else
+ 		printf("  Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
+ 
+ 	if (kdp->vendorname != NULL && (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0)
+ 		printf("  Device Name: %s\n", kdp->productname);
+ 	else
+ 		printf("  Device ID: 0x%04x\n", PCI_PRODUCT(rval));
+ #endif PCIVERBOSE
+ 
+ #define onoff(reg)	((rval & reg) ? on_str : off_str)
+ 	rval = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ #ifndef PCIVERBOSE
+ 	printf("  Command/Status Register: 0x%08x\n", rval);
+ #else
+ 	printf("  Command Register:\n");
+ 	printf("    I/O space accesses %s\n", onoff(PCI_COMMAND_IO_ENABLE));
+ 	printf("    Mem space accesses %s\n", onoff(PCI_COMMAND_MEM_ENABLE));
+ 	printf("    Bus mastering %s\n", onoff(PCI_COMMAND_MASTER_ENABLE));
+ 	printf("    Special cycles %s\n", onoff(PCI_COMMAND_SPECIAL_ENABLE));
+ 	printf("    MWI transactions %s\n",
+ 					onoff(PCI_COMMAND_INVALIDATE_ENABLE));
+ 	printf("    Palette snooping %s\n", onoff(PCI_COMMAND_PALETTE_ENABLE));
+ 	printf("    Parity error checking %s\n",
+ 					onoff(PCI_COMMAND_PARITY_ENABLE));
+ 	printf("    Address/Data stepping %s\n",
+ 					onoff(PCI_COMMAND_STEPPING_ENABLE));
+ 	printf("    System Error (SERR) %s\n", onoff(PCI_COMMAND_SERR_ENABLE));
+ 	printf("    Fast back-to-back transactions %s\n",
+ 					onoff(PCI_COMMAND_BACKTOBACK_ENABLE));
+ 	printf("  Status Register:\n");
+ 	printf("    66 MHz capable %s\n", onoff(PCI_STATUS_66MHZ_SUPPORT));
+ 	printf("    User Definable Features (UDF) support %s\n",
+ 					onoff(PCI_STATUS_UDF_SUPPORT));
+ 	printf("    Fast back-to-back capable %s\n",
+ 					onoff(PCI_STATUS_BACKTOBACK_SUPPORT));
+ 	printf("    Data parity error detected %s\n",
+ 					onoff(PCI_STATUS_PARITY_ERROR));
+ 	printf("    DEVSEL timing ");
+ 	switch (rval & PCI_STATUS_DEVSEL_MASK) {
+ 	case PCI_STATUS_DEVSEL_FAST:	printf("fast"); break;
+ 	case PCI_STATUS_DEVSEL_MEDIUM:	printf("medium"); break;
+ 	case PCI_STATUS_DEVSEL_SLOW:	printf("slow"); break;
+ 	}
+ 	printf("\n");
+ 	printf("    Slave signaled Target Abort %s\n",
+ 					onoff(PCI_STATUS_TARGET_TARGET_ABORT));
+ 	printf("    Master received Target Abort %s\n",
+ 					onoff(PCI_STATUS_MASTER_TARGET_ABORT));
+ 	printf("    Master received Master Abort %s\n",
+ 					onoff(PCI_STATUS_MASTER_ABORT));
+ 	printf("    Asserted System Error (SERR) %s\n",
+ 					onoff(PCI_STATUS_SPECIAL_ERROR));
+ 	printf("    Parity error detected %s\n",
+ 					onoff(PCI_STATUS_PARITY_DETECT));
+ #endif PCIVERBOSE
+ 
+ 	rval = pci_conf_read(pc, tag, PCI_CLASS_REG);
+ 	for (classp = pci_class; classp->name != NULL; classp++) {
+ 		if (PCI_CLASS(rval) == classp->val)
+ 			break;
+ 	}
+ 	subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
+ 	while (subclassp && subclassp->name != NULL) {
+ 		if (PCI_SUBCLASS(rval) == subclassp->val)
+ 			break;
+ 		subclassp++;
+ 	}
+ 	if (classp->name != NULL) {
+ 		printf("  Class Name: %s\n", classp->name);
+ 		if (subclassp != NULL && subclassp->name != NULL)
+ 			printf("  Subclass Name: %s\n", subclassp->name);
+ 		else
+ 			printf("  Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
+ 	} else {
+ 		printf("  Class ID: 0x%02x\n", PCI_CLASS(rval));
+ 		printf("  Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
+ 	}
+ 	printf("  Interface: 0x%02x\n", PCI_INTERFACE(rval));
+ 	printf("  Revision ID: 0x%02x\n", PCI_REVISION(rval));
+ 
+ 	rval = pci_conf_read(pc, tag, PCI_BHLC_REG);
+ 	printf("  BIST: 0x%02x\n", PCI_BIST(rval));
+ 	printf("  Header Type: 0x%02x\n", PCI_HDRTYPE(rval));
+ 	printf("  Latency Timer: 0x%02x\n", PCI_LATTIMER(rval));
+ 	printf("  Cache Line Size: 0x%02x\n", PCI_CACHELINE(rval));
+ 
+ 	rval = pci_conf_read(pc, tag, PCI_MAPREG_START);
+ 	if (PCI_MAPREG_TYPE(rval) == PCI_MAPREG_TYPE_MEM) {
+ 		printf("  Base Address: 0x%08x, type = mem",
+ 			PCI_MAPREG_MEM_ADDR(rval));
+ 		if (PCI_MAPREG_MEM_TYPE(rval) == PCI_MAPREG_MEM_TYPE_32BIT)
+ 			printf(", 32-bit");
+ 		else if (PCI_MAPREG_MEM_TYPE(rval)
+ 				== PCI_MAPREG_MEM_TYPE_32BIT_1M)
+ 			printf(", 32-bit-1M");
+ 		else if (PCI_MAPREG_MEM_TYPE(rval) == PCI_MAPREG_MEM_TYPE_64BIT)
+ 			printf(", 64-bit");
+ 
+ 		if (PCI_MAPREG_MEM_CACHEABLE(rval))
+ 			printf(", cacheable");
+ 		else
+ 			printf(", not cacheable");
+ 
+ 		printf("\n");
+ 	} else {
+ 		printf("  Base Address: 0x%08x, type = i/o\n",
+ 			PCI_MAPREG_IO_ADDR(rval));
+ 	}
+ 
+ 	rval = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
+ 	printf("  Maximum Latency: 0x%08x\n", (rval >> 24) & 0xff);
+ 	printf("  Minimum Grant: 0x%08x\n", (rval >> 16) & 0xff);
+ 	printf("  Interrupt pin: 0x%08x", PCI_INTERRUPT_PIN(rval));
+ 	switch (PCI_INTERRUPT_PIN(rval)) {
+ 	case PCI_INTERRUPT_PIN_NONE: printf("(none)"); break;
+ 	case PCI_INTERRUPT_PIN_A: printf("(pin A)"); break;
+ 	case PCI_INTERRUPT_PIN_B: printf("(pin B)"); break;
+ 	case PCI_INTERRUPT_PIN_C: printf("(pin C)"); break;
+ 	case PCI_INTERRUPT_PIN_D: printf("(pin D)"); break;
+ 	}
+ 	printf("\n");
+ 	printf("  Interrupt line: 0x%08x\n", PCI_INTERRUPT_LINE(rval));
  }
*** /a/pain/current/src/sys/dev/pci/pcireg.h	Tue Jun  3 22:49:28 1997
--- pcireg.h	Thu Oct  9 14:51:43 1997
***************
*** 73,79 ****
  #define	PCI_COMMAND_SERR_ENABLE			0x00000100
  #define	PCI_COMMAND_BACKTOBACK_ENABLE		0x00000200

! #define	PCI_STATUS_BACKTOBACK_OKAY		0x00800000
  #define	PCI_STATUS_PARITY_ERROR			0x01000000
  #define	PCI_STATUS_DEVSEL_FAST			0x00000000
  #define	PCI_STATUS_DEVSEL_MEDIUM		0x02000000
--- 73,81 ----
  #define	PCI_COMMAND_SERR_ENABLE			0x00000100
  #define	PCI_COMMAND_BACKTOBACK_ENABLE		0x00000200

! #define PCI_STATUS_66MHZ_SUPPORT		0x00200000
! #define PCI_STATUS_UDF_SUPPORT			0x00400000
! #define	PCI_STATUS_BACKTOBACK_SUPPORT		0x00800000
  #define	PCI_STATUS_PARITY_ERROR			0x01000000
  #define	PCI_STATUS_DEVSEL_FAST			0x00000000
  #define	PCI_STATUS_DEVSEL_MEDIUM		0x02000000
*** /a/pain/current/src/sys/dev/pci/pcivar.h	Tue Jun  3 22:49:28 1997
--- pcivar.h	Thu Oct  9 14:51:44 1997
***************
*** 149,154 ****
--- 149,155 ----
   * Helper functions for autoconfiguration.
   */
  void	pci_devinfo __P((pcireg_t, pcireg_t, int, char *));
+ void	pci_conf_print __P((pci_chipset_tag_t, pcitag_t));
  void	set_pci_isa_bridge_callback __P((void (*)(void *), void *));

  /*
>Release-Note:
>Audit-Trail:

Responsible-Changed-From-To: gnats-admin->kern-bug-people
Responsible-Changed-By: mikel
Responsible-Changed-When: Fri Oct 10 00:08:06 1997
Responsible-Changed-Why:
category changed from 'pending'.

State-Changed-From-To: open->closed 
State-Changed-By: thorpej 
State-Changed-When: Tue Apr 14 14:21:55 PDT 1998 
State-Changed-Why:  
Patch applied with a few changes (dump all base address registers, etc.) 
>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.49 2026/05/14 01:52:41 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.