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