LCOV - code coverage report
Current view: top level - drivers/usb/host - xhci-debugfs.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 3 225 1.3 %
Date: 2022-03-28 13:20:08 Functions: 1 24 4.2 %
Branches: 0 64 0.0 %

           Branch data     Line data    Source code
       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                 :            : 
      16                 :            : static 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                 :            : 
      27                 :            : static 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                 :            : 
      38                 :            : static 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                 :            : 
      49                 :            : static const struct debugfs_reg32 xhci_extcap_legsup[] = {
      50                 :            :         dump_register(EXTCAP_USBLEGSUP),
      51                 :            :         dump_register(EXTCAP_USBLEGCTLSTS),
      52                 :            : };
      53                 :            : 
      54                 :            : static 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                 :            : 
      67                 :            : static 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                 :            : 
      84                 :            : static struct dentry *xhci_debugfs_root;
      85                 :            : 
      86                 :          0 : static struct xhci_regset *xhci_debugfs_alloc_regset(struct xhci_hcd *xhci)
      87                 :            : {
      88                 :          0 :         struct xhci_regset      *regset;
      89                 :            : 
      90                 :          0 :         regset = kzalloc(sizeof(*regset), GFP_KERNEL);
      91         [ #  # ]:          0 :         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                 :          0 :         INIT_LIST_HEAD(&regset->list);
      99                 :          0 :         list_add_tail(&regset->list, &xhci->regset_list);
     100                 :            : 
     101                 :          0 :         return regset;
     102                 :            : }
     103                 :            : 
     104                 :          0 : static void xhci_debugfs_free_regset(struct xhci_regset *regset)
     105                 :            : {
     106                 :          0 :         if (!regset)
     107                 :            :                 return;
     108                 :            : 
     109                 :          0 :         list_del(&regset->list);
     110                 :          0 :         kfree(regset);
     111                 :            : }
     112                 :            : 
     113                 :          0 : static 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                 :          0 :         struct xhci_regset      *rgs;
     119                 :          0 :         va_list                 args;
     120                 :          0 :         struct debugfs_regset32 *regset;
     121                 :          0 :         struct usb_hcd          *hcd = xhci_to_hcd(xhci);
     122                 :            : 
     123                 :          0 :         rgs = xhci_debugfs_alloc_regset(xhci);
     124         [ #  # ]:          0 :         if (!rgs)
     125                 :          0 :                 return;
     126                 :            : 
     127                 :          0 :         va_start(args, fmt);
     128                 :          0 :         vsnprintf(rgs->name, sizeof(rgs->name), fmt, args);
     129                 :          0 :         va_end(args);
     130                 :            : 
     131                 :          0 :         regset = &rgs->regset;
     132                 :          0 :         regset->regs = regs;
     133                 :          0 :         regset->nregs = nregs;
     134                 :          0 :         regset->base = hcd->regs + base;
     135                 :            : 
     136                 :          0 :         debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset);
     137                 :            : }
     138                 :            : 
     139                 :          0 : static 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                 :          0 :         u32                     offset;
     144                 :          0 :         int                     index = 0;
     145                 :          0 :         size_t                  psic, nregs = n;
     146                 :          0 :         void __iomem            *base = &xhci->cap_regs->hc_capbase;
     147                 :            : 
     148                 :          0 :         offset = xhci_find_next_ext_cap(base, 0, cap_id);
     149         [ #  # ]:          0 :         while (offset) {
     150         [ #  # ]:          0 :                 if (cap_id == XHCI_EXT_CAPS_PROTOCOL) {
     151                 :          0 :                         psic = XHCI_EXT_PORT_PSIC(readl(base + offset + 8));
     152                 :          0 :                         nregs = min(4 + psic, n);
     153                 :            :                 }
     154                 :            : 
     155                 :          0 :                 xhci_debugfs_regset(xhci, offset, regs, nregs,
     156                 :            :                                     xhci->debugfs_root, "%s:%02d",
     157                 :            :                                     cap_name, index);
     158                 :          0 :                 offset = xhci_find_next_ext_cap(base, offset, cap_id);
     159                 :          0 :                 index++;
     160                 :            :         }
     161                 :          0 : }
     162                 :            : 
     163                 :          0 : static int xhci_ring_enqueue_show(struct seq_file *s, void *unused)
     164                 :            : {
     165                 :          0 :         dma_addr_t              dma;
     166                 :          0 :         struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
     167                 :            : 
     168                 :          0 :         dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);
     169                 :          0 :         seq_printf(s, "%pad\n", &dma);
     170                 :            : 
     171                 :          0 :         return 0;
     172                 :            : }
     173                 :            : 
     174                 :          0 : static int xhci_ring_dequeue_show(struct seq_file *s, void *unused)
     175                 :            : {
     176                 :          0 :         dma_addr_t              dma;
     177                 :          0 :         struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
     178                 :            : 
     179                 :          0 :         dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
     180                 :          0 :         seq_printf(s, "%pad\n", &dma);
     181                 :            : 
     182                 :          0 :         return 0;
     183                 :            : }
     184                 :            : 
     185                 :          0 : static int xhci_ring_cycle_show(struct seq_file *s, void *unused)
     186                 :            : {
     187                 :          0 :         struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
     188                 :            : 
     189                 :          0 :         seq_printf(s, "%d\n", ring->cycle_state);
     190                 :            : 
     191                 :          0 :         return 0;
     192                 :            : }
     193                 :            : 
     194                 :            : static 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(le32_to_cpu(trb->generic.field[0]),
     206                 :            :                                            le32_to_cpu(trb->generic.field[1]),
     207                 :            :                                            le32_to_cpu(trb->generic.field[2]),
     208                 :            :                                            le32_to_cpu(trb->generic.field[3])));
     209                 :            :         }
     210                 :            : }
     211                 :            : 
     212                 :          0 : static int xhci_ring_trb_show(struct seq_file *s, void *unused)
     213                 :            : {
     214                 :          0 :         int                     i;
     215                 :          0 :         struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
     216                 :          0 :         struct xhci_segment     *seg = ring->first_seg;
     217                 :            : 
     218         [ #  # ]:          0 :         for (i = 0; i < ring->num_segs; i++) {
     219                 :          0 :                 xhci_ring_dump_segment(s, seg);
     220                 :          0 :                 seg = seg->next;
     221                 :            :         }
     222                 :            : 
     223                 :          0 :         return 0;
     224                 :            : }
     225                 :            : 
     226                 :            : static 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                 :            : 
     233                 :          0 : static int xhci_ring_open(struct inode *inode, struct file *file)
     234                 :            : {
     235                 :          0 :         int                     i;
     236                 :          0 :         struct xhci_file_map    *f_map;
     237         [ #  # ]:          0 :         const char              *file_name = file_dentry(file)->d_iname;
     238                 :            : 
     239         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ring_files); i++) {
     240                 :          0 :                 f_map = &ring_files[i];
     241                 :            : 
     242         [ #  # ]:          0 :                 if (strcmp(f_map->name, file_name) == 0)
     243                 :            :                         break;
     244                 :            :         }
     245                 :            : 
     246                 :          0 :         return single_open(file, f_map->show, inode->i_private);
     247                 :            : }
     248                 :            : 
     249                 :            : static 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                 :            : 
     256                 :          0 : static int xhci_slot_context_show(struct seq_file *s, void *unused)
     257                 :            : {
     258                 :          0 :         struct xhci_hcd         *xhci;
     259                 :          0 :         struct xhci_slot_ctx    *slot_ctx;
     260                 :          0 :         struct xhci_slot_priv   *priv = s->private;
     261                 :          0 :         struct xhci_virt_device *dev = priv->dev;
     262                 :            : 
     263                 :          0 :         xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
     264                 :          0 :         slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
     265                 :          0 :         seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma,
     266                 :          0 :                    xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info),
     267                 :          0 :                                             le32_to_cpu(slot_ctx->dev_info2),
     268                 :          0 :                                             le32_to_cpu(slot_ctx->tt_info),
     269                 :          0 :                                             le32_to_cpu(slot_ctx->dev_state)));
     270                 :            : 
     271                 :          0 :         return 0;
     272                 :            : }
     273                 :            : 
     274                 :          0 : static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
     275                 :            : {
     276                 :          0 :         int                     dci;
     277                 :          0 :         dma_addr_t              dma;
     278                 :          0 :         struct xhci_hcd         *xhci;
     279                 :          0 :         struct xhci_ep_ctx      *ep_ctx;
     280                 :          0 :         struct xhci_slot_priv   *priv = s->private;
     281                 :          0 :         struct xhci_virt_device *dev = priv->dev;
     282                 :            : 
     283                 :          0 :         xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
     284                 :            : 
     285         [ #  # ]:          0 :         for (dci = 1; dci < 32; dci++) {
     286                 :          0 :                 ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
     287         [ #  # ]:          0 :                 dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
     288                 :          0 :                 seq_printf(s, "%pad: %s\n", &dma,
     289                 :          0 :                            xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
     290                 :          0 :                                                   le32_to_cpu(ep_ctx->ep_info2),
     291                 :          0 :                                                   le64_to_cpu(ep_ctx->deq),
     292                 :          0 :                                                   le32_to_cpu(ep_ctx->tx_info)));
     293                 :            :         }
     294                 :            : 
     295                 :          0 :         return 0;
     296                 :            : }
     297                 :            : 
     298                 :          0 : static int xhci_device_name_show(struct seq_file *s, void *unused)
     299                 :            : {
     300                 :          0 :         struct xhci_slot_priv   *priv = s->private;
     301                 :          0 :         struct xhci_virt_device *dev = priv->dev;
     302                 :            : 
     303         [ #  # ]:          0 :         seq_printf(s, "%s\n", dev_name(&dev->udev->dev));
     304                 :            : 
     305                 :          0 :         return 0;
     306                 :            : }
     307                 :            : 
     308                 :            : static 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                 :            : 
     314                 :          0 : static int xhci_context_open(struct inode *inode, struct file *file)
     315                 :            : {
     316                 :          0 :         int                     i;
     317                 :          0 :         struct xhci_file_map    *f_map;
     318         [ #  # ]:          0 :         const char              *file_name = file_dentry(file)->d_iname;
     319                 :            : 
     320         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(context_files); i++) {
     321                 :          0 :                 f_map = &context_files[i];
     322                 :            : 
     323         [ #  # ]:          0 :                 if (strcmp(f_map->name, file_name) == 0)
     324                 :            :                         break;
     325                 :            :         }
     326                 :            : 
     327                 :          0 :         return single_open(file, f_map->show, inode->i_private);
     328                 :            : }
     329                 :            : 
     330                 :            : static 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                 :            : 
     339                 :          0 : static int xhci_portsc_show(struct seq_file *s, void *unused)
     340                 :            : {
     341                 :          0 :         struct xhci_port        *port = s->private;
     342                 :          0 :         u32                     portsc;
     343                 :            : 
     344                 :          0 :         portsc = readl(port->addr);
     345                 :          0 :         seq_printf(s, "%s\n", xhci_decode_portsc(portsc));
     346                 :            : 
     347                 :          0 :         return 0;
     348                 :            : }
     349                 :            : 
     350                 :          0 : static int xhci_port_open(struct inode *inode, struct file *file)
     351                 :            : {
     352                 :          0 :         return single_open(file, xhci_portsc_show, inode->i_private);
     353                 :            : }
     354                 :            : 
     355                 :          0 : static ssize_t xhci_port_write(struct file *file,  const char __user *ubuf,
     356                 :            :                                size_t count, loff_t *ppos)
     357                 :            : {
     358                 :          0 :         struct seq_file         *s = file->private_data;
     359                 :          0 :         struct xhci_port        *port = s->private;
     360                 :          0 :         struct xhci_hcd         *xhci = hcd_to_xhci(port->rhub->hcd);
     361                 :          0 :         char                    buf[32];
     362                 :          0 :         u32                     portsc;
     363                 :          0 :         unsigned long           flags;
     364                 :            : 
     365         [ #  # ]:          0 :         if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
     366                 :            :                 return -EFAULT;
     367                 :            : 
     368         [ #  # ]:          0 :         if (!strncmp(buf, "compliance", 10)) {
     369                 :            :                 /* If CTC is clear, compliance is enabled by default */
     370         [ #  # ]:          0 :                 if (!HCC2_CTC(xhci->hcc_params2))
     371                 :          0 :                         return count;
     372                 :          0 :                 spin_lock_irqsave(&xhci->lock, flags);
     373                 :            :                 /* compliance mode can only be enabled on ports in RxDetect */
     374                 :          0 :                 portsc = readl(port->addr);
     375         [ #  # ]:          0 :                 if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
     376                 :          0 :                         spin_unlock_irqrestore(&xhci->lock, flags);
     377                 :          0 :                         return -EPERM;
     378                 :            :                 }
     379                 :          0 :                 portsc = xhci_port_state_to_neutral(portsc);
     380                 :          0 :                 portsc &= ~PORT_PLS_MASK;
     381                 :          0 :                 portsc |= PORT_LINK_STROBE | XDEV_COMP_MODE;
     382                 :          0 :                 writel(portsc, port->addr);
     383                 :          0 :                 spin_unlock_irqrestore(&xhci->lock, flags);
     384                 :            :         } else {
     385                 :            :                 return -EINVAL;
     386                 :            :         }
     387                 :          0 :         return count;
     388                 :            : }
     389                 :            : 
     390                 :            : static 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                 :            : 
     398                 :          0 : static 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         [ #  # ]:          0 :         for (i = 0; i < nentries; i++)
     407                 :          0 :                 debugfs_create_file(files[i].name, 0444, parent, data, fops);
     408                 :            : }
     409                 :            : 
     410                 :            : static 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                 :            : 
     424                 :          0 : static void xhci_debugfs_create_context_files(struct xhci_hcd *xhci,
     425                 :            :                                               struct dentry *parent,
     426                 :            :                                               int slot_id)
     427                 :            : {
     428                 :          0 :         struct xhci_virt_device *dev = xhci->devs[slot_id];
     429                 :            : 
     430                 :          0 :         xhci_debugfs_create_files(xhci, context_files,
     431                 :            :                                   ARRAY_SIZE(context_files),
     432                 :            :                                   dev->debugfs_private,
     433                 :            :                                   parent, &xhci_context_fops);
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
     437                 :            :                                   struct xhci_virt_device *dev,
     438                 :            :                                   int ep_index)
     439                 :            : {
     440                 :          0 :         struct xhci_ep_priv     *epriv;
     441                 :          0 :         struct xhci_slot_priv   *spriv = dev->debugfs_private;
     442                 :            : 
     443         [ #  # ]:          0 :         if (!spriv)
     444                 :            :                 return;
     445                 :            : 
     446         [ #  # ]:          0 :         if (spriv->eps[ep_index])
     447                 :            :                 return;
     448                 :            : 
     449                 :          0 :         epriv = kzalloc(sizeof(*epriv), GFP_KERNEL);
     450         [ #  # ]:          0 :         if (!epriv)
     451                 :            :                 return;
     452                 :            : 
     453                 :          0 :         snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
     454                 :          0 :         epriv->root = xhci_debugfs_create_ring_dir(xhci,
     455                 :            :                                                    &dev->eps[ep_index].ring,
     456                 :            :                                                    epriv->name,
     457                 :            :                                                    spriv->root);
     458                 :          0 :         spriv->eps[ep_index] = epriv;
     459                 :            : }
     460                 :            : 
     461                 :          0 : void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci,
     462                 :            :                                   struct xhci_virt_device *dev,
     463                 :            :                                   int ep_index)
     464                 :            : {
     465                 :          0 :         struct xhci_ep_priv     *epriv;
     466                 :          0 :         struct xhci_slot_priv   *spriv = dev->debugfs_private;
     467                 :            : 
     468   [ #  #  #  # ]:          0 :         if (!spriv || !spriv->eps[ep_index])
     469                 :            :                 return;
     470                 :            : 
     471                 :          0 :         epriv = spriv->eps[ep_index];
     472                 :          0 :         debugfs_remove_recursive(epriv->root);
     473                 :          0 :         spriv->eps[ep_index] = NULL;
     474                 :          0 :         kfree(epriv);
     475                 :            : }
     476                 :            : 
     477                 :          0 : void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id)
     478                 :            : {
     479                 :          0 :         struct xhci_slot_priv   *priv;
     480                 :          0 :         struct xhci_virt_device *dev = xhci->devs[slot_id];
     481                 :            : 
     482                 :          0 :         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
     483         [ #  # ]:          0 :         if (!priv)
     484                 :            :                 return;
     485                 :            : 
     486                 :          0 :         snprintf(priv->name, sizeof(priv->name), "%02d", slot_id);
     487                 :          0 :         priv->root = debugfs_create_dir(priv->name, xhci->debugfs_slots);
     488                 :          0 :         priv->dev = dev;
     489                 :          0 :         dev->debugfs_private = priv;
     490                 :            : 
     491                 :          0 :         xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring,
     492                 :            :                                      "ep00", priv->root);
     493                 :            : 
     494                 :          0 :         xhci_debugfs_create_context_files(xhci, priv->root, slot_id);
     495                 :            : }
     496                 :            : 
     497                 :          0 : void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id)
     498                 :            : {
     499                 :          0 :         int                     i;
     500                 :          0 :         struct xhci_slot_priv   *priv;
     501                 :          0 :         struct xhci_virt_device *dev = xhci->devs[slot_id];
     502                 :            : 
     503   [ #  #  #  # ]:          0 :         if (!dev || !dev->debugfs_private)
     504                 :            :                 return;
     505                 :            : 
     506                 :          0 :         priv = dev->debugfs_private;
     507                 :            : 
     508                 :          0 :         debugfs_remove_recursive(priv->root);
     509                 :            : 
     510         [ #  # ]:          0 :         for (i = 0; i < 31; i++)
     511                 :          0 :                 kfree(priv->eps[i]);
     512                 :            : 
     513                 :          0 :         kfree(priv);
     514                 :          0 :         dev->debugfs_private = NULL;
     515                 :            : }
     516                 :            : 
     517                 :            : static void xhci_debugfs_create_ports(struct xhci_hcd *xhci,
     518                 :            :                                       struct dentry *parent)
     519                 :            : {
     520                 :            :         unsigned int            num_ports;
     521                 :            :         char                    port_name[8];
     522                 :            :         struct xhci_port        *port;
     523                 :            :         struct dentry           *dir;
     524                 :            : 
     525                 :            :         num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
     526                 :            : 
     527                 :            :         parent = debugfs_create_dir("ports", parent);
     528                 :            : 
     529                 :            :         while (num_ports--) {
     530                 :            :                 scnprintf(port_name, sizeof(port_name), "port%02d",
     531                 :            :                           num_ports + 1);
     532                 :            :                 dir = debugfs_create_dir(port_name, parent);
     533                 :            :                 port = &xhci->hw_ports[num_ports];
     534                 :            :                 debugfs_create_file("portsc", 0644, dir, port, &port_fops);
     535                 :            :         }
     536                 :            : }
     537                 :            : 
     538                 :          0 : void xhci_debugfs_init(struct xhci_hcd *xhci)
     539                 :            : {
     540         [ #  # ]:          0 :         struct device           *dev = xhci_to_hcd(xhci)->self.controller;
     541                 :            : 
     542         [ #  # ]:          0 :         xhci->debugfs_root = debugfs_create_dir(dev_name(dev),
     543                 :            :                                                 xhci_debugfs_root);
     544                 :            : 
     545                 :          0 :         INIT_LIST_HEAD(&xhci->regset_list);
     546                 :            : 
     547                 :          0 :         xhci_debugfs_regset(xhci,
     548                 :            :                             0,
     549                 :            :                             xhci_cap_regs, ARRAY_SIZE(xhci_cap_regs),
     550                 :            :                             xhci->debugfs_root, "reg-cap");
     551                 :            : 
     552                 :          0 :         xhci_debugfs_regset(xhci,
     553                 :          0 :                             HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)),
     554                 :            :                             xhci_op_regs, ARRAY_SIZE(xhci_op_regs),
     555                 :            :                             xhci->debugfs_root, "reg-op");
     556                 :            : 
     557                 :          0 :         xhci_debugfs_regset(xhci,
     558                 :          0 :                             readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK,
     559                 :            :                             xhci_runtime_regs, ARRAY_SIZE(xhci_runtime_regs),
     560                 :            :                             xhci->debugfs_root, "reg-runtime");
     561                 :            : 
     562                 :          0 :         xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_LEGACY,
     563                 :            :                                    xhci_extcap_legsup,
     564                 :            :                                    ARRAY_SIZE(xhci_extcap_legsup),
     565                 :            :                                    "reg-ext-legsup");
     566                 :            : 
     567                 :          0 :         xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_PROTOCOL,
     568                 :            :                                    xhci_extcap_protocol,
     569                 :            :                                    ARRAY_SIZE(xhci_extcap_protocol),
     570                 :            :                                    "reg-ext-protocol");
     571                 :            : 
     572                 :          0 :         xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_DEBUG,
     573                 :            :                                    xhci_extcap_dbc,
     574                 :            :                                    ARRAY_SIZE(xhci_extcap_dbc),
     575                 :            :                                    "reg-ext-dbc");
     576                 :            : 
     577                 :          0 :         xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring,
     578                 :            :                                      "command-ring",
     579                 :            :                                      xhci->debugfs_root);
     580                 :            : 
     581                 :          0 :         xhci_debugfs_create_ring_dir(xhci, &xhci->event_ring,
     582                 :            :                                      "event-ring",
     583                 :            :                                      xhci->debugfs_root);
     584                 :            : 
     585                 :          0 :         xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root);
     586                 :            : 
     587                 :          0 :         xhci_debugfs_create_ports(xhci, xhci->debugfs_root);
     588                 :          0 : }
     589                 :            : 
     590                 :          0 : void xhci_debugfs_exit(struct xhci_hcd *xhci)
     591                 :            : {
     592                 :          0 :         struct xhci_regset      *rgs, *tmp;
     593                 :            : 
     594                 :          0 :         debugfs_remove_recursive(xhci->debugfs_root);
     595                 :          0 :         xhci->debugfs_root = NULL;
     596                 :          0 :         xhci->debugfs_slots = NULL;
     597                 :            : 
     598         [ #  # ]:          0 :         list_for_each_entry_safe(rgs, tmp, &xhci->regset_list, list)
     599         [ #  # ]:          0 :                 xhci_debugfs_free_regset(rgs);
     600                 :          0 : }
     601                 :            : 
     602                 :         30 : void __init xhci_debugfs_create_root(void)
     603                 :            : {
     604                 :         30 :         xhci_debugfs_root = debugfs_create_dir("xhci", usb_debug_root);
     605                 :         30 : }
     606                 :            : 
     607                 :          0 : void __exit xhci_debugfs_remove_root(void)
     608                 :            : {
     609                 :          0 :         debugfs_remove_recursive(xhci_debugfs_root);
     610                 :          0 :         xhci_debugfs_root = NULL;
     611                 :          0 : }

Generated by: LCOV version 1.14