Thread (7 messages) 7 messages, 2 authors, 2006-06-20

Re: [1/1] connector: export cn_already_initialized.

flat view

From: Evgeniy Polyakov <hidden>
Date: 2006-06-19 05:30:45
Subsystem: networking drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

On Tue, May 16, 2006 at 04:14:06PM -0700, David S. Miller (davem@davemloft.net) wrote:
From: Evgeniy Polyakov <redacted>
Date: Sat, 6 May 2006 12:40:45 +0400
quoted
Some external patches, which can be built both as static build and as
module just check that value, and thus will fail with unresolved symbol
when cn and module are built as modules.

The right set of operations should be following:
If external module is loaded and cn is not loaded or compiled into the
kernel, insmod will just fail with unresolved symbol (cn_add_callback and others),
if cn is already loaded or was built into the tree, then it has been 
initialized already and there is no need to check that value, external
module should be just loaded.

I think the right solution is to call external init functions after cn
init function, but it's ordering is not always known.
In-kernel build of connector subsystem can be handled by
making cn_init a "subsystem_init()", it will then be setup
before any possible static or modular reference as long as
those modules use module_init().

For modular case of connector, dependency of module on connector
module should handle all ordering issues, making any ordering
issue take care of itself.
Attached patch declares connector init function as subsys_init()
and returns -EAGAIN in case connector is not initialized yet.

Signed-off-by: Evgeniy Polyakov <redacted>
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 505677f..d1d964f 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -306,6 +306,9 @@ int cn_add_callback(struct cb_id *id, ch
 	int err;
 	struct cn_dev *dev = &cdev;
 
+	if (!cn_already_initialized)
+		return -EAGAIN;
+
 	err = cn_queue_add_callback(dev->cbdev, name, id, callback);
 	if (err)
 		return err;
@@ -433,7 +436,7 @@ static void cn_callback(void *data)
 	up(&notify_lock);
 }
 
-static int __init cn_init(void)
+static int __devinit cn_init(void)
 {
 	struct cn_dev *dev = &cdev;
 	int err;
@@ -454,21 +458,22 @@ static int __init cn_init(void)
 			sock_release(dev->nls->sk_socket);
 		return -EINVAL;
 	}
+	
+	cn_already_initialized = 1;
 
 	err = cn_add_callback(&dev->id, "connector", &cn_callback);
 	if (err) {
+		cn_already_initialized = 0;
 		cn_queue_free_dev(dev->cbdev);
 		if (dev->nls->sk_socket)
 			sock_release(dev->nls->sk_socket);
 		return -EINVAL;
 	}
 
-	cn_already_initialized = 1;
-
 	return 0;
 }
 
-static void __exit cn_fini(void)
+static void __devexit cn_fini(void)
 {
 	struct cn_dev *dev = &cdev;
 
@@ -480,7 +485,7 @@ static void __exit cn_fini(void)
 		sock_release(dev->nls->sk_socket);
 }
 
-module_init(cn_init);
+subsys_initcall(cn_init);
 module_exit(cn_fini);
 
 EXPORT_SYMBOL_GPL(cn_add_callback);
-- 
	Evgeniy Polyakov
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help