Commit 1fa3f57a authored by Johannes Berg's avatar Johannes Berg Committed by Emmanuel Grumbach

iwlwifi: mvm: refactor debugfs copy_from_user()

Abstract the copy_from_user() pattern into the macros defining
debugfs files, reducing the code and making adding new files
safer by avoiding having deal with copy_from_user() directly.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 7f09d704
...@@ -66,22 +66,15 @@ ...@@ -66,22 +66,15 @@
#include "iwl-prph.h" #include "iwl-prph.h"
#include "debugfs.h" #include "debugfs.h"
static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
char buf[16] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
int ret; int ret;
u32 scd_q_msk; u32 scd_q_msk;
if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
return -EIO; return -EIO;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x", &scd_q_msk) != 1) if (sscanf(buf, "%x", &scd_q_msk) != 1)
return -EINVAL; return -EINVAL;
...@@ -94,22 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, ...@@ -94,22 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
return ret; return ret;
} }
static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
char buf[8] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
int sta_id, drain, ret; int sta_id, drain, ret;
if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
return -EIO; return -EIO;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
return -EINVAL; return -EINVAL;
if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
...@@ -187,18 +173,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, ...@@ -187,18 +173,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
return ret; return ret;
} }
static ssize_t iwl_dbgfs_sram_write(struct file *file, static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf, size_t count, size_t count, loff_t *ppos)
loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
char buf[64] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
u32 offset, len; u32 offset, len;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x,%x", &offset, &len) == 2) { if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
if ((offset & 0x3) || (len & 0x3)) if ((offset & 0x3) || (len & 0x3))
return -EINVAL; return -EINVAL;
...@@ -258,22 +237,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file, ...@@ -258,22 +237,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos); return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
} }
static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data; int ret, val;
char buf[64] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
int ret;
int val;
if (!mvm->ucode_loaded) if (!mvm->ucode_loaded)
return -EIO; return -EIO;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (!strncmp("disable_power_off_d0=", buf, 21)) { if (!strncmp("disable_power_off_d0=", buf, 21)) {
if (sscanf(buf + 21, "%d", &val) != 1) if (sscanf(buf + 21, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
...@@ -568,11 +539,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, ...@@ -568,11 +539,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
} }
#undef PRINT_STAT_LE32 #undef PRINT_STAT_LE32
static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
int ret; int ret;
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
...@@ -589,12 +558,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, ...@@ -589,12 +558,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
return count; return count;
} }
static ssize_t iwl_dbgfs_fw_nmi_write(struct file *file, static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1); iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
return count; return count;
...@@ -624,17 +590,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file, ...@@ -624,17 +590,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
} }
static ssize_t static ssize_t
iwl_dbgfs_scan_ant_rxchain_write(struct file *file, iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
char buf[8] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
u8 scan_rx_ant; u8 scan_rx_ant;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
return -EINVAL; return -EINVAL;
if (scan_rx_ant > ANT_ABC) if (scan_rx_ant > ANT_ABC)
...@@ -648,18 +608,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file, ...@@ -648,18 +608,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data;
char buf[8] = {};
size_t buf_size = min(count, sizeof(buf) - 1);
int store; int store;
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%d", &store) != 1) if (sscanf(buf, "%d", &store) != 1)
return -EINVAL; return -EINVAL;
...@@ -712,6 +665,10 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, ...@@ -712,6 +665,10 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
} }
#endif #endif
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \ #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
if (!debugfs_create_file(#name, mode, parent, mvm, \ if (!debugfs_create_file(#name, mode, parent, mvm, \
&iwl_dbgfs_##name##_ops)) \ &iwl_dbgfs_##name##_ops)) \
...@@ -719,20 +676,20 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, ...@@ -719,20 +676,20 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
} while (0) } while (0)
/* Device wide debugfs entries */ /* Device wide debugfs entries */
MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
MVM_DEBUGFS_READ_FILE_OPS(stations); MVM_DEBUGFS_READ_FILE_OPS(stations);
MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi); MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
#endif #endif
int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
......
...@@ -68,17 +68,34 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ ...@@ -68,17 +68,34 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.llseek = generic_file_llseek, \ .llseek = generic_file_llseek, \
} }
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \ #define MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
argtype *arg = file->private_data; \
char buf[buflen] = {}; \
size_t buf_size = min(count, sizeof(buf) - 1); \
\
if (copy_from_user(buf, user_buf, buf_size)) \
return -EFAULT; \
\
return iwl_dbgfs_##name##_write(arg, buf, buf_size, ppos); \
} \
#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype) \
MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \ .write = _iwl_dbgfs_##name##_write, \
.read = iwl_dbgfs_##name##_read, \ .read = iwl_dbgfs_##name##_read, \
.open = simple_open, \ .open = simple_open, \
.llseek = generic_file_llseek, \ .llseek = generic_file_llseek, \
}; };
#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ #define _MVM_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype) \
MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \ .write = _iwl_dbgfs_##name##_write, \
.open = simple_open, \ .open = simple_open, \
.llseek = generic_file_llseek, \ .llseek = generic_file_llseek, \
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment