[PATCH v2] USB: complain if userspace resets an active endpoint

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxx>
Suggested-by: Bjørn Mork <bjorn@xxxxxxx>
CC: Stanislaw Gruszka <sgruszka@xxxxxxxxxx>

---


v2: Change pr_warn() to dev_warn().

[as1741b]


 drivers/usb/core/devio.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Index: usb-3.14/drivers/usb/core/devio.c
===================================================================
--- usb-3.14.orig/drivers/usb/core/devio.c
+++ usb-3.14/drivers/usb/core/devio.c
@@ -1043,6 +1043,20 @@ static int proc_bulk(struct dev_state *p
 	return ret;
 }
 
+static void check_reset_of_active_ep(struct usb_device *udev,
+		unsigned int epnum, char *ioctl_name)
+{
+	struct usb_host_endpoint **eps;
+	struct usb_host_endpoint *ep;
+
+	eps = (epnum & USB_DIR_IN) ? udev->ep_in : udev->ep_out;
+	ep = eps[epnum & 0x0f];
+	if (ep && !list_empty(&ep->urb_list))
+		dev_warn(&udev->dev, "Process %d (%s) called USBDEVFS_%s for active endpoint 0x%02x\n",
+				task_pid_nr(current), current->comm,
+				ioctl_name, epnum);
+}
+
 static int proc_resetep(struct dev_state *ps, void __user *arg)
 {
 	unsigned int ep;
@@ -1056,6 +1070,7 @@ static int proc_resetep(struct dev_state
 	ret = checkintf(ps, ret);
 	if (ret)
 		return ret;
+	check_reset_of_active_ep(ps->dev, ep, "RESETEP");
 	usb_reset_endpoint(ps->dev, ep);
 	return 0;
 }
@@ -1074,6 +1089,7 @@ static int proc_clearhalt(struct dev_sta
 	ret = checkintf(ps, ret);
 	if (ret)
 		return ret;
+	check_reset_of_active_ep(ps->dev, ep, "CLEAR_HALT");
 	if (ep & USB_DIR_IN)
 		pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f);
 	else

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux