aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>2012-03-06 04:09:40 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2012-03-06 10:53:54 -0500
commit068a4633bf42501db3ec934beff07cd50c1b7e9d (patch)
treece9f87c4caa333517d2c77d7b0c3a85dbe820c2d
parent05e5bd0f3daddb0368a433af5b58be68c62dc365 (diff)
ath6kl: Fix kernel panic while receiving fwlog during boot
"ath6kl: Defer wiphy and netdev registration till the end of ath6kl_core_init()" causes kernel panic by accessing the unallocated debug resources during boot time. To fix this, split the debug initialization funtion into two, one initializes the debug resource and the other takes care of debugfs initialization. When this issue shows up the kernel crash dump would look like ath6kl_debug_fwlog_event+0x9c/0x10a [<c10666c9>] register_lock_class+0x57/0x288 [<c1065cd3>] ? trace_hardirqs_on+0xb/0xd [<f801f4c9>] ? ath6kl_debug_fwlog_event+0x9c/0x10a [<c1066a8a>] __lock_acquire+0x96/0xbe5 [<c106007b>] ? alarmtimer_suspend+0x80/0x127 [<c10258da>] ? vprintk+0x394/0x3b1 [<f801f4c9>] ? ath6kl_debug_fwlog_event+0x9c/0x10a [<c10676b3>] lock_acquire+0xda/0xf9 [<f801f4c9>] ? ath6kl_debug_fwlog_event+0x9c/0x10a [<c1532ce3>] _raw_spin_lock+0x28/0x58 [<f801f4c9>] ? ath6kl_debug_fwlog_event+0x9c/0x10a [<f801f4c9>] ath6kl_debug_fwlog_event+0x9c/0x10a [<f80310a4>] ath6kl_wmi_control_rx+0x69d/0xb50 [ath6kl_core] [<f802d2e1>] ? ath6kl_rx+0x3c/0x839 [ath6kl_core] [<f802d35d>] ath6kl_rx+0xb8/0x839 [ath6kl_core] [<c104b81e>] ? local_clock+0x2d/0x4e [<c102a0af>] ? _local_bh_enable_ip+0x94/0x98 [<f802bfc0>] ? ath6kl_alloc_amsdu_rxbuf+0xb7/0xb7 [<f8023b28>] ath6kl_htc_rxmsg_pending_handler+0x891/0x988 [ath6kl_core] [<f802bf00>] ? ath6kl_refill_amsdu_rxbufs+0x89/0x92 [<f802d2a5>] ? aggr_timeout+0xed/0xed [ath6kl_core] [<f802bfc0>] ? ath6kl_alloc_amsdu_rxbuf+0xb7/0xb7 [<f802c420>] ? ath6kl_tx_complete+0x376/0x376 [ath6kl_core] [<f8020e92>] ath6kl_hif_intr_bh_handler+0xf7/0x33e [<c138ab00>] ? mmc_host_disable+0x15/0x3a [<f8123b5c>] ath6kl_sdio_irq_handler+0x3c/0x90 [ath6kl_sdio] [<c1392f56>] sdio_irq_thread+0xb6/0x29c [<c1392ea0>] ? sdio_claim_irq+0x1cb/0x1cb [<c103d4c0>] kthread+0x67/0x6c [<c103d459>] ? __init_kthread_worker+0x42/0x42 [<c153903a>] kernel_thread_helper+0x6/0xd BUG: unable to handle kernel NULL pointer dereference at EIP: [<f801f4d4>] ath6kl_debug_fwlog_event+0xa7/0x10a kvalo: rename new function to ath6kl_debug_init_fs() and add a comment why it's needed Reported-by: Kalle Valo <kvalo@qca.qualcomm.com> Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c9
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/debug.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h9
3 files changed, 21 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index e66cf4399b61..84dd9786622f 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -124,6 +124,8 @@ int ath6kl_core_init(struct ath6kl *ar)
124 124
125 set_bit(FIRST_BOOT, &ar->flag); 125 set_bit(FIRST_BOOT, &ar->flag);
126 126
127 ath6kl_debug_init(ar);
128
127 ret = ath6kl_init_hw_start(ar); 129 ret = ath6kl_init_hw_start(ar);
128 if (ret) { 130 if (ret) {
129 ath6kl_err("Failed to start hardware: %d\n", ret); 131 ath6kl_err("Failed to start hardware: %d\n", ret);
@@ -138,7 +140,7 @@ int ath6kl_core_init(struct ath6kl *ar)
138 if (ret) 140 if (ret)
139 goto err_rxbuf_cleanup; 141 goto err_rxbuf_cleanup;
140 142
141 ret = ath6kl_debug_init(ar); 143 ret = ath6kl_debug_init_fs(ar);
142 if (ret) { 144 if (ret) {
143 wiphy_unregister(ar->wiphy); 145 wiphy_unregister(ar->wiphy);
144 goto err_rxbuf_cleanup; 146 goto err_rxbuf_cleanup;
@@ -159,7 +161,7 @@ int ath6kl_core_init(struct ath6kl *ar)
159 ath6kl_err("Failed to instantiate a network device\n"); 161 ath6kl_err("Failed to instantiate a network device\n");
160 ret = -ENOMEM; 162 ret = -ENOMEM;
161 wiphy_unregister(ar->wiphy); 163 wiphy_unregister(ar->wiphy);
162 goto err_debug_init; 164 goto err_rxbuf_cleanup;
163 } 165 }
164 166
165 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", 167 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
@@ -167,9 +169,8 @@ int ath6kl_core_init(struct ath6kl *ar)
167 169
168 return ret; 170 return ret;
169 171
170err_debug_init:
171 ath6kl_debug_cleanup(ar);
172err_rxbuf_cleanup: 172err_rxbuf_cleanup:
173 ath6kl_debug_cleanup(ar);
173 ath6kl_htc_flush_rx_buf(ar->htc_target); 174 ath6kl_htc_flush_rx_buf(ar->htc_target);
174 ath6kl_cleanup_amsdu_rxbufs(ar); 175 ath6kl_cleanup_amsdu_rxbufs(ar);
175 ath6kl_wmi_shutdown(ar->wmi); 176 ath6kl_wmi_shutdown(ar->wmi);
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 28b516ff3d59..645f923f79b5 100755
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1722,7 +1722,7 @@ static const struct file_operations fops_power_params = {
1722 .llseek = default_llseek, 1722 .llseek = default_llseek,
1723}; 1723};
1724 1724
1725int ath6kl_debug_init(struct ath6kl *ar) 1725void ath6kl_debug_init(struct ath6kl *ar)
1726{ 1726{
1727 skb_queue_head_init(&ar->debug.fwlog_queue); 1727 skb_queue_head_init(&ar->debug.fwlog_queue);
1728 init_completion(&ar->debug.fwlog_completion); 1728 init_completion(&ar->debug.fwlog_completion);
@@ -1732,7 +1732,15 @@ int ath6kl_debug_init(struct ath6kl *ar)
1732 * value from the firmware. 1732 * value from the firmware.
1733 */ 1733 */
1734 ar->debug.fwlog_mask = 0; 1734 ar->debug.fwlog_mask = 0;
1735}
1735 1736
1737/*
1738 * Initialisation needs to happen in two stages as fwlog events can come
1739 * before cfg80211 is initialised, and debugfs depends on cfg80211
1740 * initialisation.
1741 */
1742int ath6kl_debug_init_fs(struct ath6kl *ar)
1743{
1736 ar->debugfs_phy = debugfs_create_dir("ath6kl", 1744 ar->debugfs_phy = debugfs_create_dir("ath6kl",
1737 ar->wiphy->debugfsdir); 1745 ar->wiphy->debugfsdir);
1738 if (!ar->debugfs_phy) 1746 if (!ar->debugfs_phy)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index c5d5e6c8259e..1803a0baae82 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -78,7 +78,8 @@ int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf,
78 size_t len); 78 size_t len);
79void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); 79void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive);
80void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); 80void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout);
81int ath6kl_debug_init(struct ath6kl *ar); 81void ath6kl_debug_init(struct ath6kl *ar);
82int ath6kl_debug_init_fs(struct ath6kl *ar);
82void ath6kl_debug_cleanup(struct ath6kl *ar); 83void ath6kl_debug_cleanup(struct ath6kl *ar);
83 84
84#else 85#else
@@ -128,7 +129,11 @@ static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar,
128{ 129{
129} 130}
130 131
131static inline int ath6kl_debug_init(struct ath6kl *ar) 132static inline void ath6kl_debug_init(struct ath6kl *ar)
133{
134}
135
136static inline int ath6kl_debug_init_fs(struct ath6kl *ar)
132{ 137{
133 return 0; 138 return 0;
134} 139}