aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1.c
diff options
context:
space:
mode:
authorEvgeniy Polyakov <johnpol@2ka.mipt.ru>2005-06-03 17:29:25 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-22 00:43:12 -0400
commit6adf87bd7b7832105b9c6bc08adf6a4d229f1e79 (patch)
tree1c6d17df3c4f4d753021e970a7bb898c1aabeb82 /drivers/w1/w1.c
parent4754639d88e922af451b399af09ac1bb442c35e5 (diff)
[PATCH] w1: reconnect feature.
I've created reconnect feature - if on start there are no registered families all new devices will have defailt family, later when driver for appropriate family is loaded, slaves, which were faound earlier, will still have defult family instead of right one. Reconnect feature will force control thread to run through all master devices and all slaves found and search for slaves with default family id and try to reconnect them. It does not store newly registered family and does not check only those slaves which have reg_num.family the same as being registered one - all slaves with default family are reconnected. Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/w1/w1.c')
-rw-r--r--drivers/w1/w1.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 0e6ccd46af0e..b460927ec32a 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -469,6 +469,8 @@ static void w1_slave_detach(struct w1_slave *sl)
469 device_unregister(&sl->dev); 469 device_unregister(&sl->dev);
470 w1_family_put(sl->family); 470 w1_family_put(sl->family);
471 471
472 sl->master->slave_count--;
473
472 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); 474 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
473 msg.type = W1_SLAVE_REMOVE; 475 msg.type = W1_SLAVE_REMOVE;
474 w1_netlink_send(sl->master, &msg); 476 w1_netlink_send(sl->master, &msg);
@@ -492,6 +494,20 @@ static struct w1_master *w1_search_master(unsigned long data)
492 return (found)?dev:NULL; 494 return (found)?dev:NULL;
493} 495}
494 496
497void w1_reconnect_slaves(struct w1_family *f)
498{
499 struct w1_master *dev;
500
501 spin_lock_bh(&w1_mlock);
502 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
503 dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
504 dev->name, f->fid);
505 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
506 }
507 spin_unlock_bh(&w1_mlock);
508}
509
510
495static void w1_slave_found(unsigned long data, u64 rn) 511static void w1_slave_found(unsigned long data, u64 rn)
496{ 512{
497 int slave_count; 513 int slave_count;
@@ -637,7 +653,7 @@ static int w1_control(void *data)
637 flush_signals(current); 653 flush_signals(current);
638 654
639 list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) { 655 list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
640 if (!control_needs_exit && !dev->need_exit) 656 if (!control_needs_exit && !dev->flags)
641 continue; 657 continue;
642 /* 658 /*
643 * Little race: we can create thread but not set the flag. 659 * Little race: we can create thread but not set the flag.
@@ -648,12 +664,8 @@ static int w1_control(void *data)
648 continue; 664 continue;
649 } 665 }
650 666
651 spin_lock_bh(&w1_mlock);
652 list_del(&dev->w1_master_entry);
653 spin_unlock_bh(&w1_mlock);
654
655 if (control_needs_exit) { 667 if (control_needs_exit) {
656 dev->need_exit = 1; 668 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
657 669
658 err = kill_proc(dev->kpid, SIGTERM, 1); 670 err = kill_proc(dev->kpid, SIGTERM, 1);
659 if (err) 671 if (err)
@@ -662,16 +674,42 @@ static int w1_control(void *data)
662 dev->kpid); 674 dev->kpid);
663 } 675 }
664 676
665 wait_for_completion(&dev->dev_exited); 677 if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
678 wait_for_completion(&dev->dev_exited);
679 spin_lock_bh(&w1_mlock);
680 list_del(&dev->w1_master_entry);
681 spin_unlock_bh(&w1_mlock);
682
683 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
684 list_del(&sl->w1_slave_entry);
685
686 w1_slave_detach(sl);
687 kfree(sl);
688 }
689 w1_destroy_master_attributes(dev);
690 atomic_dec(&dev->refcnt);
691 continue;
692 }
693
694 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
695 dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
696 down(&dev->mutex);
697 list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
698 if (sl->family->fid == W1_FAMILY_DEFAULT) {
699 struct w1_reg_num rn;
700 list_del(&sl->w1_slave_entry);
701 w1_slave_detach(sl);
702
703 memcpy(&rn, &sl->reg_num, sizeof(rn));
666 704
667 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { 705 kfree(sl);
668 list_del(&sl->w1_slave_entry);
669 706
670 w1_slave_detach(sl); 707 w1_attach_slave_device(dev, &rn);
671 kfree(sl); 708 }
709 }
710 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
711 up(&dev->mutex);
672 } 712 }
673 w1_destroy_master_attributes(dev);
674 atomic_dec(&dev->refcnt);
675 } 713 }
676 } 714 }
677 715
@@ -686,14 +724,14 @@ int w1_process(void *data)
686 daemonize("%s", dev->name); 724 daemonize("%s", dev->name);
687 allow_signal(SIGTERM); 725 allow_signal(SIGTERM);
688 726
689 while (!dev->need_exit) { 727 while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
690 try_to_freeze(PF_FREEZE); 728 try_to_freeze(PF_FREEZE);
691 msleep_interruptible(w1_timeout * 1000); 729 msleep_interruptible(w1_timeout * 1000);
692 730
693 if (signal_pending(current)) 731 if (signal_pending(current))
694 flush_signals(current); 732 flush_signals(current);
695 733
696 if (dev->need_exit) 734 if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
697 break; 735 break;
698 736
699 if (!dev->initialized) 737 if (!dev->initialized)