[PATCH 4/5] Clean up module init and exit

pontus.fuchs at gmail.com pontus.fuchs at gmail.com
Wed Apr 17 06:19:17 EDT 2013


From: Pontus Fuchs <pontus.fuchs at gmail.com>

Do proper error checking in init
Free wq and iounmap in exit
---
 main.c |   51 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/main.c b/main.c
index f3d7bf1..156e97e 100644
--- a/main.c
+++ b/main.c
@@ -440,20 +440,36 @@ static int __init wcn36xx_init(void)
 	struct resource *wcnss_memory;
 	int ret;
 
-	/* FIXME: the whole function needs proper error handling */
-
 	hw = wcn36xx_alloc_hw();
+	if (!hw) {
+		wcn36xx_error("failed to alloc hw");
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
 	wcn = hw->priv;
 	wcn->hw = hw;
 
 	wcn->dev = wcnss_wlan_get_device();
 	if (wcn->dev == NULL) {
 		wcn36xx_error("failed to get wcnss wlan device");
-		return -EINVAL;
+		ret = -ENOENT;
+		goto out_err;
 	}
 
 	wcn->wq = create_freezable_workqueue("wcn36xx_wq");
+	if (!wcn->wq) {
+		wcn36xx_error("failed to allocate wq");
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
 	wcn->ctl_wq = create_freezable_workqueue("wcn36xx_ctl_wq");
+	if (!wcn->ctl_wq) {
+		wcn36xx_error("failed to allocate ctl wq");
+		ret = -ENOMEM;
+		goto out_wq;
+	}
 
 	wcn36xx_init_ieee80211(wcn);
 	// TODO read me from config
@@ -474,13 +490,11 @@ static int __init wcn36xx_init(void)
 	wcn->hw->wiphy->n_addresses = ARRAY_SIZE(wcn->addresses);
 	wcn->hw->wiphy->addresses = wcn->addresses;
 
-	/* FIXME: register should be last */
-	ret = ieee80211_register_hw(wcn->hw);
-
 	wcnss_memory = wcnss_wlan_get_memory_map(wcn->dev);
 	if (wcnss_memory == NULL) {
 		wcn36xx_error("failed to get wcnss wlan memory map");
-		return -EINVAL;
+		ret = -ENOMEM;
+		goto out_wq_ctl;
 	}
 
 	wcn->tx_irq = wcnss_wlan_get_dxe_tx_irq(wcn->dev);
@@ -489,13 +503,27 @@ static int __init wcn36xx_init(void)
 	wcn->mmio = ioremap(wcnss_memory->start, resource_size(wcnss_memory));
 	if (NULL == wcn->mmio) {
 		wcn36xx_error("failed to map io memory");
-		return -EINVAL;
+		ret = -ENOMEM;
+		goto out_wq_ctl;
 	}
 
 	private_hw = hw;
 	wcn->beacon_enable = false;
 
+	ret = ieee80211_register_hw(wcn->hw);
+	if (ret)
+		goto out_unmap;
+
 	return 0;
+
+out_unmap:
+	iounmap(wcn->mmio);
+out_wq_ctl:
+	destroy_workqueue(wcn->ctl_wq);
+out_wq:
+	destroy_workqueue(wcn->wq);
+out_err:
+	return ret;
 }
 
 module_init(wcn36xx_init);
@@ -503,11 +531,12 @@ module_init(wcn36xx_init);
 static void __exit wcn36xx_exit(void)
 {
 	struct ieee80211_hw *hw = private_hw;
+	struct wcn36xx *wcn = hw->priv;
 
 	ieee80211_unregister_hw(hw);
-
-	/* FIXME: iounmap */
-
+	destroy_workqueue(wcn->ctl_wq);
+	destroy_workqueue(wcn->wq);
+	iounmap(wcn->mmio);
 	ieee80211_free_hw(hw);
 }
 module_exit(wcn36xx_exit);
-- 
1.7.10.4




More information about the wcn36xx mailing list