Skip to content

Commit

Permalink
usb: xhci: add debugfs support for ep with stream
Browse files Browse the repository at this point in the history
To show the trb ring of streams, use the exsiting ring files of bulk ep
to show trb ring of one specific stream ID, which stream ID's trb ring
will be shown, is controlled by a new debugfs file stream_id, this is to
avoid to create a large number of dir for every allocate stream IDs,
another debugfs file stream_context_array is created to show all the
allocated stream context array entries.

Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20200918131752.16488-11-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Junlisuzhou authored and gregkh committed Sep 20, 2020
1 parent 167657a commit 673d746
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
109 changes: 108 additions & 1 deletion drivers/usb/host/xhci-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,11 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
if (!epriv)
return;

epriv->show_ring = dev->eps[ep_index].ring;

snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
epriv->root = xhci_debugfs_create_ring_dir(xhci,
&dev->eps[ep_index].ring,
&epriv->show_ring,
epriv->name,
spriv->root);
spriv->eps[ep_index] = epriv;
Expand All @@ -475,6 +477,111 @@ void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci,
kfree(epriv);
}

static int xhci_stream_id_show(struct seq_file *s, void *unused)
{
struct xhci_ep_priv *epriv = s->private;

if (!epriv->stream_info)
return -EPERM;

seq_printf(s, "Show stream ID %d trb ring, supported [1 - %d]\n",
epriv->stream_id, epriv->stream_info->num_streams - 1);

return 0;
}

static int xhci_stream_id_open(struct inode *inode, struct file *file)
{
return single_open(file, xhci_stream_id_show, inode->i_private);
}

static ssize_t xhci_stream_id_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct xhci_ep_priv *epriv = s->private;
int ret;
u16 stream_id; /* MaxPStreams + 1 <= 16 */

if (!epriv->stream_info)
return -EPERM;

/* Decimal number */
ret = kstrtou16_from_user(ubuf, count, 10, &stream_id);
if (ret)
return ret;

if (stream_id == 0 || stream_id >= epriv->stream_info->num_streams)
return -EINVAL;

epriv->stream_id = stream_id;
epriv->show_ring = epriv->stream_info->stream_rings[stream_id];

return count;
}

static const struct file_operations stream_id_fops = {
.open = xhci_stream_id_open,
.write = xhci_stream_id_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static int xhci_stream_context_array_show(struct seq_file *s, void *unused)
{
struct xhci_ep_priv *epriv = s->private;
struct xhci_stream_ctx *stream_ctx;
dma_addr_t dma;
int id;

if (!epriv->stream_info)
return -EPERM;

seq_printf(s, "Allocated %d streams and %d stream context array entries\n",
epriv->stream_info->num_streams,
epriv->stream_info->num_stream_ctxs);

for (id = 0; id < epriv->stream_info->num_stream_ctxs; id++) {
stream_ctx = epriv->stream_info->stream_ctx_array + id;
dma = epriv->stream_info->ctx_array_dma + id * 16;
if (id < epriv->stream_info->num_streams)
seq_printf(s, "%pad stream id %d deq %016llx\n", &dma,
id, le64_to_cpu(stream_ctx->stream_ring));
else
seq_printf(s, "%pad stream context entry not used deq %016llx\n",
&dma, le64_to_cpu(stream_ctx->stream_ring));
}

return 0;
}
DEFINE_SHOW_ATTRIBUTE(xhci_stream_context_array);

void xhci_debugfs_create_stream_files(struct xhci_hcd *xhci,
struct xhci_virt_device *dev,
int ep_index)
{
struct xhci_slot_priv *spriv = dev->debugfs_private;
struct xhci_ep_priv *epriv;

if (!spriv || !spriv->eps[ep_index] ||
!dev->eps[ep_index].stream_info)
return;

epriv = spriv->eps[ep_index];
epriv->stream_info = dev->eps[ep_index].stream_info;

/* Show trb ring of stream ID 1 by default */
epriv->stream_id = 1;
epriv->show_ring = epriv->stream_info->stream_rings[1];
debugfs_create_file("stream_id", 0644,
epriv->root, epriv,
&stream_id_fops);
debugfs_create_file("stream_context_array", 0444,
epriv->root, epriv,
&xhci_stream_context_array_fops);
}

void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_slot_priv *priv;
Expand Down
10 changes: 10 additions & 0 deletions drivers/usb/host/xhci-debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ struct xhci_file_map {
struct xhci_ep_priv {
char name[DEBUGFS_NAMELEN];
struct dentry *root;
struct xhci_stream_info *stream_info;
struct xhci_ring *show_ring;
unsigned int stream_id;
};

struct xhci_slot_priv {
Expand All @@ -113,6 +116,9 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
int ep_index);
void xhci_debugfs_create_stream_files(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
int ep_index);
#else
static inline void xhci_debugfs_init(struct xhci_hcd *xhci) { }
static inline void xhci_debugfs_exit(struct xhci_hcd *xhci) { }
Expand All @@ -128,6 +134,10 @@ static inline void
xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
int ep_index) { }
static inline void
xhci_debugfs_create_stream_files(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
int ep_index) { }
#endif /* CONFIG_DEBUG_FS */

#endif /* __LINUX_XHCI_DEBUGFS_H */
1 change: 1 addition & 0 deletions drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -3533,6 +3533,7 @@ static int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
xhci_dbg(xhci, "Slot %u ep ctx %u now has streams.\n",
udev->slot_id, ep_index);
vdev->eps[ep_index].ep_state |= EP_HAS_STREAMS;
xhci_debugfs_create_stream_files(xhci, vdev, ep_index);
}
xhci_free_command(xhci, config_cmd);
spin_unlock_irqrestore(&xhci->lock, flags);
Expand Down

0 comments on commit 673d746

Please sign in to comment.