aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2008-02-01 08:22:48 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-03 07:25:58 -0500
commit80a9fad8e89a23c31bab9c228a88a391c4f8d698 (patch)
tree2c6d22ee53f9fca8a6b0fadc422178397eb7a07e /drivers/net/ucc_geth.c
parentf67c6275185216b47ee50c8c122adee3c562bce7 (diff)
ucc_geth: fix module removal
- uccf should be set to NULL to not double-free memory on subsequent calls; - ind_hash_q and group_hash_q lists should be initialized in the probe() function, instead of struct_init() (called by open()), otherwise there will be an oops if ucc_geth_driver removed prior 'ifconfig ethX up'; - add unregister_netdev(); - reorder geth_remove() steps. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 4ffd8739f8b7..e41da4670d0b 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2084,8 +2084,10 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
2084 if (!ugeth) 2084 if (!ugeth)
2085 return; 2085 return;
2086 2086
2087 if (ugeth->uccf) 2087 if (ugeth->uccf) {
2088 ucc_fast_free(ugeth->uccf); 2088 ucc_fast_free(ugeth->uccf);
2089 ugeth->uccf = NULL;
2090 }
2089 2091
2090 if (ugeth->p_thread_data_tx) { 2092 if (ugeth->p_thread_data_tx) {
2091 qe_muram_free(ugeth->thread_dat_tx_offset); 2093 qe_muram_free(ugeth->thread_dat_tx_offset);
@@ -2305,10 +2307,6 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
2305 ug_info = ugeth->ug_info; 2307 ug_info = ugeth->ug_info;
2306 uf_info = &ug_info->uf_info; 2308 uf_info = &ug_info->uf_info;
2307 2309
2308 /* Create CQs for hash tables */
2309 INIT_LIST_HEAD(&ugeth->group_hash_q);
2310 INIT_LIST_HEAD(&ugeth->ind_hash_q);
2311
2312 if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) || 2310 if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
2313 (uf_info->bd_mem_part == MEM_PART_MURAM))) { 2311 (uf_info->bd_mem_part == MEM_PART_MURAM))) {
2314 if (netif_msg_probe(ugeth)) 2312 if (netif_msg_probe(ugeth))
@@ -3990,6 +3988,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3990 ugeth = netdev_priv(dev); 3988 ugeth = netdev_priv(dev);
3991 spin_lock_init(&ugeth->lock); 3989 spin_lock_init(&ugeth->lock);
3992 3990
3991 /* Create CQs for hash tables */
3992 INIT_LIST_HEAD(&ugeth->group_hash_q);
3993 INIT_LIST_HEAD(&ugeth->ind_hash_q);
3994
3993 dev_set_drvdata(device, dev); 3995 dev_set_drvdata(device, dev);
3994 3996
3995 /* Set the dev->base_addr to the gfar reg region */ 3997 /* Set the dev->base_addr to the gfar reg region */
@@ -4040,9 +4042,10 @@ static int ucc_geth_remove(struct of_device* ofdev)
4040 struct net_device *dev = dev_get_drvdata(device); 4042 struct net_device *dev = dev_get_drvdata(device);
4041 struct ucc_geth_private *ugeth = netdev_priv(dev); 4043 struct ucc_geth_private *ugeth = netdev_priv(dev);
4042 4044
4043 dev_set_drvdata(device, NULL); 4045 unregister_netdev(dev);
4044 ucc_geth_memclean(ugeth);
4045 free_netdev(dev); 4046 free_netdev(dev);
4047 ucc_geth_memclean(ugeth);
4048 dev_set_drvdata(device, NULL);
4046 4049
4047 return 0; 4050 return 0;
4048} 4051}