static void ds9490r_search()

in masters/ds2490.c [664:780]


static void ds9490r_search(void *data, struct w1_master *master,
	u8 search_type, w1_slave_found_callback callback)
{
	/* When starting with an existing id, the first id returned will
	 * be that device (if it is still on the bus most likely).
	 *
	 * If the number of devices found is less than or equal to the
	 * search_limit, that number of IDs will be returned.  If there are
	 * more, search_limit IDs will be returned followed by a non-zero
	 * discrepency value.
	 */
	struct ds_device *dev = data;
	int err;
	u16 value, index;
	struct ds_status st;
	int search_limit;
	int found = 0;
	int i;

	/* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for
	 * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time.
	 */
	const unsigned long jtime = msecs_to_jiffies(1000*8/75);
	/* FIFO 128 bytes, bulk packet size 64, read a multiple of the
	 * packet size.
	 */
	const size_t bufsize = 2 * 64;
	u64 *buf, *found_ids;

	buf = kmalloc(bufsize, GFP_KERNEL);
	if (!buf)
		return;

	/*
	 * We are holding the bus mutex during the scan, but adding devices via the
	 * callback needs the bus to be unlocked. So we queue up found ids here.
	 */
	found_ids = kmalloc_array(master->max_slave_count, sizeof(u64), GFP_KERNEL);
	if (!found_ids) {
		kfree(buf);
		return;
	}

	mutex_lock(&master->bus_mutex);

	/* address to start searching at */
	if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0)
		goto search_out;
	master->search_id = 0;

	value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
		COMM_RTS;
	search_limit = master->max_slave_count;
	if (search_limit > 255)
		search_limit = 0;
	index = search_type | (search_limit << 8);
	if (ds_send_control(dev, value, index) < 0)
		goto search_out;

	do {
		schedule_timeout(jtime);

		err = ds_recv_status(dev, &st, false);
		if (err < 0 || err < sizeof(st))
			break;

		if (st.data_in_buffer_status) {
			/* Bulk in can receive partial ids, but when it does
			 * they fail crc and will be discarded anyway.
			 * That has only been seen when status in buffer
			 * is 0 and bulk is read anyway, so don't read
			 * bulk without first checking if status says there
			 * is data to read.
			 */
			err = ds_recv_data(dev, (u8 *)buf, bufsize);
			if (err < 0)
				break;
			for (i = 0; i < err/8; ++i) {
				found_ids[found++] = buf[i];
				/* can't know if there will be a discrepancy
				 * value after until the next id */
				if (found == search_limit) {
					master->search_id = buf[i];
					break;
				}
			}
		}

		if (test_bit(W1_ABORT_SEARCH, &master->flags))
			break;
	} while (!(st.status & (ST_IDLE | ST_HALT)));

	/* only continue the search if some weren't found */
	if (found <= search_limit) {
		master->search_id = 0;
	} else if (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) {
		/* Only max_slave_count will be scanned in a search,
		 * but it will start where it left off next search
		 * until all ids are identified and then it will start
		 * over.  A continued search will report the previous
		 * last id as the first id (provided it is still on the
		 * bus).
		 */
		dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, "
			"will continue next search.\n", __func__,
			master->max_slave_count);
		set_bit(W1_WARN_MAX_COUNT, &master->flags);
	}

search_out:
	mutex_unlock(&master->bus_mutex);
	kfree(buf);

	for (i = 0; i < found; i++) /* run callback for all queued up IDs */
		callback(master, found_ids[i]);
	kfree(found_ids);
}