0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef __LINUX_CDNSP_DEBUG
0011 #define __LINUX_CDNSP_DEBUG
0012
0013 static inline const char *cdnsp_trb_comp_code_string(u8 status)
0014 {
0015 switch (status) {
0016 case COMP_INVALID:
0017 return "Invalid";
0018 case COMP_SUCCESS:
0019 return "Success";
0020 case COMP_DATA_BUFFER_ERROR:
0021 return "Data Buffer Error";
0022 case COMP_BABBLE_DETECTED_ERROR:
0023 return "Babble Detected";
0024 case COMP_TRB_ERROR:
0025 return "TRB Error";
0026 case COMP_RESOURCE_ERROR:
0027 return "Resource Error";
0028 case COMP_NO_SLOTS_AVAILABLE_ERROR:
0029 return "No Slots Available Error";
0030 case COMP_INVALID_STREAM_TYPE_ERROR:
0031 return "Invalid Stream Type Error";
0032 case COMP_SLOT_NOT_ENABLED_ERROR:
0033 return "Slot Not Enabled Error";
0034 case COMP_ENDPOINT_NOT_ENABLED_ERROR:
0035 return "Endpoint Not Enabled Error";
0036 case COMP_SHORT_PACKET:
0037 return "Short Packet";
0038 case COMP_RING_UNDERRUN:
0039 return "Ring Underrun";
0040 case COMP_RING_OVERRUN:
0041 return "Ring Overrun";
0042 case COMP_VF_EVENT_RING_FULL_ERROR:
0043 return "VF Event Ring Full Error";
0044 case COMP_PARAMETER_ERROR:
0045 return "Parameter Error";
0046 case COMP_CONTEXT_STATE_ERROR:
0047 return "Context State Error";
0048 case COMP_EVENT_RING_FULL_ERROR:
0049 return "Event Ring Full Error";
0050 case COMP_INCOMPATIBLE_DEVICE_ERROR:
0051 return "Incompatible Device Error";
0052 case COMP_MISSED_SERVICE_ERROR:
0053 return "Missed Service Error";
0054 case COMP_COMMAND_RING_STOPPED:
0055 return "Command Ring Stopped";
0056 case COMP_COMMAND_ABORTED:
0057 return "Command Aborted";
0058 case COMP_STOPPED:
0059 return "Stopped";
0060 case COMP_STOPPED_LENGTH_INVALID:
0061 return "Stopped - Length Invalid";
0062 case COMP_STOPPED_SHORT_PACKET:
0063 return "Stopped - Short Packet";
0064 case COMP_MAX_EXIT_LATENCY_TOO_LARGE_ERROR:
0065 return "Max Exit Latency Too Large Error";
0066 case COMP_ISOCH_BUFFER_OVERRUN:
0067 return "Isoch Buffer Overrun";
0068 case COMP_EVENT_LOST_ERROR:
0069 return "Event Lost Error";
0070 case COMP_UNDEFINED_ERROR:
0071 return "Undefined Error";
0072 case COMP_INVALID_STREAM_ID_ERROR:
0073 return "Invalid Stream ID Error";
0074 default:
0075 return "Unknown!!";
0076 }
0077 }
0078
0079 static inline const char *cdnsp_trb_type_string(u8 type)
0080 {
0081 switch (type) {
0082 case TRB_NORMAL:
0083 return "Normal";
0084 case TRB_SETUP:
0085 return "Setup Stage";
0086 case TRB_DATA:
0087 return "Data Stage";
0088 case TRB_STATUS:
0089 return "Status Stage";
0090 case TRB_ISOC:
0091 return "Isoch";
0092 case TRB_LINK:
0093 return "Link";
0094 case TRB_EVENT_DATA:
0095 return "Event Data";
0096 case TRB_TR_NOOP:
0097 return "No-Op";
0098 case TRB_ENABLE_SLOT:
0099 return "Enable Slot Command";
0100 case TRB_DISABLE_SLOT:
0101 return "Disable Slot Command";
0102 case TRB_ADDR_DEV:
0103 return "Address Device Command";
0104 case TRB_CONFIG_EP:
0105 return "Configure Endpoint Command";
0106 case TRB_EVAL_CONTEXT:
0107 return "Evaluate Context Command";
0108 case TRB_RESET_EP:
0109 return "Reset Endpoint Command";
0110 case TRB_STOP_RING:
0111 return "Stop Ring Command";
0112 case TRB_SET_DEQ:
0113 return "Set TR Dequeue Pointer Command";
0114 case TRB_RESET_DEV:
0115 return "Reset Device Command";
0116 case TRB_FORCE_HEADER:
0117 return "Force Header Command";
0118 case TRB_CMD_NOOP:
0119 return "No-Op Command";
0120 case TRB_TRANSFER:
0121 return "Transfer Event";
0122 case TRB_COMPLETION:
0123 return "Command Completion Event";
0124 case TRB_PORT_STATUS:
0125 return "Port Status Change Event";
0126 case TRB_HC_EVENT:
0127 return "Device Controller Event";
0128 case TRB_MFINDEX_WRAP:
0129 return "MFINDEX Wrap Event";
0130 case TRB_ENDPOINT_NRDY:
0131 return "Endpoint Not ready";
0132 case TRB_HALT_ENDPOINT:
0133 return "Halt Endpoint";
0134 case TRB_FLUSH_ENDPOINT:
0135 return "FLush Endpoint";
0136 default:
0137 return "UNKNOWN";
0138 }
0139 }
0140
0141 static inline const char *cdnsp_ring_type_string(enum cdnsp_ring_type type)
0142 {
0143 switch (type) {
0144 case TYPE_CTRL:
0145 return "CTRL";
0146 case TYPE_ISOC:
0147 return "ISOC";
0148 case TYPE_BULK:
0149 return "BULK";
0150 case TYPE_INTR:
0151 return "INTR";
0152 case TYPE_STREAM:
0153 return "STREAM";
0154 case TYPE_COMMAND:
0155 return "CMD";
0156 case TYPE_EVENT:
0157 return "EVENT";
0158 }
0159
0160 return "UNKNOWN";
0161 }
0162
0163 static inline char *cdnsp_slot_state_string(u32 state)
0164 {
0165 switch (state) {
0166 case SLOT_STATE_ENABLED:
0167 return "enabled/disabled";
0168 case SLOT_STATE_DEFAULT:
0169 return "default";
0170 case SLOT_STATE_ADDRESSED:
0171 return "addressed";
0172 case SLOT_STATE_CONFIGURED:
0173 return "configured";
0174 default:
0175 return "reserved";
0176 }
0177 }
0178
0179 static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
0180 u32 field1, u32 field2, u32 field3)
0181 {
0182 int ep_id = TRB_TO_EP_INDEX(field3) - 1;
0183 int type = TRB_FIELD_TO_TYPE(field3);
0184 unsigned int ep_num;
0185 int ret;
0186 u32 temp;
0187
0188 ep_num = DIV_ROUND_UP(ep_id, 2);
0189
0190 switch (type) {
0191 case TRB_LINK:
0192 ret = snprintf(str, size,
0193 "LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c",
0194 field1, field0, GET_INTR_TARGET(field2),
0195 cdnsp_trb_type_string(type),
0196 field3 & TRB_IOC ? 'I' : 'i',
0197 field3 & TRB_CHAIN ? 'C' : 'c',
0198 field3 & TRB_TC ? 'T' : 't',
0199 field3 & TRB_CYCLE ? 'C' : 'c');
0200 break;
0201 case TRB_TRANSFER:
0202 case TRB_COMPLETION:
0203 case TRB_PORT_STATUS:
0204 case TRB_HC_EVENT:
0205 ret = snprintf(str, size,
0206 "ep%d%s(%d) type '%s' TRB %08x%08x status '%s'"
0207 " len %ld slot %ld flags %c:%c",
0208 ep_num, ep_id % 2 ? "out" : "in",
0209 TRB_TO_EP_INDEX(field3),
0210 cdnsp_trb_type_string(type), field1, field0,
0211 cdnsp_trb_comp_code_string(GET_COMP_CODE(field2)),
0212 EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
0213 field3 & EVENT_DATA ? 'E' : 'e',
0214 field3 & TRB_CYCLE ? 'C' : 'c');
0215 break;
0216 case TRB_MFINDEX_WRAP:
0217 ret = snprintf(str, size, "%s: flags %c",
0218 cdnsp_trb_type_string(type),
0219 field3 & TRB_CYCLE ? 'C' : 'c');
0220 break;
0221 case TRB_SETUP:
0222 ret = snprintf(str, size,
0223 "type '%s' bRequestType %02x bRequest %02x "
0224 "wValue %02x%02x wIndex %02x%02x wLength %d "
0225 "length %ld TD size %ld intr %ld Setup ID %ld "
0226 "flags %c:%c:%c",
0227 cdnsp_trb_type_string(type),
0228 field0 & 0xff,
0229 (field0 & 0xff00) >> 8,
0230 (field0 & 0xff000000) >> 24,
0231 (field0 & 0xff0000) >> 16,
0232 (field1 & 0xff00) >> 8,
0233 field1 & 0xff,
0234 (field1 & 0xff000000) >> 16 |
0235 (field1 & 0xff0000) >> 16,
0236 TRB_LEN(field2), GET_TD_SIZE(field2),
0237 GET_INTR_TARGET(field2),
0238 TRB_SETUPID_TO_TYPE(field3),
0239 field3 & TRB_IDT ? 'D' : 'd',
0240 field3 & TRB_IOC ? 'I' : 'i',
0241 field3 & TRB_CYCLE ? 'C' : 'c');
0242 break;
0243 case TRB_DATA:
0244 ret = snprintf(str, size,
0245 "type '%s' Buffer %08x%08x length %ld TD size %ld "
0246 "intr %ld flags %c:%c:%c:%c:%c:%c:%c",
0247 cdnsp_trb_type_string(type),
0248 field1, field0, TRB_LEN(field2),
0249 GET_TD_SIZE(field2),
0250 GET_INTR_TARGET(field2),
0251 field3 & TRB_IDT ? 'D' : 'i',
0252 field3 & TRB_IOC ? 'I' : 'i',
0253 field3 & TRB_CHAIN ? 'C' : 'c',
0254 field3 & TRB_NO_SNOOP ? 'S' : 's',
0255 field3 & TRB_ISP ? 'I' : 'i',
0256 field3 & TRB_ENT ? 'E' : 'e',
0257 field3 & TRB_CYCLE ? 'C' : 'c');
0258 break;
0259 case TRB_STATUS:
0260 ret = snprintf(str, size,
0261 "Buffer %08x%08x length %ld TD size %ld intr"
0262 "%ld type '%s' flags %c:%c:%c:%c",
0263 field1, field0, TRB_LEN(field2),
0264 GET_TD_SIZE(field2),
0265 GET_INTR_TARGET(field2),
0266 cdnsp_trb_type_string(type),
0267 field3 & TRB_IOC ? 'I' : 'i',
0268 field3 & TRB_CHAIN ? 'C' : 'c',
0269 field3 & TRB_ENT ? 'E' : 'e',
0270 field3 & TRB_CYCLE ? 'C' : 'c');
0271 break;
0272 case TRB_NORMAL:
0273 case TRB_ISOC:
0274 case TRB_EVENT_DATA:
0275 case TRB_TR_NOOP:
0276 ret = snprintf(str, size,
0277 "type '%s' Buffer %08x%08x length %ld "
0278 "TD size %ld intr %ld "
0279 "flags %c:%c:%c:%c:%c:%c:%c:%c:%c",
0280 cdnsp_trb_type_string(type),
0281 field1, field0, TRB_LEN(field2),
0282 GET_TD_SIZE(field2),
0283 GET_INTR_TARGET(field2),
0284 field3 & TRB_BEI ? 'B' : 'b',
0285 field3 & TRB_IDT ? 'T' : 't',
0286 field3 & TRB_IOC ? 'I' : 'i',
0287 field3 & TRB_CHAIN ? 'C' : 'c',
0288 field3 & TRB_NO_SNOOP ? 'S' : 's',
0289 field3 & TRB_ISP ? 'I' : 'i',
0290 field3 & TRB_ENT ? 'E' : 'e',
0291 field3 & TRB_CYCLE ? 'C' : 'c',
0292 !(field3 & TRB_EVENT_INVALIDATE) ? 'V' : 'v');
0293 break;
0294 case TRB_CMD_NOOP:
0295 case TRB_ENABLE_SLOT:
0296 ret = snprintf(str, size, "%s: flags %c",
0297 cdnsp_trb_type_string(type),
0298 field3 & TRB_CYCLE ? 'C' : 'c');
0299 break;
0300 case TRB_DISABLE_SLOT:
0301 ret = snprintf(str, size, "%s: slot %ld flags %c",
0302 cdnsp_trb_type_string(type),
0303 TRB_TO_SLOT_ID(field3),
0304 field3 & TRB_CYCLE ? 'C' : 'c');
0305 break;
0306 case TRB_ADDR_DEV:
0307 ret = snprintf(str, size,
0308 "%s: ctx %08x%08x slot %ld flags %c:%c",
0309 cdnsp_trb_type_string(type), field1, field0,
0310 TRB_TO_SLOT_ID(field3),
0311 field3 & TRB_BSR ? 'B' : 'b',
0312 field3 & TRB_CYCLE ? 'C' : 'c');
0313 break;
0314 case TRB_CONFIG_EP:
0315 ret = snprintf(str, size,
0316 "%s: ctx %08x%08x slot %ld flags %c:%c",
0317 cdnsp_trb_type_string(type), field1, field0,
0318 TRB_TO_SLOT_ID(field3),
0319 field3 & TRB_DC ? 'D' : 'd',
0320 field3 & TRB_CYCLE ? 'C' : 'c');
0321 break;
0322 case TRB_EVAL_CONTEXT:
0323 ret = snprintf(str, size,
0324 "%s: ctx %08x%08x slot %ld flags %c",
0325 cdnsp_trb_type_string(type), field1, field0,
0326 TRB_TO_SLOT_ID(field3),
0327 field3 & TRB_CYCLE ? 'C' : 'c');
0328 break;
0329 case TRB_RESET_EP:
0330 case TRB_HALT_ENDPOINT:
0331 case TRB_FLUSH_ENDPOINT:
0332 ret = snprintf(str, size,
0333 "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
0334 cdnsp_trb_type_string(type),
0335 ep_num, ep_id % 2 ? "out" : "in",
0336 TRB_TO_EP_INDEX(field3), field1, field0,
0337 TRB_TO_SLOT_ID(field3),
0338 field3 & TRB_CYCLE ? 'C' : 'c');
0339 break;
0340 case TRB_STOP_RING:
0341 ret = snprintf(str, size,
0342 "%s: ep%d%s(%d) slot %ld sp %d flags %c",
0343 cdnsp_trb_type_string(type),
0344 ep_num, ep_id % 2 ? "out" : "in",
0345 TRB_TO_EP_INDEX(field3),
0346 TRB_TO_SLOT_ID(field3),
0347 TRB_TO_SUSPEND_PORT(field3),
0348 field3 & TRB_CYCLE ? 'C' : 'c');
0349 break;
0350 case TRB_SET_DEQ:
0351 ret = snprintf(str, size,
0352 "%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld flags %c",
0353 cdnsp_trb_type_string(type),
0354 ep_num, ep_id % 2 ? "out" : "in",
0355 TRB_TO_EP_INDEX(field3), field1, field0,
0356 TRB_TO_STREAM_ID(field2),
0357 TRB_TO_SLOT_ID(field3),
0358 field3 & TRB_CYCLE ? 'C' : 'c');
0359 break;
0360 case TRB_RESET_DEV:
0361 ret = snprintf(str, size, "%s: slot %ld flags %c",
0362 cdnsp_trb_type_string(type),
0363 TRB_TO_SLOT_ID(field3),
0364 field3 & TRB_CYCLE ? 'C' : 'c');
0365 break;
0366 case TRB_ENDPOINT_NRDY:
0367 temp = TRB_TO_HOST_STREAM(field2);
0368
0369 ret = snprintf(str, size,
0370 "%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c",
0371 cdnsp_trb_type_string(type),
0372 ep_num, ep_id % 2 ? "out" : "in",
0373 TRB_TO_EP_INDEX(field3), temp,
0374 temp == STREAM_PRIME_ACK ? "(PRIME)" : "",
0375 temp == STREAM_REJECTED ? "(REJECTED)" : "",
0376 TRB_TO_DEV_STREAM(field0),
0377 field3 & TRB_STAT ? 'S' : 's',
0378 field3 & TRB_CYCLE ? 'C' : 'c');
0379 break;
0380 default:
0381 ret = snprintf(str, size,
0382 "type '%s' -> raw %08x %08x %08x %08x",
0383 cdnsp_trb_type_string(type),
0384 field0, field1, field2, field3);
0385 }
0386
0387 if (ret >= size)
0388 pr_info("CDNSP: buffer overflowed.\n");
0389
0390 return str;
0391 }
0392
0393 static inline const char *cdnsp_decode_slot_context(u32 info, u32 info2,
0394 u32 int_target, u32 state)
0395 {
0396 static char str[1024];
0397 int ret = 0;
0398 u32 speed;
0399 char *s;
0400
0401 speed = info & DEV_SPEED;
0402
0403 switch (speed) {
0404 case SLOT_SPEED_FS:
0405 s = "full-speed";
0406 break;
0407 case SLOT_SPEED_HS:
0408 s = "high-speed";
0409 break;
0410 case SLOT_SPEED_SS:
0411 s = "super-speed";
0412 break;
0413 case SLOT_SPEED_SSP:
0414 s = "super-speed plus";
0415 break;
0416 default:
0417 s = "UNKNOWN speed";
0418 }
0419
0420 ret = sprintf(str, "%s Ctx Entries %d",
0421 s, (info & LAST_CTX_MASK) >> 27);
0422
0423 ret += sprintf(str + ret, " [Intr %ld] Addr %ld State %s",
0424 GET_INTR_TARGET(int_target), state & DEV_ADDR_MASK,
0425 cdnsp_slot_state_string(GET_SLOT_STATE(state)));
0426
0427 return str;
0428 }
0429
0430 static inline const char *cdnsp_portsc_link_state_string(u32 portsc)
0431 {
0432 switch (portsc & PORT_PLS_MASK) {
0433 case XDEV_U0:
0434 return "U0";
0435 case XDEV_U1:
0436 return "U1";
0437 case XDEV_U2:
0438 return "U2";
0439 case XDEV_U3:
0440 return "U3";
0441 case XDEV_DISABLED:
0442 return "Disabled";
0443 case XDEV_RXDETECT:
0444 return "RxDetect";
0445 case XDEV_INACTIVE:
0446 return "Inactive";
0447 case XDEV_POLLING:
0448 return "Polling";
0449 case XDEV_RECOVERY:
0450 return "Recovery";
0451 case XDEV_HOT_RESET:
0452 return "Hot Reset";
0453 case XDEV_COMP_MODE:
0454 return "Compliance mode";
0455 case XDEV_TEST_MODE:
0456 return "Test mode";
0457 case XDEV_RESUME:
0458 return "Resume";
0459 default:
0460 break;
0461 }
0462
0463 return "Unknown";
0464 }
0465
0466 static inline const char *cdnsp_decode_portsc(char *str, size_t size,
0467 u32 portsc)
0468 {
0469 int ret;
0470
0471 ret = snprintf(str, size, "%s %s %s Link:%s PortSpeed:%d ",
0472 portsc & PORT_POWER ? "Powered" : "Powered-off",
0473 portsc & PORT_CONNECT ? "Connected" : "Not-connected",
0474 portsc & PORT_PED ? "Enabled" : "Disabled",
0475 cdnsp_portsc_link_state_string(portsc),
0476 DEV_PORT_SPEED(portsc));
0477
0478 if (portsc & PORT_RESET)
0479 ret += snprintf(str + ret, size - ret, "In-Reset ");
0480
0481 ret += snprintf(str + ret, size - ret, "Change: ");
0482 if (portsc & PORT_CSC)
0483 ret += snprintf(str + ret, size - ret, "CSC ");
0484 if (portsc & PORT_WRC)
0485 ret += snprintf(str + ret, size - ret, "WRC ");
0486 if (portsc & PORT_RC)
0487 ret += snprintf(str + ret, size - ret, "PRC ");
0488 if (portsc & PORT_PLC)
0489 ret += snprintf(str + ret, size - ret, "PLC ");
0490 if (portsc & PORT_CEC)
0491 ret += snprintf(str + ret, size - ret, "CEC ");
0492 ret += snprintf(str + ret, size - ret, "Wake: ");
0493 if (portsc & PORT_WKCONN_E)
0494 ret += snprintf(str + ret, size - ret, "WCE ");
0495 if (portsc & PORT_WKDISC_E)
0496 ret += snprintf(str + ret, size - ret, "WDE ");
0497
0498 return str;
0499 }
0500
0501 static inline const char *cdnsp_ep_state_string(u8 state)
0502 {
0503 switch (state) {
0504 case EP_STATE_DISABLED:
0505 return "disabled";
0506 case EP_STATE_RUNNING:
0507 return "running";
0508 case EP_STATE_HALTED:
0509 return "halted";
0510 case EP_STATE_STOPPED:
0511 return "stopped";
0512 case EP_STATE_ERROR:
0513 return "error";
0514 default:
0515 return "INVALID";
0516 }
0517 }
0518
0519 static inline const char *cdnsp_ep_type_string(u8 type)
0520 {
0521 switch (type) {
0522 case ISOC_OUT_EP:
0523 return "Isoc OUT";
0524 case BULK_OUT_EP:
0525 return "Bulk OUT";
0526 case INT_OUT_EP:
0527 return "Int OUT";
0528 case CTRL_EP:
0529 return "Ctrl";
0530 case ISOC_IN_EP:
0531 return "Isoc IN";
0532 case BULK_IN_EP:
0533 return "Bulk IN";
0534 case INT_IN_EP:
0535 return "Int IN";
0536 default:
0537 return "INVALID";
0538 }
0539 }
0540
0541 static inline const char *cdnsp_decode_ep_context(char *str, size_t size,
0542 u32 info, u32 info2,
0543 u64 deq, u32 tx_info)
0544 {
0545 u8 max_pstr, ep_state, interval, ep_type, burst, cerr, mult;
0546 bool lsa, hid;
0547 u16 maxp, avg;
0548 u32 esit;
0549 int ret;
0550
0551 esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 |
0552 CTX_TO_MAX_ESIT_PAYLOAD_LO(tx_info);
0553
0554 ep_state = info & EP_STATE_MASK;
0555 max_pstr = CTX_TO_EP_MAXPSTREAMS(info);
0556 interval = CTX_TO_EP_INTERVAL(info);
0557 mult = CTX_TO_EP_MULT(info) + 1;
0558 lsa = !!(info & EP_HAS_LSA);
0559
0560 cerr = (info2 & (3 << 1)) >> 1;
0561 ep_type = CTX_TO_EP_TYPE(info2);
0562 hid = !!(info2 & (1 << 7));
0563 burst = CTX_TO_MAX_BURST(info2);
0564 maxp = MAX_PACKET_DECODED(info2);
0565
0566 avg = EP_AVG_TRB_LENGTH(tx_info);
0567
0568 ret = snprintf(str, size, "State %s mult %d max P. Streams %d %s",
0569 cdnsp_ep_state_string(ep_state), mult,
0570 max_pstr, lsa ? "LSA " : "");
0571
0572 ret += snprintf(str + ret, size - ret,
0573 "interval %d us max ESIT payload %d CErr %d ",
0574 (1 << interval) * 125, esit, cerr);
0575
0576 ret += snprintf(str + ret, size - ret,
0577 "Type %s %sburst %d maxp %d deq %016llx ",
0578 cdnsp_ep_type_string(ep_type), hid ? "HID" : "",
0579 burst, maxp, deq);
0580
0581 ret += snprintf(str + ret, size - ret, "avg trb len %d", avg);
0582
0583 return str;
0584 }
0585
0586 #endif