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