aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-02-20 10:49:30 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-24 20:07:53 -0500
commitf080a51bef2caa9b0f647dc430bc608d5723ac29 (patch)
treed10cd4984eb5988cde6b19c4eb5f082204e3d9e0 /drivers/usb/core/devio.c
parent42d182124801573e06284200d81c3963962e753d (diff)
USB: complain if userspace resets an active endpoint
It is an error for a driver to call usb_clear_halt() or usb_reset_endpoint() while there are URBs queued for the endpoint, because the end result is not well defined. At the time the endpoint gets reset, it may or may not be actively running. As far as I know, no kernel drivers do this. But some userspace drivers do, and it seems like a good idea to bring this error to their attention. This patch adds a warning to the kernel log whenever a program invokes the USBDEVFS_CLEAR_HALT or USBDEVFS_RESETEP ioctls at an inappropriate time, and includes the name of the program. This will make it clear that any subsequent errors are not due to the misbehavior of a kernel driver. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Suggested-by: Bjørn Mork <bjorn@mork.no> CC: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 90e18f6fa2bb..f3ba2e076ee3 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1043,6 +1043,20 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
1043 return ret; 1043 return ret;
1044} 1044}
1045 1045
1046static void check_reset_of_active_ep(struct usb_device *udev,
1047 unsigned int epnum, char *ioctl_name)
1048{
1049 struct usb_host_endpoint **eps;
1050 struct usb_host_endpoint *ep;
1051
1052 eps = (epnum & USB_DIR_IN) ? udev->ep_in : udev->ep_out;
1053 ep = eps[epnum & 0x0f];
1054 if (ep && !list_empty(&ep->urb_list))
1055 dev_warn(&udev->dev, "Process %d (%s) called USBDEVFS_%s for active endpoint 0x%02x\n",
1056 task_pid_nr(current), current->comm,
1057 ioctl_name, epnum);
1058}
1059
1046static int proc_resetep(struct dev_state *ps, void __user *arg) 1060static int proc_resetep(struct dev_state *ps, void __user *arg)
1047{ 1061{
1048 unsigned int ep; 1062 unsigned int ep;
@@ -1056,6 +1070,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)
1056 ret = checkintf(ps, ret); 1070 ret = checkintf(ps, ret);
1057 if (ret) 1071 if (ret)
1058 return ret; 1072 return ret;
1073 check_reset_of_active_ep(ps->dev, ep, "RESETEP");
1059 usb_reset_endpoint(ps->dev, ep); 1074 usb_reset_endpoint(ps->dev, ep);
1060 return 0; 1075 return 0;
1061} 1076}
@@ -1074,6 +1089,7 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg)
1074 ret = checkintf(ps, ret); 1089 ret = checkintf(ps, ret);
1075 if (ret) 1090 if (ret)
1076 return ret; 1091 return ret;
1092 check_reset_of_active_ep(ps->dev, ep, "CLEAR_HALT");
1077 if (ep & USB_DIR_IN) 1093 if (ep & USB_DIR_IN)
1078 pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); 1094 pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f);
1079 else 1095 else