Skip to contentSkip to conversation

rt2x00: Correctly initialization and uninitialization of device

PATCH In review Ivo van Doorn 1 participant 1 message Apr 27, 2006

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 31/32 rt2x00: Correctly initialization and uninitialization of device

From: Ivo van Doorn <[email protected]>

Fix several hardware initialization and uninitalization problems by incorrectly flushing workqueues.
Fix the memory leak when freeing the ieee80211_hw structure. Allow device to connect to 802.11g networks by default instead of 802.11b.

drivers/net/wireless/d80211/rt2x00/rt2400pci.c +34 -23
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
@@ -1719,6 +1719,11 @@ rt2400pci_stop(struct net_device *net_de
 	}
 
 	/*
+	 * Flush out all pending work.
+	 */
+	flush_workqueue(rt2x00pci->workqueue);
+
+	/*
 	 * Free DMA rings.
 	 */
 	rt2400pci_free_rings(rt2x00pci);
@@ -2441,7 +2446,7 @@ rt2400pci_initialize(struct pci_dev *pci
 
 	rt2x00pci->workqueue = create_singlethread_workqueue(DRV_NAME);
 	if (!rt2x00pci->workqueue)
-		goto exit_iounmap;
+		goto exit;
 
 	/*
 	 * Initialize cofniguration work.
@@ -2457,21 +2462,25 @@ rt2400pci_initialize(struct pci_dev *pci
 	if (rt2400pci_init_eeprom(rt2x00pci)
 	|| rt2400pci_init_mac(rt2x00pci)
 	|| rt2400pci_init_hw(rt2x00pci))
-		goto exit_destroy_workqueue;
+		goto exit;
 
 	/*
 	 * If required start hardware button polling.
 	 */
 	rt2x00pci_button_start(rt2x00pci, rt2400pci_button_poll);
 
-	return 0;
+	/*
+	 * Register hardware.
+	 */
+	if (ieee80211_register_hw(net_dev, &rt2x00pci->hw)) {
+		ERROR("Failed to register device.\n");
+		goto exit;
+	}
 
-exit_destroy_workqueue:
-	destroy_workqueue(rt2x00pci->workqueue);
+	return 0;
 
-exit_iounmap:
-	iounmap(rt2x00pci->csr_addr);
-	rt2x00pci->csr_addr = NULL;
+exit:
+	rt2400pci_uninitialize(net_dev);
 
 	return -ENODEV;
 }
@@ -2482,26 +2491,39 @@ rt2400pci_uninitialize(struct net_device
 	struct rt2x00_pci	*rt2x00pci = ieee80211_dev_hw_data(net_dev);
 
 	/*
+	 * Unregister hardware.
+	 */
+	ieee80211_unregister_hw(net_dev);
+
+	/*
 	 * Shutdown poll_timer for hardware button.
 	 */
 	rt2x00pci_button_stop(rt2x00pci);
 
 	kfree(rt2x00pci->eeprom);
 
+	/*
+	 * Release CSR memory.
+	 */
 	if (likely(rt2x00pci->csr_addr)) {
 		iounmap(rt2x00pci->csr_addr);
 		rt2x00pci->csr_addr = NULL;
 	}
 
+	/*
+	 * Free workqueue.
+	 */
 	if (likely(rt2x00pci->workqueue)) {
-		flush_workqueue(rt2x00pci->workqueue);
 		destroy_workqueue(rt2x00pci->workqueue);
 		rt2x00pci->workqueue = NULL;
 	}
 
+	/*
+	 * Free ieee80211_hw memory.
+	 */
 	if (likely(rt2x00pci->hw.modes)) {
-			kfree(rt2x00pci->hw.modes->channels);
-			kfree(rt2x00pci->hw.modes->rates);
+		kfree(rt2x00pci->hw.modes->channels);
+		kfree(rt2x00pci->hw.modes->rates);
 		kfree(rt2x00pci->hw.modes);
 		rt2x00pci->hw.modes = NULL;
 	}
@@ -2514,7 +2536,6 @@ static int
 rt2400pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
 	struct net_device	*net_dev;
-	struct rt2x00_pci	*rt2x00pci;
 	int			status;
 
 	if (unlikely(id->driver_data != RT2460)) {
@@ -2559,19 +2580,9 @@ rt2400pci_probe(struct pci_dev *pci_dev,
 		ERROR("Failed to initialize device.\n");
 		goto exit_free_device;
 	}
-	rt2x00pci = ieee80211_dev_hw_data(net_dev);
-
-	status = ieee80211_register_hw(net_dev, &rt2x00pci->hw);
-	if (status) {
-		ERROR("Failed to register device.\n");
-		goto exit_uninitialize_device;
-	}
 
 	return 0;
 
-exit_uninitialize_device:
-	rt2400pci_uninitialize(net_dev);
-
 exit_free_device:
 	ieee80211_free_hw(net_dev);
 
@@ -2592,7 +2603,7 @@ rt2400pci_remove(struct pci_dev *pci_dev
 {
 	struct net_device	*net_dev = pci_get_drvdata(pci_dev);
 
-	ieee80211_unregister_hw(net_dev);
+	net_dev->stop(net_dev);
 
 	rt2400pci_uninitialize(net_dev);
 
drivers/net/wireless/d80211/rt2x00/rt2500pci.c +46 -31

160 lines not on this page · raw message

drivers/net/wireless/d80211/rt2x00/rt2500usb.c +46 -33

154 lines not on this page · raw message