X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fw1%2Fw1_family.c;h=a3c95bd6890af7ae20a8c63b00d3b0082f714ad0;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=6a62d2adb9d18665dda57d3168119125c7137d85;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c index 6a62d2adb..a3c95bd68 100644 --- a/drivers/w1/w1_family.c +++ b/drivers/w1/w1_family.c @@ -1,8 +1,8 @@ /* - * w1_family.c + * w1_family.c * * Copyright (c) 2004 Evgeniy Polyakov - * + * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,29 +21,21 @@ #include #include +#include /* schedule_timeout() */ +#include #include "w1_family.h" +#include "w1.h" -spinlock_t w1_flock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(w1_flock); static LIST_HEAD(w1_families); -static int w1_check_family(struct w1_family *f) -{ - if (!f->fops->rname || !f->fops->rbin || !f->fops->rval || !f->fops->rvalname) - return -EINVAL; - - return 0; -} - int w1_register_family(struct w1_family *newf) { struct list_head *ent, *n; struct w1_family *f; int ret = 0; - if (w1_check_family(newf)) - return -EINVAL; - spin_lock(&w1_flock); list_for_each_safe(ent, n, &w1_families) { f = list_entry(ent, struct w1_family, family_entry); @@ -59,9 +51,10 @@ int w1_register_family(struct w1_family *newf) newf->need_exit = 0; list_add_tail(&newf->family_entry, &w1_families); } - spin_unlock(&w1_flock); + w1_reconnect_slaves(newf); + return ret; } @@ -84,8 +77,13 @@ void w1_unregister_family(struct w1_family *fent) spin_unlock(&w1_flock); - while (atomic_read(&fent->refcnt)) - schedule_timeout(10); + while (atomic_read(&fent->refcnt)) { + printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n", + fent->fid, atomic_read(&fent->refcnt)); + + if (msleep_interruptible(1000)) + flush_signals(current); + } } /* @@ -109,6 +107,12 @@ struct w1_family * w1_family_registered(u8 fid) return (ret) ? f : NULL; } +static void __w1_family_put(struct w1_family *f) +{ + if (atomic_dec_and_test(&f->refcnt)) + f->need_exit = 1; +} + void w1_family_put(struct w1_family *f) { spin_lock(&w1_flock); @@ -116,29 +120,21 @@ void w1_family_put(struct w1_family *f) spin_unlock(&w1_flock); } -void __w1_family_put(struct w1_family *f) -{ - if (atomic_dec_and_test(&f->refcnt)) - f->need_exit = 1; -} - +#if 0 void w1_family_get(struct w1_family *f) { spin_lock(&w1_flock); __w1_family_get(f); spin_unlock(&w1_flock); - } +#endif /* 0 */ void __w1_family_get(struct w1_family *f) { + smp_mb__before_atomic_inc(); atomic_inc(&f->refcnt); + smp_mb__after_atomic_inc(); } -EXPORT_SYMBOL(w1_family_get); -EXPORT_SYMBOL(w1_family_put); -EXPORT_SYMBOL(__w1_family_get); -EXPORT_SYMBOL(__w1_family_put); -EXPORT_SYMBOL(w1_family_registered); EXPORT_SYMBOL(w1_unregister_family); EXPORT_SYMBOL(w1_register_family);