usb: xhci: Fix debugfs bandwidth reporting
Subsystems (2)
PATCH 1/1 usb: xhci: Fix debugfs bandwidth reporting
Replace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report command failure as IO error, not zero bandwidth.
--- drivers/usb/host/xhci-debugfs.c | 6 +++--- drivers/usb/host/xhci.c | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-debugfs.c +3 -3
@@ -709,7 +709,7 @@ static int xhci_ss_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_SUPER , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_SS ), s);return ret; }
@@ -718,7 +718,7 @@ static int xhci_hs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_HIGH , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_HS ), s);return ret; }
@@ -727,7 +727,7 @@ static int xhci_fs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_FULL , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_FS ), s);return ret; }
drivers/usb/host/xhci.c +2 -0
@@ -3277,6 +3277,8 @@ int xhci_get_port_bandwidth(struct xhci_hcd *xhci, struct xhci_container_ctx *ctspin_unlock_irqrestore (&xhci->lock, flags);wait_for_completion (cmd->completion); +if (cmd->status !=COMP_SUCCESS ) + ret = -EIO ; err_out:kfree (cmd->completion);kfree (cmd);
Signature · 1 line
2.48.1
Quoted 10 lines · Michal Pecio
Replace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report command failure as IO error, not zero bandwidth.
Signed-off-by Michal Pecio <[email protected]>
Added to queue
Thanks
Mathias
Quoted 5 lines · Mathias Nyman
Quoted 4 lines · Michal Pecio
Replace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Quoted 8 lines
Quoted 6 lines
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report command failure as IO error, not zero bandwidth.
Signed-off-by Michal Pecio <[email protected]>Added to queue
Hi,
Thanks for taking the patch, but can we have a last minute swap for a v2 or optionally v3?
Problem is that returning -EIO is common (the command is optional) and it upsets userspace: "grep -r" spams the console with errors, "zip -R" terminates and doesn't include remaining files, etc. So I would prefer to print an error string in this case. "Real" errors will still be returned ordinarily.
The optional v3 also renames the new directory for consistency. Technically it's a breaking change, but I believe it's permissible in debugfs, particularly for an interface only added recently.
Regards,
Michal
PATCH v2 1/1 usb: xhci: Fix debugfs bandwidth reporting
Replace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report failures properly. No attempt made at "tunneling" all possible comp codes through errno, debugfs users may inspect the result through event-ring/trbs.
---
New in v2:
- print an error string instead of returning -EIO
- document known and sometimes unobvious error cases
drivers/usb/host/xhci-debugfs.c | 10 +++++++--- drivers/usb/host/xhci.c | 9 ++++++++- 2 files changed, 15 insertions(+), 4 deletions(-)
drivers/usb/host/xhci-debugfs.c +7 -3
@@ -703,6 +703,10 @@ static int xhci_port_bw_show(struct xhci_hcd *xhci, u8 dev_speed,seq_printf (s,"port[%d] available bw: %d%%.\n" , i, ctx->bytes[i]); err_out: +if (ret == -EIO ) { +seq_puts (s,"Get Port Bandwidth failed\n" ); + ret =0 ; + }pm_runtime_put_sync (dev);xhci_free_port_bw_ctx (xhci, ctx);return ret;
@@ -713,7 +717,7 @@ static int xhci_ss_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_SUPER , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_SS ), s);return ret; }
@@ -722,7 +726,7 @@ static int xhci_hs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_HIGH , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_HS ), s);return ret; }
@@ -731,7 +735,7 @@ static int xhci_fs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_FULL , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_FS ), s);return ret; }
drivers/usb/host/xhci.c +8 -1
@@ -3262,7 +3262,12 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) }EXPORT_SYMBOL_GPL (xhci_reset_bandwidth); -/* Get the available bandwidth of the ports under the xhci roothub */ +/* +* Get the available bandwidth of the ports under the xhci roothub. +* EIO means the command failed: command not implemented or unsupported +* speed (TRB Error), some ASMedia complete with Parameter Error when +* querying the root hub (slot_id = 0), or other error or timeout. +*/ int xhci_get_port_bandwidth (struct xhci_hcd *xhci,struct xhci_container_ctx *ctx,u8 dev_speed) {
@@ -3291,6 +3296,8 @@ int xhci_get_port_bandwidth(struct xhci_hcd *xhci, struct xhci_container_ctx *ctspin_unlock_irqrestore (&xhci->lock, flags);wait_for_completion (cmd->completion); +if (cmd->status !=COMP_SUCCESS ) + ret = -EIO ; err_out:kfree (cmd->completion);kfree (cmd);
Signature · 1 line
2.48.1
PATCH v3 1/1 usb: xhci: Fix debugfs bandwidth reporting
In reply to Michal PecioReplace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report failures properly. No attempt made at "tunneling" all possible comp codes through errno, debugfs users may inspect the result through event-ring/trbs.
Rename port_bandwidth to port-bandwidth for consistency with others.
---
New in v3:
- rename port_bandwidth to port-bandwidth
New in v2:
- print an error string instead of returning -EIO
- document known and sometimes unobvious error cases
drivers/usb/host/xhci-debugfs.c | 12 ++++++++---- drivers/usb/host/xhci.c | 9 ++++++++- 2 files changed, 16 insertions(+), 5 deletions(-)
drivers/usb/host/xhci-debugfs.c +8 -4
@@ -703,6 +703,10 @@ static int xhci_port_bw_show(struct xhci_hcd *xhci, u8 dev_speed,seq_printf (s,"port[%d] available bw: %d%%.\n" , i, ctx->bytes[i]); err_out: +if (ret == -EIO ) { +seq_puts (s,"Get Port Bandwidth failed\n" ); + ret =0 ; + }pm_runtime_put_sync (dev);xhci_free_port_bw_ctx (xhci, ctx);return ret;
@@ -713,7 +717,7 @@ static int xhci_ss_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_SUPER , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_SS ), s);return ret; }
@@ -722,7 +726,7 @@ static int xhci_hs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_HIGH , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_HS ), s);return ret; }
@@ -731,7 +735,7 @@ static int xhci_fs_bw_show(struct seq_file *s, void *unused)int ret;struct xhci_hcd *xhci = (struct xhci_hcd *)s->private; - ret =xhci_port_bw_show (xhci,USB_SPEED_FULL , s); + ret =xhci_port_bw_show (xhci,DEV_PORT_SPEED (XDEV_FS ), s);return ret; }
@@ -767,7 +771,7 @@ static const struct file_operations bw_fops = {static void xhci_debugfs_create_bandwidth (struct xhci_hcd *xhci,struct dentry *parent) { - parent =debugfs_create_dir ("port_bandwidth" , parent); + parent =debugfs_create_dir ("port-bandwidth" , parent); xhci_debugfs_create_files(xhci, bw_context_files, ARRAY_SIZE(bw_context_files),
drivers/usb/host/xhci.c +8 -1
@@ -3262,7 +3262,12 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) }EXPORT_SYMBOL_GPL (xhci_reset_bandwidth); -/* Get the available bandwidth of the ports under the xhci roothub */ +/* +* Get the available bandwidth of the ports under the xhci roothub. +* EIO means the command failed: command not implemented or unsupported +* speed (TRB Error), some ASMedia complete with Parameter Error when +* querying the root hub (slot_id = 0), or other error or timeout. +*/ int xhci_get_port_bandwidth (struct xhci_hcd *xhci,struct xhci_container_ctx *ctx,u8 dev_speed) {
@@ -3291,6 +3296,8 @@ int xhci_get_port_bandwidth(struct xhci_hcd *xhci, struct xhci_container_ctx *ctspin_unlock_irqrestore (&xhci->lock, flags);wait_for_completion (cmd->completion); +if (cmd->status !=COMP_SUCCESS ) + ret = -EIO ; err_out:kfree (cmd->completion);kfree (cmd);
Signature · 1 line
2.48.1
Quoted 11 lines · Michal Pecio
Quoted 10 lines · Mathias Nyman
Quoted 9 lines · Michal Pecio
Replace kernel USB speed numbers with xHCI protocol IDs expected by HW. They are numerically equal up to high speed, but instead of SuperSpeed we were querying SuperSpeed+.
Gen1 hardware rejects such commands with TRB Error, which resulted in zero available bandwidth being shown.
While at that, report command failure as IO error, not zero bandwidth.
Quoted 9 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Michal Pecio <[email protected]>Added to queue
Hi,
Thanks for taking the patch, but can we have a last minute swap for a v2 or optionally v3?
Sure, no problem.
Quoted 10 lines
Problem is that returning
-EIOis common (the command is optional) and it upsets userspace: "grep -r" spams the console with errors, "zip -R" terminates and doesn't include remaining files, etc. So I would prefer to print an error string in this case. "Real" errors will still be returned ordinarily.The optional v3 also renames the new directory for consistency. Technically it's a breaking change, but I believe it's permissible in debugfs, particularly for an interface only added recently.
lets stick with v2, avoiding possible breakage due to debugfs file rename.
Thanks
Mathias