Ejemplo n.º 1
0
static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
{
	struct wil_memio_block io;
	void *block;
	void __iomem *a;
	int rc = 0;

	if (copy_from_user(&io, data, sizeof(io)))
		return -EFAULT;

	wil_dbg_ioctl(wil, "IO: addr = 0x%08x size = 0x%08x op = 0x%08x\n",
		      io.addr, io.size, io.op);

	/* size */
	if (io.size % 4) {
		wil_err(wil, "size is not multiple of 4:  0x%08x\n", io.size);
		return -EINVAL;
	}

	a = wil_ioc_addr(wil, io.addr, io.size, io.op);
	if (!a) {
		wil_err(wil, "invalid address 0x%08x, op = 0x%08x\n", io.addr,
			io.op);
		return -EINVAL;
	}

	block = kmalloc(io.size, GFP_USER);
	if (!block)
		return -ENOMEM;

	/* operation */
	switch (io.op & wil_mmio_op_mask) {
	case wil_mmio_read:
		wil_memcpy_fromio_32(block, a, io.size);
		wil_hex_dump_ioctl("Read  ", block, io.size);
		if (copy_to_user(io.block, block, io.size)) {
			rc = -EFAULT;
			goto out_free;
		}
		break;
	case wil_mmio_write:
		if (copy_from_user(block, io.block, io.size)) {
			rc = -EFAULT;
			goto out_free;
		}
		wil_memcpy_toio_32(a, block, io.size);
		wmb(); /* make sure write propagated to HW */
		wil_hex_dump_ioctl("Write ", block, io.size);
		break;
	default:
		wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op);
		rc = -EINVAL;
		break;
	}

out_free:
	kfree(block);
	return rc;
}
Ejemplo n.º 2
0
void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil,
			       volatile void __iomem *dst,
			       const void *src, size_t count)
{
	wil_halp_vote(wil);
	wil_memcpy_toio_32(dst, src, count);
	wil_halp_unvote(wil);
}