Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9afc33e3 authored by Maya Erez's avatar Maya Erez
Browse files

wil6210: prevent ioctl access while in reset or suspend



Accessing some of the memory of the device while the device is
resetting or suspending may cause unexpected error as the HW is still
not in a stable state. Prevent this access to guarantee successful
read/write memory operations.

Change-Id: Idbf046e21726ec8d074161f75643f34137d6ec24
Signed-off-by: default avatarAhmad Masri <amasri@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent caa945c1
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -70,6 +71,7 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
	struct wil_memio io;
	void __iomem *a;
	bool need_copy = false;
	int rc;

	if (copy_from_user(&io, data, sizeof(io)))
		return -EFAULT;
@@ -83,6 +85,11 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
			io.op);
		return -EINVAL;
	}

	rc = wil_mem_access_lock(wil);
	if (rc)
		return rc;

	/* operation */
	switch (io.op & wil_mmio_op_mask) {
	case wil_mmio_read:
@@ -97,9 +104,12 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
#endif
	default:
		wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op);
		wil_mem_access_unlock(wil);
		return -EINVAL;
	}

	wil_mem_access_unlock(wil);

	if (need_copy) {
		wil_dbg_ioctl(wil,
			      "IO done: addr(0x%08x) val(0x%08x) op(0x%08x)\n",
@@ -141,6 +151,12 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
	if (!block)
		return -ENOMEM;

	rc = wil_mem_access_lock(wil);
	if (rc) {
		kfree(block);
		return rc;
	}

	/* operation */
	switch (io.op & wil_mmio_op_mask) {
	case wil_mmio_read:
@@ -148,14 +164,14 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
		wil_hex_dump_ioctl("Read  ", block, io.size);
		if (copy_to_user(io.block, block, io.size)) {
			rc = -EFAULT;
			goto out_free;
			goto out_unlock;
		}
		break;
#if defined(CONFIG_WIL6210_WRITE_IOCTL)
	case wil_mmio_write:
		if (copy_from_user(block, io.block, io.size)) {
			rc = -EFAULT;
			goto out_free;
			goto out_unlock;
		}
		wil_memcpy_toio_32(a, block, io.size);
		wmb(); /* make sure write propagated to HW */
@@ -168,7 +184,8 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
		break;
	}

out_free:
out_unlock:
	wil_mem_access_unlock(wil);
	kfree(block);
	return rc;
}