linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] usb: gadget: f_fs: add "zombie" mode
@ 2014-10-06 11:25 Robert Baldyga
  2014-10-06 12:36 ` Michal Nazarewicz
  2014-10-07  2:28 ` Felipe Balbi
  0 siblings, 2 replies; 21+ messages in thread
From: Robert Baldyga @ 2014-10-06 11:25 UTC (permalink / raw)
  To: balbi
  Cc: gregkh, linux-usb, linux-kernel, mina86, andrzej.p, k.opasiak,
	Robert Baldyga

Since we can compose gadgets from many functions, there is the problem
related to gadget breakage while FunctionFS daemon being closed. In some
cases it's strongly desired to keep gadget alive for a while, despite
FunctionFS files are closed, to allow another functions to complete
some presumably critical operations.

For this purpose this patch introduces "zombie" mode. It can be enabled
by setting mount option "zombie=1", and results with defering function
closure to the moment of reopening ep0 file or filesystem umount.

When ffs->state == FFS_ZOMBIE:
- function is still binded and visible to host,
- setup requests are automatically stalled,
- all another transfers are refused,
- opening ep0 causes function close, and then FunctionFS is ready for
  descriptors and string write,
- umount of functionfs cause function close.

Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
---
 drivers/usb/gadget/function/f_fs.c | 25 ++++++++++++++++++++++---
 drivers/usb/gadget/function/u_fs.h |  4 ++++
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 7c6771d..5581bec 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -606,6 +606,8 @@ static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait)
 		}
 	case FFS_CLOSING:
 		break;
+	case FFS_ZOMBIE:
+		break;
 	}
 
 	mutex_unlock(&ffs->mutex);
@@ -1152,6 +1154,7 @@ struct ffs_sb_fill_data {
 	struct ffs_file_perms perms;
 	umode_t root_mode;
 	const char *dev_name;
+	bool zombie_mode;
 	struct ffs_data *ffs_data;
 };
 
@@ -1222,6 +1225,12 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
 
 		/* Interpret option */
 		switch (eq - opts) {
+		case 6:
+			if (!memcmp(opts, "zombie", 6))
+				data->zombie_mode  = !!value;
+			else
+				goto invalid;
+			break;
 		case 5:
 			if (!memcmp(opts, "rmode", 5))
 				data->root_mode  = (value & 0555) | S_IFDIR;
@@ -1286,6 +1295,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
 			.gid = GLOBAL_ROOT_GID,
 		},
 		.root_mode = S_IFDIR | 0500,
+		.zombie_mode = false,
 	};
 	struct dentry *rv;
 	int ret;
@@ -1302,6 +1312,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
 	if (unlikely(!ffs))
 		return ERR_PTR(-ENOMEM);
 	ffs->file_perms = data.perms;
+	ffs->zombie_mode = data.zombie_mode;
 
 	ffs->dev_name = kstrdup(dev_name, GFP_KERNEL);
 	if (unlikely(!ffs->dev_name)) {
@@ -1389,7 +1400,9 @@ static void ffs_data_opened(struct ffs_data *ffs)
 	ENTER();
 
 	atomic_inc(&ffs->ref);
-	atomic_inc(&ffs->opened);
+	if (atomic_add_return(1, &ffs->opened) == 1)
+		if (ffs->state == FFS_ZOMBIE)
+			ffs_data_reset(ffs);
 }
 
 static void ffs_data_put(struct ffs_data *ffs)
@@ -1411,8 +1424,14 @@ static void ffs_data_closed(struct ffs_data *ffs)
 	ENTER();
 
 	if (atomic_dec_and_test(&ffs->opened)) {
-		ffs->state = FFS_CLOSING;
-		ffs_data_reset(ffs);
+		if (ffs->zombie_mode) {
+			ffs->state = FFS_ZOMBIE;
+			if (ffs->setup_state == FFS_SETUP_PENDING)
+				__ffs_ep0_stall(ffs);
+		} else {
+			ffs->state = FFS_CLOSING;
+			ffs_data_reset(ffs);
+		}
 	}
 
 	ffs_data_put(ffs);
diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h
index cd128e3..7a4abbe 100644
--- a/drivers/usb/gadget/function/u_fs.h
+++ b/drivers/usb/gadget/function/u_fs.h
@@ -92,6 +92,8 @@ enum ffs_state {
 	 */
 	FFS_ACTIVE,
 
+	FFS_ZOMBIE,
+
 	/*
 	 * All endpoints have been closed.  This state is also set if
 	 * we encounter an unrecoverable error.  The only
@@ -251,6 +253,8 @@ struct ffs_data {
 		kgid_t				gid;
 	}				file_perms;
 
+	bool zombie_mode;
+
 	/*
 	 * The endpoint files, filled by ffs_epfiles_create(),
 	 * destroyed by ffs_epfiles_destroy().
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-10-09 10:56 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-06 11:25 [PATCH] usb: gadget: f_fs: add "zombie" mode Robert Baldyga
2014-10-06 12:36 ` Michal Nazarewicz
2014-10-06 12:51   ` Robert Baldyga
2014-10-06 14:07     ` Michal Nazarewicz
2014-10-07  2:28 ` Felipe Balbi
2014-10-07  6:33   ` Robert Baldyga
2014-10-07 14:06     ` Felipe Balbi
2014-10-07 15:01       ` Krzysztof Opasiak
2014-10-07 15:28         ` Felipe Balbi
2014-10-07 16:37           ` Krzysztof Opasiak
2014-10-07 16:51             ` Felipe Balbi
2014-10-07 17:15               ` Alan Stern
2014-10-07 17:57                 ` Felipe Balbi
2014-10-07 18:42                   ` Alan Stern
2014-10-07 18:57                     ` Felipe Balbi
2014-10-07 19:16                       ` Alan Stern
2014-10-07 20:08                     ` Michal Nazarewicz
2014-10-08 10:09                       ` Krzysztof Opasiak
2014-10-08 11:28                         ` Michal Nazarewicz
2014-10-08 14:52                       ` Alan Stern
2014-10-09 10:56                         ` Michal Nazarewicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).