mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()
[ Upstream commit befdf8978a
]
This patch wrap up a helper function __mlx4_remove_one() which does the tear
down function but preserve the drv_data. Functions like
mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out
releasing drvdata.
Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ff2005a4a5
commit
6ddc168fe0
2 changed files with 89 additions and 69 deletions
|
@ -1798,15 +1798,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
|||
/* Allow large DMA segments, up to the firmware limit of 1 GB */
|
||||
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
|
||||
|
||||
priv = kzalloc(sizeof *priv, GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&pdev->dev, "Device struct alloc failed, "
|
||||
"aborting.\n");
|
||||
err = -ENOMEM;
|
||||
goto err_release_regions;
|
||||
}
|
||||
|
||||
dev = &priv->dev;
|
||||
dev = pci_get_drvdata(pdev);
|
||||
priv = mlx4_priv(dev);
|
||||
dev->pdev = pdev;
|
||||
INIT_LIST_HEAD(&priv->ctx_list);
|
||||
spin_lock_init(&priv->ctx_lock);
|
||||
|
@ -1967,8 +1960,7 @@ slave_start:
|
|||
mlx4_sense_init(dev);
|
||||
mlx4_start_sense(dev);
|
||||
|
||||
priv->pci_dev_data = pci_dev_data;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
priv->removed = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -2035,73 +2027,100 @@ err_disable_pdev:
|
|||
static int __devinit mlx4_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct mlx4_priv *priv;
|
||||
struct mlx4_dev *dev;
|
||||
|
||||
printk_once(KERN_INFO "%s", mlx4_version);
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
dev = &priv->dev;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
priv->pci_dev_data = id->driver_data;
|
||||
|
||||
return __mlx4_init_one(pdev, id->driver_data);
|
||||
}
|
||||
|
||||
static void __mlx4_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct mlx4_dev *dev = pci_get_drvdata(pdev);
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int pci_dev_data;
|
||||
int p;
|
||||
|
||||
if (priv->removed)
|
||||
return;
|
||||
|
||||
pci_dev_data = priv->pci_dev_data;
|
||||
|
||||
/* in SRIOV it is not allowed to unload the pf's
|
||||
* driver while there are alive vf's */
|
||||
if (mlx4_is_master(dev)) {
|
||||
if (mlx4_how_many_lives_vf(dev))
|
||||
printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
|
||||
}
|
||||
mlx4_stop_sense(dev);
|
||||
mlx4_unregister_device(dev);
|
||||
|
||||
for (p = 1; p <= dev->caps.num_ports; p++) {
|
||||
mlx4_cleanup_port_info(&priv->port[p]);
|
||||
mlx4_CLOSE_PORT(dev, p);
|
||||
}
|
||||
|
||||
mlx4_cleanup_counters_table(dev);
|
||||
mlx4_cleanup_mcg_table(dev);
|
||||
mlx4_cleanup_qp_table(dev);
|
||||
mlx4_cleanup_srq_table(dev);
|
||||
mlx4_cleanup_cq_table(dev);
|
||||
mlx4_cmd_use_polling(dev);
|
||||
mlx4_cleanup_eq_table(dev);
|
||||
mlx4_cleanup_mr_table(dev);
|
||||
mlx4_cleanup_xrcd_table(dev);
|
||||
mlx4_cleanup_pd_table(dev);
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev);
|
||||
|
||||
iounmap(priv->kar);
|
||||
mlx4_uar_free(dev, &priv->driver_uar);
|
||||
mlx4_cleanup_uar_table(dev);
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_clear_steering(dev);
|
||||
mlx4_free_eq_table(dev);
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_close_hca(dev);
|
||||
if (mlx4_is_slave(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_cmd_cleanup(dev);
|
||||
|
||||
if (dev->flags & MLX4_FLAG_MSI_X)
|
||||
pci_disable_msix(pdev);
|
||||
if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
|
||||
mlx4_warn(dev, "Disabling sriov\n");
|
||||
pci_disable_sriov(pdev);
|
||||
}
|
||||
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_free_ownership(dev);
|
||||
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
priv->pci_dev_data = pci_dev_data;
|
||||
priv->removed = 1;
|
||||
}
|
||||
|
||||
static void mlx4_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct mlx4_dev *dev = pci_get_drvdata(pdev);
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int p;
|
||||
|
||||
if (dev) {
|
||||
/* in SRIOV it is not allowed to unload the pf's
|
||||
* driver while there are alive vf's */
|
||||
if (mlx4_is_master(dev)) {
|
||||
if (mlx4_how_many_lives_vf(dev))
|
||||
printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
|
||||
}
|
||||
mlx4_stop_sense(dev);
|
||||
mlx4_unregister_device(dev);
|
||||
|
||||
for (p = 1; p <= dev->caps.num_ports; p++) {
|
||||
mlx4_cleanup_port_info(&priv->port[p]);
|
||||
mlx4_CLOSE_PORT(dev, p);
|
||||
}
|
||||
|
||||
mlx4_cleanup_counters_table(dev);
|
||||
mlx4_cleanup_mcg_table(dev);
|
||||
mlx4_cleanup_qp_table(dev);
|
||||
mlx4_cleanup_srq_table(dev);
|
||||
mlx4_cleanup_cq_table(dev);
|
||||
mlx4_cmd_use_polling(dev);
|
||||
mlx4_cleanup_eq_table(dev);
|
||||
mlx4_cleanup_mr_table(dev);
|
||||
mlx4_cleanup_xrcd_table(dev);
|
||||
mlx4_cleanup_pd_table(dev);
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev);
|
||||
|
||||
iounmap(priv->kar);
|
||||
mlx4_uar_free(dev, &priv->driver_uar);
|
||||
mlx4_cleanup_uar_table(dev);
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_clear_steering(dev);
|
||||
mlx4_free_eq_table(dev);
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_close_hca(dev);
|
||||
if (mlx4_is_slave(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_cmd_cleanup(dev);
|
||||
|
||||
if (dev->flags & MLX4_FLAG_MSI_X)
|
||||
pci_disable_msix(pdev);
|
||||
if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
|
||||
mlx4_warn(dev, "Disabling sriov\n");
|
||||
pci_disable_sriov(pdev);
|
||||
}
|
||||
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_free_ownership(dev);
|
||||
kfree(priv);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
__mlx4_remove_one(pdev);
|
||||
kfree(priv);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
int mlx4_restart_one(struct pci_dev *pdev)
|
||||
|
@ -2111,7 +2130,7 @@ int mlx4_restart_one(struct pci_dev *pdev)
|
|||
int pci_dev_data;
|
||||
|
||||
pci_dev_data = priv->pci_dev_data;
|
||||
mlx4_remove_one(pdev);
|
||||
__mlx4_remove_one(pdev);
|
||||
return __mlx4_init_one(pdev, pci_dev_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -723,6 +723,7 @@ struct mlx4_priv {
|
|||
spinlock_t ctx_lock;
|
||||
|
||||
int pci_dev_data;
|
||||
int removed;
|
||||
|
||||
struct list_head pgdir_list;
|
||||
struct mutex pgdir_mutex;
|
||||
|
|
Loading…
Reference in a new issue