diff options
Diffstat (limited to 'drivers/w1/w1.c')
| -rw-r--r-- | drivers/w1/w1.c | 269 |
1 files changed, 202 insertions, 67 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 66efa96c4603..b96f61b15dc6 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
| @@ -46,18 +46,29 @@ MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); | |||
| 46 | MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); | 46 | MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); |
| 47 | 47 | ||
| 48 | static int w1_timeout = 10; | 48 | static int w1_timeout = 10; |
| 49 | int w1_max_slave_count = 10; | 49 | int w1_max_slave_count = 64; |
| 50 | int w1_max_slave_ttl = 10; | 50 | int w1_max_slave_ttl = 10; |
| 51 | 51 | ||
| 52 | module_param_named(timeout, w1_timeout, int, 0); | 52 | module_param_named(timeout, w1_timeout, int, 0); |
| 53 | MODULE_PARM_DESC(timeout, "time in seconds between automatic slave searches"); | ||
| 54 | /* A search stops when w1_max_slave_count devices have been found in that | ||
| 55 | * search. The next search will start over and detect the same set of devices | ||
| 56 | * on a static 1-wire bus. Memory is not allocated based on this number, just | ||
| 57 | * on the number of devices known to the kernel. Having a high number does not | ||
| 58 | * consume additional resources. As a special case, if there is only one | ||
| 59 | * device on the network and w1_max_slave_count is set to 1, the device id can | ||
| 60 | * be read directly skipping the normal slower search process. | ||
| 61 | */ | ||
| 53 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); | 62 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); |
| 63 | MODULE_PARM_DESC(max_slave_count, | ||
| 64 | "maximum number of slaves detected in a search"); | ||
| 54 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); | 65 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); |
| 66 | MODULE_PARM_DESC(slave_ttl, | ||
| 67 | "Number of searches not seeing a slave before it will be removed"); | ||
| 55 | 68 | ||
| 56 | DEFINE_MUTEX(w1_mlock); | 69 | DEFINE_MUTEX(w1_mlock); |
| 57 | LIST_HEAD(w1_masters); | 70 | LIST_HEAD(w1_masters); |
| 58 | 71 | ||
| 59 | static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn); | ||
| 60 | |||
| 61 | static int w1_master_match(struct device *dev, struct device_driver *drv) | 72 | static int w1_master_match(struct device *dev, struct device_driver *drv) |
| 62 | { | 73 | { |
| 63 | return 1; | 74 | return 1; |
| @@ -81,19 +92,10 @@ static void w1_slave_release(struct device *dev) | |||
| 81 | { | 92 | { |
| 82 | struct w1_slave *sl = dev_to_w1_slave(dev); | 93 | struct w1_slave *sl = dev_to_w1_slave(dev); |
| 83 | 94 | ||
| 84 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name); | 95 | dev_dbg(dev, "%s: Releasing %s [%p]\n", __func__, sl->name, sl); |
| 85 | |||
| 86 | while (atomic_read(&sl->refcnt)) { | ||
| 87 | dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n", | ||
| 88 | sl->name, atomic_read(&sl->refcnt)); | ||
| 89 | if (msleep_interruptible(1000)) | ||
| 90 | flush_signals(current); | ||
| 91 | } | ||
| 92 | 96 | ||
| 93 | w1_family_put(sl->family); | 97 | w1_family_put(sl->family); |
| 94 | sl->master->slave_count--; | 98 | sl->master->slave_count--; |
| 95 | |||
| 96 | complete(&sl->released); | ||
| 97 | } | 99 | } |
| 98 | 100 | ||
| 99 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) | 101 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) |
| @@ -243,7 +245,9 @@ static ssize_t w1_master_attribute_store_search(struct device * dev, | |||
| 243 | mutex_lock(&md->mutex); | 245 | mutex_lock(&md->mutex); |
| 244 | md->search_count = tmp; | 246 | md->search_count = tmp; |
| 245 | mutex_unlock(&md->mutex); | 247 | mutex_unlock(&md->mutex); |
| 246 | wake_up_process(md->thread); | 248 | /* Only wake if it is going to be searching. */ |
| 249 | if (tmp) | ||
| 250 | wake_up_process(md->thread); | ||
| 247 | 251 | ||
| 248 | return count; | 252 | return count; |
| 249 | } | 253 | } |
| @@ -277,7 +281,6 @@ static ssize_t w1_master_attribute_store_pullup(struct device *dev, | |||
| 277 | mutex_lock(&md->mutex); | 281 | mutex_lock(&md->mutex); |
| 278 | md->enable_pullup = tmp; | 282 | md->enable_pullup = tmp; |
| 279 | mutex_unlock(&md->mutex); | 283 | mutex_unlock(&md->mutex); |
| 280 | wake_up_process(md->thread); | ||
| 281 | 284 | ||
| 282 | return count; | 285 | return count; |
| 283 | } | 286 | } |
| @@ -314,6 +317,24 @@ static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct devic | |||
| 314 | return count; | 317 | return count; |
| 315 | } | 318 | } |
| 316 | 319 | ||
| 320 | static ssize_t w1_master_attribute_store_max_slave_count(struct device *dev, | ||
| 321 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 322 | { | ||
| 323 | int tmp; | ||
| 324 | struct w1_master *md = dev_to_w1_master(dev); | ||
| 325 | |||
| 326 | if (kstrtoint(buf, 0, &tmp) == -EINVAL || tmp < 1) | ||
| 327 | return -EINVAL; | ||
| 328 | |||
| 329 | mutex_lock(&md->mutex); | ||
| 330 | md->max_slave_count = tmp; | ||
| 331 | /* allow each time the max_slave_count is updated */ | ||
| 332 | clear_bit(W1_WARN_MAX_COUNT, &md->flags); | ||
| 333 | mutex_unlock(&md->mutex); | ||
| 334 | |||
| 335 | return count; | ||
| 336 | } | ||
| 337 | |||
| 317 | static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf) | 338 | static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf) |
| 318 | { | 339 | { |
| 319 | struct w1_master *md = dev_to_w1_master(dev); | 340 | struct w1_master *md = dev_to_w1_master(dev); |
| @@ -352,23 +373,20 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, | |||
| 352 | { | 373 | { |
| 353 | struct w1_master *md = dev_to_w1_master(dev); | 374 | struct w1_master *md = dev_to_w1_master(dev); |
| 354 | int c = PAGE_SIZE; | 375 | int c = PAGE_SIZE; |
| 376 | struct list_head *ent, *n; | ||
| 377 | struct w1_slave *sl = NULL; | ||
| 355 | 378 | ||
| 356 | mutex_lock(&md->mutex); | 379 | mutex_lock(&md->list_mutex); |
| 357 | |||
| 358 | if (md->slave_count == 0) | ||
| 359 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); | ||
| 360 | else { | ||
| 361 | struct list_head *ent, *n; | ||
| 362 | struct w1_slave *sl; | ||
| 363 | 380 | ||
| 364 | list_for_each_safe(ent, n, &md->slist) { | 381 | list_for_each_safe(ent, n, &md->slist) { |
| 365 | sl = list_entry(ent, struct w1_slave, w1_slave_entry); | 382 | sl = list_entry(ent, struct w1_slave, w1_slave_entry); |
| 366 | 383 | ||
| 367 | c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name); | 384 | c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name); |
| 368 | } | ||
| 369 | } | 385 | } |
| 386 | if (!sl) | ||
| 387 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); | ||
| 370 | 388 | ||
| 371 | mutex_unlock(&md->mutex); | 389 | mutex_unlock(&md->list_mutex); |
| 372 | 390 | ||
| 373 | return PAGE_SIZE - c; | 391 | return PAGE_SIZE - c; |
| 374 | } | 392 | } |
| @@ -422,19 +440,22 @@ static int w1_atoreg_num(struct device *dev, const char *buf, size_t count, | |||
| 422 | } | 440 | } |
| 423 | 441 | ||
| 424 | /* Searches the slaves in the w1_master and returns a pointer or NULL. | 442 | /* Searches the slaves in the w1_master and returns a pointer or NULL. |
| 425 | * Note: must hold the mutex | 443 | * Note: must not hold list_mutex |
| 426 | */ | 444 | */ |
| 427 | static struct w1_slave *w1_slave_search_device(struct w1_master *dev, | 445 | struct w1_slave *w1_slave_search_device(struct w1_master *dev, |
| 428 | struct w1_reg_num *rn) | 446 | struct w1_reg_num *rn) |
| 429 | { | 447 | { |
| 430 | struct w1_slave *sl; | 448 | struct w1_slave *sl; |
| 449 | mutex_lock(&dev->list_mutex); | ||
| 431 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { | 450 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { |
| 432 | if (sl->reg_num.family == rn->family && | 451 | if (sl->reg_num.family == rn->family && |
| 433 | sl->reg_num.id == rn->id && | 452 | sl->reg_num.id == rn->id && |
| 434 | sl->reg_num.crc == rn->crc) { | 453 | sl->reg_num.crc == rn->crc) { |
| 454 | mutex_unlock(&dev->list_mutex); | ||
| 435 | return sl; | 455 | return sl; |
| 436 | } | 456 | } |
| 437 | } | 457 | } |
| 458 | mutex_unlock(&dev->list_mutex); | ||
| 438 | return NULL; | 459 | return NULL; |
| 439 | } | 460 | } |
| 440 | 461 | ||
| @@ -491,7 +512,10 @@ static ssize_t w1_master_attribute_store_remove(struct device *dev, | |||
| 491 | mutex_lock(&md->mutex); | 512 | mutex_lock(&md->mutex); |
| 492 | sl = w1_slave_search_device(md, &rn); | 513 | sl = w1_slave_search_device(md, &rn); |
| 493 | if (sl) { | 514 | if (sl) { |
| 494 | w1_slave_detach(sl); | 515 | result = w1_slave_detach(sl); |
| 516 | /* refcnt 0 means it was detached in the call */ | ||
| 517 | if (result == 0) | ||
| 518 | result = count; | ||
| 495 | } else { | 519 | } else { |
| 496 | dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family, | 520 | dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family, |
| 497 | (unsigned long long)rn.id); | 521 | (unsigned long long)rn.id); |
| @@ -516,7 +540,7 @@ static ssize_t w1_master_attribute_store_remove(struct device *dev, | |||
| 516 | static W1_MASTER_ATTR_RO(name, S_IRUGO); | 540 | static W1_MASTER_ATTR_RO(name, S_IRUGO); |
| 517 | static W1_MASTER_ATTR_RO(slaves, S_IRUGO); | 541 | static W1_MASTER_ATTR_RO(slaves, S_IRUGO); |
| 518 | static W1_MASTER_ATTR_RO(slave_count, S_IRUGO); | 542 | static W1_MASTER_ATTR_RO(slave_count, S_IRUGO); |
| 519 | static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO); | 543 | static W1_MASTER_ATTR_RW(max_slave_count, S_IRUGO | S_IWUSR | S_IWGRP); |
| 520 | static W1_MASTER_ATTR_RO(attempts, S_IRUGO); | 544 | static W1_MASTER_ATTR_RO(attempts, S_IRUGO); |
| 521 | static W1_MASTER_ATTR_RO(timeout, S_IRUGO); | 545 | static W1_MASTER_ATTR_RO(timeout, S_IRUGO); |
| 522 | static W1_MASTER_ATTR_RO(pointer, S_IRUGO); | 546 | static W1_MASTER_ATTR_RO(pointer, S_IRUGO); |
| @@ -686,12 +710,14 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
| 686 | dev_set_uevent_suppress(&sl->dev, false); | 710 | dev_set_uevent_suppress(&sl->dev, false); |
| 687 | kobject_uevent(&sl->dev.kobj, KOBJ_ADD); | 711 | kobject_uevent(&sl->dev.kobj, KOBJ_ADD); |
| 688 | 712 | ||
| 713 | mutex_lock(&sl->master->list_mutex); | ||
| 689 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); | 714 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); |
| 715 | mutex_unlock(&sl->master->list_mutex); | ||
| 690 | 716 | ||
| 691 | return 0; | 717 | return 0; |
| 692 | } | 718 | } |
| 693 | 719 | ||
| 694 | static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | 720 | int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) |
| 695 | { | 721 | { |
| 696 | struct w1_slave *sl; | 722 | struct w1_slave *sl; |
| 697 | struct w1_family *f; | 723 | struct w1_family *f; |
| @@ -713,8 +739,8 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
| 713 | 739 | ||
| 714 | memset(&msg, 0, sizeof(msg)); | 740 | memset(&msg, 0, sizeof(msg)); |
| 715 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); | 741 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); |
| 716 | atomic_set(&sl->refcnt, 0); | 742 | atomic_set(&sl->refcnt, 1); |
| 717 | init_completion(&sl->released); | 743 | atomic_inc(&sl->master->refcnt); |
| 718 | 744 | ||
| 719 | /* slave modules need to be loaded in a context with unlocked mutex */ | 745 | /* slave modules need to be loaded in a context with unlocked mutex */ |
| 720 | mutex_unlock(&dev->mutex); | 746 | mutex_unlock(&dev->mutex); |
| @@ -754,23 +780,48 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
| 754 | return 0; | 780 | return 0; |
| 755 | } | 781 | } |
| 756 | 782 | ||
| 757 | void w1_slave_detach(struct w1_slave *sl) | 783 | int w1_unref_slave(struct w1_slave *sl) |
| 758 | { | 784 | { |
| 759 | struct w1_netlink_msg msg; | 785 | struct w1_master *dev = sl->master; |
| 760 | 786 | int refcnt; | |
| 761 | dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl); | 787 | mutex_lock(&dev->list_mutex); |
| 762 | 788 | refcnt = atomic_sub_return(1, &sl->refcnt); | |
| 763 | list_del(&sl->w1_slave_entry); | 789 | if (refcnt == 0) { |
| 764 | 790 | struct w1_netlink_msg msg; | |
| 765 | memset(&msg, 0, sizeof(msg)); | 791 | |
| 766 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); | 792 | dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, |
| 767 | msg.type = W1_SLAVE_REMOVE; | 793 | sl->name, sl); |
| 768 | w1_netlink_send(sl->master, &msg); | 794 | |
| 769 | 795 | list_del(&sl->w1_slave_entry); | |
| 770 | device_unregister(&sl->dev); | 796 | |
| 797 | memset(&msg, 0, sizeof(msg)); | ||
| 798 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); | ||
| 799 | msg.type = W1_SLAVE_REMOVE; | ||
| 800 | w1_netlink_send(sl->master, &msg); | ||
| 801 | |||
| 802 | device_unregister(&sl->dev); | ||
| 803 | #ifdef DEBUG | ||
| 804 | memset(sl, 0, sizeof(*sl)); | ||
| 805 | #endif | ||
| 806 | kfree(sl); | ||
| 807 | } | ||
| 808 | atomic_dec(&dev->refcnt); | ||
| 809 | mutex_unlock(&dev->list_mutex); | ||
| 810 | return refcnt; | ||
| 811 | } | ||
| 771 | 812 | ||
| 772 | wait_for_completion(&sl->released); | 813 | int w1_slave_detach(struct w1_slave *sl) |
| 773 | kfree(sl); | 814 | { |
| 815 | /* Only detach a slave once as it decreases the refcnt each time. */ | ||
| 816 | int destroy_now; | ||
| 817 | mutex_lock(&sl->master->list_mutex); | ||
| 818 | destroy_now = !test_bit(W1_SLAVE_DETACH, &sl->flags); | ||
| 819 | set_bit(W1_SLAVE_DETACH, &sl->flags); | ||
| 820 | mutex_unlock(&sl->master->list_mutex); | ||
| 821 | |||
| 822 | if (destroy_now) | ||
| 823 | destroy_now = !w1_unref_slave(sl); | ||
| 824 | return destroy_now ? 0 : -EBUSY; | ||
| 774 | } | 825 | } |
| 775 | 826 | ||
| 776 | struct w1_master *w1_search_master_id(u32 id) | 827 | struct w1_master *w1_search_master_id(u32 id) |
| @@ -799,7 +850,7 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id) | |||
| 799 | 850 | ||
| 800 | mutex_lock(&w1_mlock); | 851 | mutex_lock(&w1_mlock); |
| 801 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 852 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
| 802 | mutex_lock(&dev->mutex); | 853 | mutex_lock(&dev->list_mutex); |
| 803 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { | 854 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { |
| 804 | if (sl->reg_num.family == id->family && | 855 | if (sl->reg_num.family == id->family && |
| 805 | sl->reg_num.id == id->id && | 856 | sl->reg_num.id == id->id && |
| @@ -810,7 +861,7 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id) | |||
| 810 | break; | 861 | break; |
| 811 | } | 862 | } |
| 812 | } | 863 | } |
| 813 | mutex_unlock(&dev->mutex); | 864 | mutex_unlock(&dev->list_mutex); |
| 814 | 865 | ||
| 815 | if (found) | 866 | if (found) |
| 816 | break; | 867 | break; |
| @@ -830,6 +881,7 @@ void w1_reconnect_slaves(struct w1_family *f, int attach) | |||
| 830 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " | 881 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " |
| 831 | "for family %02x.\n", dev->name, f->fid); | 882 | "for family %02x.\n", dev->name, f->fid); |
| 832 | mutex_lock(&dev->mutex); | 883 | mutex_lock(&dev->mutex); |
| 884 | mutex_lock(&dev->list_mutex); | ||
| 833 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 885 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
| 834 | /* If it is a new family, slaves with the default | 886 | /* If it is a new family, slaves with the default |
| 835 | * family driver and are that family will be | 887 | * family driver and are that family will be |
| @@ -841,14 +893,19 @@ void w1_reconnect_slaves(struct w1_family *f, int attach) | |||
| 841 | (!attach && sl->family->fid == f->fid)) { | 893 | (!attach && sl->family->fid == f->fid)) { |
| 842 | struct w1_reg_num rn; | 894 | struct w1_reg_num rn; |
| 843 | 895 | ||
| 896 | mutex_unlock(&dev->list_mutex); | ||
| 844 | memcpy(&rn, &sl->reg_num, sizeof(rn)); | 897 | memcpy(&rn, &sl->reg_num, sizeof(rn)); |
| 845 | w1_slave_detach(sl); | 898 | /* If it was already in use let the automatic |
| 846 | 899 | * scan pick it up again later. | |
| 847 | w1_attach_slave_device(dev, &rn); | 900 | */ |
| 901 | if (!w1_slave_detach(sl)) | ||
| 902 | w1_attach_slave_device(dev, &rn); | ||
| 903 | mutex_lock(&dev->list_mutex); | ||
| 848 | } | 904 | } |
| 849 | } | 905 | } |
| 850 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " | 906 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " |
| 851 | "has been finished.\n", dev->name); | 907 | "has been finished.\n", dev->name); |
| 908 | mutex_unlock(&dev->list_mutex); | ||
| 852 | mutex_unlock(&dev->mutex); | 909 | mutex_unlock(&dev->mutex); |
| 853 | } | 910 | } |
| 854 | mutex_unlock(&w1_mlock); | 911 | mutex_unlock(&w1_mlock); |
| @@ -876,7 +933,12 @@ void w1_slave_found(struct w1_master *dev, u64 rn) | |||
| 876 | } | 933 | } |
| 877 | 934 | ||
| 878 | /** | 935 | /** |
| 879 | * Performs a ROM Search & registers any devices found. | 936 | * w1_search() - Performs a ROM Search & registers any devices found. |
| 937 | * @dev: The master device to search | ||
| 938 | * @search_type: W1_SEARCH to search all devices, or W1_ALARM_SEARCH | ||
| 939 | * to return only devices in the alarmed state | ||
| 940 | * @cb: Function to call when a device is found | ||
| 941 | * | ||
| 880 | * The 1-wire search is a simple binary tree search. | 942 | * The 1-wire search is a simple binary tree search. |
| 881 | * For each bit of the address, we read two bits and write one bit. | 943 | * For each bit of the address, we read two bits and write one bit. |
| 882 | * The bit written will put to sleep all devies that don't match that bit. | 944 | * The bit written will put to sleep all devies that don't match that bit. |
| @@ -886,8 +948,6 @@ void w1_slave_found(struct w1_master *dev, u64 rn) | |||
| 886 | * | 948 | * |
| 887 | * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com | 949 | * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com |
| 888 | * | 950 | * |
| 889 | * @dev The master device to search | ||
| 890 | * @cb Function to call when a device is found | ||
| 891 | */ | 951 | */ |
| 892 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) | 952 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) |
| 893 | { | 953 | { |
| @@ -898,7 +958,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
| 898 | u8 triplet_ret = 0; | 958 | u8 triplet_ret = 0; |
| 899 | 959 | ||
| 900 | search_bit = 0; | 960 | search_bit = 0; |
| 901 | rn = last_rn = 0; | 961 | rn = dev->search_id; |
| 962 | last_rn = 0; | ||
| 902 | last_device = 0; | 963 | last_device = 0; |
| 903 | last_zero = -1; | 964 | last_zero = -1; |
| 904 | 965 | ||
| @@ -945,7 +1006,7 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
| 945 | else | 1006 | else |
| 946 | search_bit = ((last_rn >> i) & 0x1); | 1007 | search_bit = ((last_rn >> i) & 0x1); |
| 947 | 1008 | ||
| 948 | /** Read two bits and write one bit */ | 1009 | /* Read two bits and write one bit */ |
| 949 | triplet_ret = w1_triplet(dev, search_bit); | 1010 | triplet_ret = w1_triplet(dev, search_bit); |
| 950 | 1011 | ||
| 951 | /* quit if no device responded */ | 1012 | /* quit if no device responded */ |
| @@ -960,8 +1021,7 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
| 960 | tmp64 = (triplet_ret >> 2); | 1021 | tmp64 = (triplet_ret >> 2); |
| 961 | rn |= (tmp64 << i); | 1022 | rn |= (tmp64 << i); |
| 962 | 1023 | ||
| 963 | /* ensure we're called from kthread and not by netlink callback */ | 1024 | if (test_bit(W1_ABORT_SEARCH, &dev->flags)) { |
| 964 | if (!dev->priv && kthread_should_stop()) { | ||
| 965 | mutex_unlock(&dev->bus_mutex); | 1025 | mutex_unlock(&dev->bus_mutex); |
| 966 | dev_dbg(&dev->dev, "Abort w1_search\n"); | 1026 | dev_dbg(&dev->dev, "Abort w1_search\n"); |
| 967 | return; | 1027 | return; |
| @@ -970,11 +1030,30 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb | |||
| 970 | mutex_unlock(&dev->bus_mutex); | 1030 | mutex_unlock(&dev->bus_mutex); |
| 971 | 1031 | ||
| 972 | if ( (triplet_ret & 0x03) != 0x03 ) { | 1032 | if ( (triplet_ret & 0x03) != 0x03 ) { |
| 973 | if ( (desc_bit == last_zero) || (last_zero < 0)) | 1033 | if ((desc_bit == last_zero) || (last_zero < 0)) { |
| 974 | last_device = 1; | 1034 | last_device = 1; |
| 1035 | dev->search_id = 0; | ||
| 1036 | } else { | ||
| 1037 | dev->search_id = rn; | ||
| 1038 | } | ||
| 975 | desc_bit = last_zero; | 1039 | desc_bit = last_zero; |
| 976 | cb(dev, rn); | 1040 | cb(dev, rn); |
| 977 | } | 1041 | } |
| 1042 | |||
| 1043 | if (!last_device && slave_count == dev->max_slave_count && | ||
| 1044 | !test_bit(W1_WARN_MAX_COUNT, &dev->flags)) { | ||
| 1045 | /* Only max_slave_count will be scanned in a search, | ||
| 1046 | * but it will start where it left off next search | ||
| 1047 | * until all ids are identified and then it will start | ||
| 1048 | * over. A continued search will report the previous | ||
| 1049 | * last id as the first id (provided it is still on the | ||
| 1050 | * bus). | ||
| 1051 | */ | ||
| 1052 | dev_info(&dev->dev, "%s: max_slave_count %d reached, " | ||
| 1053 | "will continue next search.\n", __func__, | ||
| 1054 | dev->max_slave_count); | ||
| 1055 | set_bit(W1_WARN_MAX_COUNT, &dev->flags); | ||
| 1056 | } | ||
| 978 | } | 1057 | } |
| 979 | } | 1058 | } |
| 980 | 1059 | ||
| @@ -983,17 +1062,24 @@ void w1_search_process_cb(struct w1_master *dev, u8 search_type, | |||
| 983 | { | 1062 | { |
| 984 | struct w1_slave *sl, *sln; | 1063 | struct w1_slave *sl, *sln; |
| 985 | 1064 | ||
| 1065 | mutex_lock(&dev->list_mutex); | ||
| 986 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) | 1066 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) |
| 987 | clear_bit(W1_SLAVE_ACTIVE, &sl->flags); | 1067 | clear_bit(W1_SLAVE_ACTIVE, &sl->flags); |
| 1068 | mutex_unlock(&dev->list_mutex); | ||
| 988 | 1069 | ||
| 989 | w1_search_devices(dev, search_type, cb); | 1070 | w1_search_devices(dev, search_type, cb); |
| 990 | 1071 | ||
| 1072 | mutex_lock(&dev->list_mutex); | ||
| 991 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 1073 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
| 992 | if (!test_bit(W1_SLAVE_ACTIVE, &sl->flags) && !--sl->ttl) | 1074 | if (!test_bit(W1_SLAVE_ACTIVE, &sl->flags) && !--sl->ttl) { |
| 1075 | mutex_unlock(&dev->list_mutex); | ||
| 993 | w1_slave_detach(sl); | 1076 | w1_slave_detach(sl); |
| 1077 | mutex_lock(&dev->list_mutex); | ||
| 1078 | } | ||
| 994 | else if (test_bit(W1_SLAVE_ACTIVE, &sl->flags)) | 1079 | else if (test_bit(W1_SLAVE_ACTIVE, &sl->flags)) |
| 995 | sl->ttl = dev->slave_ttl; | 1080 | sl->ttl = dev->slave_ttl; |
| 996 | } | 1081 | } |
| 1082 | mutex_unlock(&dev->list_mutex); | ||
| 997 | 1083 | ||
| 998 | if (dev->search_count > 0) | 1084 | if (dev->search_count > 0) |
| 999 | dev->search_count--; | 1085 | dev->search_count--; |
| @@ -1004,6 +1090,32 @@ static void w1_search_process(struct w1_master *dev, u8 search_type) | |||
| 1004 | w1_search_process_cb(dev, search_type, w1_slave_found); | 1090 | w1_search_process_cb(dev, search_type, w1_slave_found); |
| 1005 | } | 1091 | } |
| 1006 | 1092 | ||
| 1093 | /** | ||
| 1094 | * w1_process_callbacks() - execute each dev->async_list callback entry | ||
| 1095 | * @dev: w1_master device | ||
| 1096 | * | ||
| 1097 | * Return: 1 if there were commands to executed 0 otherwise | ||
| 1098 | */ | ||
| 1099 | int w1_process_callbacks(struct w1_master *dev) | ||
| 1100 | { | ||
| 1101 | int ret = 0; | ||
| 1102 | struct w1_async_cmd *async_cmd, *async_n; | ||
| 1103 | |||
| 1104 | /* The list can be added to in another thread, loop until it is empty */ | ||
| 1105 | while (!list_empty(&dev->async_list)) { | ||
| 1106 | list_for_each_entry_safe(async_cmd, async_n, &dev->async_list, | ||
| 1107 | async_entry) { | ||
| 1108 | /* drop the lock, if it is a search it can take a long | ||
| 1109 | * time */ | ||
| 1110 | mutex_unlock(&dev->list_mutex); | ||
| 1111 | async_cmd->cb(dev, async_cmd); | ||
| 1112 | ret = 1; | ||
| 1113 | mutex_lock(&dev->list_mutex); | ||
| 1114 | } | ||
| 1115 | } | ||
| 1116 | return ret; | ||
| 1117 | } | ||
| 1118 | |||
| 1007 | int w1_process(void *data) | 1119 | int w1_process(void *data) |
| 1008 | { | 1120 | { |
| 1009 | struct w1_master *dev = (struct w1_master *) data; | 1121 | struct w1_master *dev = (struct w1_master *) data; |
| @@ -1011,23 +1123,46 @@ int w1_process(void *data) | |||
| 1011 | * time can be calculated in jiffies once. | 1123 | * time can be calculated in jiffies once. |
| 1012 | */ | 1124 | */ |
| 1013 | const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000); | 1125 | const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000); |
| 1126 | /* remainder if it woke up early */ | ||
| 1127 | unsigned long jremain = 0; | ||
| 1014 | 1128 | ||
| 1015 | while (!kthread_should_stop()) { | 1129 | for (;;) { |
| 1016 | if (dev->search_count) { | 1130 | |
| 1131 | if (!jremain && dev->search_count) { | ||
| 1017 | mutex_lock(&dev->mutex); | 1132 | mutex_lock(&dev->mutex); |
| 1018 | w1_search_process(dev, W1_SEARCH); | 1133 | w1_search_process(dev, W1_SEARCH); |
| 1019 | mutex_unlock(&dev->mutex); | 1134 | mutex_unlock(&dev->mutex); |
| 1020 | } | 1135 | } |
| 1021 | 1136 | ||
| 1137 | mutex_lock(&dev->list_mutex); | ||
| 1138 | /* Note, w1_process_callback drops the lock while processing, | ||
| 1139 | * but locks it again before returning. | ||
| 1140 | */ | ||
| 1141 | if (!w1_process_callbacks(dev) && jremain) { | ||
| 1142 | /* a wake up is either to stop the thread, process | ||
| 1143 | * callbacks, or search, it isn't process callbacks, so | ||
| 1144 | * schedule a search. | ||
| 1145 | */ | ||
| 1146 | jremain = 1; | ||
| 1147 | } | ||
| 1148 | |||
| 1022 | try_to_freeze(); | 1149 | try_to_freeze(); |
| 1023 | __set_current_state(TASK_INTERRUPTIBLE); | 1150 | __set_current_state(TASK_INTERRUPTIBLE); |
| 1024 | 1151 | ||
| 1152 | /* hold list_mutex until after interruptible to prevent loosing | ||
| 1153 | * the wakeup signal when async_cmd is added. | ||
| 1154 | */ | ||
| 1155 | mutex_unlock(&dev->list_mutex); | ||
| 1156 | |||
| 1025 | if (kthread_should_stop()) | 1157 | if (kthread_should_stop()) |
| 1026 | break; | 1158 | break; |
| 1027 | 1159 | ||
| 1028 | /* Only sleep when the search is active. */ | 1160 | /* Only sleep when the search is active. */ |
| 1029 | if (dev->search_count) | 1161 | if (dev->search_count) { |
| 1030 | schedule_timeout(jtime); | 1162 | if (!jremain) |
| 1163 | jremain = jtime; | ||
| 1164 | jremain = schedule_timeout(jremain); | ||
| 1165 | } | ||
| 1031 | else | 1166 | else |
| 1032 | schedule(); | 1167 | schedule(); |
| 1033 | } | 1168 | } |
