aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1
diff options
context:
space:
mode:
authorDavid Fries <David@Fries.net>2014-01-15 23:29:23 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-07 18:40:18 -0500
commitd53f0a2c0574e6414dceeec59ae5a9e749bd058b (patch)
tree7cd0c86e616ea1a271e13cff8aad611e51c469d2 /drivers/w1
parentda78b7e74ac5964015bed78d27e1fca8bae8e29a (diff)
w1: ds2490 fix and enable hardware search
The hardware search was failing without the COMM_RST flag. Enabled the flag and rewrote the function to handle more than one buffer of results and to continuing where the search left off. Remove hardware search note from the limitations now that it works. The "w1: ds2490 USB setup fixes" change went from 23.16 seconds to about 3 seconds, this takes the time for the search down to .307346 seconds. Signed-off-by: David Fries <David@Fries.net> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/masters/ds2490.c108
1 files changed, 86 insertions, 22 deletions
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index cd59e12e8a78..db0bf3229bb6 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -698,37 +698,102 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
698 return !(err == len); 698 return !(err == len);
699} 699}
700 700
701#if 0 701static void ds9490r_search(void *data, struct w1_master *master,
702 702 u8 search_type, w1_slave_found_callback callback)
703static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search)
704{ 703{
704 /* When starting with an existing id, the first id returned will
705 * be that device (if it is still on the bus most likely).
706 *
707 * If the number of devices found is less than or equal to the
708 * search_limit, that number of IDs will be returned. If there are
709 * more, search_limit IDs will be returned followed by a non-zero
710 * discrepency value.
711 */
712 struct ds_device *dev = data;
705 int err; 713 int err;
706 u16 value, index; 714 u16 value, index;
707 struct ds_status st; 715 struct ds_status st;
716 u8 st_buf[ST_SIZE];
717 int search_limit;
718 int found = 0;
719 int i;
708 720
709 memset(buf, 0, sizeof(buf)); 721 /* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for
710 722 * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time.
711 err = ds_send_data(ds_dev, (unsigned char *)&init, 8); 723 */
712 if (err) 724 const unsigned long jtime = msecs_to_jiffies(1000*8/75);
713 return err; 725 /* FIFO 128 bytes, bulk packet size 64, read a multiple of the
726 * packet size.
727 */
728 u64 buf[2*64/8];
714 729
715 ds_wait_status(ds_dev, &st); 730 /* address to start searching at */
731 if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0)
732 return;
733 master->search_id = 0;
734
735 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
736 COMM_RTS;
737 search_limit = master->max_slave_count;
738 if (search_limit > 255)
739 search_limit = 0;
740 index = search_type | (search_limit << 8);
741 if (ds_send_control(dev, value, index) < 0)
742 return;
716 743
717 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; 744 do {
718 index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); 745 schedule_timeout(jtime);
719 err = ds_send_control(ds_dev, value, index);
720 if (err)
721 return err;
722 746
723 ds_wait_status(ds_dev, &st); 747 if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) <
748 sizeof(st)) {
749 break;
750 }
724 751
725 err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); 752 if (st.data_in_buffer_status) {
726 if (err < 0) 753 /* Bulk in can receive partial ids, but when it does
727 return err; 754 * they fail crc and will be discarded anyway.
755 * That has only been seen when status in buffer
756 * is 0 and bulk is read anyway, so don't read
757 * bulk without first checking if status says there
758 * is data to read.
759 */
760 err = ds_recv_data(dev, (u8 *)buf, sizeof(buf));
761 if (err < 0)
762 break;
763 for (i = 0; i < err/8; ++i) {
764 ++found;
765 if (found <= search_limit)
766 callback(master, buf[i]);
767 /* can't know if there will be a discrepancy
768 * value after until the next id */
769 if (found == search_limit)
770 master->search_id = buf[i];
771 }
772 }
728 773
729 return err/8; 774 if (test_bit(W1_ABORT_SEARCH, &master->flags))
775 break;
776 } while (!(st.status & (ST_IDLE | ST_HALT)));
777
778 /* only continue the search if some weren't found */
779 if (found <= search_limit) {
780 master->search_id = 0;
781 } else if (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) {
782 /* Only max_slave_count will be scanned in a search,
783 * but it will start where it left off next search
784 * until all ids are identified and then it will start
785 * over. A continued search will report the previous
786 * last id as the first id (provided it is still on the
787 * bus).
788 */
789 dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, "
790 "will continue next search.\n", __func__,
791 master->max_slave_count);
792 set_bit(W1_WARN_MAX_COUNT, &master->flags);
793 }
730} 794}
731 795
796#if 0
732static int ds_match_access(struct ds_device *dev, u64 init) 797static int ds_match_access(struct ds_device *dev, u64 init)
733{ 798{
734 int err; 799 int err;
@@ -902,6 +967,7 @@ static int ds_w1_init(struct ds_device *dev)
902 dev->master.write_block = &ds9490r_write_block; 967 dev->master.write_block = &ds9490r_write_block;
903 dev->master.reset_bus = &ds9490r_reset; 968 dev->master.reset_bus = &ds9490r_reset;
904 dev->master.set_pullup = &ds9490r_set_pullup; 969 dev->master.set_pullup = &ds9490r_set_pullup;
970 dev->master.search = &ds9490r_search;
905 971
906 return w1_add_master_device(&dev->master); 972 return w1_add_master_device(&dev->master);
907} 973}
@@ -920,13 +986,11 @@ static int ds_probe(struct usb_interface *intf,
920 struct ds_device *dev; 986 struct ds_device *dev;
921 int i, err, alt; 987 int i, err, alt;
922 988
923 dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); 989 dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);
924 if (!dev) { 990 if (!dev) {
925 printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); 991 printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");
926 return -ENOMEM; 992 return -ENOMEM;
927 } 993 }
928 dev->spu_sleep = 0;
929 dev->spu_bit = 0;
930 dev->udev = usb_get_dev(udev); 994 dev->udev = usb_get_dev(udev);
931 if (!dev->udev) { 995 if (!dev->udev) {
932 err = -ENOMEM; 996 err = -ENOMEM;