aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2011-01-18 10:02:19 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-20 02:18:13 -0500
commit6cca200362b46a6845b3f07367f5068a427161e1 (patch)
tree7f61585e158691935618afa591219ae343d27b8c
parent80f8f1027b99660897bdeaeae73002185d829906 (diff)
vxge: cleanup probe error paths
Reorder the commands to be in the inverse order of their allocations (instead of the random order they appear to be in), propagate return code on errors from pci_request_region and register_netdev, reduce the config_dev_cnt and total_dev_cnt counters on remove, and return the correct error code for vdev->vpaths kzalloc failures. Also, prevent leaking of vdev->vpaths memory and netdev in vxge_probe error path due to freeing for these not occurring in vxge_device_unregister. Signed-off-by: Jon Mason <jon.mason@exar.com> Signed-off-by: Sivakumar Subramani <sivakumar.subramani@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxge/vxge-main.c55
1 files changed, 25 insertions, 30 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index c81a6512c683..ecf9a8ee6838 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -3348,7 +3348,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
3348 vxge_debug_init(VXGE_ERR, 3348 vxge_debug_init(VXGE_ERR,
3349 "%s: vpath memory allocation failed", 3349 "%s: vpath memory allocation failed",
3350 vdev->ndev->name); 3350 vdev->ndev->name);
3351 ret = -ENODEV; 3351 ret = -ENOMEM;
3352 goto _out1; 3352 goto _out1;
3353 } 3353 }
3354 3354
@@ -3369,11 +3369,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
3369 if (vdev->config.gro_enable) 3369 if (vdev->config.gro_enable)
3370 ndev->features |= NETIF_F_GRO; 3370 ndev->features |= NETIF_F_GRO;
3371 3371
3372 if (register_netdev(ndev)) { 3372 ret = register_netdev(ndev);
3373 if (ret) {
3373 vxge_debug_init(vxge_hw_device_trace_level_get(hldev), 3374 vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
3374 "%s: %s : device registration failed!", 3375 "%s: %s : device registration failed!",
3375 ndev->name, __func__); 3376 ndev->name, __func__);
3376 ret = -ENODEV;
3377 goto _out2; 3377 goto _out2;
3378 } 3378 }
3379 3379
@@ -3444,6 +3444,11 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev)
3444 /* in 2.6 will call stop() if device is up */ 3444 /* in 2.6 will call stop() if device is up */
3445 unregister_netdev(dev); 3445 unregister_netdev(dev);
3446 3446
3447 kfree(vdev->vpaths);
3448
3449 /* we are safe to free it now */
3450 free_netdev(dev);
3451
3447 vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", 3452 vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered",
3448 buf); 3453 buf);
3449 vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, 3454 vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf,
@@ -4335,10 +4340,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4335 goto _exit1; 4340 goto _exit1;
4336 } 4341 }
4337 4342
4338 if (pci_request_region(pdev, 0, VXGE_DRIVER_NAME)) { 4343 ret = pci_request_region(pdev, 0, VXGE_DRIVER_NAME);
4344 if (ret) {
4339 vxge_debug_init(VXGE_ERR, 4345 vxge_debug_init(VXGE_ERR,
4340 "%s : request regions failed", __func__); 4346 "%s : request regions failed", __func__);
4341 ret = -ENODEV;
4342 goto _exit1; 4347 goto _exit1;
4343 } 4348 }
4344 4349
@@ -4643,8 +4648,9 @@ _exit6:
4643_exit5: 4648_exit5:
4644 vxge_device_unregister(hldev); 4649 vxge_device_unregister(hldev);
4645_exit4: 4650_exit4:
4646 pci_disable_sriov(pdev); 4651 pci_set_drvdata(pdev, NULL);
4647 vxge_hw_device_terminate(hldev); 4652 vxge_hw_device_terminate(hldev);
4653 pci_disable_sriov(pdev);
4648_exit3: 4654_exit3:
4649 iounmap(attr.bar0); 4655 iounmap(attr.bar0);
4650_exit2: 4656_exit2:
@@ -4655,7 +4661,7 @@ _exit0:
4655 kfree(ll_config); 4661 kfree(ll_config);
4656 kfree(device_config); 4662 kfree(device_config);
4657 driver_config->config_dev_cnt--; 4663 driver_config->config_dev_cnt--;
4658 pci_set_drvdata(pdev, NULL); 4664 driver_config->total_dev_cnt--;
4659 return ret; 4665 return ret;
4660} 4666}
4661 4667
@@ -4668,45 +4674,34 @@ _exit0:
4668static void __devexit vxge_remove(struct pci_dev *pdev) 4674static void __devexit vxge_remove(struct pci_dev *pdev)
4669{ 4675{
4670 struct __vxge_hw_device *hldev; 4676 struct __vxge_hw_device *hldev;
4671 struct vxgedev *vdev = NULL; 4677 struct vxgedev *vdev;
4672 struct net_device *dev; 4678 int i;
4673 int i = 0;
4674 4679
4675 hldev = pci_get_drvdata(pdev); 4680 hldev = pci_get_drvdata(pdev);
4676
4677 if (hldev == NULL) 4681 if (hldev == NULL)
4678 return; 4682 return;
4679 4683
4680 dev = hldev->ndev; 4684 vdev = netdev_priv(hldev->ndev);
4681 vdev = netdev_priv(dev);
4682 4685
4683 vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__); 4686 vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__);
4684
4685 vxge_debug_init(vdev->level_trace, "%s : removing PCI device...", 4687 vxge_debug_init(vdev->level_trace, "%s : removing PCI device...",
4686 __func__); 4688 __func__);
4687 vxge_device_unregister(hldev);
4688 4689
4689 for (i = 0; i < vdev->no_of_vpath; i++) { 4690 for (i = 0; i < vdev->no_of_vpath; i++)
4690 vxge_free_mac_add_list(&vdev->vpaths[i]); 4691 vxge_free_mac_add_list(&vdev->vpaths[i]);
4691 vdev->vpaths[i].mcast_addr_cnt = 0;
4692 vdev->vpaths[i].mac_addr_cnt = 0;
4693 }
4694
4695 kfree(vdev->vpaths);
4696 4692
4693 vxge_device_unregister(hldev);
4694 pci_set_drvdata(pdev, NULL);
4695 /* Do not call pci_disable_sriov here, as it will break child devices */
4696 vxge_hw_device_terminate(hldev);
4697 iounmap(vdev->bar0); 4697 iounmap(vdev->bar0);
4698 4698 pci_release_region(pdev, 0);
4699 /* we are safe to free it now */ 4699 pci_disable_device(pdev);
4700 free_netdev(dev); 4700 driver_config->config_dev_cnt--;
4701 driver_config->total_dev_cnt--;
4701 4702
4702 vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered", 4703 vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered",
4703 __func__, __LINE__); 4704 __func__, __LINE__);
4704
4705 vxge_hw_device_terminate(hldev);
4706
4707 pci_disable_device(pdev);
4708 pci_release_region(pdev, 0);
4709 pci_set_drvdata(pdev, NULL);
4710 vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__, 4705 vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__,
4711 __LINE__); 4706 __LINE__);
4712} 4707}