|
@@ -535,6 +535,83 @@ done:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/* Proc memrw file write handler.
|
|
|
+ * This function is called when the 'memrw' file is opened for writing
|
|
|
+ * This function can be used to write to a memory location.
|
|
|
+ */
|
|
|
+static ssize_t
|
|
|
+mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
|
|
|
+ loff_t *ppos)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ char cmd;
|
|
|
+ struct mwifiex_ds_mem_rw mem_rw;
|
|
|
+ u16 cmd_action;
|
|
|
+ struct mwifiex_private *priv = (void *)file->private_data;
|
|
|
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
|
|
+ char *buf = (void *)addr;
|
|
|
+ size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1));
|
|
|
+
|
|
|
+ if (!buf)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ if (copy_from_user(buf, ubuf, buf_size)) {
|
|
|
+ ret = -EFAULT;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
|
|
|
+ if (ret != 3) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((cmd == 'r') || (cmd == 'R')) {
|
|
|
+ cmd_action = HostCmd_ACT_GEN_GET;
|
|
|
+ mem_rw.value = 0;
|
|
|
+ } else if ((cmd == 'w') || (cmd == 'W')) {
|
|
|
+ cmd_action = HostCmd_ACT_GEN_SET;
|
|
|
+ } else {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(&priv->mem_rw, &mem_rw, sizeof(mem_rw));
|
|
|
+ if (mwifiex_send_cmd(priv, HostCmd_CMD_MEM_ACCESS, cmd_action, 0,
|
|
|
+ &mem_rw, true))
|
|
|
+ ret = -1;
|
|
|
+ else
|
|
|
+ ret = count;
|
|
|
+
|
|
|
+done:
|
|
|
+ free_page(addr);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/* Proc memrw file read handler.
|
|
|
+ * This function is called when the 'memrw' file is opened for reading
|
|
|
+ * This function can be used to read from a memory location.
|
|
|
+ */
|
|
|
+static ssize_t
|
|
|
+mwifiex_memrw_read(struct file *file, char __user *ubuf,
|
|
|
+ size_t count, loff_t *ppos)
|
|
|
+{
|
|
|
+ struct mwifiex_private *priv = (void *)file->private_data;
|
|
|
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
|
|
+ char *buf = (char *)addr;
|
|
|
+ int ret, pos = 0;
|
|
|
+
|
|
|
+ if (!buf)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ pos += snprintf(buf, PAGE_SIZE, "0x%x 0x%x\n", priv->mem_rw.addr,
|
|
|
+ priv->mem_rw.value);
|
|
|
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
|
|
|
+
|
|
|
+ free_page(addr);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static u32 saved_offset = -1, saved_bytes = -1;
|
|
|
|
|
|
/*
|
|
@@ -749,6 +826,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog);
|
|
|
MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
|
|
|
MWIFIEX_DFS_FILE_OPS(regrdwr);
|
|
|
MWIFIEX_DFS_FILE_OPS(rdeeprom);
|
|
|
+MWIFIEX_DFS_FILE_OPS(memrw);
|
|
|
MWIFIEX_DFS_FILE_OPS(hscfg);
|
|
|
MWIFIEX_DFS_FILE_OPS(histogram);
|
|
|
|
|
@@ -773,6 +851,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
|
|
|
MWIFIEX_DFS_ADD_FILE(regrdwr);
|
|
|
MWIFIEX_DFS_ADD_FILE(rdeeprom);
|
|
|
MWIFIEX_DFS_ADD_FILE(fw_dump);
|
|
|
+ MWIFIEX_DFS_ADD_FILE(memrw);
|
|
|
MWIFIEX_DFS_ADD_FILE(hscfg);
|
|
|
MWIFIEX_DFS_ADD_FILE(histogram);
|
|
|
}
|