usb: gadget: f_fs: add poll for endpoint 0 66/87866/2 accepted/tizen/mobile/20160912.093254 submit/tizen/20160912.020407
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Wed, 7 Sep 2016 19:24:12 +0000 (21:24 +0200)
committerJoonyoung Shim <jy0922.shim@samsung.com>
Mon, 12 Sep 2016 01:56:20 +0000 (10:56 +0900)
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>
[Backported from mainline commit 23de91e]
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Change-Id: I4286847252357b4796cc3794ce71d5a4ec2af9f5

drivers/usb/gadget/f_fs.c

index 250fc8a..ac03922 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/usb/composite.h>
 #include <linux/usb/functionfs.h>
 
+#include <linux/poll.h>
+
 
 #define FUNCTIONFS_MAGIC       0xa647361 /* Chosen by a honest dice roll ;) */
 
@@ -736,6 +738,47 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
        return ret;
 }
 
+static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait)
+{
+       struct ffs_data *ffs = file->private_data;
+       unsigned int mask = POLLWRNORM;
+       int ret;
+
+       poll_wait(file, &ffs->ev.waitq, wait);
+
+       ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
+       if (unlikely(ret < 0))
+               return mask;
+
+       switch (ffs->state) {
+       case FFS_READ_DESCRIPTORS:
+       case FFS_READ_STRINGS:
+               mask |= POLLOUT;
+               break;
+
+       case FFS_ACTIVE:
+               switch (ffs->setup_state) {
+               case FFS_NO_SETUP:
+                       if (ffs->ev.count)
+                               mask |= POLLIN;
+                       break;
+
+               case FFS_SETUP_PENDING:
+               case FFS_SETUP_CANCELED:
+                       mask |= (POLLIN | POLLOUT);
+                       break;
+               }
+       case FFS_CLOSING:
+               break;
+       case FFS_DEACTIVATED:
+               break;
+       }
+
+       mutex_unlock(&ffs->mutex);
+
+       return mask;
+}
+
 static const struct file_operations ffs_ep0_operations = {
        .llseek =       no_llseek,
 
@@ -744,6 +787,7 @@ static const struct file_operations ffs_ep0_operations = {
        .read =         ffs_ep0_read,
        .release =      ffs_ep0_release,
        .unlocked_ioctl =       ffs_ep0_ioctl,
+       .poll =         ffs_ep0_poll,
 };