Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Cleanup pci_conf_print_caplist. Use table. The...



details:   https://anonhg.NetBSD.org/src/rev/5ed0270a2d03
branches:  trunk
changeset: 333208:5ed0270a2d03
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Oct 23 13:44:37 2014 +0000

description:
- Cleanup pci_conf_print_caplist. Use table. The reason why it loops twice
  is that some capabilities appear multiple times (e.g. HyperTransport cap).
- Print the specification revision of Power Management and AGP not in
  the capability list part but in the detail part.

diffstat:

 sys/dev/pci/pci_subr.c |  194 +++++++++++++++++++++---------------------------
 1 files changed, 84 insertions(+), 110 deletions(-)

diffs (240 lines):

diff -r 257a585522ef -r 5ed0270a2d03 sys/dev/pci/pci_subr.c
--- a/sys/dev/pci/pci_subr.c    Thu Oct 23 13:40:15 2014 +0000
+++ b/sys/dev/pci/pci_subr.c    Thu Oct 23 13:44:37 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci_subr.c,v 1.131 2014/10/23 13:40:15 msaitoh Exp $   */
+/*     $NetBSD: pci_subr.c,v 1.132 2014/10/23 13:44:37 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.131 2014/10/23 13:40:15 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.132 2014/10/23 13:44:37 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -969,6 +969,20 @@
                printf("\n");
 }
 
+static void
+pci_conf_print_agp_cap(const pcireg_t *regs, int capoff)
+{
+       pcireg_t rval;
+
+       printf("\n  AGP Capabilities Register\n");
+
+       rval = regs[o2i(capoff)];
+       printf("    Revision: %d.%d\n",
+           PCI_CAP_AGP_MAJOR(rval), PCI_CAP_AGP_MINOR(rval));
+
+       /* XXX need more */
+}
+
 static const char *
 pci_conf_print_pcipm_cap_aux(uint16_t caps)
 {
@@ -1796,6 +1810,35 @@
        onoff("Transaction Pending", reg, PCI_AFSR_TP);
 }
 
+static struct {
+       pcireg_t cap;
+       const char *name;
+       void (*printfunc)(const pcireg_t *, int);
+} pci_captab[] = {
+       { PCI_CAP_RESERVED0,    "reserved",     NULL },
+       { PCI_CAP_PWRMGMT,      "Power Management", pci_conf_print_pcipm_cap },
+       { PCI_CAP_AGP,          "AGP",          pci_conf_print_agp_cap },
+       { PCI_CAP_VPD,          "VPD",          NULL },
+       { PCI_CAP_SLOTID,       "SlotID",       NULL },
+       { PCI_CAP_MSI,          "MSI",          pci_conf_print_msi_cap }, 
+       { PCI_CAP_CPCI_HOTSWAP, "CompactPCI Hot-swapping", NULL },
+       { PCI_CAP_PCIX,         "PCI-X",        pci_conf_print_pcix_cap },
+       { PCI_CAP_LDT,          "HyperTransport", NULL },
+       { PCI_CAP_VENDSPEC,     "Vendor-specific",
+         pci_conf_print_vendspec_cap },
+       { PCI_CAP_DEBUGPORT,    "Debug Port",   pci_conf_print_debugport_cap },
+       { PCI_CAP_CPCI_RSRCCTL, "CompactPCI Resource Control", NULL },
+       { PCI_CAP_HOTPLUG,      "Hot-Plug",     NULL },
+       { PCI_CAP_SUBVENDOR,    "Subsystem vendor ID",
+         pci_conf_print_subsystem_cap },
+       { PCI_CAP_AGP8,         "AGP 8x",       NULL },
+       { PCI_CAP_SECURE,       "Secure Device", NULL },
+       { PCI_CAP_PCIEXPRESS,   "PCI Express",  pci_conf_print_pcie_cap },
+       { PCI_CAP_MSIX,         "MSI-X",        pci_conf_print_msix_cap },
+       { PCI_CAP_SATA,         "SATA",         NULL },
+       { PCI_CAP_PCIAF,        "Advanced Features", pci_conf_print_pciaf_cap }
+};
+
 static void
 pci_conf_print_caplist(
 #ifdef _KERNEL
@@ -1804,11 +1847,16 @@
     const pcireg_t *regs, int capoff)
 {
        int off;
+       pcireg_t foundcap;
        pcireg_t rval;
-       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;
+       bool foundtable[__arraycount(pci_captab)];
+       unsigned int i;
 
+       /* Clear table */
+       for (i = 0; i < __arraycount(pci_captab); i++)
+               foundtable[i] = false;
+
+       /* Print capability register's offset and the type first */
        for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
             off != 0;
             off = PCI_CAPLIST_NEXT(regs[o2i(off)])) {
@@ -1816,113 +1864,39 @@
                printf("  Capability register at 0x%02x\n", off);
 
                printf("    type: 0x%02x (", PCI_CAPLIST_CAP(rval));
-               switch (PCI_CAPLIST_CAP(rval)) {
-               case PCI_CAP_RESERVED0:
-                       printf("reserved");
-                       break;
-               case PCI_CAP_PWRMGMT:
-                       printf("Power Management, rev. %s",
-                           pci_conf_print_pcipm_cap_pmrev(
-                                   (rval >> 16) & 0x07));
-                       pcipm_off = off;
-                       break;
-               case PCI_CAP_AGP:
-                       printf("AGP, rev. %d.%d",
-                               PCI_CAP_AGP_MAJOR(rval),
-                               PCI_CAP_AGP_MINOR(rval));
-                       break;
-               case PCI_CAP_VPD:
-                       printf("VPD");
-                       break;
-               case PCI_CAP_SLOTID:
-                       printf("SlotID");
-                       break;
-               case PCI_CAP_MSI:
-                       printf("MSI");
-                       msi_off = off;
-                       break;
-               case PCI_CAP_CPCI_HOTSWAP:
-                       printf("CompactPCI Hot-swapping");
-                       break;
-               case PCI_CAP_PCIX:
-                       pcix_off = off;
-                       printf("PCI-X");
-                       break;
-               case PCI_CAP_LDT:
-                       printf("HyperTransport");
-                       break;
-               case PCI_CAP_VENDSPEC:
-                       vendspec_off = off;
-                       printf("Vendor-specific");
-                       break;
-               case PCI_CAP_DEBUGPORT:
-                       printf("Debug Port");
-                       debugport_off = off;
-                       break;
-               case PCI_CAP_CPCI_RSRCCTL:
-                       printf("CompactPCI Resource Control");
-                       break;
-               case PCI_CAP_HOTPLUG:
-                       printf("Hot-Plug");
-                       break;
-               case PCI_CAP_SUBVENDOR:
-                       printf("Subsystem vendor ID");
-                       subsystem_off = off;
-                       break;
-               case PCI_CAP_AGP8:
-                       printf("AGP 8x");
-                       break;
-               case PCI_CAP_SECURE:
-                       printf("Secure Device");
-                       break;
-               case PCI_CAP_PCIEXPRESS:
-                       printf("PCI Express");
-                       pcie_off = off;
-                       break;
-               case PCI_CAP_MSIX:
-                       printf("MSI-X");
-                       msix_off = off;
-                       break;
-               case PCI_CAP_SATA:
-                       printf("SATA");
-                       break;
-               case PCI_CAP_PCIAF:
-                       printf("Advanced Features");
-                       pciaf_off = off;
-                       break;
-               default:
-                       printf("unknown");
+               foundcap = PCI_CAPLIST_CAP(rval);
+               if (foundcap < __arraycount(pci_captab)) {
+                       printf("%s)\n", pci_captab[foundcap].name);
+                       /* Mark as found */
+                       foundtable[foundcap] = true;
+               } else
+                       printf("unknown)\n");
+       }
+
+       /*
+        * And then, print the detail of each capability registers
+        * in capability value's order.
+        */
+       for (i = 0; i < __arraycount(pci_captab); i++) {
+               if (foundtable[i] == false)
+                       continue;
+
+               /*
+                * The type was found. Search capability list again and
+                * print all capabilities that the capabiliy type is
+                * the same. This is required because some capabilities
+                * appear multiple times (e.g. HyperTransport capability).
+                */
+               for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
+                    off != 0;
+                    off = PCI_CAPLIST_NEXT(regs[o2i(off)])) {
+                       rval = regs[o2i(off)];
+                       foundcap = PCI_CAPLIST_CAP(rval);
+                       if ((i == foundcap)
+                           && (pci_captab[foundcap].printfunc != NULL))
+                               pci_captab[foundcap].printfunc(regs, off);
                }
-               printf(")\n");
        }
-       if (pcipm_off != -1)
-               pci_conf_print_pcipm_cap(regs, pcipm_off);
-       /* XXX AGP */
-       /* XXX VPD */
-       /* XXX SLOTID */
-       if (msi_off != -1)
-               pci_conf_print_msi_cap(regs, msi_off);
-       /* XXX CPCI_HOTSWAP */
-       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);
-       if (debugport_off != -1)
-               pci_conf_print_debugport_cap(regs, debugport_off);
-       /* XXX CPCI_RSRCCTL */
-       /* XXX HOTPLUG */
-       if (subsystem_off != -1)
-               pci_conf_print_subsystem_cap(regs, subsystem_off);
-       /* XXX AGP8 */
-       /* XXX SECURE */
-       if (pcie_off != -1)
-               pci_conf_print_pcie_cap(regs, pcie_off);
-       if (msix_off != -1)
-               pci_conf_print_msix_cap(regs, msix_off);
-       /* XXX SATA */
-       if (pciaf_off != -1)
-               pci_conf_print_pciaf_cap(regs, pciaf_off);
 }
 
 /* Print the Secondary Status Register. */



Home | Main Index | Thread Index | Old Index