Skip to content

Commit

Permalink
usb: gadget: ffs: add eventfd notification about ffs events
Browse files Browse the repository at this point in the history
Add eventfd which notifies userspace about ep0 events and AIO completion
events. It simplifies using of FunctionFS with event loop, because now
we need to poll on single file (instead of polling on ep0 and eventfd's
supplied to AIO layer).

FunctionFS eventfd is not triggered if another eventfd is supplied to
AIO layer (in AIO request). It can be useful, for example, when we want
to handle AIO transations for chosen endpoint in separate thread.

Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Robert Baldyga authored and Felipe Balbi committed Jan 27, 2015
1 parent acba23f commit 5e33f6f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
29 changes: 28 additions & 1 deletion drivers/usb/gadget/function/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/aio.h>
#include <linux/mmu_context.h>
#include <linux/poll.h>
#include <linux/eventfd.h>

#include "u_fs.h"
#include "u_f.h"
Expand Down Expand Up @@ -153,6 +154,8 @@ struct ffs_io_data {

struct usb_ep *ep;
struct usb_request *req;

struct ffs_data *ffs;
};

struct ffs_desc_helper {
Expand Down Expand Up @@ -674,6 +677,9 @@ static void ffs_user_copy_worker(struct work_struct *work)

aio_complete(io_data->kiocb, ret, ret);

if (io_data->ffs->ffs_eventfd && !io_data->kiocb->ki_eventfd)
eventfd_signal(io_data->ffs->ffs_eventfd, 1);

usb_ep_free_request(io_data->ep, io_data->req);

io_data->kiocb->private = NULL;
Expand Down Expand Up @@ -827,6 +833,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
io_data->buf = data;
io_data->ep = ep->ep;
io_data->req = req;
io_data->ffs = epfile->ffs;

req->context = io_data;
req->complete = ffs_epfile_async_io_complete;
Expand Down Expand Up @@ -1510,6 +1517,9 @@ static void ffs_data_clear(struct ffs_data *ffs)
if (ffs->epfiles)
ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);

if (ffs->ffs_eventfd)
eventfd_ctx_put(ffs->ffs_eventfd);

kfree(ffs->raw_descs_data);
kfree(ffs->raw_strings);
kfree(ffs->stringtabs);
Expand Down Expand Up @@ -2169,7 +2179,8 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
FUNCTIONFS_HAS_HS_DESC |
FUNCTIONFS_HAS_SS_DESC |
FUNCTIONFS_HAS_MS_OS_DESC |
FUNCTIONFS_VIRTUAL_ADDR)) {
FUNCTIONFS_VIRTUAL_ADDR |
FUNCTIONFS_EVENTFD)) {
ret = -ENOSYS;
goto error;
}
Expand All @@ -2180,6 +2191,20 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
goto error;
}

if (flags & FUNCTIONFS_EVENTFD) {
if (len < 4)
goto error;
ffs->ffs_eventfd =
eventfd_ctx_fdget((int)get_unaligned_le32(data));
if (IS_ERR(ffs->ffs_eventfd)) {
ret = PTR_ERR(ffs->ffs_eventfd);
ffs->ffs_eventfd = NULL;
goto error;
}
data += 4;
len -= 4;
}

/* Read fs_count, hs_count and ss_count (if present) */
for (i = 0; i < 3; ++i) {
if (!(flags & (1 << i))) {
Expand Down Expand Up @@ -2454,6 +2479,8 @@ static void __ffs_event_add(struct ffs_data *ffs,
pr_vdebug("adding event %d\n", type);
ffs->ev.types[ffs->ev.count++] = type;
wake_up_locked(&ffs->ev.waitq);
if (ffs->ffs_eventfd)
eventfd_signal(ffs->ffs_eventfd, 1);
}

static void ffs_event_add(struct ffs_data *ffs,
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/function/u_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ struct ffs_data {
kgid_t gid;
} file_perms;

struct eventfd_ctx *ffs_eventfd;
bool no_disconnect;
struct work_struct reset_work;

Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/usb/functionfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum functionfs_flags {
FUNCTIONFS_HAS_SS_DESC = 4,
FUNCTIONFS_HAS_MS_OS_DESC = 8,
FUNCTIONFS_VIRTUAL_ADDR = 16,
FUNCTIONFS_EVENTFD = 32,
};

/* Descriptor of an non-audio endpoint */
Expand Down

0 comments on commit 5e33f6f

Please sign in to comment.