+static void
+cap_rclink(struct device *d, int where)
+{
+ u32 esd;
+ int num_links;
+ int i;
+ static const char elt_types[][9] = { "Config", "Egress", "Internal" };
+ char buf[8];
+
+ printf("Root Complex Link\n");
+ if (verbose < 2)
+ return;
+
+ if (!config_fetch(d, where + 4, PCI_RCLINK_LINK1 - 4))
+ return;
+
+ esd = get_conf_long(d, where + PCI_RCLINK_ESD);
+ num_links = BITS(esd, 8, 8);
+ printf("\t\tDesc:\tPortNumber=%02x ComponentID=%02x EltType=%s\n",
+ BITS(esd, 24, 8),
+ BITS(esd, 16, 8),
+ TABLE(elt_types, BITS(esd, 0, 8), buf));
+
+ for (i=0; i<num_links; i++)
+ {
+ int pos = where + PCI_RCLINK_LINK1 + i*PCI_RCLINK_LINK_SIZE;
+ u32 desc;
+ u32 addr_lo, addr_hi;
+
+ printf("\t\tLink%d:\t", i);
+ if (!config_fetch(d, pos, PCI_RCLINK_LINK_SIZE))
+ {
+ printf("<unreadable>\n");
+ return;
+ }
+ desc = get_conf_long(d, pos + PCI_RCLINK_LINK_DESC);
+ addr_lo = get_conf_long(d, pos + PCI_RCLINK_LINK_ADDR);
+ addr_hi = get_conf_long(d, pos + PCI_RCLINK_LINK_ADDR + 4);
+
+ printf("Desc:\tTargetPort=%02x TargetComponent=%02x AssocRCRB%c LinkType=%s LinkValid%c\n",
+ BITS(desc, 24, 8),
+ BITS(desc, 16, 8),
+ FLAG(desc, 4),
+ ((desc & 2) ? "Config" : "MemMapped"),
+ FLAG(desc, 1));
+
+ if (desc & 2)
+ {
+ int n = addr_lo & 7;
+ if (!n)
+ n = 8;
+ printf("\t\t\tAddr:\t%02x:%02x.%d CfgSpace=%08x%08x\n",
+ BITS(addr_lo, 20, n),
+ BITS(addr_lo, 15, 5),
+ BITS(addr_lo, 12, 3),
+ addr_hi, addr_lo);
+ }
+ else
+ printf("\t\t\tAddr:\t%08x%08x\n", addr_hi, addr_lo);
+ }
+}
+
+static void
+cap_evendor(struct device *d, int where)
+{
+ u32 hdr;
+
+ printf("Vendor Specific Information: ");
+ if (!config_fetch(d, where + PCI_EVNDR_HEADER, 4))
+ {
+ printf("<unreadable>\n");
+ return;
+ }
+
+ hdr = get_conf_long(d, where + PCI_EVNDR_HEADER);
+ printf("ID=%04x Rev=%d Len=%03x <?>\n",
+ BITS(hdr, 0, 16),
+ BITS(hdr, 16, 4),
+ BITS(hdr, 20, 12));
+}
+
+static void
+cap_l1pm(struct device *d, int where)
+{
+ u32 l1_cap;
+ int power_on_scale;
+
+ printf("L1 PM Substates\n");
+
+ if (verbose < 2)
+ return;
+
+ if (!config_fetch(d, where + 4, 4))
+ {
+ printf("\t\t<unreadable>\n");
+ return;
+ }
+
+ l1_cap = get_conf_long(d, where + 4);
+ printf("\t\tL1SubCap: ");
+ printf("PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c L1_PM_Substates%c\n",
+ FLAG(l1_cap, 1),
+ FLAG(l1_cap, 2),
+ FLAG(l1_cap, 4),
+ FLAG(l1_cap, 8),
+ FLAG(l1_cap, 16));
+
+ if (BITS(l1_cap, 0, 1) || BITS(l1_cap, 2, 1))
+ {
+ printf("\t\t\t PortCommonModeRestoreTime=%dus ",
+ BITS(l1_cap, 8,8));
+
+ power_on_scale = BITS(l1_cap, 16, 2);
+
+ printf("PortTPowerOnTime=");
+ switch (power_on_scale)
+ {
+ case 0:
+ printf("%dus\n", BITS(l1_cap, 19, 5) * 2);
+ break;
+ case 1:
+ printf("%dus\n", BITS(l1_cap, 19, 5) * 10);
+ break;
+ case 2:
+ printf("%dus\n", BITS(l1_cap, 19, 5) * 100);
+ break;
+ default:
+ printf("<error>\n");
+ break;
+ }
+ }
+}
+