linux/drivers/usb/dwc3/debug.h
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/**
   3 * debug.h - DesignWare USB3 DRD Controller Debug Header
   4 *
   5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
   6 *
   7 * Authors: Felipe Balbi <balbi@ti.com>,
   8 *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
   9 */
  10
  11#ifndef __DWC3_DEBUG_H
  12#define __DWC3_DEBUG_H
  13
  14#include "core.h"
  15
  16/**
  17 * dwc3_gadget_ep_cmd_string - returns endpoint command string
  18 * @cmd: command code
  19 */
  20static inline const char *
  21dwc3_gadget_ep_cmd_string(u8 cmd)
  22{
  23        switch (cmd) {
  24        case DWC3_DEPCMD_DEPSTARTCFG:
  25                return "Start New Configuration";
  26        case DWC3_DEPCMD_ENDTRANSFER:
  27                return "End Transfer";
  28        case DWC3_DEPCMD_UPDATETRANSFER:
  29                return "Update Transfer";
  30        case DWC3_DEPCMD_STARTTRANSFER:
  31                return "Start Transfer";
  32        case DWC3_DEPCMD_CLEARSTALL:
  33                return "Clear Stall";
  34        case DWC3_DEPCMD_SETSTALL:
  35                return "Set Stall";
  36        case DWC3_DEPCMD_GETEPSTATE:
  37                return "Get Endpoint State";
  38        case DWC3_DEPCMD_SETTRANSFRESOURCE:
  39                return "Set Endpoint Transfer Resource";
  40        case DWC3_DEPCMD_SETEPCONFIG:
  41                return "Set Endpoint Configuration";
  42        default:
  43                return "UNKNOWN command";
  44        }
  45}
  46
  47/**
  48 * dwc3_gadget_generic_cmd_string - returns generic command string
  49 * @cmd: command code
  50 */
  51static inline const char *
  52dwc3_gadget_generic_cmd_string(u8 cmd)
  53{
  54        switch (cmd) {
  55        case DWC3_DGCMD_SET_LMP:
  56                return "Set LMP";
  57        case DWC3_DGCMD_SET_PERIODIC_PAR:
  58                return "Set Periodic Parameters";
  59        case DWC3_DGCMD_XMIT_FUNCTION:
  60                return "Transmit Function Wake Device Notification";
  61        case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
  62                return "Set Scratchpad Buffer Array Address Lo";
  63        case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
  64                return "Set Scratchpad Buffer Array Address Hi";
  65        case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
  66                return "Selected FIFO Flush";
  67        case DWC3_DGCMD_ALL_FIFO_FLUSH:
  68                return "All FIFO Flush";
  69        case DWC3_DGCMD_SET_ENDPOINT_NRDY:
  70                return "Set Endpoint NRDY";
  71        case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
  72                return "Run SoC Bus Loopback Test";
  73        default:
  74                return "UNKNOWN";
  75        }
  76}
  77
  78/**
  79 * dwc3_gadget_link_string - returns link name
  80 * @link_state: link state code
  81 */
  82static inline const char *
  83dwc3_gadget_link_string(enum dwc3_link_state link_state)
  84{
  85        switch (link_state) {
  86        case DWC3_LINK_STATE_U0:
  87                return "U0";
  88        case DWC3_LINK_STATE_U1:
  89                return "U1";
  90        case DWC3_LINK_STATE_U2:
  91                return "U2";
  92        case DWC3_LINK_STATE_U3:
  93                return "U3";
  94        case DWC3_LINK_STATE_SS_DIS:
  95                return "SS.Disabled";
  96        case DWC3_LINK_STATE_RX_DET:
  97                return "RX.Detect";
  98        case DWC3_LINK_STATE_SS_INACT:
  99                return "SS.Inactive";
 100        case DWC3_LINK_STATE_POLL:
 101                return "Polling";
 102        case DWC3_LINK_STATE_RECOV:
 103                return "Recovery";
 104        case DWC3_LINK_STATE_HRESET:
 105                return "Hot Reset";
 106        case DWC3_LINK_STATE_CMPLY:
 107                return "Compliance";
 108        case DWC3_LINK_STATE_LPBK:
 109                return "Loopback";
 110        case DWC3_LINK_STATE_RESET:
 111                return "Reset";
 112        case DWC3_LINK_STATE_RESUME:
 113                return "Resume";
 114        default:
 115                return "UNKNOWN link state\n";
 116        }
 117}
 118
 119/**
 120 * dwc3_trb_type_string - returns TRB type as a string
 121 * @type: the type of the TRB
 122 */
 123static inline const char *dwc3_trb_type_string(unsigned int type)
 124{
 125        switch (type) {
 126        case DWC3_TRBCTL_NORMAL:
 127                return "normal";
 128        case DWC3_TRBCTL_CONTROL_SETUP:
 129                return "setup";
 130        case DWC3_TRBCTL_CONTROL_STATUS2:
 131                return "status2";
 132        case DWC3_TRBCTL_CONTROL_STATUS3:
 133                return "status3";
 134        case DWC3_TRBCTL_CONTROL_DATA:
 135                return "data";
 136        case DWC3_TRBCTL_ISOCHRONOUS_FIRST:
 137                return "isoc-first";
 138        case DWC3_TRBCTL_ISOCHRONOUS:
 139                return "isoc";
 140        case DWC3_TRBCTL_LINK_TRB:
 141                return "link";
 142        default:
 143                return "UNKNOWN";
 144        }
 145}
 146
 147static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
 148{
 149        switch (state) {
 150        case EP0_UNCONNECTED:
 151                return "Unconnected";
 152        case EP0_SETUP_PHASE:
 153                return "Setup Phase";
 154        case EP0_DATA_PHASE:
 155                return "Data Phase";
 156        case EP0_STATUS_PHASE:
 157                return "Status Phase";
 158        default:
 159                return "UNKNOWN";
 160        }
 161}
 162
 163/**
 164 * dwc3_gadget_event_string - returns event name
 165 * @event: the event code
 166 */
 167static inline const char *
 168dwc3_gadget_event_string(char *str, const struct dwc3_event_devt *event)
 169{
 170        enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK;
 171
 172        switch (event->type) {
 173        case DWC3_DEVICE_EVENT_DISCONNECT:
 174                sprintf(str, "Disconnect: [%s]",
 175                                dwc3_gadget_link_string(state));
 176                break;
 177        case DWC3_DEVICE_EVENT_RESET:
 178                sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state));
 179                break;
 180        case DWC3_DEVICE_EVENT_CONNECT_DONE:
 181                sprintf(str, "Connection Done [%s]",
 182                                dwc3_gadget_link_string(state));
 183                break;
 184        case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
 185                sprintf(str, "Link Change [%s]",
 186                                dwc3_gadget_link_string(state));
 187                break;
 188        case DWC3_DEVICE_EVENT_WAKEUP:
 189                sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state));
 190                break;
 191        case DWC3_DEVICE_EVENT_EOPF:
 192                sprintf(str, "End-Of-Frame [%s]",
 193                                dwc3_gadget_link_string(state));
 194                break;
 195        case DWC3_DEVICE_EVENT_SOF:
 196                sprintf(str, "Start-Of-Frame [%s]",
 197                                dwc3_gadget_link_string(state));
 198                break;
 199        case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
 200                sprintf(str, "Erratic Error [%s]",
 201                                dwc3_gadget_link_string(state));
 202                break;
 203        case DWC3_DEVICE_EVENT_CMD_CMPL:
 204                sprintf(str, "Command Complete [%s]",
 205                                dwc3_gadget_link_string(state));
 206                break;
 207        case DWC3_DEVICE_EVENT_OVERFLOW:
 208                sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state));
 209                break;
 210        default:
 211                sprintf(str, "UNKNOWN");
 212        }
 213
 214        return str;
 215}
 216
 217static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str)
 218{
 219        switch (t & USB_RECIP_MASK) {
 220        case USB_RECIP_INTERFACE:
 221                sprintf(str, "Get Interface Status(Intf = %d, Length = %d)",
 222                        i, l);
 223                break;
 224        case USB_RECIP_ENDPOINT:
 225                sprintf(str, "Get Endpoint Status(ep%d%s)",
 226                        i & ~USB_DIR_IN,
 227                        i & USB_DIR_IN ? "in" : "out");
 228                break;
 229        }
 230}
 231
 232static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v,
 233                                                 __u16 i, char *str)
 234{
 235        switch (t & USB_RECIP_MASK) {
 236        case USB_RECIP_DEVICE:
 237                sprintf(str, "%s Device Feature(%s%s)",
 238                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
 239                        ({char *s;
 240                                switch (v) {
 241                                case USB_DEVICE_SELF_POWERED:
 242                                        s = "Self Powered";
 243                                        break;
 244                                case USB_DEVICE_REMOTE_WAKEUP:
 245                                        s = "Remote Wakeup";
 246                                        break;
 247                                case USB_DEVICE_TEST_MODE:
 248                                        s = "Test Mode";
 249                                        break;
 250                                case USB_DEVICE_U1_ENABLE:
 251                                        s = "U1 Enable";
 252                                        break;
 253                                case USB_DEVICE_U2_ENABLE:
 254                                        s = "U2 Enable";
 255                                        break;
 256                                case USB_DEVICE_LTM_ENABLE:
 257                                        s = "LTM Enable";
 258                                        break;
 259                                default:
 260                                        s = "UNKNOWN";
 261                                } s; }),
 262                        v == USB_DEVICE_TEST_MODE ?
 263                        ({ char *s;
 264                                switch (i) {
 265                                case TEST_J:
 266                                        s = ": TEST_J";
 267                                        break;
 268                                case TEST_K:
 269                                        s = ": TEST_K";
 270                                        break;
 271                                case TEST_SE0_NAK:
 272                                        s = ": TEST_SE0_NAK";
 273                                        break;
 274                                case TEST_PACKET:
 275                                        s = ": TEST_PACKET";
 276                                        break;
 277                                case TEST_FORCE_EN:
 278                                        s = ": TEST_FORCE_EN";
 279                                        break;
 280                                default:
 281                                        s = ": UNKNOWN";
 282                                } s; }) : "");
 283                break;
 284        case USB_RECIP_INTERFACE:
 285                sprintf(str, "%s Interface Feature(%s)",
 286                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
 287                        v == USB_INTRF_FUNC_SUSPEND ?
 288                        "Function Suspend" : "UNKNOWN");
 289                break;
 290        case USB_RECIP_ENDPOINT:
 291                sprintf(str, "%s Endpoint Feature(%s ep%d%s)",
 292                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
 293                        v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
 294                        i & ~USB_DIR_IN,
 295                        i & USB_DIR_IN ? "in" : "out");
 296                break;
 297        }
 298}
 299
 300static inline void dwc3_decode_set_address(__u16 v, char *str)
 301{
 302        sprintf(str, "Set Address(Addr = %02x)", v);
 303}
 304
 305static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v,
 306                                                  __u16 i, __u16 l, char *str)
 307{
 308        sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)",
 309                b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
 310                ({ char *s;
 311                        switch (v >> 8) {
 312                        case USB_DT_DEVICE:
 313                                s = "Device";
 314                                break;
 315                        case USB_DT_CONFIG:
 316                                s = "Configuration";
 317                                break;
 318                        case USB_DT_STRING:
 319                                s = "String";
 320                                break;
 321                        case USB_DT_INTERFACE:
 322                                s = "Interface";
 323                                break;
 324                        case USB_DT_ENDPOINT:
 325                                s = "Endpoint";
 326                                break;
 327                        case USB_DT_DEVICE_QUALIFIER:
 328                                s = "Device Qualifier";
 329                                break;
 330                        case USB_DT_OTHER_SPEED_CONFIG:
 331                                s = "Other Speed Config";
 332                                break;
 333                        case USB_DT_INTERFACE_POWER:
 334                                s = "Interface Power";
 335                                break;
 336                        case USB_DT_OTG:
 337                                s = "OTG";
 338                                break;
 339                        case USB_DT_DEBUG:
 340                                s = "Debug";
 341                                break;
 342                        case USB_DT_INTERFACE_ASSOCIATION:
 343                                s = "Interface Association";
 344                                break;
 345                        case USB_DT_BOS:
 346                                s = "BOS";
 347                                break;
 348                        case USB_DT_DEVICE_CAPABILITY:
 349                                s = "Device Capability";
 350                                break;
 351                        case USB_DT_PIPE_USAGE:
 352                                s = "Pipe Usage";
 353                                break;
 354                        case USB_DT_SS_ENDPOINT_COMP:
 355                                s = "SS Endpoint Companion";
 356                                break;
 357                        case USB_DT_SSP_ISOC_ENDPOINT_COMP:
 358                                s = "SSP Isochronous Endpoint Companion";
 359                                break;
 360                        default:
 361                                s = "UNKNOWN";
 362                                break;
 363                        } s; }), v & 0xff, l);
 364}
 365
 366
 367static inline void dwc3_decode_get_configuration(__u16 l, char *str)
 368{
 369        sprintf(str, "Get Configuration(Length = %d)", l);
 370}
 371
 372static inline void dwc3_decode_set_configuration(__u8 v, char *str)
 373{
 374        sprintf(str, "Set Configuration(Config = %d)", v);
 375}
 376
 377static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str)
 378{
 379        sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l);
 380}
 381
 382static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str)
 383{
 384        sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v);
 385}
 386
 387static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str)
 388{
 389        sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l);
 390}
 391
 392static inline void dwc3_decode_set_sel(__u16 l, char *str)
 393{
 394        sprintf(str, "Set SEL(Length = %d)", l);
 395}
 396
 397static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str)
 398{
 399        sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v);
 400}
 401
 402/**
 403 * dwc3_decode_ctrl - returns a string represetion of ctrl request
 404 */
 405static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType,
 406                __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength)
 407{
 408        switch (bRequest) {
 409        case USB_REQ_GET_STATUS:
 410                dwc3_decode_get_status(bRequestType, wIndex, wLength, str);
 411                break;
 412        case USB_REQ_CLEAR_FEATURE:
 413        case USB_REQ_SET_FEATURE:
 414                dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue,
 415                                              wIndex, str);
 416                break;
 417        case USB_REQ_SET_ADDRESS:
 418                dwc3_decode_set_address(wValue, str);
 419                break;
 420        case USB_REQ_GET_DESCRIPTOR:
 421        case USB_REQ_SET_DESCRIPTOR:
 422                dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue,
 423                                               wIndex, wLength, str);
 424                break;
 425        case USB_REQ_GET_CONFIGURATION:
 426                dwc3_decode_get_configuration(wLength, str);
 427                break;
 428        case USB_REQ_SET_CONFIGURATION:
 429                dwc3_decode_set_configuration(wValue, str);
 430                break;
 431        case USB_REQ_GET_INTERFACE:
 432                dwc3_decode_get_intf(wIndex, wLength, str);
 433                break;
 434        case USB_REQ_SET_INTERFACE:
 435                dwc3_decode_set_intf(wValue, wIndex, str);
 436                break;
 437        case USB_REQ_SYNCH_FRAME:
 438                dwc3_decode_synch_frame(wIndex, wLength, str);
 439                break;
 440        case USB_REQ_SET_SEL:
 441                dwc3_decode_set_sel(wLength, str);
 442                break;
 443        case USB_REQ_SET_ISOCH_DELAY:
 444                dwc3_decode_set_isoch_delay(wValue, str);
 445                break;
 446        default:
 447                sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x",
 448                        bRequestType, bRequest,
 449                        cpu_to_le16(wValue) & 0xff,
 450                        cpu_to_le16(wValue) >> 8,
 451                        cpu_to_le16(wIndex) & 0xff,
 452                        cpu_to_le16(wIndex) >> 8,
 453                        cpu_to_le16(wLength) & 0xff,
 454                        cpu_to_le16(wLength) >> 8);
 455        }
 456
 457        return str;
 458}
 459
 460/**
 461 * dwc3_ep_event_string - returns event name
 462 * @event: then event code
 463 */
 464static inline const char *
 465dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event,
 466                     u32 ep0state)
 467{
 468        u8 epnum = event->endpoint_number;
 469        size_t len;
 470        int status;
 471        int ret;
 472
 473        ret = sprintf(str, "ep%d%s: ", epnum >> 1,
 474                        (epnum & 1) ? "in" : "out");
 475        if (ret < 0)
 476                return "UNKNOWN";
 477
 478        switch (event->endpoint_event) {
 479        case DWC3_DEPEVT_XFERCOMPLETE:
 480                strcat(str, "Transfer Complete");
 481                len = strlen(str);
 482
 483                if (epnum <= 1)
 484                        sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state));
 485                break;
 486        case DWC3_DEPEVT_XFERINPROGRESS:
 487                strcat(str, "Transfer In-Progress");
 488                break;
 489        case DWC3_DEPEVT_XFERNOTREADY:
 490                strcat(str, "Transfer Not Ready");
 491                status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE;
 492                strcat(str, status ? " (Active)" : " (Not Active)");
 493
 494                /* Control Endpoints */
 495                if (epnum <= 1) {
 496                        int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status);
 497
 498                        switch (phase) {
 499                        case DEPEVT_STATUS_CONTROL_DATA:
 500                                strcat(str, " [Data Phase]");
 501                                break;
 502                        case DEPEVT_STATUS_CONTROL_STATUS:
 503                                strcat(str, " [Status Phase]");
 504                        }
 505                }
 506                break;
 507        case DWC3_DEPEVT_RXTXFIFOEVT:
 508                strcat(str, "FIFO");
 509                break;
 510        case DWC3_DEPEVT_STREAMEVT:
 511                status = event->status;
 512
 513                switch (status) {
 514                case DEPEVT_STREAMEVT_FOUND:
 515                        sprintf(str + ret, " Stream %d Found",
 516                                        event->parameters);
 517                        break;
 518                case DEPEVT_STREAMEVT_NOTFOUND:
 519                default:
 520                        strcat(str, " Stream Not Found");
 521                        break;
 522                }
 523
 524                break;
 525        case DWC3_DEPEVT_EPCMDCMPLT:
 526                strcat(str, "Endpoint Command Complete");
 527                break;
 528        default:
 529                sprintf(str, "UNKNOWN");
 530        }
 531
 532        return str;
 533}
 534
 535/**
 536 * dwc3_gadget_event_type_string - return event name
 537 * @event: the event code
 538 */
 539static inline const char *dwc3_gadget_event_type_string(u8 event)
 540{
 541        switch (event) {
 542        case DWC3_DEVICE_EVENT_DISCONNECT:
 543                return "Disconnect";
 544        case DWC3_DEVICE_EVENT_RESET:
 545                return "Reset";
 546        case DWC3_DEVICE_EVENT_CONNECT_DONE:
 547                return "Connect Done";
 548        case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
 549                return "Link Status Change";
 550        case DWC3_DEVICE_EVENT_WAKEUP:
 551                return "Wake-Up";
 552        case DWC3_DEVICE_EVENT_HIBER_REQ:
 553                return "Hibernation";
 554        case DWC3_DEVICE_EVENT_EOPF:
 555                return "End of Periodic Frame";
 556        case DWC3_DEVICE_EVENT_SOF:
 557                return "Start of Frame";
 558        case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
 559                return "Erratic Error";
 560        case DWC3_DEVICE_EVENT_CMD_CMPL:
 561                return "Command Complete";
 562        case DWC3_DEVICE_EVENT_OVERFLOW:
 563                return "Overflow";
 564        default:
 565                return "UNKNOWN";
 566        }
 567}
 568
 569static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state)
 570{
 571        const union dwc3_event evt = (union dwc3_event) event;
 572
 573        if (evt.type.is_devspec)
 574                return dwc3_gadget_event_string(str, &evt.devt);
 575        else
 576                return dwc3_ep_event_string(str, &evt.depevt, ep0state);
 577}
 578
 579static inline const char *dwc3_ep_cmd_status_string(int status)
 580{
 581        switch (status) {
 582        case -ETIMEDOUT:
 583                return "Timed Out";
 584        case 0:
 585                return "Successful";
 586        case DEPEVT_TRANSFER_NO_RESOURCE:
 587                return "No Resource";
 588        case DEPEVT_TRANSFER_BUS_EXPIRY:
 589                return "Bus Expiry";
 590        default:
 591                return "UNKNOWN";
 592        }
 593}
 594
 595static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
 596{
 597        switch (status) {
 598        case -ETIMEDOUT:
 599                return "Timed Out";
 600        case 0:
 601                return "Successful";
 602        case 1:
 603                return "Error";
 604        default:
 605                return "UNKNOWN";
 606        }
 607}
 608
 609
 610#ifdef CONFIG_DEBUG_FS
 611extern void dwc3_debugfs_init(struct dwc3 *);
 612extern void dwc3_debugfs_exit(struct dwc3 *);
 613#else
 614static inline void dwc3_debugfs_init(struct dwc3 *d)
 615{  }
 616static inline void dwc3_debugfs_exit(struct dwc3 *d)
 617{  }
 618#endif
 619#endif /* __DWC3_DEBUG_H */
 620