1 From foo@baz Wed Jun 18 20:03:44 PDT 2014
2 From: Wei Yang <weiyang@linux.vnet.ibm.com>
3 Date: Sun, 1 Jun 2014 15:25:20 +0800
4 Subject: net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()
6 From: Wei Yang <weiyang@linux.vnet.ibm.com>
8 [ Upstream commit befdf8978accecac2e0739e6b5075afc62db37fe ]
10 This patch wrap up a helper function __mlx4_remove_one() which does the tear
11 down function but preserve the drv_data. Functions like
12 mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out
15 Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
16 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18 drivers/net/ethernet/mellanox/mlx4/main.c | 145 ++++++++++++++++--------------
19 drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1
20 2 files changed, 83 insertions(+), 63 deletions(-)
22 --- a/drivers/net/ethernet/mellanox/mlx4/main.c
23 +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
24 @@ -1798,15 +1798,8 @@ static int __mlx4_init_one(struct pci_de
25 /* Allow large DMA segments, up to the firmware limit of 1 GB */
26 dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
28 - priv = kzalloc(sizeof *priv, GFP_KERNEL);
30 - dev_err(&pdev->dev, "Device struct alloc failed, "
33 - goto err_release_regions;
37 + dev = pci_get_drvdata(pdev);
38 + priv = mlx4_priv(dev);
40 INIT_LIST_HEAD(&priv->ctx_list);
41 spin_lock_init(&priv->ctx_lock);
42 @@ -1967,8 +1960,7 @@ slave_start:
44 mlx4_start_sense(dev);
46 - priv->pci_dev_data = pci_dev_data;
47 - pci_set_drvdata(pdev, dev);
52 @@ -2035,73 +2027,100 @@ err_disable_pdev:
53 static int __devinit mlx4_init_one(struct pci_dev *pdev,
54 const struct pci_device_id *id)
56 + struct mlx4_priv *priv;
57 + struct mlx4_dev *dev;
59 printk_once(KERN_INFO "%s", mlx4_version);
61 + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
66 + pci_set_drvdata(pdev, dev);
67 + priv->pci_dev_data = id->driver_data;
69 return __mlx4_init_one(pdev, id->driver_data);
72 -static void mlx4_remove_one(struct pci_dev *pdev)
73 +static void __mlx4_remove_one(struct pci_dev *pdev)
75 struct mlx4_dev *dev = pci_get_drvdata(pdev);
76 struct mlx4_priv *priv = mlx4_priv(dev);
81 - /* in SRIOV it is not allowed to unload the pf's
82 - * driver while there are alive vf's */
83 - if (mlx4_is_master(dev)) {
84 - if (mlx4_how_many_lives_vf(dev))
85 - printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
87 - mlx4_stop_sense(dev);
88 - mlx4_unregister_device(dev);
92 - for (p = 1; p <= dev->caps.num_ports; p++) {
93 - mlx4_cleanup_port_info(&priv->port[p]);
94 - mlx4_CLOSE_PORT(dev, p);
96 + pci_dev_data = priv->pci_dev_data;
98 - mlx4_cleanup_counters_table(dev);
99 - mlx4_cleanup_mcg_table(dev);
100 - mlx4_cleanup_qp_table(dev);
101 - mlx4_cleanup_srq_table(dev);
102 - mlx4_cleanup_cq_table(dev);
103 - mlx4_cmd_use_polling(dev);
104 - mlx4_cleanup_eq_table(dev);
105 - mlx4_cleanup_mr_table(dev);
106 - mlx4_cleanup_xrcd_table(dev);
107 - mlx4_cleanup_pd_table(dev);
108 + /* in SRIOV it is not allowed to unload the pf's
109 + * driver while there are alive vf's */
110 + if (mlx4_is_master(dev)) {
111 + if (mlx4_how_many_lives_vf(dev))
112 + printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
114 + mlx4_stop_sense(dev);
115 + mlx4_unregister_device(dev);
117 - if (mlx4_is_master(dev))
118 - mlx4_free_resource_tracker(dev);
119 + for (p = 1; p <= dev->caps.num_ports; p++) {
120 + mlx4_cleanup_port_info(&priv->port[p]);
121 + mlx4_CLOSE_PORT(dev, p);
124 - iounmap(priv->kar);
125 - mlx4_uar_free(dev, &priv->driver_uar);
126 - mlx4_cleanup_uar_table(dev);
127 - if (!mlx4_is_slave(dev))
128 - mlx4_clear_steering(dev);
129 - mlx4_free_eq_table(dev);
130 - if (mlx4_is_master(dev))
131 - mlx4_multi_func_cleanup(dev);
132 - mlx4_close_hca(dev);
133 - if (mlx4_is_slave(dev))
134 - mlx4_multi_func_cleanup(dev);
135 - mlx4_cmd_cleanup(dev);
137 - if (dev->flags & MLX4_FLAG_MSI_X)
138 - pci_disable_msix(pdev);
139 - if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
140 - mlx4_warn(dev, "Disabling sriov\n");
141 - pci_disable_sriov(pdev);
143 + mlx4_cleanup_counters_table(dev);
144 + mlx4_cleanup_mcg_table(dev);
145 + mlx4_cleanup_qp_table(dev);
146 + mlx4_cleanup_srq_table(dev);
147 + mlx4_cleanup_cq_table(dev);
148 + mlx4_cmd_use_polling(dev);
149 + mlx4_cleanup_eq_table(dev);
150 + mlx4_cleanup_mr_table(dev);
151 + mlx4_cleanup_xrcd_table(dev);
152 + mlx4_cleanup_pd_table(dev);
154 + if (mlx4_is_master(dev))
155 + mlx4_free_resource_tracker(dev);
157 + iounmap(priv->kar);
158 + mlx4_uar_free(dev, &priv->driver_uar);
159 + mlx4_cleanup_uar_table(dev);
160 + if (!mlx4_is_slave(dev))
161 + mlx4_clear_steering(dev);
162 + mlx4_free_eq_table(dev);
163 + if (mlx4_is_master(dev))
164 + mlx4_multi_func_cleanup(dev);
165 + mlx4_close_hca(dev);
166 + if (mlx4_is_slave(dev))
167 + mlx4_multi_func_cleanup(dev);
168 + mlx4_cmd_cleanup(dev);
170 - if (!mlx4_is_slave(dev))
171 - mlx4_free_ownership(dev);
173 - pci_release_regions(pdev);
174 - pci_disable_device(pdev);
175 - pci_set_drvdata(pdev, NULL);
176 + if (dev->flags & MLX4_FLAG_MSI_X)
177 + pci_disable_msix(pdev);
178 + if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
179 + mlx4_warn(dev, "Disabling sriov\n");
180 + pci_disable_sriov(pdev);
183 + if (!mlx4_is_slave(dev))
184 + mlx4_free_ownership(dev);
186 + pci_release_regions(pdev);
187 + pci_disable_device(pdev);
188 + memset(priv, 0, sizeof(*priv));
189 + priv->pci_dev_data = pci_dev_data;
193 +static void mlx4_remove_one(struct pci_dev *pdev)
195 + struct mlx4_dev *dev = pci_get_drvdata(pdev);
196 + struct mlx4_priv *priv = mlx4_priv(dev);
198 + __mlx4_remove_one(pdev);
200 + pci_set_drvdata(pdev, NULL);
203 int mlx4_restart_one(struct pci_dev *pdev)
204 @@ -2111,7 +2130,7 @@ int mlx4_restart_one(struct pci_dev *pde
207 pci_dev_data = priv->pci_dev_data;
208 - mlx4_remove_one(pdev);
209 + __mlx4_remove_one(pdev);
210 return __mlx4_init_one(pdev, pci_dev_data);
213 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
214 +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
215 @@ -723,6 +723,7 @@ struct mlx4_priv {
221 struct list_head pgdir_list;
222 struct mutex pgdir_mutex;