/*
 * libiio - Library for interfacing industrial I/O (IIO) devices
 *
 * Copyright (C) 2014 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * */

#include "debug.h"
#include "iio-private.h"
#include "sort.h"

#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef WITH_LOCAL_CONFIG
#include <ini.h>
#endif

#define DEFAULT_TIMEOUT_MS 1000

#define NB_BLOCKS 4

#define BLOCK_ALLOC_IOCTL   _IOWR('i', 0xa0, struct block_alloc_req)
#define BLOCK_FREE_IOCTL      _IO('i', 0xa1)
#define BLOCK_QUERY_IOCTL   _IOWR('i', 0xa2, struct block)
#define BLOCK_ENQUEUE_IOCTL _IOWR('i', 0xa3, struct block)
#define BLOCK_DEQUEUE_IOCTL _IOWR('i', 0xa4, struct block)

#define BLOCK_FLAG_CYCLIC BIT(1)

/* Forward declarations */
static ssize_t local_read_dev_attr(const struct iio_device *dev,
		const char *attr, char *dst, size_t len, enum iio_attr_type type);
static ssize_t local_read_chn_attr(const struct iio_channel *chn,
		const char *attr, char *dst, size_t len);
static ssize_t local_write_dev_attr(const struct iio_device *dev,
		const char *attr, const char *src, size_t len, enum iio_attr_type type);
static ssize_t local_write_chn_attr(const struct iio_channel *chn,
		const char *attr, const char *src, size_t len);

struct block_alloc_req {
	uint32_t type,
		 size,
		 count,
		 id;
};

struct block {
	uint32_t id,
		 size,
		 bytes_used,
		 type,
		 flags,
		 offset;
	uint64_t timestamp;
};

struct iio_context_pdata {
	unsigned int rw_timeout_ms;
};

struct iio_device_pdata {
	int fd;
	bool blocking;
	unsigned int samples_count;
	unsigned int max_nb_blocks;
	unsigned int allocated_nb_blocks;

	struct block *blocks;
	void **addrs;
	int last_dequeued;
	bool is_high_speed, cyclic, cyclic_buffer_enqueued, buffer_enabled;

	int cancel_fd;
};

struct iio_channel_pdata {
	char *enable_fn;
	struct iio_channel_attr *protected_attrs;
	unsigned int nb_protected_attrs;
};

static const char * const device_attrs_blacklist[] = {
	"dev",
	"uevent",
};

static const char * const buffer_attrs_reserved[] = {
	"length",
	"enable",
};

static int ioctl_nointr(int fd, unsigned long request, void *data)
{
	int ret;

	do {
		ret = ioctl(fd, request, data);
	} while (ret == -1 && errno == EINTR);

	return ret;
}

static void local_free_channel_pdata(struct iio_channel *chn)
{
	if (chn->pdata) {
		free(chn->pdata->enable_fn);
		free(chn->pdata);
	}
}

static void local_free_pdata(struct iio_device *device)
{
	unsigned int i;

	for (i = 0; i < device->nb_channels; i++)
		local_free_channel_pdata(device->channels[i]);

	if (device->pdata) {
		free(device->pdata->blocks);
		free(device->pdata->addrs);
		free(device->pdata);
	}
}

static void local_shutdown(struct iio_context *ctx)
{
	/* Free the backend data stored in every device structure */
	unsigned int i;

	for (i = 0; i < ctx->nb_devices; i++) {
		struct iio_device *dev = ctx->devices[i];

		iio_device_close(dev);
		local_free_pdata(dev);
	}

	free(ctx->pdata);
}

/** Shrinks the first nb characters of a string
 * e.g. strcut("foobar", 4) replaces the content with "ar". */
static void strcut(char *str, int nb)
{
	char *ptr = str + nb;
	while (*ptr)
		*str++ = *ptr++;
	*str = 0;
}

static int set_channel_name(struct iio_channel *chn)
{
	struct iio_channel_pdata *pdata = chn->pdata;
	size_t prefix_len = 0;
	const char *attr0;
	const char *ptr;
	unsigned int i;

	if (chn->nb_attrs + pdata->nb_protected_attrs < 2)
		return 0;

	if (chn->nb_attrs)
		attr0 = ptr = chn->attrs[0].name;
	else
		attr0 = ptr = pdata->protected_attrs[0].name;

	while (true) {
		bool can_fix = true;
		size_t len;

		ptr = strchr(ptr, '_');
		if (!ptr)
			break;

		len = ptr - attr0 + 1;
		for (i = 1; can_fix && i < chn->nb_attrs; i++)
			can_fix = !strncmp(attr0, chn->attrs[i].name, len);

		for (i = !chn->nb_attrs;
				can_fix && i < pdata->nb_protected_attrs; i++) {
			can_fix = !strncmp(attr0,
					pdata->protected_attrs[i].name, len);
		}

		if (!can_fix)
			break;

		prefix_len = len;
		ptr = ptr + 1;
	}

	if (prefix_len) {
		char *name;

		name = malloc(prefix_len);
		if (!name)
			return -ENOMEM;
		strncpy(name, attr0, prefix_len - 1);
		name[prefix_len - 1] = '\0';
		DEBUG("Setting name of channel %s to %s\n", chn->id, name);
		chn->name = name;

		/* Shrink the attribute name */
		for (i = 0; i < chn->nb_attrs; i++)
			strcut(chn->attrs[i].name, prefix_len);
		for (i = 0; i < pdata->nb_protected_attrs; i++)
			strcut(pdata->protected_attrs[i].name, prefix_len);
	}

	return 0;
}

/*
 * Used to generate the timeout parameter for operations like poll. Returns the
 * number of ms until it is timeout_rel ms after the time specified in start. If
 * timeout_rel is 0 returns -1 to indicate no timeout.
 *
 * The timeout that is specified for IIO operations is the maximum time a buffer
 * push() or refill() operation should take before returning. poll() is used to
 * wait for either data activity or for the timeout to elapse. poll() might get
 * interrupted in which case it is called again or the read()/write() operation
 * might not complete the full buffer size in one call in which case we go back
 * to poll() again as well. Passing the same timeout as before would increase
 * the total timeout and if repeated interruptions occur (e.g. by a timer
 * signal) the operation might never time out or with significant delay. Hence
 * before each poll() invocation the timeout is recalculated relative to the
 * start of refill() or push() operation.
 */
static int get_rel_timeout_ms(struct timespec *start, unsigned int timeout_rel)
{
	struct timespec now;
	int diff_ms;

	if (timeout_rel == 0) /* No timeout */
		return -1;

	clock_gettime(CLOCK_MONOTONIC, &now);

	diff_ms = (now.tv_sec - start->tv_sec) * 1000;
	diff_ms += (now.tv_nsec - start->tv_nsec) / 1000000;

	if (diff_ms >= timeout_rel) /* Expired */
		return 0;
	if (diff_ms > 0) /* Should never be false, but lets be safe */
		timeout_rel -= diff_ms;
	if (timeout_rel > INT_MAX)
		return INT_MAX;

	return (int) timeout_rel;
}

static int device_check_ready(const struct iio_device *dev, short events,
	struct timespec *start)
{
	struct pollfd pollfd[2] = {
		{
			.fd = dev->pdata->fd,
			.events = events,
		}, {
			.fd = dev->pdata->cancel_fd,
			.events = POLLIN,
		}
	};
	unsigned int rw_timeout_ms = dev->ctx->pdata->rw_timeout_ms;
	int timeout_rel;
	int ret;

	if (!dev->pdata->blocking)
		return 0;

	do {
		timeout_rel = get_rel_timeout_ms(start, rw_timeout_ms);
		ret = poll(pollfd, 2, timeout_rel);
	} while (ret == -1 && errno == EINTR);

	if ((pollfd[1].revents & POLLIN))
		return -EBADF;

	if (ret < 0)
		return -errno;
	if (!ret)
		return -ETIMEDOUT;
	if (pollfd[0].revents & POLLNVAL)
		return -EBADF;
	if (!(pollfd[0].revents & events))
		return -EIO;
	return 0;
}

static ssize_t local_read(const struct iio_device *dev,
		void *dst, size_t len, uint32_t *mask, size_t words)
{
	struct iio_device_pdata *pdata = dev->pdata;
	uintptr_t ptr = (uintptr_t) dst;
	struct timespec start;
	ssize_t readsize;
	ssize_t ret;

	if (pdata->fd == -1)
		return -EBADF;
	if (words != dev->words)
		return -EINVAL;

	memcpy(mask, dev->mask, words);

	if (len == 0)
		return 0;

	clock_gettime(CLOCK_MONOTONIC, &start);

	while (len > 0) {
		ret = device_check_ready(dev, POLLIN, &start);
		if (ret < 0)
			break;

		do {
			ret = read(pdata->fd, (void *) ptr, len);
		} while (ret == -1 && errno == EINTR);

		if (ret == -1) {
			if (pdata->blocking && errno == EAGAIN)
				continue;
			ret = -errno;
			break;
		} else if (ret == 0) {
			ret = -EIO;
			break;
		}

		ptr += ret;
		len -= ret;
	}

	readsize = (ssize_t)(ptr - (uintptr_t) dst);
	if ((ret > 0 || ret == -EAGAIN) && (readsize > 0))
		return readsize;
	else
		return ret;
}

static ssize_t local_write(const struct iio_device *dev,
		const void *src, size_t len)
{
	struct iio_device_pdata *pdata = dev->pdata;
	uintptr_t ptr = (uintptr_t) src;
	struct timespec start;
	ssize_t writtensize;
	ssize_t ret;

	if (pdata->fd == -1)
		return -EBADF;

	if (len == 0)
		return 0;

	clock_gettime(CLOCK_MONOTONIC, &start);

	while (len > 0) {
		ret = device_check_ready(dev, POLLOUT, &start);
		if (ret < 0)
			break;

		do {
			ret = write(pdata->fd, (void *) ptr, len);
		} while (ret == -1 && errno == EINTR);

		if (ret == -1) {
			if (pdata->blocking && errno == EAGAIN)
				continue;

			ret = -errno;
			break;
		} else if (ret == 0) {
			ret = -EIO;
			break;
		}

		ptr += ret;
		len -= ret;
	}

	writtensize = (ssize_t)(ptr - (uintptr_t) src);
	if ((ret > 0 || ret == -EAGAIN) && (writtensize > 0))
		return writtensize;
	else
		return ret;
}

static ssize_t local_enable_buffer(const struct iio_device *dev)
{
	struct iio_device_pdata *pdata = dev->pdata;
	ssize_t ret = 0;

	if (!pdata->buffer_enabled) {
		ret = local_write_dev_attr(dev,
				"buffer/enable", "1", 2, false);
		if (ret >= 0)
			pdata->buffer_enabled = true;
	}

	return ret;
}

static int local_set_kernel_buffers_count(const struct iio_device *dev,
		unsigned int nb_blocks)
{
	struct iio_device_pdata *pdata = dev->pdata;

	if (pdata->fd != -1)
		return -EBUSY;

	pdata->max_nb_blocks = nb_blocks;

	return 0;
}

static ssize_t local_get_buffer(const struct iio_device *dev,
		void **addr_ptr, size_t bytes_used,
		uint32_t *mask, size_t words)
{
	struct block block;
	struct iio_device_pdata *pdata = dev->pdata;
	struct timespec start;
	char err_str[1024];
	int f = pdata->fd;
	ssize_t ret;

	if (!pdata->is_high_speed)
		return -ENOSYS;
	if (f == -1)
		return -EBADF;
	if (!addr_ptr)
		return -EINVAL;

	if (pdata->last_dequeued >= 0) {
		struct block *last_block = &pdata->blocks[pdata->last_dequeued];

		if (pdata->cyclic) {
			if (pdata->cyclic_buffer_enqueued)
				return -EBUSY;
			pdata->blocks[0].flags |= BLOCK_FLAG_CYCLIC;
			pdata->cyclic_buffer_enqueued = true;
		}

		last_block->bytes_used = bytes_used;
		ret = (ssize_t) ioctl_nointr(f,
				BLOCK_ENQUEUE_IOCTL, last_block);
		if (ret) {
			ret = (ssize_t) -errno;
			iio_strerror(errno, err_str, sizeof(err_str));
			ERROR("Unable to enqueue block: %s\n", err_str);
			return ret;
		}

		if (pdata->cyclic) {
			*addr_ptr = pdata->addrs[pdata->last_dequeued];
			return (ssize_t) last_block->bytes_used;
		}

		pdata->last_dequeued = -1;
	}

	clock_gettime(CLOCK_MONOTONIC, &start);

	do {
		ret = (ssize_t) device_check_ready(dev, POLLIN | POLLOUT, &start);
		if (ret < 0)
			return ret;

		memset(&block, 0, sizeof(block));
		ret = (ssize_t) ioctl_nointr(f, BLOCK_DEQUEUE_IOCTL, &block);
	} while (pdata->blocking && ret == -1 && errno == EAGAIN);

	if (ret) {
		ret = (ssize_t) -errno;
		if ((!pdata->blocking && ret != -EAGAIN) ||
				(pdata->blocking && ret != -ETIMEDOUT)) {
			iio_strerror(errno, err_str, sizeof(err_str));
			ERROR("Unable to dequeue block: %s\n", err_str);
		}
		return ret;
	}

	/* Requested buffer size is too big! */
	if (pdata->last_dequeued < 0 && bytes_used != block.size)
		return -EFBIG;

	pdata->last_dequeued = block.id;
	*addr_ptr = pdata->addrs[block.id];
	return (ssize_t) block.bytes_used;
}

static ssize_t local_read_all_dev_attrs(const struct iio_device *dev,
		char *dst, size_t len, enum iio_attr_type type)
{
	unsigned int i, nb;
	char **attrs;
	char *ptr = dst;

	switch (type) {
		case IIO_ATTR_TYPE_DEVICE:
			nb =  dev->nb_attrs;
			attrs = dev->attrs;
			break;
		case IIO_ATTR_TYPE_DEBUG:
			nb =  dev->nb_debug_attrs;
			attrs = dev->debug_attrs;
			break;
		case IIO_ATTR_TYPE_BUFFER:
			nb =  dev->nb_buffer_attrs;
			attrs = dev->buffer_attrs;
			break;
		default:
			return -EINVAL;
			break;
	}

	for (i = 0; len >= 4 && i < nb; i++) {
		/* Recursive! */
		ssize_t ret = local_read_dev_attr(dev, attrs[i],
				ptr + 4, len - 4, type);
		*(uint32_t *) ptr = iio_htobe32(ret);

		/* Align the length to 4 bytes */
		if (ret > 0 && ret & 3)
			ret = ((ret >> 2) + 1) << 2;
		ptr += 4 + (ret < 0 ? 0 : ret);
		len -= 4 + (ret < 0 ? 0 : ret);
	}

	return ptr - dst;
}

static ssize_t local_read_all_chn_attrs(const struct iio_channel *chn,
		char *dst, size_t len)
{
	unsigned int i;
	char *ptr = dst;

	for (i = 0; len >= 4 && i < chn->nb_attrs; i++) {
		/* Recursive! */
		ssize_t ret = local_read_chn_attr(chn,
				chn->attrs[i].name, ptr + 4, len - 4);
		*(uint32_t *) ptr = iio_htobe32(ret);

		/* Align the length to 4 bytes */
		if (ret > 0 && ret & 3)
			ret = ((ret >> 2) + 1) << 2;
		ptr += 4 + (ret < 0 ? 0 : ret);
		len -= 4 + (ret < 0 ? 0 : ret);
	}

	return ptr - dst;
}

static int local_buffer_analyze(unsigned int nb, const char *src, size_t len)
{
	while (nb--) {
		int32_t val;

		if (len < 4)
			return -EINVAL;

		val = (int32_t) iio_be32toh(*(uint32_t *) src);
		src += 4;
		len -= 4;

		if (val > 0) {
			if ((uint32_t) val > len)
				return -EINVAL;

			/* Align the length to 4 bytes */
			if (val & 3)
				val = ((val >> 2) + 1) << 2;
			len -= val;
			src += val;
		}
	}

	/* We should have analyzed the whole buffer by now */
	return !len ? 0 : -EINVAL;
}

static ssize_t local_write_all_dev_attrs(const struct iio_device *dev,
		const char *src, size_t len, enum iio_attr_type type)
{
	unsigned int i, nb;
	char **attrs;
	const char *ptr = src;

	switch (type) {
		case IIO_ATTR_TYPE_DEVICE:
			nb =  dev->nb_attrs;
			attrs = dev->attrs;
			break;
		case IIO_ATTR_TYPE_DEBUG:
			nb =  dev->nb_debug_attrs;
			attrs = dev->debug_attrs;
			break;
		case IIO_ATTR_TYPE_BUFFER:
			nb =  dev->nb_buffer_attrs;
			attrs = dev->buffer_attrs;
			break;
		default:
			return -EINVAL;
			break;
	}

	/* First step: Verify that the buffer is in the correct format */
	if (local_buffer_analyze(nb, src, len))
		return -EINVAL;

	/* Second step: write the attributes */
	for (i = 0; i < nb; i++) {
		int32_t val = (int32_t) iio_be32toh(*(uint32_t *) ptr);
		ptr += 4;

		if (val > 0) {
			local_write_dev_attr(dev, attrs[i], ptr, val, type);

			/* Align the length to 4 bytes */
			if (val & 3)
				val = ((val >> 2) + 1) << 2;
			ptr += val;
		}
	}

	return ptr - src;
}

static ssize_t local_write_all_chn_attrs(const struct iio_channel *chn,
		const char *src, size_t len)
{
	unsigned int i, nb = chn->nb_attrs;
	const char *ptr = src;

	/* First step: Verify that the buffer is in the correct format */
	if (local_buffer_analyze(nb, src, len))
		return -EINVAL;

	/* Second step: write the attributes */
	for (i = 0; i < nb; i++) {
		int32_t val = (int32_t) iio_be32toh(*(uint32_t *) ptr);
		ptr += 4;

		if (val > 0) {
			local_write_chn_attr(chn, chn->attrs[i].name, ptr, val);

			/* Align the length to 4 bytes */
			if (val & 3)
				val = ((val >> 2) + 1) << 2;
			ptr += val;
		}
	}

	return ptr - src;
}

static ssize_t local_read_dev_attr(const struct iio_device *dev,
		const char *attr, char *dst, size_t len, enum iio_attr_type type)
{
	FILE *f;
	char buf[1024];
	ssize_t ret;

	if (!attr)
		return local_read_all_dev_attrs(dev, dst, len, type);

	switch (type) {
		case IIO_ATTR_TYPE_DEVICE:
			iio_snprintf(buf, sizeof(buf), "/sys/bus/iio/devices/%s/%s",
					dev->id, attr);
			break;
		case IIO_ATTR_TYPE_DEBUG:
			iio_snprintf(buf, sizeof(buf), "/sys/kernel/debug/iio/%s/%s",
					dev->id, attr);
			break;
		case IIO_ATTR_TYPE_BUFFER:
			iio_snprintf(buf, sizeof(buf), "/sys/bus/iio/devices/%s/buffer/%s",
					dev->id, attr);
			break;
		default:
			return -EINVAL;
	}

	f = fopen(buf, "re");
	if (!f)
		return -errno;

	ret = fread(dst, 1, len, f);
	if (ret > 0)
		dst[ret - 1] = '\0';
	fflush(f);
	if (ferror(f))
		ret = -errno;
	fclose(f);
	return ret ? ret : -EIO;
}

static ssize_t local_write_dev_attr(const struct iio_device *dev,
		const char *attr, const char *src, size_t len, enum iio_attr_type type)
{
	FILE *f;
	char buf[1024];
	ssize_t ret;

	if (!attr)
		return local_write_all_dev_attrs(dev, src, len, type);

	switch (type) {
		case IIO_ATTR_TYPE_DEVICE:
			iio_snprintf(buf, sizeof(buf), "/sys/bus/iio/devices/%s/%s",
					dev->id, attr);
			break;
		case IIO_ATTR_TYPE_DEBUG:
			iio_snprintf(buf, sizeof(buf), "/sys/kernel/debug/iio/%s/%s",
					dev->id, attr);
			break;
		case IIO_ATTR_TYPE_BUFFER:
			iio_snprintf(buf, sizeof(buf), "/sys/bus/iio/devices/%s/buffer/%s",
					dev->id, attr);
			break;
		default:
			return -EINVAL;
	}

	f = fopen(buf, "we");
	if (!f)
		return -errno;

	ret = fwrite(src, 1, len, f);
	fflush(f);
	if (ferror(f))
		ret = -errno;
	fclose(f);
	return ret ? ret : -EIO;
}

static const char * get_filename(const struct iio_channel *chn,
		const char *attr)
{
	unsigned int i;
	for (i = 0; i < chn->nb_attrs; i++)
		if (!strcmp(attr, chn->attrs[i].name))
			return chn->attrs[i].filename;
	return attr;
}

static ssize_t local_read_chn_attr(const struct iio_channel *chn,
		const char *attr, char *dst, size_t len)
{
	if (!attr)
		return local_read_all_chn_attrs(chn, dst, len);

	attr = get_filename(chn, attr);
	return local_read_dev_attr(chn->dev, attr, dst, len, false);
}

static ssize_t local_write_chn_attr(const struct iio_channel *chn,
		const char *attr, const char *src, size_t len)
{
	if (!attr)
		return local_write_all_chn_attrs(chn, src, len);

	attr = get_filename(chn, attr);
	return local_write_dev_attr(chn->dev, attr, src, len, false);
}

static int channel_write_state(const struct iio_channel *chn, bool en)
{
	ssize_t ret;

	if (!chn->pdata->enable_fn) {
		ERROR("Libiio bug: No \"en\" attribute parsed\n");
		return -EINVAL;
	}

	ret = local_write_chn_attr(chn, chn->pdata->enable_fn, en ? "1" : "0", 2);
	if (ret < 0)
		return (int) ret;
	else
		return 0;
}

static int enable_high_speed(const struct iio_device *dev)
{
	struct block_alloc_req req;
	struct iio_device_pdata *pdata = dev->pdata;
	unsigned int nb_blocks;
	unsigned int i;
	int ret, fd = pdata->fd;

	/*
	 * For the BLOCK_ALLOC_IOCTL ioctl it is not possible to distingush
	 * between an error during the allocation (e.g. incorrect size) or
	 * whether the high-speed interface is not supported. BLOCK_FREE_IOCTL does
	 * never fail if the device supports the high-speed interface, so we use it
	 * here. Calling it when no blocks are allocated the ioctl has no effect.
	 */
	ret = ioctl_nointr(fd, BLOCK_FREE_IOCTL, NULL);
	if (ret < 0)
		return -ENOSYS;

	if (pdata->cyclic) {
		nb_blocks = 1;
		DEBUG("Enabling cyclic mode\n");
	} else {
		nb_blocks = pdata->max_nb_blocks;
		DEBUG("Cyclic mode not enabled\n");
	}

	pdata->blocks = calloc(nb_blocks, sizeof(*pdata->blocks));
	if (!pdata->blocks)
		return -ENOMEM;

	pdata->addrs = calloc(nb_blocks, sizeof(*pdata->addrs));
	if (!pdata->addrs) {
		free(pdata->blocks);
		pdata->blocks = NULL;
		return -ENOMEM;
	}

	req.id = 0;
	req.type = 0;
	req.size = pdata->samples_count *
		iio_device_get_sample_size_mask(dev, dev->mask, dev->words);
	req.count = nb_blocks;

	ret = ioctl_nointr(fd, BLOCK_ALLOC_IOCTL, &req);
	if (ret < 0) {
		ret = -errno;
		goto err_freemem;
	}

	if (req.count == 0) {
		ret = -ENOMEM;
		goto err_block_free;
	}

	/* We might get less blocks than what we asked for */
	pdata->allocated_nb_blocks = req.count;

	/* mmap all the blocks */
	for (i = 0; i < pdata->allocated_nb_blocks; i++) {
		pdata->blocks[i].id = i;
		ret = ioctl_nointr(fd, BLOCK_QUERY_IOCTL, &pdata->blocks[i]);
		if (ret) {
			ret = -errno;
			goto err_munmap;
		}

		ret = ioctl_nointr(fd, BLOCK_ENQUEUE_IOCTL, &pdata->blocks[i]);
		if (ret) {
			ret = -errno;
			goto err_munmap;
		}

		pdata->addrs[i] = mmap(0, pdata->blocks[i].size,
				PROT_READ | PROT_WRITE,
				MAP_SHARED, fd, pdata->blocks[i].offset);
		if (pdata->addrs[i] == MAP_FAILED) {
			ret = -errno;
			goto err_munmap;
		}
	}

	pdata->last_dequeued = -1;
	return 0;

err_munmap:
	for (; i > 0; i--)
		munmap(pdata->addrs[i - 1], pdata->blocks[i - 1].size);
err_block_free:
	ioctl_nointr(fd, BLOCK_FREE_IOCTL, 0);
	pdata->allocated_nb_blocks = 0;
err_freemem:
	free(pdata->addrs);
	pdata->addrs = NULL;
	free(pdata->blocks);
	pdata->blocks = NULL;
	return ret;
}

static int local_open(const struct iio_device *dev,
		size_t samples_count, bool cyclic)
{
	unsigned int i;
	int ret;
	char buf[1024];
	struct iio_device_pdata *pdata = dev->pdata;

	if (pdata->fd != -1)
		return -EBUSY;

	ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false);
	if (ret < 0)
		return ret;

	iio_snprintf(buf, sizeof(buf), "%lu", (unsigned long) samples_count);
	ret = local_write_dev_attr(dev, "buffer/length",
			buf, strlen(buf) + 1, false);
	if (ret < 0)
		return ret;

	pdata->cancel_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
	if (pdata->cancel_fd == -1)
		return -errno;

	iio_snprintf(buf, sizeof(buf), "/dev/%s", dev->id);
	pdata->fd = open(buf, O_RDWR | O_CLOEXEC | O_NONBLOCK);
	if (pdata->fd == -1) {
		ret = -errno;
		goto err_close_cancel_fd;
	}

	/* Disable channels */
	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];
		if (chn->index >= 0 && !iio_channel_is_enabled(chn)) {
			ret = channel_write_state(chn, false);
			if (ret < 0)
				goto err_close;
		}
	}
	/* Enable channels */
	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];
		if (chn->index >= 0 && iio_channel_is_enabled(chn)) {
			ret = channel_write_state(chn, true);
			if (ret < 0)
				goto err_close;
		}
	}

	pdata->cyclic = cyclic;
	pdata->cyclic_buffer_enqueued = false;
	pdata->buffer_enabled = false;
	pdata->samples_count = samples_count;

	ret = enable_high_speed(dev);
	if (ret < 0 && ret != -ENOSYS)
		goto err_close;

	pdata->is_high_speed = !ret;

	if (!pdata->is_high_speed) {
		unsigned long size = samples_count * pdata->max_nb_blocks;
		WARNING("High-speed mode not enabled\n");

		/* Cyclic mode is only supported in high-speed mode */
		if (cyclic) {
			ret = -EPERM;
			goto err_close;
		}

		/* Increase the size of the kernel buffer, when using the
		 * low-speed interface. This avoids losing samples when
		 * refilling the iio_buffer. */
		iio_snprintf(buf, sizeof(buf), "%lu", size);
		ret = local_write_dev_attr(dev, "buffer/length",
				buf, strlen(buf) + 1, false);
		if (ret < 0)
			goto err_close;
	}

	ret = local_enable_buffer(dev);
	if (ret < 0)
		goto err_close;

	return 0;
err_close:
	close(pdata->fd);
	pdata->fd = -1;
err_close_cancel_fd:
	close(pdata->cancel_fd);
	pdata->cancel_fd = -1;
	return ret;
}

static int local_close(const struct iio_device *dev)
{
	struct iio_device_pdata *pdata = dev->pdata;
	unsigned int i;
	int ret;

	if (pdata->fd == -1)
		return -EBADF;

	if (pdata->is_high_speed) {
		unsigned int i;
		for (i = 0; i < pdata->allocated_nb_blocks; i++)
			munmap(pdata->addrs[i], pdata->blocks[i].size);
		ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0);
		pdata->allocated_nb_blocks = 0;
		free(pdata->addrs);
		pdata->addrs = NULL;
		free(pdata->blocks);
		pdata->blocks = NULL;
	}

	ret = close(pdata->fd);
	if (ret)
		return ret;

	close(pdata->cancel_fd);

	pdata->fd = -1;
	pdata->cancel_fd = -1;

	ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false);

	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];

		if (chn->pdata->enable_fn)
			channel_write_state(chn, false);
	}

	return (ret < 0) ? ret : 0;
}

static int local_get_fd(const struct iio_device *dev)
{
	if (dev->pdata->fd == -1)
		return -EBADF;
	else
		return dev->pdata->fd;
}

static int local_set_blocking_mode(const struct iio_device *dev, bool blocking)
{
	if (dev->pdata->fd == -1)
		return -EBADF;

	if (dev->pdata->cyclic)
		return -EPERM;

	dev->pdata->blocking = blocking;

	return 0;
}

static int local_get_trigger(const struct iio_device *dev,
		const struct iio_device **trigger)
{
	char buf[1024];
	unsigned int i;
	ssize_t nb = local_read_dev_attr(dev, "trigger/current_trigger",
			buf, sizeof(buf), false);
	if (nb < 0) {
		*trigger = NULL;
		return (int) nb;
	}

	if (buf[0] == '\0') {
		*trigger = NULL;
		return 0;
	}

	nb = dev->ctx->nb_devices;
	for (i = 0; i < (size_t) nb; i++) {
		const struct iio_device *cur = dev->ctx->devices[i];
		if (cur->name && !strcmp(cur->name, buf)) {
			*trigger = cur;
			return 0;
		}
	}
	return -ENXIO;
}

static int local_set_trigger(const struct iio_device *dev,
		const struct iio_device *trigger)
{
	ssize_t nb;
	const char *value = trigger ? trigger->name : "";
	nb = local_write_dev_attr(dev, "trigger/current_trigger",
			value, strlen(value) + 1, false);
	if (nb < 0)
		return (int) nb;
	else
		return 0;
}

static bool is_channel(const char *attr, bool strict)
{
	char *ptr = NULL;
	if (!strncmp(attr, "in_timestamp_", sizeof("in_timestamp_") - 1))
		return true;
	if (!strncmp(attr, "in_", 3))
		ptr = strchr(attr + 3, '_');
	else if (!strncmp(attr, "out_", 4))
		ptr = strchr(attr + 4, '_');
	if (!ptr)
		return false;
	if (!strict)
		return true;
	if (*(ptr - 1) >= '0' && *(ptr - 1) <= '9')
		return true;

	if (find_channel_modifier(ptr + 1, NULL) != IIO_NO_MOD)
		return true;
	return false;
}

static char * get_channel_id(const char *attr)
{
	char *res, *ptr;
	size_t len;

	attr = strchr(attr, '_') + 1;
	ptr = strchr(attr, '_');
	if (find_channel_modifier(ptr + 1, &len) != IIO_NO_MOD)
		ptr += len + 1;

	res = malloc(ptr - attr + 1);
	if (!res)
		return NULL;

	memcpy(res, attr, ptr - attr);
	res[ptr - attr] = 0;
	return res;
}

static char * get_short_attr_name(struct iio_channel *chn, const char *attr)
{
	char *ptr = strchr(attr, '_') + 1;
	size_t len;

	ptr = strchr(ptr, '_') + 1;
	if (find_channel_modifier(ptr, &len) != IIO_NO_MOD)
		ptr += len + 1;

	if (chn->name) {
		size_t len = strlen(chn->name);
		if (strncmp(chn->name, ptr, len) == 0 && ptr[len] == '_')
			ptr += len + 1;
	}

	return iio_strdup(ptr);
}

static int read_device_name(struct iio_device *dev)
{
	char buf[1024];
	ssize_t ret = iio_device_attr_read(dev, "name", buf, sizeof(buf));
	if (ret < 0)
		return ret;
	else if (ret == 0)
		return -EIO;

	dev->name = iio_strdup(buf);
	if (!dev->name)
		return -ENOMEM;
	else
		return 0;
}

static int add_attr_to_device(struct iio_device *dev, const char *attr)
{
	char **attrs, *name;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(device_attrs_blacklist); i++)
		if (!strcmp(device_attrs_blacklist[i], attr))
			return 0;

	if (!strcmp(attr, "name"))
		return read_device_name(dev);

	name = iio_strdup(attr);
	if (!name)
		return -ENOMEM;

	attrs = realloc(dev->attrs, (1 + dev->nb_attrs) * sizeof(char *));
	if (!attrs) {
		free(name);
		return -ENOMEM;
	}

	attrs[dev->nb_attrs++] = name;
	dev->attrs = attrs;
	DEBUG("Added attr \'%s\' to device \'%s\'\n", attr, dev->id);
	return 0;
}

static int handle_protected_scan_element_attr(struct iio_channel *chn,
			const char *name, const char *path)
{
	struct iio_device *dev = chn->dev;
	char buf[1024];
	int ret;

	if (!strcmp(name, "index")) {
		ret = local_read_dev_attr(dev, path, buf, sizeof(buf), false);
		if (ret > 0)
			chn->index = atol(buf);

	} else if (!strcmp(name, "type")) {
		ret = local_read_dev_attr(dev, path, buf, sizeof(buf), false);
		if (ret > 0) {
			char endian, sign;

			if (strchr(buf, 'X')) {
				sscanf(buf, "%ce:%c%u/%uX%u>>%u", &endian, &sign,
					&chn->format.bits, &chn->format.length,
					&chn->format.repeat, &chn->format.shift);
			} else {
				chn->format.repeat = 1;
				sscanf(buf, "%ce:%c%u/%u>>%u", &endian, &sign,
					&chn->format.bits, &chn->format.length,
					&chn->format.shift);
			}
			chn->format.is_signed = (sign == 's' || sign == 'S');
			chn->format.is_fully_defined =
					(sign == 'S' || sign == 'U'||
					chn->format.bits == chn->format.length);
			chn->format.is_be = endian == 'b';
		}

	} else if (!strcmp(name, "en")) {
		if (chn->pdata->enable_fn) {
			ERROR("Libiio bug: \"en\" attribute already parsed for channel %s!\n",
					chn->id);
			return -EINVAL;
		}

		chn->pdata->enable_fn = iio_strdup(path);
		if (!chn->pdata->enable_fn)
			return -ENOMEM;

	} else {
		return -EINVAL;
	}

	return 0;
}

static int handle_scan_elements(struct iio_channel *chn)
{
	struct iio_channel_pdata *pdata = chn->pdata;
	unsigned int i;

	for (i = 0; i < pdata->nb_protected_attrs; i++) {
		int ret = handle_protected_scan_element_attr(chn,
				pdata->protected_attrs[i].name,
				pdata->protected_attrs[i].filename);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int add_protected_attr(struct iio_channel *chn, char *name, char *fn)
{
	struct iio_channel_pdata *pdata = chn->pdata;
	struct iio_channel_attr *attrs;

	attrs = realloc(pdata->protected_attrs,
			(1 + pdata->nb_protected_attrs) * sizeof(*attrs));
	if (!attrs)
		return -ENOMEM;

	attrs[pdata->nb_protected_attrs].name = name;
	attrs[pdata->nb_protected_attrs++].filename = fn;
	pdata->protected_attrs = attrs;

	DEBUG("Add protected attr \'%s\' to channel \'%s\'\n", name, chn->id);
	return 0;
}

static void free_protected_attrs(struct iio_channel *chn)
{
	struct iio_channel_pdata *pdata = chn->pdata;
	unsigned int i;

	for (i = 0; i < pdata->nb_protected_attrs; i++) {
		free(pdata->protected_attrs[i].name);
		free(pdata->protected_attrs[i].filename);
	}

	free(pdata->protected_attrs);
	pdata->nb_protected_attrs = 0;
	pdata->protected_attrs = NULL;
}

static int add_attr_to_channel(struct iio_channel *chn,
		const char *attr, const char *path, bool is_scan_element)
{
	struct iio_channel_attr *attrs;
	char *fn, *name = get_short_attr_name(chn, attr);
	if (!name)
		return -ENOMEM;

	fn = iio_strdup(path);
	if (!fn)
		goto err_free_name;

	if (is_scan_element) {
		int ret = add_protected_attr(chn, name, fn);

		if (ret < 0)
			goto err_free_fn;

		return 0;
	}

	attrs = realloc(chn->attrs, (1 + chn->nb_attrs) *
			sizeof(struct iio_channel_attr));
	if (!attrs)
		goto err_free_fn;

	attrs[chn->nb_attrs].filename = fn;
	attrs[chn->nb_attrs++].name = name;
	chn->attrs = attrs;
	DEBUG("Added attr \'%s\' to channel \'%s\'\n", name, chn->id);
	return 0;

err_free_fn:
	free(fn);
err_free_name:
	free(name);
	return -ENOMEM;
}

static int add_channel_to_device(struct iio_device *dev,
		struct iio_channel *chn)
{
	struct iio_channel **channels = realloc(dev->channels,
			(dev->nb_channels + 1) * sizeof(struct iio_channel *));
	if (!channels)
		return -ENOMEM;

	channels[dev->nb_channels++] = chn;
	dev->channels = channels;
	DEBUG("Added %s channel \'%s\' to device \'%s\'\n",
		chn->is_output ? "output" : "input", chn->id, dev->id);

	return 0;
}

static int add_device_to_context(struct iio_context *ctx,
		struct iio_device *dev)
{
	struct iio_device **devices = realloc(ctx->devices,
			(ctx->nb_devices + 1) * sizeof(struct iio_device *));
	if (!devices)
		return -ENOMEM;

	devices[ctx->nb_devices++] = dev;
	ctx->devices = devices;
	DEBUG("Added device \'%s\' to context \'%s\'\n", dev->id, ctx->name);
	return 0;
}

static struct iio_channel *create_channel(struct iio_device *dev,
		char *id, const char *attr, const char *path,
		bool is_scan_element)
{
	struct iio_channel *chn = zalloc(sizeof(*chn));
	if (!chn)
		return NULL;

	chn->pdata = zalloc(sizeof(*chn->pdata));
	if (!chn->pdata)
		goto err_free_chn;

	if (!strncmp(attr, "out_", 4))
		chn->is_output = true;
	else if (strncmp(attr, "in_", 3))
		goto err_free_chn_pdata;

	chn->dev = dev;
	chn->id = id;
	chn->is_scan_element = is_scan_element;
	chn->index = -ENOENT;

	if (!add_attr_to_channel(chn, attr, path, is_scan_element))
		return chn;

err_free_chn_pdata:
	free(chn->pdata->enable_fn);
	free(chn->pdata);
err_free_chn:
	free(chn);
	return NULL;
}

static int add_channel(struct iio_device *dev, const char *name,
	const char *path, bool dir_is_scan_elements)
{
	struct iio_channel *chn;
	char *channel_id;
	unsigned int i;
	int ret;

	channel_id = get_channel_id(name);
	if (!channel_id)
		return -ENOMEM;

	for (i = 0; i < dev->nb_channels; i++) {
		chn = dev->channels[i];
		if (!strcmp(chn->id, channel_id)
				&& chn->is_output == (name[0] == 'o')) {
			free(channel_id);
			ret = add_attr_to_channel(chn, name, path,
					dir_is_scan_elements);
			chn->is_scan_element = dir_is_scan_elements && !ret;
			return ret;
		}
	}

	chn = create_channel(dev, channel_id, name, path, dir_is_scan_elements);
	if (!chn) {
		free(channel_id);
		return -ENXIO;
	}

	iio_channel_init_finalize(chn);

	ret = add_channel_to_device(dev, chn);
	if (ret) {
		free(chn->pdata->enable_fn);
		free(chn->pdata);
		free_channel(chn);
	}
	return ret;
}

/*
 * Possible return values:
 * 0 = Attribute should not be moved to the channel
 * 1 = Attribute should be moved to the channel and it is a shared attribute
 * 2 = Attribute should be moved to the channel and it is a private attribute
 */
static unsigned int is_global_attr(struct iio_channel *chn, const char *attr)
{
	unsigned int len;
	char *ptr;

	if (!chn->is_output && !strncmp(attr, "in_", 3))
		attr += 3;
	else if (chn->is_output && !strncmp(attr, "out_", 4))
		attr += 4;
	else
		return 0;

	ptr = strchr(attr, '_');
	if (!ptr)
		return 0;

	len = ptr - attr;

	if (strncmp(chn->id, attr, len))
		return 0;

	DEBUG("Found match: %s and %s\n", chn->id, attr);
	if (chn->id[len] >= '0' && chn->id[len] <= '9') {
		if (chn->name) {
			size_t name_len = strlen(chn->name);
			if (strncmp(chn->name, attr + len + 1, name_len) == 0 &&
				attr[len + 1 + name_len] == '_')
				return 2;
		}
		return 1;
	} else if (chn->id[len] != '_') {
		return 0;
	}

	if (find_channel_modifier(chn->id + len + 1, NULL) != IIO_NO_MOD)
		return 1;

	return 0;
}

static int detect_global_attr(struct iio_device *dev, const char *attr,
	unsigned int level, bool *match)
{
	unsigned int i;

	*match = false;
	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];
		if (is_global_attr(chn, attr) == level) {
			int ret;
			*match = true;
			ret = add_attr_to_channel(chn, attr, attr, false);
			if (ret)
				return ret;
		}
	}

	return 0;
}

static int detect_and_move_global_attrs(struct iio_device *dev)
{
	unsigned int i;
	char **ptr = dev->attrs;

	for (i = 0; i < dev->nb_attrs; i++) {
		const char *attr = dev->attrs[i];
		bool match;
		int ret;

		ret = detect_global_attr(dev, attr, 2, &match);
		if (ret)
			return ret;

		if (!match) {
			ret = detect_global_attr(dev, attr, 1, &match);
			if (ret)
				return ret;
		}

		if (match) {
			free(dev->attrs[i]);
			dev->attrs[i] = NULL;
		}
	}

	/* Find channels without an index */
	for (i = 0; i < dev->nb_attrs; i++) {
		const char *attr = dev->attrs[i];
		int ret;

		if (!dev->attrs[i])
			continue;

		if (is_channel(attr, false)) {
			ret = add_channel(dev, attr, attr, false);
			if (ret)
				return ret;

			free(dev->attrs[i]);
			dev->attrs[i] = NULL;
		}
	}

	for (i = 0; i < dev->nb_attrs; i++) {
		if (dev->attrs[i])
			*ptr++ = dev->attrs[i];
	}

	dev->nb_attrs = ptr - dev->attrs;
	if (!dev->nb_attrs) {
		free(dev->attrs);
		dev->attrs = NULL;
	}

	return 0;
}

static int add_buffer_attr(void *d, const char *path)
{
	struct iio_device *dev = (struct iio_device *) d;
	const char *name = strrchr(path, '/') + 1;
	char **attrs, *attr;
	int i;

	for (i = 0; i < ARRAY_SIZE(buffer_attrs_reserved); i++)
		if (!strcmp(buffer_attrs_reserved[i], name))
			return 0;

	attr = iio_strdup(name);
	if (!attr)
		return -ENOMEM;

	attrs = realloc(dev->buffer_attrs, (1 + dev->nb_buffer_attrs) * sizeof(char *));
	if (!attrs) {
		free(attr);
		return -ENOMEM;
	}

	attrs[dev->nb_buffer_attrs++] = attr;
	dev->buffer_attrs = attrs;
	DEBUG("Added buffer attr \'%s\' to device \'%s\'\n", attr, dev->id);
	return 0;
}

static int add_attr_or_channel_helper(struct iio_device *dev,
		const char *path, bool dir_is_scan_elements)
{
	char buf[1024];
	const char *name = strrchr(path, '/') + 1;

	if (dir_is_scan_elements) {
		iio_snprintf(buf, sizeof(buf), "scan_elements/%s", name);
		path = buf;
	} else {
		if (!is_channel(name, true))
			return add_attr_to_device(dev, name);
		path = name;
	}

	return add_channel(dev, name, path, dir_is_scan_elements);
}

static int add_attr_or_channel(void *d, const char *path)
{
	return add_attr_or_channel_helper((struct iio_device *) d, path, false);
}

static int add_scan_element(void *d, const char *path)
{
	return add_attr_or_channel_helper((struct iio_device *) d, path, true);
}

static int foreach_in_dir(void *d, const char *path, bool is_dir,
		int (*callback)(void *, const char *))
{
	struct dirent *entry;
	DIR *dir;
	int ret = 0;

	dir = opendir(path);
	if (!dir)
		return -errno;

	while (true) {
		struct stat st;
		char buf[1024];

		errno = 0;
		entry = readdir(dir);
		if (!entry) {
			if (!errno)
				break;

			ret = -errno;
			iio_strerror(errno, buf, sizeof(buf));
			ERROR("Unable to open directory %s: %s\n", path, buf);
			goto out_close_dir;
		}

		iio_snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
		if (stat(buf, &st) < 0) {
			ret = -errno;
			iio_strerror(errno, buf, sizeof(buf));
			ERROR("Unable to stat file: %s\n", buf);
			goto out_close_dir;
		}

		if (is_dir && S_ISDIR(st.st_mode) && entry->d_name[0] != '.')
			ret = callback(d, buf);
		else if (!is_dir && S_ISREG(st.st_mode))
			ret = callback(d, buf);
		else
			continue;

		if (ret < 0)
			goto out_close_dir;
	}

out_close_dir:
	closedir(dir);
	return ret;
}

static int add_scan_elements(struct iio_device *dev, const char *devpath)
{
	struct stat st;
	char buf[1024];

	iio_snprintf(buf, sizeof(buf), "%s/scan_elements", devpath);

	if (!stat(buf, &st) && S_ISDIR(st.st_mode)) {
		int ret = foreach_in_dir(dev, buf, false, add_scan_element);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int add_buffer_attributes(struct iio_device *dev, const char *devpath)
{
	struct stat st;
	char buf[1024];

	iio_snprintf(buf, sizeof(buf), "%s/buffer", devpath);

	if (!stat(buf, &st) && S_ISDIR(st.st_mode)) {
		int ret = foreach_in_dir(dev, buf, false, add_buffer_attr);
		if (ret < 0)
			return ret;

		qsort(dev->buffer_attrs, dev->nb_buffer_attrs, sizeof(char *),
			iio_buffer_attr_compare);
	}

	return 0;
}

static int create_device(void *d, const char *path)
{
	uint32_t *mask = NULL;
	unsigned int i;
	int ret;
	struct iio_context *ctx = d;
	struct iio_device *dev = zalloc(sizeof(*dev));
	if (!dev)
		return -ENOMEM;

	dev->pdata = zalloc(sizeof(*dev->pdata));
	if (!dev->pdata) {
		free(dev);
		return -ENOMEM;
	}

	dev->pdata->fd = -1;
	dev->pdata->blocking = true;
	dev->pdata->max_nb_blocks = NB_BLOCKS;

	dev->ctx = ctx;
	dev->id = iio_strdup(strrchr(path, '/') + 1);
	if (!dev->id) {
		local_free_pdata(dev);
		free(dev);
		return -ENOMEM;
	}

	ret = foreach_in_dir(dev, path, false, add_attr_or_channel);
	if (ret < 0)
		goto err_free_device;

	ret = add_buffer_attributes(dev, path);
	if (ret < 0)
		goto err_free_device;

	ret = add_scan_elements(dev, path);
	if (ret < 0)
		goto err_free_scan_elements;

	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];

		set_channel_name(chn);
		ret = handle_scan_elements(chn);
		free_protected_attrs(chn);
		if (ret < 0)
			goto err_free_scan_elements;
	}

	ret = detect_and_move_global_attrs(dev);
	if (ret < 0)
		goto err_free_device;

	/* sorting is done after global attrs are added */
	for (i = 0; i < dev->nb_channels; i++) {
		struct iio_channel *chn = dev->channels[i];
		qsort(chn->attrs,  chn->nb_attrs, sizeof(struct iio_channel_attr),
			iio_channel_attr_compare);
	}
	qsort(dev->attrs, dev->nb_attrs, sizeof(char *),
		iio_device_attr_compare);

	dev->words = (dev->nb_channels + 31) / 32;
	if (dev->words) {
		mask = calloc(dev->words, sizeof(*mask));
		if (!mask) {
			ret = -ENOMEM;
			goto err_free_device;
		}
	}

	dev->mask = mask;

	ret = add_device_to_context(ctx, dev);
	if (!ret)
		return 0;

err_free_scan_elements:
	for (i = 0; i < dev->nb_channels; i++)
		free_protected_attrs(dev->channels[i]);
err_free_device:
	local_free_pdata(dev);
	free_device(dev);
	return ret;
}

static int add_debug_attr(void *d, const char *path)
{
	struct iio_device *dev = d;
	const char *attr = strrchr(path, '/') + 1;
	char **attrs, *name = iio_strdup(attr);
	if (!name)
		return -ENOMEM;

	attrs = realloc(dev->debug_attrs,
			(1 + dev->nb_debug_attrs) * sizeof(char *));
	if (!attrs) {
		free(name);
		return -ENOMEM;
	}

	attrs[dev->nb_debug_attrs++] = name;
	dev->debug_attrs = attrs;
	DEBUG("Added debug attr \'%s\' to device \'%s\'\n", name, dev->id);
	return 0;
}

static int add_debug(void *d, const char *path)
{
	struct iio_context *ctx = d;
	const char *name = strrchr(path, '/') + 1;
	struct iio_device *dev = iio_context_find_device(ctx, name);
	if (!dev)
		return -ENODEV;
	else
		return foreach_in_dir(dev, path, false, add_debug_attr);
}

static int local_set_timeout(struct iio_context *ctx, unsigned int timeout)
{
	ctx->pdata->rw_timeout_ms = timeout;
	return 0;
}

static void local_cancel(const struct iio_device *dev)
{
	struct iio_device_pdata *pdata = dev->pdata;
	uint64_t event = 1;
	int ret;

	ret = write(pdata->cancel_fd, &event, sizeof(event));
	if (ret == -1) {
		/* If this happens something went very seriously wrong */
		char err_str[1024];
		iio_strerror(errno, err_str, sizeof(err_str));
		ERROR("Unable to signal cancellation event: %s\n", err_str);
	}
}

static struct iio_context * local_clone(
		const struct iio_context *ctx __attribute__((unused)))
{
	return local_create_context();
}

static const struct iio_backend_ops local_ops = {
	.clone = local_clone,
	.open = local_open,
	.close = local_close,
	.get_fd = local_get_fd,
	.set_blocking_mode = local_set_blocking_mode,
	.read = local_read,
	.write = local_write,
	.set_kernel_buffers_count = local_set_kernel_buffers_count,
	.get_buffer = local_get_buffer,
	.read_device_attr = local_read_dev_attr,
	.write_device_attr = local_write_dev_attr,
	.read_channel_attr = local_read_chn_attr,
	.write_channel_attr = local_write_chn_attr,
	.get_trigger = local_get_trigger,
	.set_trigger = local_set_trigger,
	.shutdown = local_shutdown,
	.set_timeout = local_set_timeout,
	.cancel = local_cancel,
};

static void init_data_scale(struct iio_channel *chn)
{
	char buf[1024];
	ssize_t ret;

	ret = iio_channel_attr_read(chn, "scale", buf, sizeof(buf));
	if (ret < 0) {
		chn->format.with_scale = false;
	} else {
		chn->format.with_scale = true;
		chn->format.scale = atof(buf);
	}
}

static void init_scan_elements(struct iio_context *ctx)
{
	unsigned int i, j;

	for (i = 0; i < ctx->nb_devices; i++) {
		struct iio_device *dev = ctx->devices[i];

		for (j = 0; j < dev->nb_channels; j++)
			init_data_scale(dev->channels[j]);
	}
}

#ifdef WITH_LOCAL_CONFIG
static int populate_context_attrs(struct iio_context *ctx, const char *file)
{
	struct INI *ini;
	int ret;

	ini = ini_open(file);
	if (!ini) {
		/* INI file not present -> not an error */
		if (errno == ENOENT)
			return 0;
		else
			return -errno;
	}

	while (true) {
		const char *section;
		size_t len;

		ret = ini_next_section(ini, &section, &len);
		if (ret <= 0)
			goto out_close_ini;

		if (!strncmp(section, "Context Attributes", len))
			break;
	}

	do {
		const char *key, *value;
		char *new_key, *new_val;
		size_t klen, vlen;

		ret = ini_read_pair(ini, &key, &klen, &value, &vlen);
		if (ret <= 0)
			break;

		/* Create a dup of the strings read from the INI, since they are
		 * not NULL-terminated. */
		new_key = strndup(key, klen);
		new_val = strndup(value, vlen);

		if (!new_key || !new_val)
			ret = -ENOMEM;
		else
			ret = iio_context_add_attr(ctx, new_key, new_val);

		free(new_key);
		free(new_val);
	} while (!ret);

out_close_ini:
	ini_close(ini);
	return ret;
}
#endif

struct iio_context * local_create_context(void)
{
	int ret = -ENOMEM;
	unsigned int len;
	struct utsname uts;
	struct iio_context *ctx = zalloc(sizeof(*ctx));
	if (!ctx)
		goto err_set_errno;

	ctx->ops = &local_ops;
	ctx->name = "local";

	ctx->pdata = zalloc(sizeof(*ctx->pdata));
	if (!ctx->pdata) {
		free(ctx);
		goto err_set_errno;
	}

	local_set_timeout(ctx, DEFAULT_TIMEOUT_MS);

	uname(&uts);
	len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release)
		+ strlen(uts.version) + strlen(uts.machine);
	ctx->description = malloc(len + 5); /* 4 spaces + EOF */
	if (!ctx->description) {
		free(ctx->pdata);
		free(ctx);
		goto err_set_errno;
	}

	iio_snprintf(ctx->description, len + 5, "%s %s %s %s %s", uts.sysname,
			uts.nodename, uts.release, uts.version, uts.machine);

	ret = foreach_in_dir(ctx, "/sys/bus/iio/devices", true, create_device);
	if (ret < 0)
		goto err_context_destroy;

	qsort(ctx->devices, ctx->nb_devices, sizeof(struct iio_device *),
		iio_device_compare);

	foreach_in_dir(ctx, "/sys/kernel/debug/iio", true, add_debug);

	init_scan_elements(ctx);

#ifdef WITH_LOCAL_CONFIG
	ret = populate_context_attrs(ctx, "/etc/libiio.ini");
	if (ret < 0)
		goto err_context_destroy;
#endif

	ret = iio_context_add_attr(ctx, "local,kernel", uts.release);
	if (ret < 0)
		goto err_context_destroy;

	ret = iio_context_init(ctx);
	if (ret < 0)
		goto err_context_destroy;

	return ctx;

err_context_destroy:
	iio_context_destroy(ctx);
err_set_errno:
	errno = -ret;
	return NULL;
}

static int check_device(void *d, const char *path)
{
	*(bool *)d = true;
	return 0;
}

int local_context_scan(struct iio_scan_result *scan_result)
{
	struct iio_context_info **info;
	bool exists = false;
	char *desc, *uri;
	int ret;

	ret = foreach_in_dir(&exists, "/sys/bus/iio", true, check_device);
	if (ret < 0 || !exists)
		return 0;

	desc = iio_strdup("Local devices");
	if (!desc)
		return -ENOMEM;

	uri = iio_strdup("local:");
	if (!uri)
		goto err_free_desc;

	info = iio_scan_result_add(scan_result, 1);
	if (!info)
		goto err_free_uri;

	info[0]->description = desc;
	info[0]->uri = uri;
	return 0;

err_free_uri:
	free(uri);
err_free_desc:
	free(desc);
	return -ENOMEM;
}
