Пример #1
0
/* Read a variable number of 32-bit values. Parameter count is not allowed to
 * exceed USB_MAX_IOREAD32_COUNT.
 */
int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
		 unsigned int count)
{
	int r;
	int i;
	zd_addr_t *a16;
	u16 *v16;
	unsigned int count16;

	if (count > USB_MAX_IOREAD32_COUNT)
		return -EINVAL;

	/* Allocate a single memory block for values and addresses. */
	count16 = 2*count;
	a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
		                   GFP_KERNEL);
	if (!a16) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error ENOMEM in allocation of a16\n");
		r = -ENOMEM;
		goto out;
	}
	v16 = (u16 *)(a16 + count16);

	for (i = 0; i < count; i++) {
		int j = 2*i;
		/* We read the high word always first. */
		a16[j] = inc_addr(addr[i]);
		a16[j+1] = addr[i];
	}

	r = zd_ioread16v_locked(chip, v16, a16, count16);
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error: zd_ioread16v_locked. Error number %d\n", r);
		goto out;
	}

	for (i = 0; i < count; i++) {
		int j = 2*i;
		values[i] = (v16[j] << 16) | v16[j+1];
	}

out:
	kfree((void *)a16);
	return r;
}
Пример #2
0
/* Read a variable number of 32-bit values. Parameter count is not allowed to
 * exceed USB_MAX_IOREAD32_COUNT.
 */
int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
		 unsigned int count)
{
	int r;
	int i;
	zd_addr_t a16[USB_MAX_IOREAD32_COUNT * 2];
	u16 v16[USB_MAX_IOREAD32_COUNT * 2];
	unsigned int count16;

	if (count > USB_MAX_IOREAD32_COUNT)
		return -EINVAL;

	/* Use stack for values and addresses. */
	count16 = 2 * count;
	BUG_ON(count16 * sizeof(zd_addr_t) > sizeof(a16));
	BUG_ON(count16 * sizeof(u16) > sizeof(v16));

	for (i = 0; i < count; i++) {
		int j = 2*i;
		/* We read the high word always first. */
		a16[j] = inc_addr(addr[i]);
		a16[j+1] = addr[i];
	}

	r = zd_ioread16v_locked(chip, v16, a16, count16);
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error: %s. Error number %d\n", __func__, r);
		return r;
	}

	for (i = 0; i < count; i++) {
		int j = 2*i;
		values[i] = (v16[j] << 16) | v16[j+1];
	}

	return 0;
}