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(&regset->list); in xhci_debugfs_alloc_regset()
99 list_add_tail(&regset->list, &xhci->regset_list); in xhci_debugfs_alloc_regset()
109 list_del(&regset->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()
136 regset->dev = hcd->self.controller; in xhci_debugfs_regset()
138 debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset); in xhci_debugfs_regset()
141 static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id, in xhci_debugfs_extcap_regset() argument
148 void __iomem *base = &xhci->cap_regs->hc_capbase; in xhci_debugfs_extcap_regset()
157 xhci_debugfs_regset(xhci, offset, regs, nregs, in xhci_debugfs_extcap_regset()
158 xhci->debugfs_root, "%s:%02d", in xhci_debugfs_extcap_regset()
168 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_enqueue_show()
170 dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); in xhci_ring_enqueue_show()
179 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_dequeue_show()
181 dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); in xhci_ring_dequeue_show()
189 struct xhci_ring *ring = *(struct xhci_ring **)s->private; in xhci_ring_cycle_show()
191 seq_printf(s, "%d\n", ring->cycle_state); in xhci_ring_cycle_show()
205 trb = &seg->trbs[i]; in xhci_ring_dump_segment()
206 dma = seg->dma + i * sizeof(*trb); in xhci_ring_dump_segment()
207 seq_printf(s, "%2u %pad: %s\n", seg->num, &dma, in xhci_ring_dump_segment()
208 xhci_decode_trb(str, XHCI_MSG_MAX, le32_to_cpu(trb->generic.field[0]), in xhci_ring_dump_segment()
209 le32_to_cpu(trb->generic.field[1]), in xhci_ring_dump_segment()
210 le32_to_cpu(trb->generic.field[2]), in xhci_ring_dump_segment()
211 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 xhci_for_each_ring_seg(ring->first_seg, seg) in xhci_ring_trb_show()
237 return single_open(file, f_map->show, inode->i_private); in xhci_ring_open()
249 struct xhci_hcd *xhci; in xhci_slot_context_show() local
251 struct xhci_slot_priv *priv = s->private; in xhci_slot_context_show()
252 struct xhci_virt_device *dev = priv->dev; in xhci_slot_context_show()
255 xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); in xhci_slot_context_show()
256 slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); in xhci_slot_context_show()
257 seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, in xhci_slot_context_show()
259 le32_to_cpu(slot_ctx->dev_info), in xhci_slot_context_show()
260 le32_to_cpu(slot_ctx->dev_info2), in xhci_slot_context_show()
261 le32_to_cpu(slot_ctx->tt_info), in xhci_slot_context_show()
262 le32_to_cpu(slot_ctx->dev_state))); in xhci_slot_context_show()
271 struct xhci_hcd *xhci; in xhci_endpoint_context_show() local
273 struct xhci_slot_priv *priv = s->private; in xhci_endpoint_context_show()
274 struct xhci_virt_device *dev = priv->dev; in xhci_endpoint_context_show()
277 xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); in xhci_endpoint_context_show()
280 ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); in xhci_endpoint_context_show()
281 dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params); in xhci_endpoint_context_show()
284 le32_to_cpu(ep_ctx->ep_info), in xhci_endpoint_context_show()
285 le32_to_cpu(ep_ctx->ep_info2), in xhci_endpoint_context_show()
286 le64_to_cpu(ep_ctx->deq), in xhci_endpoint_context_show()
287 le32_to_cpu(ep_ctx->tx_info)), in xhci_endpoint_context_show()
288 dev->eps[ep_index].ep_state); in xhci_endpoint_context_show()
296 struct xhci_slot_priv *priv = s->private; in xhci_device_name_show()
297 struct xhci_virt_device *dev = priv->dev; in xhci_device_name_show()
299 seq_printf(s, "%s\n", dev_name(&dev->udev->dev)); in xhci_device_name_show()
306 {"slot-context", xhci_slot_context_show, },
307 {"ep-context", xhci_endpoint_context_show, },
314 return single_open(file, f_map->show, inode->i_private); in xhci_context_open()
328 struct xhci_port *port = s->private; in xhci_portsc_show()
332 portsc = readl(port->addr); in xhci_portsc_show()
340 return single_open(file, xhci_portsc_show, inode->i_private); in xhci_port_open()
346 struct seq_file *s = file->private_data; in xhci_port_write()
347 struct xhci_port *port = s->private; in xhci_port_write()
348 struct xhci_hcd *xhci = hcd_to_xhci(port->rhub->hcd); in xhci_port_write() local
353 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) in xhci_port_write()
354 return -EFAULT; in xhci_port_write()
358 if (!HCC2_CTC(xhci->hcc_params2)) in xhci_port_write()
360 spin_lock_irqsave(&xhci->lock, flags); in xhci_port_write()
362 portsc = readl(port->addr); in xhci_port_write()
364 spin_unlock_irqrestore(&xhci->lock, flags); in xhci_port_write()
365 return -EPERM; in xhci_port_write()
370 writel(portsc, port->addr); in xhci_port_write()
371 spin_unlock_irqrestore(&xhci->lock, flags); in xhci_port_write()
373 return -EINVAL; in xhci_port_write()
386 static void xhci_debugfs_create_files(struct xhci_hcd *xhci, in xhci_debugfs_create_files() argument
399 static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, in xhci_debugfs_create_ring_dir() argument
407 xhci_debugfs_create_files(xhci, ring_files, ARRAY_SIZE(ring_files), in xhci_debugfs_create_ring_dir()
413 static void xhci_debugfs_create_context_files(struct xhci_hcd *xhci, in xhci_debugfs_create_context_files() argument
417 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_create_context_files()
419 xhci_debugfs_create_files(xhci, context_files, in xhci_debugfs_create_context_files()
421 dev->debugfs_private, in xhci_debugfs_create_context_files()
425 void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, in xhci_debugfs_create_endpoint() argument
430 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_create_endpoint()
435 if (spriv->eps[ep_index]) in xhci_debugfs_create_endpoint()
442 epriv->show_ring = dev->eps[ep_index].ring; in xhci_debugfs_create_endpoint()
444 snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); in xhci_debugfs_create_endpoint()
445 epriv->root = xhci_debugfs_create_ring_dir(xhci, in xhci_debugfs_create_endpoint()
446 &epriv->show_ring, in xhci_debugfs_create_endpoint()
447 epriv->name, in xhci_debugfs_create_endpoint()
448 spriv->root); in xhci_debugfs_create_endpoint()
449 spriv->eps[ep_index] = epriv; in xhci_debugfs_create_endpoint()
452 void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci, in xhci_debugfs_remove_endpoint() argument
457 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_remove_endpoint()
459 if (!spriv || !spriv->eps[ep_index]) in xhci_debugfs_remove_endpoint()
462 epriv = spriv->eps[ep_index]; in xhci_debugfs_remove_endpoint()
463 debugfs_remove_recursive(epriv->root); in xhci_debugfs_remove_endpoint()
464 spriv->eps[ep_index] = NULL; in xhci_debugfs_remove_endpoint()
470 struct xhci_ep_priv *epriv = s->private; in xhci_stream_id_show()
472 if (!epriv->stream_info) in xhci_stream_id_show()
473 return -EPERM; in xhci_stream_id_show()
475 seq_printf(s, "Show stream ID %d trb ring, supported [1 - %d]\n", in xhci_stream_id_show()
476 epriv->stream_id, epriv->stream_info->num_streams - 1); in xhci_stream_id_show()
483 return single_open(file, xhci_stream_id_show, inode->i_private); in xhci_stream_id_open()
489 struct seq_file *s = file->private_data; in xhci_stream_id_write()
490 struct xhci_ep_priv *epriv = s->private; in xhci_stream_id_write()
494 if (!epriv->stream_info) in xhci_stream_id_write()
495 return -EPERM; in xhci_stream_id_write()
502 if (stream_id == 0 || stream_id >= epriv->stream_info->num_streams) in xhci_stream_id_write()
503 return -EINVAL; in xhci_stream_id_write()
505 epriv->stream_id = stream_id; in xhci_stream_id_write()
506 epriv->show_ring = epriv->stream_info->stream_rings[stream_id]; in xhci_stream_id_write()
521 struct xhci_ep_priv *epriv = s->private; in xhci_stream_context_array_show()
526 if (!epriv->stream_info) in xhci_stream_context_array_show()
527 return -EPERM; in xhci_stream_context_array_show()
530 epriv->stream_info->num_streams, in xhci_stream_context_array_show()
531 epriv->stream_info->num_stream_ctxs); in xhci_stream_context_array_show()
533 for (id = 0; id < epriv->stream_info->num_stream_ctxs; id++) { in xhci_stream_context_array_show()
534 stream_ctx = epriv->stream_info->stream_ctx_array + id; in xhci_stream_context_array_show()
535 dma = epriv->stream_info->ctx_array_dma + id * 16; in xhci_stream_context_array_show()
536 if (id < epriv->stream_info->num_streams) in xhci_stream_context_array_show()
538 id, le64_to_cpu(stream_ctx->stream_ring)); in xhci_stream_context_array_show()
541 &dma, le64_to_cpu(stream_ctx->stream_ring)); in xhci_stream_context_array_show()
548 void xhci_debugfs_create_stream_files(struct xhci_hcd *xhci, in xhci_debugfs_create_stream_files() argument
552 struct xhci_slot_priv *spriv = dev->debugfs_private; in xhci_debugfs_create_stream_files()
555 if (!spriv || !spriv->eps[ep_index] || in xhci_debugfs_create_stream_files()
556 !dev->eps[ep_index].stream_info) in xhci_debugfs_create_stream_files()
559 epriv = spriv->eps[ep_index]; in xhci_debugfs_create_stream_files()
560 epriv->stream_info = dev->eps[ep_index].stream_info; in xhci_debugfs_create_stream_files()
563 epriv->stream_id = 1; in xhci_debugfs_create_stream_files()
564 epriv->show_ring = epriv->stream_info->stream_rings[1]; in xhci_debugfs_create_stream_files()
566 epriv->root, epriv, in xhci_debugfs_create_stream_files()
569 epriv->root, epriv, in xhci_debugfs_create_stream_files()
573 void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) in xhci_debugfs_create_slot() argument
576 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_create_slot()
582 snprintf(priv->name, sizeof(priv->name), "%02d", slot_id); in xhci_debugfs_create_slot()
583 priv->root = debugfs_create_dir(priv->name, xhci->debugfs_slots); in xhci_debugfs_create_slot()
584 priv->dev = dev; in xhci_debugfs_create_slot()
585 dev->debugfs_private = priv; in xhci_debugfs_create_slot()
587 xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring, in xhci_debugfs_create_slot()
588 "ep00", priv->root); in xhci_debugfs_create_slot()
590 xhci_debugfs_create_context_files(xhci, priv->root, slot_id); in xhci_debugfs_create_slot()
593 void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id) in xhci_debugfs_remove_slot() argument
597 struct xhci_virt_device *dev = xhci->devs[slot_id]; in xhci_debugfs_remove_slot()
599 if (!dev || !dev->debugfs_private) in xhci_debugfs_remove_slot()
602 priv = dev->debugfs_private; in xhci_debugfs_remove_slot()
604 debugfs_remove_recursive(priv->root); in xhci_debugfs_remove_slot()
607 kfree(priv->eps[i]); in xhci_debugfs_remove_slot()
610 dev->debugfs_private = NULL; in xhci_debugfs_remove_slot()
613 static void xhci_debugfs_create_ports(struct xhci_hcd *xhci, in xhci_debugfs_create_ports() argument
621 num_ports = HCS_MAX_PORTS(xhci->hcs_params1); in xhci_debugfs_create_ports()
625 while (num_ports--) { in xhci_debugfs_create_ports()
629 port = &xhci->hw_ports[num_ports]; in xhci_debugfs_create_ports()
634 void xhci_debugfs_init(struct xhci_hcd *xhci) in xhci_debugfs_init() argument
636 struct device *dev = xhci_to_hcd(xhci)->self.controller; in xhci_debugfs_init()
638 xhci->debugfs_root = debugfs_create_dir(dev_name(dev), in xhci_debugfs_init()
641 INIT_LIST_HEAD(&xhci->regset_list); in xhci_debugfs_init()
643 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
646 xhci->debugfs_root, "reg-cap"); in xhci_debugfs_init()
648 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
649 HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)), in xhci_debugfs_init()
651 xhci->debugfs_root, "reg-op"); in xhci_debugfs_init()
653 xhci_debugfs_regset(xhci, in xhci_debugfs_init()
654 readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK, in xhci_debugfs_init()
656 xhci->debugfs_root, "reg-runtime"); in xhci_debugfs_init()
658 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_LEGACY, in xhci_debugfs_init()
661 "reg-ext-legsup"); in xhci_debugfs_init()
663 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_PROTOCOL, in xhci_debugfs_init()
666 "reg-ext-protocol"); in xhci_debugfs_init()
668 xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_DEBUG, in xhci_debugfs_init()
671 "reg-ext-dbc"); in xhci_debugfs_init()
673 xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring, in xhci_debugfs_init()
674 "command-ring", in xhci_debugfs_init()
675 xhci->debugfs_root); in xhci_debugfs_init()
677 xhci_debugfs_create_ring_dir(xhci, &xhci->interrupters[0]->event_ring, in xhci_debugfs_init()
678 "event-ring", in xhci_debugfs_init()
679 xhci->debugfs_root); in xhci_debugfs_init()
681 xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root); in xhci_debugfs_init()
683 xhci_debugfs_create_ports(xhci, xhci->debugfs_root); in xhci_debugfs_init()
686 void xhci_debugfs_exit(struct xhci_hcd *xhci) in xhci_debugfs_exit() argument
690 debugfs_remove_recursive(xhci->debugfs_root); in xhci_debugfs_exit()
691 xhci->debugfs_root = NULL; in xhci_debugfs_exit()
692 xhci->debugfs_slots = NULL; in xhci_debugfs_exit()
694 list_for_each_entry_safe(rgs, tmp, &xhci->regset_list, list) in xhci_debugfs_exit()
700 xhci_debugfs_root = debugfs_create_dir("xhci", usb_debug_root); in xhci_debugfs_create_root()