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:
(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.