There were individual waitqueues for each epfile but eps_enable
would iterate through all of them, resulting in essentially the
same wakeup time.

The waitqueue represents the function being enabled, so a central
waitqueue in ffs_data makes more sense and is less redundant.

Also use wake_up_interruptible to reflect use of
wait_event_interruptible.

Signed-off-by: Jerry Zhang <[email protected]>
---
 drivers/usb/gadget/function/f_fs.c | 19 ++++++++++---------
 drivers/usb/gadget/function/u_fs.h |  3 +++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index 48de9e013ba8..0abb2e14eb9a 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -127,7 +127,6 @@ struct ffs_ep {
 struct ffs_epfile {
        /* Protects ep->ep and ep->req. */
        struct mutex                    mutex;
-       wait_queue_head_t               wait;
 
        struct ffs_data                 *ffs;
        struct ffs_ep                   *ep;    /* P: ffs->eps_lock */
@@ -890,7 +889,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct 
ffs_io_data *io_data)
                if (file->f_flags & O_NONBLOCK)
                        return -EAGAIN;
 
-               ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
+               ret = wait_event_interruptible(
+                               epfile->ffs->wait, (ep = epfile->ep));
                if (ret)
                        return -EINTR;
        }
@@ -1204,7 +1204,8 @@ static long ffs_epfile_ioctl(struct file *file, unsigned 
code,
                if (file->f_flags & O_NONBLOCK)
                        return -EAGAIN;
 
-               ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
+               ret = wait_event_interruptible(
+                               epfile->ffs->wait, (ep = epfile->ep));
                if (ret)
                        return -EINTR;
        }
@@ -1602,7 +1603,8 @@ static void ffs_data_put(struct ffs_data *ffs)
                pr_info("%s(): freeing\n", __func__);
                ffs_data_clear(ffs);
                BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
-                      waitqueue_active(&ffs->ep0req_completion.wait));
+                      waitqueue_active(&ffs->ep0req_completion.wait) ||
+                      waitqueue_active(&ffs->wait));
                kfree(ffs->dev_name);
                kfree(ffs);
        }
@@ -1649,6 +1651,7 @@ static struct ffs_data *ffs_data_new(void)
        mutex_init(&ffs->mutex);
        spin_lock_init(&ffs->eps_lock);
        init_waitqueue_head(&ffs->ev.waitq);
+       init_waitqueue_head(&ffs->wait);
        init_completion(&ffs->ep0req_completion);
 
        /* XXX REVISIT need to update it in some places, or do we? */
@@ -1770,7 +1773,6 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
        for (i = 1; i <= count; ++i, ++epfile) {
                epfile->ffs = ffs;
                mutex_init(&epfile->mutex);
-               init_waitqueue_head(&epfile->wait);
                if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
                        sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]);
                else
@@ -1795,8 +1797,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile 
*epfiles, unsigned count)
        ENTER();
 
        for (; count; --count, ++epfile) {
-               BUG_ON(mutex_is_locked(&epfile->mutex) ||
-                      waitqueue_active(&epfile->wait));
+               BUG_ON(mutex_is_locked(&epfile->mutex));
                if (epfile->dentry) {
                        d_delete(epfile->dentry);
                        dput(epfile->dentry);
@@ -1883,11 +1884,11 @@ static int ffs_func_eps_enable(struct ffs_function 
*func)
                        break;
                }
 
-               wake_up(&epfile->wait);
-
                ++ep;
                ++epfile;
        }
+
+       wake_up_interruptible(&ffs->wait);
        spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
 
        return ret;
diff --git a/drivers/usb/gadget/function/u_fs.h 
b/drivers/usb/gadget/function/u_fs.h
index 4b6969451cdc..052ea89c7f99 100644
--- a/drivers/usb/gadget/function/u_fs.h
+++ b/drivers/usb/gadget/function/u_fs.h
@@ -214,6 +214,9 @@ struct ffs_data {
 #define FFS_FL_CALL_CLOSED_CALLBACK 0
 #define FFS_FL_BOUND                1
 
+       /* For waking up blocked threads when function is enabled. */
+       wait_queue_head_t               wait;
+
        /* Active function */
        struct ffs_function             *func;
 
-- 
2.12.2.816.g2cccc81164-goog

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

Reply via email to