From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:35147 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753592AbbGaQ7N (ORCPT ); Fri, 31 Jul 2015 12:59:13 -0400 Subject: Patch "USB: usbfs: allow URBs to be reaped after disconnection" has been added to the 3.14-stable tree To: stern@rowland.harvard.edu, christopher.a.dickens@gmail.com, gregkh@linuxfoundation.org, hdegoede@redhat.com Cc: , From: Date: Fri, 31 Jul 2015 09:59:12 -0700 Message-ID: <143836195214194@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: This is a note to let you know that I've just added the patch titled USB: usbfs: allow URBs to be reaped after disconnection to the 3.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: usb-usbfs-allow-urbs-to-be-reaped-after-disconnection.patch and it can be found in the queue-3.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >>From 3f2cee73b650921b2e214bf487b2061a1c266504 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 29 Jan 2015 11:29:13 -0500 Subject: USB: usbfs: allow URBs to be reaped after disconnection From: Alan Stern commit 3f2cee73b650921b2e214bf487b2061a1c266504 upstream. The usbfs API has a peculiar hole: Users are not allowed to reap their URBs after the device has been disconnected. There doesn't seem to be any good reason for this; it is an ad-hoc inconsistency. The patch allows users to issue the USBDEVFS_REAPURB and USBDEVFS_REAPURBNDELAY ioctls (together with their 32-bit counterparts on 64-bit systems) even after the device is gone. If no URBs are pending for a disconnected device then the ioctls will return -ENODEV rather than -EAGAIN, because obviously no new URBs will ever be able to complete. The patch also adds a new capability flag for USBDEVFS_GET_CAPABILITIES to indicate that the reap-after-disconnect feature is supported. Signed-off-by: Alan Stern Tested-by: Chris Dickens Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 63 ++++++++++++++++++++++---------------- include/uapi/linux/usbdevice_fs.h | 3 + 2 files changed, 39 insertions(+), 27 deletions(-) --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1591,7 +1591,7 @@ static struct async *reap_as(struct dev_ for (;;) { __set_current_state(TASK_INTERRUPTIBLE); as = async_getcompleted(ps); - if (as) + if (as || !connected(ps)) break; if (signal_pending(current)) break; @@ -1614,7 +1614,7 @@ static int proc_reapurb(struct dev_state } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) @@ -1623,10 +1623,11 @@ static int proc_reapurbnonblock(struct d struct async *as; as = async_getcompleted(ps); - retval = -EAGAIN; if (as) { retval = processcompl(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -1756,7 +1757,7 @@ static int proc_reapurb_compat(struct de } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) @@ -1764,11 +1765,12 @@ static int proc_reapurbnonblock_compat(s int retval; struct async *as; - retval = -EAGAIN; as = async_getcompleted(ps); if (as) { retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -1940,7 +1942,8 @@ static int proc_get_capabilities(struct { __u32 caps; - caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; + caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM | + USBDEVFS_CAP_REAP_AFTER_DISCONNECT; if (!ps->dev->bus->no_stop_on_short) caps |= USBDEVFS_CAP_BULK_CONTINUATION; if (ps->dev->bus->sg_tablesize) @@ -2001,6 +2004,32 @@ static long usbdev_do_ioctl(struct file return -EPERM; usb_lock_device(dev); + + /* Reap operations are allowed even after disconnection */ + switch (cmd) { + case USBDEVFS_REAPURB: + snoop(&dev->dev, "%s: REAPURB\n", __func__); + ret = proc_reapurb(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY: + snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); + ret = proc_reapurbnonblock(ps, p); + goto done; + +#ifdef CONFIG_COMPAT + case USBDEVFS_REAPURB32: + snoop(&dev->dev, "%s: REAPURB32\n", __func__); + ret = proc_reapurb_compat(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY32: + snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); + ret = proc_reapurbnonblock_compat(ps, p); + goto done; +#endif + } + if (!connected(ps)) { usb_unlock_device(dev); return -ENODEV; @@ -2094,16 +2123,6 @@ static long usbdev_do_ioctl(struct file inode->i_mtime = CURRENT_TIME; break; - case USBDEVFS_REAPURB32: - snoop(&dev->dev, "%s: REAPURB32\n", __func__); - ret = proc_reapurb_compat(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY32: - snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); - ret = proc_reapurbnonblock_compat(ps, p); - break; - case USBDEVFS_IOCTL32: snoop(&dev->dev, "%s: IOCTL32\n", __func__); ret = proc_ioctl_compat(ps, ptr_to_compat(p)); @@ -2115,16 +2134,6 @@ static long usbdev_do_ioctl(struct file ret = proc_unlinkurb(ps, p); break; - case USBDEVFS_REAPURB: - snoop(&dev->dev, "%s: REAPURB\n", __func__); - ret = proc_reapurb(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY: - snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); - ret = proc_reapurbnonblock(ps, p); - break; - case USBDEVFS_DISCSIGNAL: snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); ret = proc_disconnectsignal(ps, p); @@ -2161,6 +2170,8 @@ static long usbdev_do_ioctl(struct file ret = proc_disconnect_claim(ps, p); break; } + + done: usb_unlock_device(dev); if (ret >= 0) inode->i_atime = CURRENT_TIME; --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h @@ -125,11 +125,12 @@ struct usbdevfs_hub_portinfo { char port [127]; /* e.g. port 3 connects to device 27 */ }; -/* Device capability flags */ +/* System and bus capability flags */ #define USBDEVFS_CAP_ZERO_PACKET 0x01 #define USBDEVFS_CAP_BULK_CONTINUATION 0x02 #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04 #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 +#define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ Patches currently in stable-queue which might be from stern@rowland.harvard.edu are queue-3.14/usb-usbfs-allow-urbs-to-be-reaped-after-disconnection.patch queue-3.14/usb-devio-fix-a-condition-in-async_completed.patch