--- zzzz-none-000/linux-4.4.271/drivers/net/wireless/ath/wil6210/ioctl.c 2021-06-03 06:22:09.000000000 +0000 +++ dakota-7530ac-750/linux-4.4.271/drivers/net/wireless/ath/wil6210/ioctl.c 2023-01-11 09:25:42.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014 Qualcomm Atheros, Inc. + * 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 @@ -46,7 +47,7 @@ } off = a - wil->csr; - if (size >= WIL6210_MEM_SIZE - off) { + if (size >= wil->bar_size - off) { wil_err(wil, "Requested block does not fit into memory: " "off = 0x%08x size = 0x%08x\n", off, size); return NULL; @@ -60,6 +61,7 @@ struct wil_memio io; void __iomem *a; bool need_copy = false; + int rc; if (copy_from_user(&io, data, sizeof(io))) return -EFAULT; @@ -73,20 +75,29 @@ 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: io.val = readl(a); need_copy = true; break; +#if defined(CONFIG_WIL6210_WRITE_IOCTL) case wil_mmio_write: writel(io.val, a); wmb(); /* make sure write propagated to HW */ break; +#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" @@ -129,6 +140,12 @@ 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: @@ -136,38 +153,48 @@ 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 */ wil_hex_dump_ioctl("Write ", block, io.size); break; +#endif default: wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op); rc = -EINVAL; break; } -out_free: +out_unlock: + wil_mem_access_unlock(wil); kfree(block); return rc; } int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd) { + int ret; + switch (cmd) { case WIL_IOCTL_MEMIO: - return wil_ioc_memio_dword(wil, data); + ret = wil_ioc_memio_dword(wil, data); + break; case WIL_IOCTL_MEMIO_BLOCK: - return wil_ioc_memio_block(wil, data); + ret = wil_ioc_memio_block(wil, data); + break; default: wil_dbg_ioctl(wil, "Unsupported IOCTL 0x%04x\n", cmd); return -ENOIOCTLCMD; } + + wil_dbg_ioctl(wil, "ioctl(0x%04x) -> %d\n", cmd, ret); + return ret; }