Annotation of embedaddon/pciutils/ls-ecaps.c, revision 1.1
1.1 ! misho 1: /*
! 2: * The PCI Utilities -- Show Extended Capabilities
! 3: *
! 4: * Copyright (c) 1997--2010 Martin Mares <mj@ucw.cz>
! 5: *
! 6: * Can be freely distributed and used under the terms of the GNU GPL.
! 7: */
! 8:
! 9: #include <stdio.h>
! 10: #include <string.h>
! 11:
! 12: #include "lspci.h"
! 13:
! 14: static void
! 15: cap_tph(struct device *d, int where)
! 16: {
! 17: u32 tph_cap;
! 18: printf("Transaction Processing Hints\n");
! 19: if (verbose < 2)
! 20: return;
! 21:
! 22: if (!config_fetch(d, where + PCI_TPH_CAPABILITIES, 4))
! 23: return;
! 24:
! 25: tph_cap = get_conf_long(d, where + PCI_TPH_CAPABILITIES);
! 26:
! 27: if (tph_cap & PCI_TPH_INTVEC_SUP)
! 28: printf("\t\tInterrupt vector mode supported\n");
! 29: if (tph_cap & PCI_TPH_DEV_SUP)
! 30: printf("\t\tDevice specific mode supported\n");
! 31: if (tph_cap & PCI_TPH_EXT_REQ_SUP)
! 32: printf("\t\tExtended requester support\n");
! 33:
! 34: switch (tph_cap & PCI_TPH_ST_LOC_MASK) {
! 35: case PCI_TPH_ST_NONE:
! 36: printf("\t\tNo steering table available\n");
! 37: break;
! 38: case PCI_TPH_ST_CAP:
! 39: printf("\t\tSteering table in TPH capability structure\n");
! 40: break;
! 41: case PCI_TPH_ST_MSIX:
! 42: printf("\t\tSteering table in MSI-X table\n");
! 43: break;
! 44: default:
! 45: printf("\t\tReserved steering table location\n");
! 46: break;
! 47: }
! 48: }
! 49:
! 50: static u32
! 51: cap_ltr_scale(u8 scale)
! 52: {
! 53: return 1 << (scale * 5);
! 54: }
! 55:
! 56: static void
! 57: cap_ltr(struct device *d, int where)
! 58: {
! 59: u32 scale;
! 60: u16 snoop, nosnoop;
! 61: printf("Latency Tolerance Reporting\n");
! 62: if (verbose < 2)
! 63: return;
! 64:
! 65: if (!config_fetch(d, where + PCI_LTR_MAX_SNOOP, 4))
! 66: return;
! 67:
! 68: snoop = get_conf_word(d, where + PCI_LTR_MAX_SNOOP);
! 69: scale = cap_ltr_scale((snoop >> PCI_LTR_SCALE_SHIFT) & PCI_LTR_SCALE_MASK);
! 70: printf("\t\tMax snoop latency: %lldns\n",
! 71: ((unsigned long long)snoop & PCI_LTR_VALUE_MASK) * scale);
! 72:
! 73: nosnoop = get_conf_word(d, where + PCI_LTR_MAX_NOSNOOP);
! 74: scale = cap_ltr_scale((nosnoop >> PCI_LTR_SCALE_SHIFT) & PCI_LTR_SCALE_MASK);
! 75: printf("\t\tMax no snoop latency: %lldns\n",
! 76: ((unsigned long long)nosnoop & PCI_LTR_VALUE_MASK) * scale);
! 77: }
! 78:
! 79: static void
! 80: cap_dsn(struct device *d, int where)
! 81: {
! 82: u32 t1, t2;
! 83: if (!config_fetch(d, where + 4, 8))
! 84: return;
! 85: t1 = get_conf_long(d, where + 4);
! 86: t2 = get_conf_long(d, where + 8);
! 87: printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
! 88: t2 >> 24, (t2 >> 16) & 0xff, (t2 >> 8) & 0xff, t2 & 0xff,
! 89: t1 >> 24, (t1 >> 16) & 0xff, (t1 >> 8) & 0xff, t1 & 0xff);
! 90: }
! 91:
! 92: static void
! 93: cap_aer(struct device *d, int where)
! 94: {
! 95: u32 l;
! 96:
! 97: printf("Advanced Error Reporting\n");
! 98: if (verbose < 2)
! 99: return;
! 100:
! 101: if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 24))
! 102: return;
! 103:
! 104: l = get_conf_long(d, where + PCI_ERR_UNCOR_STATUS);
! 105: printf("\t\tUESta:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
! 106: "MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
! 107: FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
! 108: FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
! 109: FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
! 110: FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
! 111: l = get_conf_long(d, where + PCI_ERR_UNCOR_MASK);
! 112: printf("\t\tUEMsk:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
! 113: "MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
! 114: FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
! 115: FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
! 116: FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
! 117: FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
! 118: l = get_conf_long(d, where + PCI_ERR_UNCOR_SEVER);
! 119: printf("\t\tUESvrt:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
! 120: "MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
! 121: FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
! 122: FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
! 123: FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
! 124: FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
! 125: l = get_conf_long(d, where + PCI_ERR_COR_STATUS);
! 126: printf("\t\tCESta:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
! 127: FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
! 128: FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
! 129: l = get_conf_long(d, where + PCI_ERR_COR_MASK);
! 130: printf("\t\tCEMsk:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
! 131: FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
! 132: FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
! 133: l = get_conf_long(d, where + PCI_ERR_CAP);
! 134: printf("\t\tAERCap:\tFirst Error Pointer: %02x, GenCap%c CGenEn%c ChkCap%c ChkEn%c\n",
! 135: PCI_ERR_CAP_FEP(l), FLAG(l, PCI_ERR_CAP_ECRC_GENC), FLAG(l, PCI_ERR_CAP_ECRC_GENE),
! 136: FLAG(l, PCI_ERR_CAP_ECRC_CHKC), FLAG(l, PCI_ERR_CAP_ECRC_CHKE));
! 137:
! 138: }
! 139:
! 140: static void
! 141: cap_acs(struct device *d, int where)
! 142: {
! 143: u16 w;
! 144:
! 145: printf("Access Control Services\n");
! 146: if (verbose < 2)
! 147: return;
! 148:
! 149: if (!config_fetch(d, where + PCI_ACS_CAP, 4))
! 150: return;
! 151:
! 152: w = get_conf_word(d, where + PCI_ACS_CAP);
! 153: printf("\t\tACSCap:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
! 154: "DirectTrans%c\n",
! 155: FLAG(w, PCI_ACS_CAP_VALID), FLAG(w, PCI_ACS_CAP_BLOCK), FLAG(w, PCI_ACS_CAP_REQ_RED),
! 156: FLAG(w, PCI_ACS_CAP_CMPLT_RED), FLAG(w, PCI_ACS_CAP_FORWARD), FLAG(w, PCI_ACS_CAP_EGRESS),
! 157: FLAG(w, PCI_ACS_CAP_TRANS));
! 158: w = get_conf_word(d, where + PCI_ACS_CTRL);
! 159: printf("\t\tACSCtl:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
! 160: "DirectTrans%c\n",
! 161: FLAG(w, PCI_ACS_CTRL_VALID), FLAG(w, PCI_ACS_CTRL_BLOCK), FLAG(w, PCI_ACS_CTRL_REQ_RED),
! 162: FLAG(w, PCI_ACS_CTRL_CMPLT_RED), FLAG(w, PCI_ACS_CTRL_FORWARD), FLAG(w, PCI_ACS_CTRL_EGRESS),
! 163: FLAG(w, PCI_ACS_CTRL_TRANS));
! 164: }
! 165:
! 166: static void
! 167: cap_ari(struct device *d, int where)
! 168: {
! 169: u16 w;
! 170:
! 171: printf("Alternative Routing-ID Interpretation (ARI)\n");
! 172: if (verbose < 2)
! 173: return;
! 174:
! 175: if (!config_fetch(d, where + PCI_ARI_CAP, 4))
! 176: return;
! 177:
! 178: w = get_conf_word(d, where + PCI_ARI_CAP);
! 179: printf("\t\tARICap:\tMFVC%c ACS%c, Next Function: %d\n",
! 180: FLAG(w, PCI_ARI_CAP_MFVC), FLAG(w, PCI_ARI_CAP_ACS),
! 181: PCI_ARI_CAP_NFN(w));
! 182: w = get_conf_word(d, where + PCI_ARI_CTRL);
! 183: printf("\t\tARICtl:\tMFVC%c ACS%c, Function Group: %d\n",
! 184: FLAG(w, PCI_ARI_CTRL_MFVC), FLAG(w, PCI_ARI_CTRL_ACS),
! 185: PCI_ARI_CTRL_FG(w));
! 186: }
! 187:
! 188: static void
! 189: cap_ats(struct device *d, int where)
! 190: {
! 191: u16 w;
! 192:
! 193: printf("Address Translation Service (ATS)\n");
! 194: if (verbose < 2)
! 195: return;
! 196:
! 197: if (!config_fetch(d, where + PCI_ATS_CAP, 4))
! 198: return;
! 199:
! 200: w = get_conf_word(d, where + PCI_ATS_CAP);
! 201: printf("\t\tATSCap:\tInvalidate Queue Depth: %02x\n", PCI_ATS_CAP_IQD(w));
! 202: w = get_conf_word(d, where + PCI_ATS_CTRL);
! 203: printf("\t\tATSCtl:\tEnable%c, Smallest Translation Unit: %02x\n",
! 204: FLAG(w, PCI_ATS_CTRL_ENABLE), PCI_ATS_CTRL_STU(w));
! 205: }
! 206:
! 207: static void
! 208: cap_sriov(struct device *d, int where)
! 209: {
! 210: u16 b;
! 211: u16 w;
! 212: u32 l;
! 213: int i;
! 214:
! 215: printf("Single Root I/O Virtualization (SR-IOV)\n");
! 216: if (verbose < 2)
! 217: return;
! 218:
! 219: if (!config_fetch(d, where + PCI_IOV_CAP, 0x3c))
! 220: return;
! 221:
! 222: l = get_conf_long(d, where + PCI_IOV_CAP);
! 223: printf("\t\tIOVCap:\tMigration%c, Interrupt Message Number: %03x\n",
! 224: FLAG(l, PCI_IOV_CAP_VFM), PCI_IOV_CAP_IMN(l));
! 225: w = get_conf_word(d, where + PCI_IOV_CTRL);
! 226: printf("\t\tIOVCtl:\tEnable%c Migration%c Interrupt%c MSE%c ARIHierarchy%c\n",
! 227: FLAG(w, PCI_IOV_CTRL_VFE), FLAG(w, PCI_IOV_CTRL_VFME),
! 228: FLAG(w, PCI_IOV_CTRL_VFMIE), FLAG(w, PCI_IOV_CTRL_MSE),
! 229: FLAG(w, PCI_IOV_CTRL_ARI));
! 230: w = get_conf_word(d, where + PCI_IOV_STATUS);
! 231: printf("\t\tIOVSta:\tMigration%c\n", FLAG(w, PCI_IOV_STATUS_MS));
! 232: w = get_conf_word(d, where + PCI_IOV_INITIALVF);
! 233: printf("\t\tInitial VFs: %d, ", w);
! 234: w = get_conf_word(d, where + PCI_IOV_TOTALVF);
! 235: printf("Total VFs: %d, ", w);
! 236: w = get_conf_word(d, where + PCI_IOV_NUMVF);
! 237: printf("Number of VFs: %d, ", w);
! 238: b = get_conf_byte(d, where + PCI_IOV_FDL);
! 239: printf("Function Dependency Link: %02x\n", b);
! 240: w = get_conf_word(d, where + PCI_IOV_OFFSET);
! 241: printf("\t\tVF offset: %d, ", w);
! 242: w = get_conf_word(d, where + PCI_IOV_STRIDE);
! 243: printf("stride: %d, ", w);
! 244: w = get_conf_word(d, where + PCI_IOV_DID);
! 245: printf("Device ID: %04x\n", w);
! 246: l = get_conf_long(d, where + PCI_IOV_SUPPS);
! 247: printf("\t\tSupported Page Size: %08x, ", l);
! 248: l = get_conf_long(d, where + PCI_IOV_SYSPS);
! 249: printf("System Page Size: %08x\n", l);
! 250:
! 251: for (i=0; i < PCI_IOV_NUM_BAR; i++)
! 252: {
! 253: u32 addr;
! 254: int type;
! 255: u32 h;
! 256: l = get_conf_long(d, where + PCI_IOV_BAR_BASE + 4*i);
! 257: if (l == 0xffffffff)
! 258: l = 0;
! 259: if (!l)
! 260: continue;
! 261: printf("\t\tRegion %d: Memory at ", i);
! 262: addr = l & PCI_ADDR_MEM_MASK;
! 263: type = l & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
! 264: if (type == PCI_BASE_ADDRESS_MEM_TYPE_64)
! 265: {
! 266: i++;
! 267: h = get_conf_long(d, where + PCI_IOV_BAR_BASE + (i*4));
! 268: printf("%08x", h);
! 269: }
! 270: printf("%08x (%s-bit, %sprefetchable)\n",
! 271: addr,
! 272: (type == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32" : "64",
! 273: (l & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-");
! 274: }
! 275:
! 276: l = get_conf_long(d, where + PCI_IOV_MSAO);
! 277: printf("\t\tVF Migration: offset: %08x, BIR: %x\n", PCI_IOV_MSA_OFFSET(l),
! 278: PCI_IOV_MSA_BIR(l));
! 279: }
! 280:
! 281: static void
! 282: cap_vc(struct device *d, int where)
! 283: {
! 284: u32 cr1, cr2;
! 285: u16 ctrl, status;
! 286: int evc_cnt;
! 287: int arb_table_pos;
! 288: int i, j;
! 289: static const char ref_clocks[][6] = { "100ns" };
! 290: static const char arb_selects[8][7] = { "Fixed", "WRR32", "WRR64", "WRR128", "??4", "??5", "??6", "??7" };
! 291: static const char vc_arb_selects[8][8] = { "Fixed", "WRR32", "WRR64", "WRR128", "TWRR128", "WRR256", "??6", "??7" };
! 292: char buf[8];
! 293:
! 294: printf("Virtual Channel\n");
! 295: if (verbose < 2)
! 296: return;
! 297:
! 298: if (!config_fetch(d, where + 4, 0x1c - 4))
! 299: return;
! 300:
! 301: cr1 = get_conf_long(d, where + PCI_VC_PORT_REG1);
! 302: cr2 = get_conf_long(d, where + PCI_VC_PORT_REG2);
! 303: ctrl = get_conf_word(d, where + PCI_VC_PORT_CTRL);
! 304: status = get_conf_word(d, where + PCI_VC_PORT_STATUS);
! 305:
! 306: evc_cnt = BITS(cr1, 0, 3);
! 307: printf("\t\tCaps:\tLPEVC=%d RefClk=%s PATEntryBits=%d\n",
! 308: BITS(cr1, 4, 3),
! 309: TABLE(ref_clocks, BITS(cr1, 8, 2), buf),
! 310: 1 << BITS(cr1, 10, 2));
! 311:
! 312: printf("\t\tArb:");
! 313: for (i=0; i<8; i++)
! 314: if (arb_selects[i][0] != '?' || cr2 & (1 << i))
! 315: printf("%c%s%c", (i ? ' ' : '\t'), arb_selects[i], FLAG(cr2, 1 << i));
! 316: arb_table_pos = BITS(cr2, 24, 8);
! 317:
! 318: printf("\n\t\tCtrl:\tArbSelect=%s\n", TABLE(arb_selects, BITS(ctrl, 1, 3), buf));
! 319: printf("\t\tStatus:\tInProgress%c\n", FLAG(status, 1));
! 320:
! 321: if (arb_table_pos)
! 322: {
! 323: arb_table_pos = where + 16*arb_table_pos;
! 324: printf("\t\tPort Arbitration Table [%x] <?>\n", arb_table_pos);
! 325: }
! 326:
! 327: for (i=0; i<=evc_cnt; i++)
! 328: {
! 329: int pos = where + PCI_VC_RES_CAP + 12*i;
! 330: u32 rcap, rctrl;
! 331: u16 rstatus;
! 332: int pat_pos;
! 333:
! 334: printf("\t\tVC%d:\t", i);
! 335: if (!config_fetch(d, pos, 12))
! 336: {
! 337: printf("<unreadable>\n");
! 338: continue;
! 339: }
! 340: rcap = get_conf_long(d, pos);
! 341: rctrl = get_conf_long(d, pos+4);
! 342: rstatus = get_conf_word(d, pos+8);
! 343:
! 344: pat_pos = BITS(rcap, 24, 8);
! 345: printf("Caps:\tPATOffset=%02x MaxTimeSlots=%d RejSnoopTrans%c\n",
! 346: pat_pos,
! 347: BITS(rcap, 16, 6) + 1,
! 348: FLAG(rcap, 1 << 15));
! 349:
! 350: printf("\t\t\tArb:");
! 351: for (j=0; j<8; j++)
! 352: if (vc_arb_selects[j][0] != '?' || rcap & (1 << j))
! 353: printf("%c%s%c", (j ? ' ' : '\t'), vc_arb_selects[j], FLAG(rcap, 1 << j));
! 354:
! 355: printf("\n\t\t\tCtrl:\tEnable%c ID=%d ArbSelect=%s TC/VC=%02x\n",
! 356: FLAG(rctrl, 1 << 31),
! 357: BITS(rctrl, 24, 3),
! 358: TABLE(vc_arb_selects, BITS(rctrl, 17, 3), buf),
! 359: BITS(rctrl, 0, 8));
! 360:
! 361: printf("\t\t\tStatus:\tNegoPending%c InProgress%c\n",
! 362: FLAG(rstatus, 2),
! 363: FLAG(rstatus, 1));
! 364:
! 365: if (pat_pos)
! 366: printf("\t\t\tPort Arbitration Table <?>\n");
! 367: }
! 368: }
! 369:
! 370: static void
! 371: cap_rclink(struct device *d, int where)
! 372: {
! 373: u32 esd;
! 374: int num_links;
! 375: int i;
! 376: static const char elt_types[][9] = { "Config", "Egress", "Internal" };
! 377: char buf[8];
! 378:
! 379: printf("Root Complex Link\n");
! 380: if (verbose < 2)
! 381: return;
! 382:
! 383: if (!config_fetch(d, where + 4, PCI_RCLINK_LINK1 - 4))
! 384: return;
! 385:
! 386: esd = get_conf_long(d, where + PCI_RCLINK_ESD);
! 387: num_links = BITS(esd, 8, 8);
! 388: printf("\t\tDesc:\tPortNumber=%02x ComponentID=%02x EltType=%s\n",
! 389: BITS(esd, 24, 8),
! 390: BITS(esd, 16, 8),
! 391: TABLE(elt_types, BITS(esd, 0, 8), buf));
! 392:
! 393: for (i=0; i<num_links; i++)
! 394: {
! 395: int pos = where + PCI_RCLINK_LINK1 + i*PCI_RCLINK_LINK_SIZE;
! 396: u32 desc;
! 397: u32 addr_lo, addr_hi;
! 398:
! 399: printf("\t\tLink%d:\t", i);
! 400: if (!config_fetch(d, pos, PCI_RCLINK_LINK_SIZE))
! 401: {
! 402: printf("<unreadable>\n");
! 403: return;
! 404: }
! 405: desc = get_conf_long(d, pos + PCI_RCLINK_LINK_DESC);
! 406: addr_lo = get_conf_long(d, pos + PCI_RCLINK_LINK_ADDR);
! 407: addr_hi = get_conf_long(d, pos + PCI_RCLINK_LINK_ADDR + 4);
! 408:
! 409: printf("Desc:\tTargetPort=%02x TargetComponent=%02x AssocRCRB%c LinkType=%s LinkValid%c\n",
! 410: BITS(desc, 24, 8),
! 411: BITS(desc, 16, 8),
! 412: FLAG(desc, 4),
! 413: ((desc & 2) ? "Config" : "MemMapped"),
! 414: FLAG(desc, 1));
! 415:
! 416: if (desc & 2)
! 417: {
! 418: int n = addr_lo & 7;
! 419: if (!n)
! 420: n = 8;
! 421: printf("\t\t\tAddr:\t%02x:%02x.%d CfgSpace=%08x%08x\n",
! 422: BITS(addr_lo, 20, n),
! 423: BITS(addr_lo, 15, 5),
! 424: BITS(addr_lo, 12, 3),
! 425: addr_hi, addr_lo);
! 426: }
! 427: else
! 428: printf("\t\t\tAddr:\t%08x%08x\n", addr_hi, addr_lo);
! 429: }
! 430: }
! 431:
! 432: static void
! 433: cap_evendor(struct device *d, int where)
! 434: {
! 435: u32 hdr;
! 436:
! 437: printf("Vendor Specific Information: ");
! 438: if (!config_fetch(d, where + PCI_EVNDR_HEADER, 4))
! 439: {
! 440: printf("<unreadable>\n");
! 441: return;
! 442: }
! 443:
! 444: hdr = get_conf_long(d, where + PCI_EVNDR_HEADER);
! 445: printf("ID=%04x Rev=%d Len=%03x <?>\n",
! 446: BITS(hdr, 0, 16),
! 447: BITS(hdr, 16, 4),
! 448: BITS(hdr, 20, 12));
! 449: }
! 450:
! 451: void
! 452: show_ext_caps(struct device *d)
! 453: {
! 454: int where = 0x100;
! 455: char been_there[0x1000];
! 456: memset(been_there, 0, 0x1000);
! 457: do
! 458: {
! 459: u32 header;
! 460: int id, version;
! 461:
! 462: if (!config_fetch(d, where, 4))
! 463: break;
! 464: header = get_conf_long(d, where);
! 465: if (!header)
! 466: break;
! 467: id = header & 0xffff;
! 468: version = (header >> 16) & 0xf;
! 469: printf("\tCapabilities: [%03x", where);
! 470: if (verbose > 1)
! 471: printf(" v%d", version);
! 472: printf("] ");
! 473: if (been_there[where]++)
! 474: {
! 475: printf("<chain looped>\n");
! 476: break;
! 477: }
! 478: switch (id)
! 479: {
! 480: case PCI_EXT_CAP_ID_AER:
! 481: cap_aer(d, where);
! 482: break;
! 483: case PCI_EXT_CAP_ID_VC:
! 484: case PCI_EXT_CAP_ID_VC2:
! 485: cap_vc(d, where);
! 486: break;
! 487: case PCI_EXT_CAP_ID_DSN:
! 488: cap_dsn(d, where);
! 489: break;
! 490: case PCI_EXT_CAP_ID_PB:
! 491: printf("Power Budgeting <?>\n");
! 492: break;
! 493: case PCI_EXT_CAP_ID_RCLINK:
! 494: cap_rclink(d, where);
! 495: break;
! 496: case PCI_EXT_CAP_ID_RCILINK:
! 497: printf("Root Complex Internal Link <?>\n");
! 498: break;
! 499: case PCI_EXT_CAP_ID_RCECOLL:
! 500: printf("Root Complex Event Collector <?>\n");
! 501: break;
! 502: case PCI_EXT_CAP_ID_MFVC:
! 503: printf("Multi-Function Virtual Channel <?>\n");
! 504: break;
! 505: case PCI_EXT_CAP_ID_RBCB:
! 506: printf("Root Bridge Control Block <?>\n");
! 507: break;
! 508: case PCI_EXT_CAP_ID_VNDR:
! 509: cap_evendor(d, where);
! 510: break;
! 511: case PCI_EXT_CAP_ID_ACS:
! 512: cap_acs(d, where);
! 513: break;
! 514: case PCI_EXT_CAP_ID_ARI:
! 515: cap_ari(d, where);
! 516: break;
! 517: case PCI_EXT_CAP_ID_ATS:
! 518: cap_ats(d, where);
! 519: break;
! 520: case PCI_EXT_CAP_ID_SRIOV:
! 521: cap_sriov(d, where);
! 522: break;
! 523: case PCI_EXT_CAP_ID_TPH:
! 524: cap_tph(d, where);
! 525: break;
! 526: case PCI_EXT_CAP_ID_LTR:
! 527: cap_ltr(d, where);
! 528: break;
! 529: default:
! 530: printf("#%02x\n", id);
! 531: break;
! 532: }
! 533: where = (header >> 20) & ~3;
! 534: } while (where);
! 535: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>