diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-11-13 03:10:21 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2013-12-09 15:29:04 -0500 |
commit | 1fa3f57a1ca19ad45ff5fa248d509fc442e82a63 (patch) | |
tree | a424611bc2bc266b8a933d5b931b52c6f8337e9f | |
parent | 7f09d70436729dee9dfa7ab11fda9d384c4bdf9f (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.c | 87 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/debugfs.h | 25 |
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 | ||
69 | static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, | 69 | static 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 | ||
97 | static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, | 90 | static 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 | ||
190 | static ssize_t iwl_dbgfs_sram_write(struct file *file, | 176 | static 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 | ||
261 | static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, | 240 | static 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 | ||
571 | static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | 542 | static 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 | ||
592 | static ssize_t iwl_dbgfs_fw_nmi_write(struct file *file, | 561 | static 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 | ||
626 | static ssize_t | 592 | static ssize_t |
627 | iwl_dbgfs_scan_ant_rxchain_write(struct file *file, | 593 | iwl_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 |
651 | static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, | 611 | static 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 */ |
722 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); | 679 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); |
723 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); | 680 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); |
724 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); | 681 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); |
725 | MVM_DEBUGFS_READ_FILE_OPS(stations); | 682 | MVM_DEBUGFS_READ_FILE_OPS(stations); |
726 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); | 683 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); |
727 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); | 684 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); |
728 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); | 685 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); |
729 | MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); | 686 | MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); |
730 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); | 687 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); |
731 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi); | 688 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); |
732 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); | 689 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); |
733 | 690 | ||
734 | #ifdef CONFIG_PM_SLEEP | 691 | #ifdef CONFIG_PM_SLEEP |
735 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); | 692 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8); |
736 | #endif | 693 | #endif |
737 | 694 | ||
738 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | 695 | int 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) \ |
72 | static 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) \ | ||
87 | MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ | ||
72 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 88 | static 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) \ |
96 | MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ | ||
80 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 97 | static 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 | }; |