diff options
author | Robert Baldyga <r.baldyga@samsung.com> | 2014-02-10 04:42:43 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-02-18 11:53:01 -0500 |
commit | 23de91e970a410a30b5927b9a749ed1dfd914140 (patch) | |
tree | ee67f15420838b54584eddafde60e8dbc797ab98 /drivers/usb/gadget | |
parent | 0a7b1f8a70a59fd8215a937f77da20e003b9fc49 (diff) |
usb: gadget: f_fs: add poll for endpoint 0
This patch adds poll function for file representing ep0.
Ability of read from or write to ep0 file is related with actual state of ffs:
- When desctiptors or strings are not written yet, POLLOUT flag is set.
- If there is any event to read, POLLIN flag is set.
- If setup request was read, POLLIN and POLLOUT flag is set, to allow
send response (by performing I/O operation consistent with setup request
direction) or set stall (by performing I/O operation opposite setup
request direction).
Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index b65a5029deed..20321631f0f4 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/usb/composite.h> | 28 | #include <linux/usb/composite.h> |
29 | #include <linux/usb/functionfs.h> | 29 | #include <linux/usb/functionfs.h> |
30 | 30 | ||
31 | #include <linux/poll.h> | ||
32 | |||
31 | #include "u_fs.h" | 33 | #include "u_fs.h" |
32 | #include "configfs.h" | 34 | #include "configfs.h" |
33 | 35 | ||
@@ -570,6 +572,45 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) | |||
570 | return ret; | 572 | return ret; |
571 | } | 573 | } |
572 | 574 | ||
575 | static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait) | ||
576 | { | ||
577 | struct ffs_data *ffs = file->private_data; | ||
578 | unsigned int mask = POLLWRNORM; | ||
579 | int ret; | ||
580 | |||
581 | poll_wait(file, &ffs->ev.waitq, wait); | ||
582 | |||
583 | ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK); | ||
584 | if (unlikely(ret < 0)) | ||
585 | return mask; | ||
586 | |||
587 | switch (ffs->state) { | ||
588 | case FFS_READ_DESCRIPTORS: | ||
589 | case FFS_READ_STRINGS: | ||
590 | mask |= POLLOUT; | ||
591 | break; | ||
592 | |||
593 | case FFS_ACTIVE: | ||
594 | switch (ffs->setup_state) { | ||
595 | case FFS_NO_SETUP: | ||
596 | if (ffs->ev.count) | ||
597 | mask |= POLLIN; | ||
598 | break; | ||
599 | |||
600 | case FFS_SETUP_PENDING: | ||
601 | case FFS_SETUP_CANCELLED: | ||
602 | mask |= (POLLIN | POLLOUT); | ||
603 | break; | ||
604 | } | ||
605 | case FFS_CLOSING: | ||
606 | break; | ||
607 | } | ||
608 | |||
609 | mutex_unlock(&ffs->mutex); | ||
610 | |||
611 | return mask; | ||
612 | } | ||
613 | |||
573 | static const struct file_operations ffs_ep0_operations = { | 614 | static const struct file_operations ffs_ep0_operations = { |
574 | .llseek = no_llseek, | 615 | .llseek = no_llseek, |
575 | 616 | ||
@@ -578,6 +619,7 @@ static const struct file_operations ffs_ep0_operations = { | |||
578 | .read = ffs_ep0_read, | 619 | .read = ffs_ep0_read, |
579 | .release = ffs_ep0_release, | 620 | .release = ffs_ep0_release, |
580 | .unlocked_ioctl = ffs_ep0_ioctl, | 621 | .unlocked_ioctl = ffs_ep0_ioctl, |
622 | .poll = ffs_ep0_poll, | ||
581 | }; | 623 | }; |
582 | 624 | ||
583 | 625 | ||