On Tue, May 16, 2006 at 04:14:06PM -0700, David S. Miller ([EMAIL PROTECTED])
wrote:
> From: Evgeniy Polyakov <[EMAIL PROTECTED]>
> Date: Sat, 6 May 2006 12:40:45 +0400
>
> > 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 <[EMAIL PROTECTED]>
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(¬ify_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
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html