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>
This commit is contained in:
parent
f67c627518
commit
80a9fad8e8
@ -2084,8 +2084,10 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
|
|||||||
if (!ugeth)
|
if (!ugeth)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ugeth->uccf)
|
if (ugeth->uccf) {
|
||||||
ucc_fast_free(ugeth->uccf);
|
ucc_fast_free(ugeth->uccf);
|
||||||
|
ugeth->uccf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ugeth->p_thread_data_tx) {
|
if (ugeth->p_thread_data_tx) {
|
||||||
qe_muram_free(ugeth->thread_dat_tx_offset);
|
qe_muram_free(ugeth->thread_dat_tx_offset);
|
||||||
@ -2305,10 +2307,6 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
|
|||||||
ug_info = ugeth->ug_info;
|
ug_info = ugeth->ug_info;
|
||||||
uf_info = &ug_info->uf_info;
|
uf_info = &ug_info->uf_info;
|
||||||
|
|
||||||
/* Create CQs for hash tables */
|
|
||||||
INIT_LIST_HEAD(&ugeth->group_hash_q);
|
|
||||||
INIT_LIST_HEAD(&ugeth->ind_hash_q);
|
|
||||||
|
|
||||||
if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
|
if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
|
||||||
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
|
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
|
||||||
if (netif_msg_probe(ugeth))
|
if (netif_msg_probe(ugeth))
|
||||||
@ -3990,6 +3988,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
|
|||||||
ugeth = netdev_priv(dev);
|
ugeth = netdev_priv(dev);
|
||||||
spin_lock_init(&ugeth->lock);
|
spin_lock_init(&ugeth->lock);
|
||||||
|
|
||||||
|
/* Create CQs for hash tables */
|
||||||
|
INIT_LIST_HEAD(&ugeth->group_hash_q);
|
||||||
|
INIT_LIST_HEAD(&ugeth->ind_hash_q);
|
||||||
|
|
||||||
dev_set_drvdata(device, dev);
|
dev_set_drvdata(device, dev);
|
||||||
|
|
||||||
/* Set the dev->base_addr to the gfar reg region */
|
/* Set the dev->base_addr to the gfar reg region */
|
||||||
@ -4040,9 +4042,10 @@ static int ucc_geth_remove(struct of_device* ofdev)
|
|||||||
struct net_device *dev = dev_get_drvdata(device);
|
struct net_device *dev = dev_get_drvdata(device);
|
||||||
struct ucc_geth_private *ugeth = netdev_priv(dev);
|
struct ucc_geth_private *ugeth = netdev_priv(dev);
|
||||||
|
|
||||||
dev_set_drvdata(device, NULL);
|
unregister_netdev(dev);
|
||||||
ucc_geth_memclean(ugeth);
|
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
|
ucc_geth_memclean(ugeth);
|
||||||
|
dev_set_drvdata(device, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user