aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-11-13 03:10:21 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-12-09 15:29:04 -0500
commit1fa3f57a1ca19ad45ff5fa248d509fc442e82a63 (patch)
treea424611bc2bc266b8a933d5b931b52c6f8337e9f
parent7f09d70436729dee9dfa7ab11fda9d384c4bdf9f (diff)
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: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c87
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h25
2 files changed, 43 insertions, 69 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 6850a2d94bcb..931723a03a43 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -66,22 +66,15 @@
66#include "iwl-prph.h" 66#include "iwl-prph.h"
67#include "debugfs.h" 67#include "debugfs.h"
68 68
69static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, 69static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
70 const char __user *user_buf,
71 size_t count, loff_t *ppos) 70 size_t count, loff_t *ppos)
72{ 71{
73 struct iwl_mvm *mvm = file->private_data;
74 char buf[16] = {};
75 size_t buf_size = min(count, sizeof(buf) - 1);
76 int ret; 72 int ret;
77 u32 scd_q_msk; 73 u32 scd_q_msk;
78 74
79 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 75 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
80 return -EIO; 76 return -EIO;
81 77
82 if (copy_from_user(buf, user_buf, buf_size))
83 return -EFAULT;
84
85 if (sscanf(buf, "%x", &scd_q_msk) != 1) 78 if (sscanf(buf, "%x", &scd_q_msk) != 1)
86 return -EINVAL; 79 return -EINVAL;
87 80
@@ -94,22 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
94 return ret; 87 return ret;
95} 88}
96 89
97static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, 90static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
98 const char __user *user_buf,
99 size_t count, loff_t *ppos) 91 size_t count, loff_t *ppos)
100{ 92{
101 struct iwl_mvm *mvm = file->private_data;
102 struct ieee80211_sta *sta; 93 struct ieee80211_sta *sta;
103 char buf[8] = {};
104 size_t buf_size = min(count, sizeof(buf) - 1);
105 int sta_id, drain, ret; 94 int sta_id, drain, ret;
106 95
107 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 96 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
108 return -EIO; 97 return -EIO;
109 98
110 if (copy_from_user(buf, user_buf, buf_size))
111 return -EFAULT;
112
113 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) 99 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
114 return -EINVAL; 100 return -EINVAL;
115 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) 101 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 return ret; 173 return ret;
188} 174}
189 175
190static ssize_t iwl_dbgfs_sram_write(struct file *file, 176static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
191 const char __user *user_buf, size_t count, 177 size_t count, loff_t *ppos)
192 loff_t *ppos)
193{ 178{
194 struct iwl_mvm *mvm = file->private_data;
195 char buf[64] = {};
196 size_t buf_size = min(count, sizeof(buf) - 1);
197 u32 offset, len; 179 u32 offset, len;
198 180
199 if (copy_from_user(buf, user_buf, buf_size))
200 return -EFAULT;
201
202 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 181 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
203 if ((offset & 0x3) || (len & 0x3)) 182 if ((offset & 0x3) || (len & 0x3))
204 return -EINVAL; 183 return -EINVAL;
@@ -258,22 +237,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
258 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 237 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
259} 238}
260 239
261static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, 240static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
262 const char __user *user_buf,
263 size_t count, loff_t *ppos) 241 size_t count, loff_t *ppos)
264{ 242{
265 struct iwl_mvm *mvm = file->private_data; 243 int ret, val;
266 char buf[64] = {};
267 size_t buf_size = min(count, sizeof(buf) - 1);
268 int ret;
269 int val;
270 244
271 if (!mvm->ucode_loaded) 245 if (!mvm->ucode_loaded)
272 return -EIO; 246 return -EIO;
273 247
274 if (copy_from_user(buf, user_buf, buf_size))
275 return -EFAULT;
276
277 if (!strncmp("disable_power_off_d0=", buf, 21)) { 248 if (!strncmp("disable_power_off_d0=", buf, 21)) {
278 if (sscanf(buf + 21, "%d", &val) != 1) 249 if (sscanf(buf + 21, "%d", &val) != 1)
279 return -EINVAL; 250 return -EINVAL;
@@ -568,11 +539,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
568} 539}
569#undef PRINT_STAT_LE32 540#undef PRINT_STAT_LE32
570 541
571static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 542static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
572 const char __user *user_buf,
573 size_t count, loff_t *ppos) 543 size_t count, loff_t *ppos)
574{ 544{
575 struct iwl_mvm *mvm = file->private_data;
576 int ret; 545 int ret;
577 546
578 mutex_lock(&mvm->mutex); 547 mutex_lock(&mvm->mutex);
@@ -589,12 +558,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
589 return count; 558 return count;
590} 559}
591 560
592static ssize_t iwl_dbgfs_fw_nmi_write(struct file *file, 561static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
593 const char __user *user_buf,
594 size_t count, loff_t *ppos) 562 size_t count, loff_t *ppos)
595{ 563{
596 struct iwl_mvm *mvm = file->private_data;
597
598 iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1); 564 iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
599 565
600 return count; 566 return count;
@@ -624,17 +590,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
624} 590}
625 591
626static ssize_t 592static ssize_t
627iwl_dbgfs_scan_ant_rxchain_write(struct file *file, 593iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
628 const char __user *user_buf,
629 size_t count, loff_t *ppos) 594 size_t count, loff_t *ppos)
630{ 595{
631 struct iwl_mvm *mvm = file->private_data;
632 char buf[8] = {};
633 size_t buf_size = min(count, sizeof(buf) - 1);
634 u8 scan_rx_ant; 596 u8 scan_rx_ant;
635 597
636 if (copy_from_user(buf, user_buf, buf_size))
637 return -EFAULT;
638 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) 598 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
639 return -EINVAL; 599 return -EINVAL;
640 if (scan_rx_ant > ANT_ABC) 600 if (scan_rx_ant > ANT_ABC)
@@ -648,18 +608,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
648} 608}
649 609
650#ifdef CONFIG_PM_SLEEP 610#ifdef CONFIG_PM_SLEEP
651static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, 611static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
652 const char __user *user_buf,
653 size_t count, loff_t *ppos) 612 size_t count, loff_t *ppos)
654{ 613{
655 struct iwl_mvm *mvm = file->private_data;
656 char buf[8] = {};
657 size_t buf_size = min(count, sizeof(buf) - 1);
658 int store; 614 int store;
659 615
660 if (copy_from_user(buf, user_buf, buf_size))
661 return -EFAULT;
662
663 if (sscanf(buf, "%d", &store) != 1) 616 if (sscanf(buf, "%d", &store) != 1)
664 return -EINVAL; 617 return -EINVAL;
665 618
@@ -712,6 +665,10 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
712} 665}
713#endif 666#endif
714 667
668#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
669 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
670#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
671 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
715#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \ 672#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
716 if (!debugfs_create_file(#name, mode, parent, mvm, \ 673 if (!debugfs_create_file(#name, mode, parent, mvm, \
717 &iwl_dbgfs_##name##_ops)) \ 674 &iwl_dbgfs_##name##_ops)) \
@@ -719,20 +676,20 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
719 } while (0) 676 } while (0)
720 677
721/* Device wide debugfs entries */ 678/* Device wide debugfs entries */
722MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); 679MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
723MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 680MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
724MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 681MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
725MVM_DEBUGFS_READ_FILE_OPS(stations); 682MVM_DEBUGFS_READ_FILE_OPS(stations);
726MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 683MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
727MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 684MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
728MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); 685MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
729MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 686MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
730MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 687MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
731MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi); 688MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
732MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); 689MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
733 690
734#ifdef CONFIG_PM_SLEEP 691#ifdef CONFIG_PM_SLEEP
735MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); 692MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
736#endif 693#endif
737 694
738int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 695int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
index faa73b80b624..85f9f958bfd2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
@@ -68,17 +68,34 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
68 .llseek = generic_file_llseek, \ 68 .llseek = generic_file_llseek, \
69} 69}
70 70
71#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \ 71#define MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
72static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
73 const char __user *user_buf, \
74 size_t count, loff_t *ppos) \
75{ \
76 argtype *arg = file->private_data; \
77 char buf[buflen] = {}; \
78 size_t buf_size = min(count, sizeof(buf) - 1); \
79 \
80 if (copy_from_user(buf, user_buf, buf_size)) \
81 return -EFAULT; \
82 \
83 return iwl_dbgfs_##name##_write(arg, buf, buf_size, ppos); \
84} \
85
86#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype) \
87MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
72static const struct file_operations iwl_dbgfs_##name##_ops = { \ 88static const struct file_operations iwl_dbgfs_##name##_ops = { \
73 .write = iwl_dbgfs_##name##_write, \ 89 .write = _iwl_dbgfs_##name##_write, \
74 .read = iwl_dbgfs_##name##_read, \ 90 .read = iwl_dbgfs_##name##_read, \
75 .open = simple_open, \ 91 .open = simple_open, \
76 .llseek = generic_file_llseek, \ 92 .llseek = generic_file_llseek, \
77}; 93};
78 94
79#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ 95#define _MVM_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype) \
96MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
80static const struct file_operations iwl_dbgfs_##name##_ops = { \ 97static const struct file_operations iwl_dbgfs_##name##_ops = { \
81 .write = iwl_dbgfs_##name##_write, \ 98 .write = _iwl_dbgfs_##name##_write, \
82 .open = simple_open, \ 99 .open = simple_open, \
83 .llseek = generic_file_llseek, \ 100 .llseek = generic_file_llseek, \
84}; 101};