linux/drivers/usb/host/xhci-debugfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * xhci-debugfs.c - xHCI debugfs interface
   4 *
   5 * Copyright (C) 2017 Intel Corporation
   6 *
   7 * Author: Lu Baolu <baolu.lu@linux.intel.com>
   8 */
   9
  10#include <linux/slab.h>
  11#include <linux/uaccess.h>
  12
  13#include "xhci.h"
  14#include "xhci-debugfs.h"
  15
  16static const struct debugfs_reg32 xhci_cap_regs[] = {
  17        dump_register(CAPLENGTH),
  18        dump_register(HCSPARAMS1),
  19        dump_register(HCSPARAMS2),
  20        dump_register(HCSPARAMS3),
  21        dump_register(HCCPARAMS1),
  22        dump_register(DOORBELLOFF),
  23        dump_register(RUNTIMEOFF),
  24        dump_register(HCCPARAMS2),
  25};
  26
  27static const struct debugfs_reg32 xhci_op_regs[] = {
  28        dump_register(USBCMD),
  29        dump_register(USBSTS),
  30        dump_register(PAGESIZE),
  31        dump_register(DNCTRL),
  32        dump_register(CRCR),
  33        dump_register(DCBAAP_LOW),
  34        dump_register(DCBAAP_HIGH),
  35        dump_register(CONFIG),
  36};
  37
  38static const struct debugfs_reg32 xhci_runtime_regs[] = {
  39        dump_register(MFINDEX),
  40        dump_register(IR0_IMAN),
  41        dump_register(IR0_IMOD),
  42        dump_register(IR0_ERSTSZ),
  43        dump_register(IR0_ERSTBA_LOW),
  44        dump_register(IR0_ERSTBA_HIGH),
  45        dump_register(IR0_ERDP_LOW),
  46        dump_register(IR0_ERDP_HIGH),
  47};
  48
  49static const struct debugfs_reg32 xhci_extcap_legsup[] = {
  50        dump_register(EXTCAP_USBLEGSUP),
  51        dump_register(EXTCAP_USBLEGCTLSTS),
  52};
  53
  54static const struct debugfs_reg32 xhci_extcap_protocol[] = {
  55        dump_register(EXTCAP_REVISION),
  56        dump_register(EXTCAP_NAME),
  57        dump_register(EXTCAP_PORTINFO),
  58        dump_register(EXTCAP_PORTTYPE),
  59        dump_register(EXTCAP_MANTISSA1),
  60        dump_register(EXTCAP_MANTISSA2),
  61        dump_register(EXTCAP_MANTISSA3),
  62        dump_register(EXTCAP_MANTISSA4),
  63        dump_register(EXTCAP_MANTISSA5),
  64        dump_register(EXTCAP_MANTISSA6),
  65};
  66
  67static const struct debugfs_reg32 xhci_extcap_dbc[] = {
  68        dump_register(EXTCAP_DBC_CAPABILITY),
  69        dump_register(EXTCAP_DBC_DOORBELL),
  70        dump_register(EXTCAP_DBC_ERSTSIZE),
  71        dump_register(EXTCAP_DBC_ERST_LOW),
  72        dump_register(EXTCAP_DBC_ERST_HIGH),
  73        dump_register(EXTCAP_DBC_ERDP_LOW),
  74        dump_register(EXTCAP_DBC_ERDP_HIGH),
  75        dump_register(EXTCAP_DBC_CONTROL),
  76        dump_register(EXTCAP_DBC_STATUS),
  77        dump_register(EXTCAP_DBC_PORTSC),
  78        dump_register(EXTCAP_DBC_CONT_LOW),
  79        dump_register(EXTCAP_DBC_CONT_HIGH),
  80        dump_register(EXTCAP_DBC_DEVINFO1),
  81        dump_register(EXTCAP_DBC_DEVINFO2),
  82};
  83
  84static struct dentry *xhci_debugfs_root;
  85
  86static struct xhci_regset *xhci_debugfs_alloc_regset(struct xhci_hcd *xhci)
  87{
  88        struct xhci_regset      *regset;
  89
  90        regset = kzalloc(sizeof(*regset), GFP_KERNEL);
  91        if (!regset)
  92                return NULL;
  93
  94        /*
  95         * The allocation and free of regset are executed in order.
  96         * We needn't a lock here.
  97         */
  98        INIT_LIST_HEAD(&regset->list);
  99        list_add_tail(&regset->list, &xhci->regset_list);
 100
 101        return regset;
 102}
 103
 104static void xhci_debugfs_free_regset(struct xhci_regset *regset)
 105{
 106        if (!regset)
 107                return;
 108
 109        list_del(&regset->list);
 110        kfree(regset);
 111}
 112
 113static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base,
 114                                const struct debugfs_reg32 *regs,
 115                                size_t nregs, struct dentry *parent,
 116                                const char *fmt, ...)
 117{
 118        struct xhci_regset      *rgs;
 119        va_list                 args;
 120        struct debugfs_regset32 *regset;
 121        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
 122
 123        rgs = xhci_debugfs_alloc_regset(xhci);
 124        if (!rgs)
 125                return;
 126
 127        va_start(args, fmt);
 128        vsnprintf(rgs->name, sizeof(rgs->name), fmt, args);
 129        va_end(args);
 130
 131        regset = &rgs->regset;
 132        regset->regs = regs;
 133        regset->nregs = nregs;
 134        regset->base = hcd->regs + base;
 135
 136        debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset);
 137}
 138
 139static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id,
 140                                       const struct debugfs_reg32 *regs,
 141                                       size_t n, const char *cap_name)
 142{
 143        u32                     offset;
 144        int                     index = 0;
 145        size_t                  psic, nregs = n;
 146        void __iomem            *base = &xhci->cap_regs->hc_capbase;
 147
 148        offset = xhci_find_next_ext_cap(base, 0, cap_id);
 149        while (offset) {
 150                if (cap_id == XHCI_EXT_CAPS_PROTOCOL) {
 151                        psic = XHCI_EXT_PORT_PSIC(readl(base + offset + 8));
 152                        nregs = min(4 + psic, n);
 153                }
 154
 155                xhci_debugfs_regset(xhci, offset, regs, nregs,
 156                                    xhci->debugfs_root, "%s:%02d",
 157                                    cap_name, index);
 158                offset = xhci_find_next_ext_cap(base, offset, cap_id);
 159                index++;
 160        }
 161}
 162
 163static int xhci_ring_enqueue_show(struct seq_file *s, void *unused)
 164{
 165        dma_addr_t              dma;
 166        struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
 167
 168        dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);
 169        seq_printf(s, "%pad\n", &dma);
 170
 171        return 0;
 172}
 173
 174static int xhci_ring_dequeue_show(struct seq_file *s, void *unused)
 175{
 176        dma_addr_t              dma;
 177        struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
 178
 179        dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
 180        seq_printf(s, "%pad\n", &dma);
 181
 182        return 0;
 183}
 184
 185static int xhci_ring_cycle_show(struct seq_file *s, void *unused)
 186{
 187        struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
 188
 189        seq_printf(s, "%d\n", ring->cycle_state);
 190
 191        return 0;
 192}
 193
 194static void xhci_ring_dump_segment(struct seq_file *s,
 195                                   struct xhci_segment *seg)
 196{
 197        int                     i;
 198        dma_addr_t              dma;
 199        union xhci_trb          *trb;
 200
 201        for (i = 0; i < TRBS_PER_SEGMENT; i++) {
 202                trb = &seg->trbs[i];
 203                dma = seg->dma + i * sizeof(*trb);
 204                seq_printf(s, "%pad: %s\n", &dma,
 205                           xhci_decode_trb(trb->generic.field[0],
 206                                           trb->generic.field[1],
 207                                           trb->generic.field[2],
 208                                           trb->generic.field[3]));
 209        }
 210}
 211
 212static int xhci_ring_trb_show(struct seq_file *s, void *unused)
 213{
 214        int                     i;
 215        struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
 216        struct xhci_segment     *seg = ring->first_seg;
 217
 218        for (i = 0; i < ring->num_segs; i++) {
 219                xhci_ring_dump_segment(s, seg);
 220                seg = seg->next;
 221        }
 222
 223        return 0;
 224}
 225
 226static struct xhci_file_map ring_files[] = {
 227        {"enqueue",             xhci_ring_enqueue_show, },
 228        {"dequeue",             xhci_ring_dequeue_show, },
 229        {"cycle",               xhci_ring_cycle_show, },
 230        {"trbs",                xhci_ring_trb_show, },
 231};
 232
 233static int xhci_ring_open(struct inode *inode, struct file *file)
 234{
 235        int                     i;
 236        struct xhci_file_map    *f_map;
 237        const char              *file_name = file_dentry(file)->d_iname;
 238
 239        for (i = 0; i < ARRAY_SIZE(ring_files); i++) {
 240                f_map = &ring_files[i];
 241
 242                if (strcmp(f_map->name, file_name) == 0)
 243                        break;
 244        }
 245
 246        return single_open(file, f_map->show, inode->i_private);
 247}
 248
 249static const struct file_operations xhci_ring_fops = {
 250        .open                   = xhci_ring_open,
 251        .read                   = seq_read,
 252        .llseek                 = seq_lseek,
 253        .release                = single_release,
 254};
 255
 256static int xhci_slot_context_show(struct seq_file *s, void *unused)
 257{
 258        struct xhci_hcd         *xhci;
 259        struct xhci_slot_ctx    *slot_ctx;
 260        struct xhci_slot_priv   *priv = s->private;
 261        struct xhci_virt_device *dev = priv->dev;
 262
 263        xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
 264        slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
 265        seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma,
 266                   xhci_decode_slot_context(slot_ctx->dev_info,
 267                                            slot_ctx->dev_info2,
 268                                            slot_ctx->tt_info,
 269                                            slot_ctx->dev_state));
 270
 271        return 0;
 272}
 273
 274static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
 275{
 276        int                     dci;
 277        dma_addr_t              dma;
 278        struct xhci_hcd         *xhci;
 279        struct xhci_ep_ctx      *ep_ctx;
 280        struct xhci_slot_priv   *priv = s->private;
 281        struct xhci_virt_device *dev = priv->dev;
 282
 283        xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
 284
 285        for (dci = 1; dci < 32; dci++) {
 286                ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
 287                dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
 288                seq_printf(s, "%pad: %s\n", &dma,
 289                           xhci_decode_ep_context(ep_ctx->ep_info,
 290                                                  ep_ctx->ep_info2,
 291                                                  ep_ctx->deq,
 292                                                  ep_ctx->tx_info));
 293        }
 294
 295        return 0;
 296}
 297
 298static int xhci_device_name_show(struct seq_file *s, void *unused)
 299{
 300        struct xhci_slot_priv   *priv = s->private;
 301        struct xhci_virt_device *dev = priv->dev;
 302
 303        seq_printf(s, "%s\n", dev_name(&dev->udev->dev));
 304
 305        return 0;
 306}
 307
 308static struct xhci_file_map context_files[] = {
 309        {"name",                xhci_device_name_show, },
 310        {"slot-context",        xhci_slot_context_show, },
 311        {"ep-context",          xhci_endpoint_context_show, },
 312};
 313
 314static int xhci_context_open(struct inode *inode, struct file *file)
 315{
 316        int                     i;
 317        struct xhci_file_map    *f_map;
 318        const char              *file_name = file_dentry(file)->d_iname;
 319
 320        for (i = 0; i < ARRAY_SIZE(context_files); i++) {
 321                f_map = &context_files[i];
 322
 323                if (strcmp(f_map->name, file_name) == 0)
 324                        break;
 325        }
 326
 327        return single_open(file, f_map->show, inode->i_private);
 328}
 329
 330static const struct file_operations xhci_context_fops = {
 331        .open                   = xhci_context_open,
 332        .read                   = seq_read,
 333        .llseek                 = seq_lseek,
 334        .release                = single_release,
 335};
 336
 337
 338
 339static int xhci_portsc_show(struct seq_file *s, void *unused)
 340{
 341        struct xhci_port        *port = s->private;
 342        u32                     portsc;
 343
 344        portsc = readl(port->addr);
 345        seq_printf(s, "%s\n", xhci_decode_portsc(portsc));
 346
 347        return 0;
 348}
 349
 350static int xhci_port_open(struct inode *inode, struct file *file)
 351{
 352        return single_open(file, xhci_portsc_show, inode->i_private);
 353}
 354
 355static ssize_t xhci_port_write(struct file *file,  const char __user *ubuf,
 356                               size_t count, loff_t *ppos)
 357{
 358        struct seq_file         *s = file->private_data;
 359        struct xhci_port        *port = s->private;
 360        struct xhci_hcd         *xhci = hcd_to_xhci(port->rhub->hcd);
 361        char                    buf[32];
 362        u32                     portsc;
 363        unsigned long           flags;
 364
 365        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 366                return -EFAULT;
 367
 368        if (!strncmp(buf, "compliance", 10)) {
 369                /* If CTC is clear, compliance is enabled by default */
 370                if (!HCC2_CTC(xhci->hcc_params2))
 371                        return count;
 372                spin_lock_irqsave(&xhci->lock, flags);
 373                /* compliance mode can only be enabled on ports in RxDetect */
 374                portsc = readl(port->addr);
 375                if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
 376                        spin_unlock_irqrestore(&xhci->lock, flags);
 377                        return -EPERM;
 378                }
 379                portsc = xhci_port_state_to_neutral(portsc);
 380                portsc &= ~PORT_PLS_MASK;
 381                portsc |= PORT_LINK_STROBE | XDEV_COMP_MODE;
 382                writel(portsc, port->addr);
 383                spin_unlock_irqrestore(&xhci->lock, flags);
 384        } else {
 385                return -EINVAL;
 386        }
 387        return count;
 388}
 389
 390static const struct file_operations port_fops = {
 391        .open                   = xhci_port_open,
 392        .write                  = xhci_port_write,
 393        .read                   = seq_read,
 394        .llseek                 = seq_lseek,
 395        .release                = single_release,
 396};
 397
 398static void xhci_debugfs_create_files(struct xhci_hcd *xhci,
 399                                      struct xhci_file_map *files,
 400                                      size_t nentries, void *data,
 401                                      struct dentry *parent,
 402                                      const struct file_operations *fops)
 403{
 404        int                     i;
 405
 406        for (i = 0; i < nentries; i++)
 407                debugfs_create_file(files[i].name, 0444, parent, data, fops);
 408}
 409
 410static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci,
 411                                                   struct xhci_ring **ring,
 412                                                   const char *name,
 413                                                   struct dentry *parent)
 414{
 415        struct dentry           *dir;
 416
 417        dir = debugfs_create_dir(name, parent);
 418        xhci_debugfs_create_files(xhci, ring_files, ARRAY_SIZE(ring_files),
 419                                  ring, dir, &xhci_ring_fops);
 420
 421        return dir;
 422}
 423
 424static void xhci_debugfs_create_context_files(struct xhci_hcd *xhci,
 425                                              struct dentry *parent,
 426                                              int slot_id)
 427{
 428        struct xhci_virt_device *dev = xhci->devs[slot_id];
 429
 430        xhci_debugfs_create_files(xhci, context_files,
 431                                  ARRAY_SIZE(context_files),
 432                                  dev->debugfs_private,
 433                                  parent, &xhci_context_fops);
 434}
 435
 436void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
 437                                  struct xhci_virt_device *dev,
 438                                  int ep_index)
 439{
 440        struct xhci_ep_priv     *epriv;
 441        struct xhci_slot_priv   *spriv = dev->debugfs_private;
 442
 443        if (spriv->eps[ep_index])
 444                return;
 445
 446        epriv = kzalloc(sizeof(*epriv), GFP_KERNEL);
 447        if (!epriv)
 448                return;
 449
 450        snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
 451        epriv->root = xhci_debugfs_create_ring_dir(xhci,
 452                                                   &dev->eps[ep_index].ring,
 453                                                   epriv->name,
 454                                                   spriv->root);
 455        spriv->eps[ep_index] = epriv;
 456}
 457
 458void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci,
 459                                  struct xhci_virt_device *dev,
 460                                  int ep_index)
 461{
 462        struct xhci_ep_priv     *epriv;
 463        struct xhci_slot_priv   *spriv = dev->debugfs_private;
 464
 465        if (!spriv || !spriv->eps[ep_index])
 466                return;
 467
 468        epriv = spriv->eps[ep_index];
 469        debugfs_remove_recursive(epriv->root);
 470        spriv->eps[ep_index] = NULL;
 471        kfree(epriv);
 472}
 473
 474void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id)
 475{
 476        struct xhci_slot_priv   *priv;
 477        struct xhci_virt_device *dev = xhci->devs[slot_id];
 478
 479        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 480        if (!priv)
 481                return;
 482
 483        snprintf(priv->name, sizeof(priv->name), "%02d", slot_id);
 484        priv->root = debugfs_create_dir(priv->name, xhci->debugfs_slots);
 485        priv->dev = dev;
 486        dev->debugfs_private = priv;
 487
 488        xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring,
 489                                     "ep00", priv->root);
 490
 491        xhci_debugfs_create_context_files(xhci, priv->root, slot_id);
 492}
 493
 494void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id)
 495{
 496        int                     i;
 497        struct xhci_slot_priv   *priv;
 498        struct xhci_virt_device *dev = xhci->devs[slot_id];
 499
 500        if (!dev || !dev->debugfs_private)
 501                return;
 502
 503        priv = dev->debugfs_private;
 504
 505        debugfs_remove_recursive(priv->root);
 506
 507        for (i = 0; i < 31; i++)
 508                kfree(priv->eps[i]);
 509
 510        kfree(priv);
 511        dev->debugfs_private = NULL;
 512}
 513
 514static void xhci_debugfs_create_ports(struct xhci_hcd *xhci,
 515                                      struct dentry *parent)
 516{
 517        unsigned int            num_ports;
 518        char                    port_name[8];
 519        struct xhci_port        *port;
 520        struct dentry           *dir;
 521
 522        num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
 523
 524        parent = debugfs_create_dir("ports", parent);
 525
 526        while (num_ports--) {
 527                scnprintf(port_name, sizeof(port_name), "port%02d",
 528                          num_ports + 1);
 529                dir = debugfs_create_dir(port_name, parent);
 530                port = &xhci->hw_ports[num_ports];
 531                debugfs_create_file("portsc", 0644, dir, port, &port_fops);
 532        }
 533}
 534
 535void xhci_debugfs_init(struct xhci_hcd *xhci)
 536{
 537        struct device           *dev = xhci_to_hcd(xhci)->self.controller;
 538
 539        xhci->debugfs_root = debugfs_create_dir(dev_name(dev),
 540                                                xhci_debugfs_root);
 541
 542        INIT_LIST_HEAD(&xhci->regset_list);
 543
 544        xhci_debugfs_regset(xhci,
 545                            0,
 546                            xhci_cap_regs, ARRAY_SIZE(xhci_cap_regs),
 547                            xhci->debugfs_root, "reg-cap");
 548
 549        xhci_debugfs_regset(xhci,
 550                            HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)),
 551                            xhci_op_regs, ARRAY_SIZE(xhci_op_regs),
 552                            xhci->debugfs_root, "reg-op");
 553
 554        xhci_debugfs_regset(xhci,
 555                            readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK,
 556                            xhci_runtime_regs, ARRAY_SIZE(xhci_runtime_regs),
 557                            xhci->debugfs_root, "reg-runtime");
 558
 559        xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_LEGACY,
 560                                   xhci_extcap_legsup,
 561                                   ARRAY_SIZE(xhci_extcap_legsup),
 562                                   "reg-ext-legsup");
 563
 564        xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_PROTOCOL,
 565                                   xhci_extcap_protocol,
 566                                   ARRAY_SIZE(xhci_extcap_protocol),
 567                                   "reg-ext-protocol");
 568
 569        xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_DEBUG,
 570                                   xhci_extcap_dbc,
 571                                   ARRAY_SIZE(xhci_extcap_dbc),
 572                                   "reg-ext-dbc");
 573
 574        xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring,
 575                                     "command-ring",
 576                                     xhci->debugfs_root);
 577
 578        xhci_debugfs_create_ring_dir(xhci, &xhci->event_ring,
 579                                     "event-ring",
 580                                     xhci->debugfs_root);
 581
 582        xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root);
 583
 584        xhci_debugfs_create_ports(xhci, xhci->debugfs_root);
 585}
 586
 587void xhci_debugfs_exit(struct xhci_hcd *xhci)
 588{
 589        struct xhci_regset      *rgs, *tmp;
 590
 591        debugfs_remove_recursive(xhci->debugfs_root);
 592        xhci->debugfs_root = NULL;
 593        xhci->debugfs_slots = NULL;
 594
 595        list_for_each_entry_safe(rgs, tmp, &xhci->regset_list, list)
 596                xhci_debugfs_free_regset(rgs);
 597}
 598
 599void __init xhci_debugfs_create_root(void)
 600{
 601        xhci_debugfs_root = debugfs_create_dir("xhci", usb_debug_root);
 602}
 603
 604void __exit xhci_debugfs_remove_root(void)
 605{
 606        debugfs_remove_recursive(xhci_debugfs_root);
 607        xhci_debugfs_root = NULL;
 608}
 609