Lines Matching +full:generic +full:- +full:xhci
1 // SPDX-License-Identifier: GPL-2.0
3 * xhci-debugfs.c - xHCI debugfs interface
13 #include "xhci.h"
14 #include "xhci-debugfs.h"
86 static struct xhci_regset *xhci_debugfs_alloc_regset(struct xhci_hcd *xhci) in xhci_debugfs_alloc_regset() argument
98 INIT_LIST_HEAD(®set->list); in xhci_debugfs_alloc_regset()
99 list_add_tail(®set->list, &xhci->regset_list); in xhci_debugfs_alloc_regset()
109 list_del(®set->list); in xhci_debugfs_free_regset()
114 static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base, in xhci_debugfs_regset() argument
122 struct usb_hcd *hcd = xhci_to_hcd(xhci); in xhci_debugfs_regset()
124 rgs = xhci_debugfs_alloc_regset(xhci); in xhci_debugfs_regset()
129 vsnprintf(rgs->name, sizeof(rgs->name), fmt, args); in xhci_debugfs_regset()
132 regset = &rgs->regset; in xhci_debugfs_regset()
133 regset->regs = regs; in xhci_debugfs_regset()
134 regset->nregs = nregs; in xhci_debugfs_regset()
135 regset->base = hcd->regs + base; in xhci_debugfs_regset()
137 debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset); in xhci_debugfs_regset()
140 static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id, in xhci_debugfs_extcap_regset() argument
147 void __iomem *base = &xhci->cap_regs->hc_capbase; in xhci_debugfs_extcap_regset()
156 xhci_debugfs_regset(xhci, offset, regs, nregs, in xhci_debugfs_extcap_regset()
157 xhci->debugfs_root, "%s:%02d", in xhci_debugfs_extcap_regset()
167 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_enqueue_show()
169 dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); in xhci_ring_enqueue_show()
178 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_dequeue_show()
180 dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); in xhci_ring_dequeue_show()
188 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_cycle_show()
190 seq_printf(s, "%d\n", ring->cycle_state); in xhci_ring_cycle_show()
204 trb = &seg->trbs[i]; in xhci_ring_dump_segment()
205 dma = seg->dma + i * sizeof(*trb); in xhci_ring_dump_segment()
207 xhci_decode_trb(str, XHCI_MSG_MAX, le32_to_cpu(trb->generic.field[0]), in xhci_ring_dump_segment()
208 le32_to_cpu(trb->generic.field[1]), in xhci_ring_dump_segment()
209 le32_to_cpu(trb->generic.field[2]), in xhci_ring_dump_segment()
210 le32_to_cpu(trb->generic.field[3]))); in xhci_ring_dump_segment()
217 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_trb_show()
218 struct xhci_segment *seg = ring->first_seg; in xhci_ring_trb_show()
220 for (i = 0; i < ring->num_segs; i++) { in xhci_ring_trb_show()
222 seg = seg->next; in xhci_ring_trb_show()
239 const char *file_name = file_dentry(file)->d_iname; in xhci_ring_open()
244 if (strcmp(f_map->name, file_name) == 0) in xhci_ring_open()
248 return single_open(file, f_map->show, inode->i_private); in xhci_ring_open()
260 struct xhci_hcd *xhci; in xhci_slot_context_show() local
262 struct xhci_slot_priv *priv = s->private; in xhci_slot_context_show()
263 struct xhci_virt_device *dev = priv->dev; in xhci_slot_context_show()
266 xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); in xhci_slot_context_show()
267 slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); in xhci_slot_context_show()
268 seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, in xhci_slot_context_show()
270 le32_to_cpu(slot_ctx->dev_info), in xhci_slot_context_show()
271 le32_to_cpu(slot_ctx->dev_info2), in xhci_slot_context_show()
272 le32_to_cpu(slot_ctx->tt_info), in xhci_slot_context_show()
273 le32_to_cpu(slot_ctx->dev_state))); in xhci_slot_context_show()
282 struct xhci_hcd *xhci; in xhci_endpoint_context_show() local
284 struct xhci_slot_priv *priv = s->private; in xhci_endpoint_context_show()
285 struct xhci_virt_device *dev = priv->dev; in xhci_endpoint_context_show()
288 xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); in xhci_endpoint_context_show()
291 ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); in xhci_endpoint_context_show()
292 dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params); in xhci_endpoint_context_show()
295 le32_to_cpu(ep_ctx->ep_info), in xhci_endpoint_context_show()
296 le32_to_cpu(ep_ctx->ep_info2), in xhci_endpoint_context_show()
297 le64_to_cpu(ep_ctx->deq), in xhci_endpoint_context_show()
298 le32_to_cpu(ep_ctx->tx_info))); in xhci_endpoint_context_show()
306 struct xhci_slot_priv *priv = s->private; in xhci_device_name_show()
307 struct xhci_virt_device *dev = priv->dev; in xhci_device_name_show()
309 seq_printf(s, "%s\n", dev_name(&dev->udev->dev)); in xhci_device_name_show()
316 {"slot-context", xhci_slot_context_show, },
317 {"ep-context", xhci_endpoint_context_show, },
324 const char *file_name = file_dentry(file)->d_iname; in xhci_context_open()
329 if (strcmp(f_map->name, file_name) == 0) in xhci_context_open()
333 return single_open(file, f_map->show, inode->i_private); in xhci_context_open()
347 struct xhci_port *port = s->private; in xhci_portsc_show()
351 portsc = readl(port->addr); in xhci_portsc_show()
359 return single_open(file, xhci_portsc_show, inode->i_private); in xhci_port_open()
365 struct seq_file *s = file->private_data; in xhci_port_write()
366 struct xhci_port *port = s->private; in xhci_port_write()
367 struct xhci_hcd *xhci = hcd_to_xhci(port->rhub->hcd); in xhci_port_write() local
372 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) in xhci_port_write()
373 return -EFAULT; in xhci_port_write()
377 if (!HCC2_CTC(xhci->hcc_params2)) in xhci_port_write()
379 spin_lock_irqsave(&xhci->lock, flags); in xhci_port_write()
381 portsc = readl(port->addr); in xhci_port_write()
383 spin_unlock_irqrestore(&xhci->lock, flags); in xhci_port_write()
384 return -EPERM; in xhci_port_write()
389 writel(portsc, port->addr); in xhci_port_write()
390 spin_unlock_irqrestore(&xhci->lock, flags); in xhci_port_write()
392 return -EINVAL; in xhci_port_write()
405 static void xhci_debugfs_create_files(struct xhci_hcd *xhci, in xhci_debugfs_create_files() argument
417 static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, in xhci_debugfs_create_ring_dir() argument
425 xhci_debugfs_create_files(xhci, ring_files, ARRAY_SIZE(ring_files), in xhci_debugfs_create_ring_dir()
431 static void xhci_debugfs_create_context_files(struct xhci_hcd *xhci, in xhci_debugfs_create_context_files() argument
435 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_create_context_files()
437 xhci_debugfs_create_files(xhci, context_files, in xhci_debugfs_create_context_files()
439 dev->debugfs_private, in xhci_debugfs_create_context_files()
443 void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, in xhci_debugfs_create_endpoint() argument
448 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_create_endpoint()
453 if (spriv->eps[ep_index]) in xhci_debugfs_create_endpoint()
460 epriv->show_ring = dev->eps[ep_index].ring; in xhci_debugfs_create_endpoint()
462 snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); in xhci_debugfs_create_endpoint()
463 epriv->root = xhci_debugfs_create_ring_dir(xhci, in xhci_debugfs_create_endpoint()
464 &epriv->show_ring, in xhci_debugfs_create_endpoint()
465 epriv->name, in xhci_debugfs_create_endpoint()
466 spriv->root); in xhci_debugfs_create_endpoint()
467 spriv->eps[ep_index] = epriv; in xhci_debugfs_create_endpoint()
470 void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci, in xhci_debugfs_remove_endpoint() argument
475 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_remove_endpoint()
477 if (!spriv || !spriv->eps[ep_index]) in xhci_debugfs_remove_endpoint()
480 epriv = spriv->eps[ep_index]; in xhci_debugfs_remove_endpoint()
481 debugfs_remove_recursive(epriv->root); in xhci_debugfs_remove_endpoint()
482 spriv->eps[ep_index] = NULL; in xhci_debugfs_remove_endpoint()
488 struct xhci_ep_priv *epriv = s->private; in xhci_stream_id_show()
490 if (!epriv->stream_info) in xhci_stream_id_show()
491 return -EPERM; in xhci_stream_id_show()
493 seq_printf(s, "Show stream ID %d trb ring, supported [1 - %d]\n", in xhci_stream_id_show()
494 epriv->stream_id, epriv->stream_info->num_streams - 1); in xhci_stream_id_show()
501 return single_open(file, xhci_stream_id_show, inode->i_private); in xhci_stream_id_open()
507 struct seq_file *s = file->private_data; in xhci_stream_id_write()
508 struct xhci_ep_priv *epriv = s->private; in xhci_stream_id_write()
512 if (!epriv->stream_info) in xhci_stream_id_write()
513 return -EPERM; in xhci_stream_id_write()
520 if (stream_id == 0 || stream_id >= epriv->stream_info->num_streams) in xhci_stream_id_write()
521 return -EINVAL; in xhci_stream_id_write()
523 epriv->stream_id = stream_id; in xhci_stream_id_write()
524 epriv->show_ring = epriv->stream_info->stream_rings[stream_id]; in xhci_stream_id_write()
539 struct xhci_ep_priv *epriv = s->private; in xhci_stream_context_array_show()
544 if (!epriv->stream_info) in xhci_stream_context_array_show()
545 return -EPERM; in xhci_stream_context_array_show()
548 epriv->stream_info->num_streams, in xhci_stream_context_array_show()
549 epriv->stream_info->num_stream_ctxs); in xhci_stream_context_array_show()
551 for (id = 0; id < epriv->stream_info->num_stream_ctxs; id++) { in xhci_stream_context_array_show()
552 stream_ctx = epriv->stream_info->stream_ctx_array + id; in xhci_stream_context_array_show()
553 dma = epriv->stream_info->ctx_array_dma + id * 16; in xhci_stream_context_array_show()
554 if (id < epriv->stream_info->num_streams) in xhci_stream_context_array_show()
556 id, le64_to_cpu(stream_ctx->stream_ring)); in xhci_stream_context_array_show()
559 &dma, le64_to_cpu(stream_ctx->stream_ring)); in xhci_stream_context_array_show()
566 void xhci_debugfs_create_stream_files(struct xhci_hcd *xhci, in xhci_debugfs_create_stream_files() argument
570 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_create_stream_files()
573 if (!spriv || !spriv->eps[ep_index] || in xhci_debugfs_create_stream_files()
574 !dev->eps[ep_index].stream_info) in xhci_debugfs_create_stream_files()
577 epriv = spriv->eps[ep_index]; in xhci_debugfs_create_stream_files()
578 epriv->stream_info = dev->eps[ep_index].stream_info; in xhci_debugfs_create_stream_files()
581 epriv->stream_id = 1; in xhci_debugfs_create_stream_files()
582 epriv->show_ring = epriv->stream_info->stream_rings[1]; in xhci_debugfs_create_stream_files()
584 epriv->root, epriv, in xhci_debugfs_create_stream_files()
587 epriv->root, epriv, in xhci_debugfs_create_stream_files()
591 void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) in xhci_debugfs_create_slot() argument
594 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_create_slot()
600 snprintf(priv->name, sizeof(priv->name), "%02d", slot_id); in xhci_debugfs_create_slot()
601 priv->root = debugfs_create_dir(priv->name, xhci->debugfs_slots); in xhci_debugfs_create_slot()
602 priv->dev = dev; in xhci_debugfs_create_slot()
603 dev->debugfs_private = priv; in xhci_debugfs_create_slot()
605 xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring, in xhci_debugfs_create_slot()
606 "ep00", priv->root); in xhci_debugfs_create_slot()
608 xhci_debugfs_create_context_files(xhci, priv->root, slot_id); in xhci_debugfs_create_slot()
611 void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id) in xhci_debugfs_remove_slot() argument
615 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_remove_slot()
617 if (!dev || !dev->debugfs_private) in xhci_debugfs_remove_slot()
620 priv = dev->debugfs_private; in xhci_debugfs_remove_slot()
622 debugfs_remove_recursive(priv->root); in xhci_debugfs_remove_slot()
625 kfree(priv->eps[i]); in xhci_debugfs_remove_slot()
628 dev->debugfs_private = NULL; in xhci_debugfs_remove_slot()
631 static void xhci_debugfs_create_ports(struct xhci_hcd *xhci, in xhci_debugfs_create_ports() argument
639 num_ports = HCS_MAX_PORTS(xhci->hcs_params1); in xhci_debugfs_create_ports()
643 while (num_ports--) { in xhci_debugfs_create_ports()
647 port = &xhci->hw_ports[num_ports]; in xhci_debugfs_create_ports()
652 void xhci_debugfs_init(struct xhci_hcd *xhci) in xhci_debugfs_init() argument
654 struct device *dev = xhci_to_hcd(xhci)->self.controller; in xhci_debugfs_init()
656 xhci->debugfs_root = debugfs_create_dir(dev_name(dev), in xhci_debugfs_init()
659 INIT_LIST_HEAD(&xhci->regset_list); in xhci_debugfs_init()
661 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
664 xhci->debugfs_root, "reg-cap"); in xhci_debugfs_init()
666 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
667 HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)), in xhci_debugfs_init()
669 xhci->debugfs_root, "reg-op"); in xhci_debugfs_init()
671 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
672 readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK, in xhci_debugfs_init()
674 xhci->debugfs_root, "reg-runtime"); in xhci_debugfs_init()
676 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_LEGACY, in xhci_debugfs_init()
679 "reg-ext-legsup"); in xhci_debugfs_init()
681 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_PROTOCOL, in xhci_debugfs_init()
684 "reg-ext-protocol"); in xhci_debugfs_init()
686 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_DEBUG, in xhci_debugfs_init()
689 "reg-ext-dbc"); in xhci_debugfs_init()
691 xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring, in xhci_debugfs_init()
692 "command-ring", in xhci_debugfs_init()
693 xhci->debugfs_root); in xhci_debugfs_init()
695 xhci_debugfs_create_ring_dir(xhci, &xhci->event_ring, in xhci_debugfs_init()
696 "event-ring", in xhci_debugfs_init()
697 xhci->debugfs_root); in xhci_debugfs_init()
699 xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root); in xhci_debugfs_init()
701 xhci_debugfs_create_ports(xhci, xhci->debugfs_root); in xhci_debugfs_init()
704 void xhci_debugfs_exit(struct xhci_hcd *xhci) in xhci_debugfs_exit() argument
708 debugfs_remove_recursive(xhci->debugfs_root); in xhci_debugfs_exit()
709 xhci->debugfs_root = NULL; in xhci_debugfs_exit()
710 xhci->debugfs_slots = NULL; in xhci_debugfs_exit()
712 list_for_each_entry_safe(rgs, tmp, &xhci->regset_list, list) in xhci_debugfs_exit()
718 xhci_debugfs_root = debugfs_create_dir("xhci", usb_debug_root); in xhci_debugfs_create_root()