/* 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; }
/* 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; }