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);
}