file storage gadget: Compilation as built-in?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

I have some questions concerning to the file storage gadget (g_file_storage) and its compilation as built-in driver: AFAIK, the driver initialization fails cause the file system is not available when the driver tries to init the backing file (please correct me if I'm wrong). Now, for solving this issue I have used a notifier-chain that informs about the availability of the root file system (see below patch). This implementation works when the driver is compiled as loadable module too.

Now to my questions: Do you see any disavantages in my proposed solution? Do you expect any problems when using a notifier in that way? Or do you have a better idea for solving the mentioned issue?


Thanks in advance, and sorry for the possible silly questions,


Luis



diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c4e62a6..63daf2f 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4132,7 +4132,7 @@ static int __init fsg_alloc(void)
 }


-static int __init fsg_init(void)
+static int __init fsg_init_rootfs(void)
 {
 	int		rc;
 	struct fsg_dev	*fsg;
@@ -4144,6 +4144,24 @@ static int __init fsg_init(void)
 		kref_put(&fsg->ref, fsg_release);
 	return rc;
 }
+
+static int mount_rootfs_notifier_event(struct notifier_block *this, unsigned long event,
+				       void *ptr)
+{
+	int ret;
+	ret = fsg_init_rootfs();
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block mount_rootfs_fsg_notifier = {
+        .notifier_call  = mount_rootfs_notifier_event,
+};
+
+static int __init fsg_init(void)
+{
+	return mount_rootfs_register_notifier(&mount_rootfs_fsg_notifier);
+}
+
 module_init(fsg_init);


diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index b86fa2f..9443a8b 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -151,6 +151,21 @@ extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
 extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
 	unsigned long val, void *v, int nr_to_call, int *nr_calls);

+extern int __mount_rootfs_register_notifier(struct notifier_block *nb);
+extern int __mount_rootfs_unregister_notifier(struct notifier_block *nb);
+
+#if defined(MODULE)
+static inline int mount_rootfs_register_notifier(struct notifier_block *nb)
+{
+	int ret = -EINVAL;
+	if (nb->notifier_call)
+		ret = nb->notifier_call(nb, 0, NULL);
+	return ret;
+}
+#else
+# define mount_rootfs_register_notifier(nb)	__mount_rootfs_register_notifier(nb)
+#endif
+
 #define NOTIFY_DONE		0x0000		/* Don't care */
 #define NOTIFY_OK		0x0001		/* Suits me */
 #define NOTIFY_STOP_MASK	0x8000		/* Don't call further */
diff --git a/init/do_mounts.c b/init/do_mounts.c
index d055b19..33a16e2 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -29,6 +29,10 @@ static int __initdata root_wait;

 dev_t ROOT_DEV;

+/* Internal variables for the mounted rootfs notification */
+static struct work_struct mount_rootfs_worker;
+static RAW_NOTIFIER_HEAD(mount_rootfs_chain);
+
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
@@ -212,6 +216,24 @@ static void __init get_fs_names(char *page)
 	*s = '\0';
 }

+static void mount_rootfs_notifier_work_func(struct work_struct *work)
+{
+	raw_notifier_call_chain(&mount_rootfs_chain, 0, NULL);
+}
+
+int __mount_rootfs_register_notifier(struct notifier_block *nb)
+{
+	return raw_notifier_chain_register(&mount_rootfs_chain, nb);
+}
+
+int __mount_rootfs_unregister_notifier(struct notifier_block *nb)
+{
+	return raw_notifier_chain_unregister(&mount_rootfs_chain, nb);
+}
+
+EXPORT_SYMBOL(__mount_rootfs_register_notifier);
+EXPORT_SYMBOL(__mount_rootfs_unregister_notifier);
+
 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
 {
 	int err = sys_mount(name, "/root", fs, flags, data);
@@ -224,6 +246,11 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)
 	       current->fs->pwd.mnt->mnt_sb->s_type->name,
 	       current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?
 	       " readonly" : "");
+
+	/* Init the data for the rootfs notifier */
+	INIT_WORK(&mount_rootfs_worker, mount_rootfs_notifier_work_func);
+	schedule_work(&mount_rootfs_worker);
+	
 	return 0;
 }


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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux