hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/arch/powerpc/kernel/pci_dn.c
....@@ -1,23 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * pci_dn.c
34 *
45 * Copyright (C) 2001 Todd Inglett, IBM Corporation
56 *
67 * PCI manipulation via device_nodes.
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
218 */
229 #include <linux/kernel.h>
2310 #include <linux/pci.h>
....@@ -137,9 +124,28 @@
137124 return NULL;
138125 }
139126
127
+#ifdef CONFIG_EEH
128
+static struct eeh_dev *eeh_dev_init(struct pci_dn *pdn)
129
+{
130
+ struct eeh_dev *edev;
131
+
132
+ /* Allocate EEH device */
133
+ edev = kzalloc(sizeof(*edev), GFP_KERNEL);
134
+ if (!edev)
135
+ return NULL;
136
+
137
+ /* Associate EEH device with OF node */
138
+ pdn->edev = edev;
139
+ edev->pdn = pdn;
140
+ edev->bdfn = (pdn->busno << 8) | pdn->devfn;
141
+ edev->controller = pdn->phb;
142
+
143
+ return edev;
144
+}
145
+#endif /* CONFIG_EEH */
146
+
140147 #ifdef CONFIG_PCI_IOV
141
-static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
142
- int vf_index,
148
+static struct pci_dn *add_one_sriov_vf_pdn(struct pci_dn *parent,
143149 int busno, int devfn)
144150 {
145151 struct pci_dn *pdn;
....@@ -156,7 +162,6 @@
156162 pdn->parent = parent;
157163 pdn->busno = busno;
158164 pdn->devfn = devfn;
159
- pdn->vf_index = vf_index;
160165 pdn->pe_number = IODA_INVALID_PE;
161166 INIT_LIST_HEAD(&pdn->child_list);
162167 INIT_LIST_HEAD(&pdn->list);
....@@ -164,17 +169,15 @@
164169
165170 return pdn;
166171 }
167
-#endif
168172
169
-struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
173
+struct pci_dn *add_sriov_vf_pdns(struct pci_dev *pdev)
170174 {
171
-#ifdef CONFIG_PCI_IOV
172175 struct pci_dn *parent, *pdn;
173176 int i;
174177
175178 /* Only support IOV for now */
176
- if (!pdev->is_physfn)
177
- return pci_get_pdn(pdev);
179
+ if (WARN_ON(!pdev->is_physfn))
180
+ return NULL;
178181
179182 /* Check if VFs have been populated */
180183 pdn = pci_get_pdn(pdev);
....@@ -189,7 +192,7 @@
189192 for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
190193 struct eeh_dev *edev __maybe_unused;
191194
192
- pdn = add_one_dev_pci_data(parent, i,
195
+ pdn = add_one_sriov_vf_pdn(parent,
193196 pci_iov_virtfn_bus(pdev, i),
194197 pci_iov_virtfn_devfn(pdev, i));
195198 if (!pdn) {
....@@ -202,34 +205,23 @@
202205 /* Create the EEH device for the VF */
203206 edev = eeh_dev_init(pdn);
204207 BUG_ON(!edev);
208
+
209
+ /* FIXME: these should probably be populated by the EEH probe */
205210 edev->physfn = pdev;
211
+ edev->vf_index = i;
206212 #endif /* CONFIG_EEH */
207213 }
208
-#endif /* CONFIG_PCI_IOV */
209
-
210214 return pci_get_pdn(pdev);
211215 }
212216
213
-void remove_dev_pci_data(struct pci_dev *pdev)
217
+void remove_sriov_vf_pdns(struct pci_dev *pdev)
214218 {
215
-#ifdef CONFIG_PCI_IOV
216219 struct pci_dn *parent;
217220 struct pci_dn *pdn, *tmp;
218221 int i;
219222
220
- /*
221
- * VF and VF PE are created/released dynamically, so we need to
222
- * bind/unbind them. Otherwise the VF and VF PE would be mismatched
223
- * when re-enabling SR-IOV.
224
- */
225
- if (pdev->is_virtfn) {
226
- pdn = pci_get_pdn(pdev);
227
- pdn->pe_number = IODA_INVALID_PE;
228
- return;
229
- }
230
-
231223 /* Only support IOV PF for now */
232
- if (!pdev->is_physfn)
224
+ if (WARN_ON(!pdev->is_physfn))
233225 return;
234226
235227 /* Check if VFs have been populated */
....@@ -271,7 +263,7 @@
271263 * have a configured PE.
272264 */
273265 if (edev->pe)
274
- eeh_rmv_from_parent_pe(edev);
266
+ eeh_pe_tree_remove(edev);
275267
276268 pdn->edev = NULL;
277269 kfree(edev);
....@@ -284,8 +276,8 @@
284276 kfree(pdn);
285277 }
286278 }
287
-#endif /* CONFIG_PCI_IOV */
288279 }
280
+#endif /* CONFIG_PCI_IOV */
289281
290282 struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
291283 struct device_node *dn)
....@@ -338,6 +330,7 @@
338330 INIT_LIST_HEAD(&pdn->list);
339331 parent = of_get_parent(dn);
340332 pdn->parent = parent ? PCI_DN(parent) : NULL;
333
+ of_node_put(parent);
341334 if (pdn->parent)
342335 list_add_tail(&pdn->list, &pdn->parent->child_list);
343336
....@@ -349,6 +342,7 @@
349342 {
350343 struct pci_dn *pdn = dn ? PCI_DN(dn) : NULL;
351344 struct device_node *parent;
345
+ struct pci_dev *pdev;
352346 #ifdef CONFIG_EEH
353347 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
354348
....@@ -362,12 +356,28 @@
362356 WARN_ON(!list_empty(&pdn->child_list));
363357 list_del(&pdn->list);
364358
359
+ /* Drop the parent pci_dn's ref to our backing dt node */
365360 parent = of_get_parent(dn);
366361 if (parent)
367362 of_node_put(parent);
368363
369
- dn->data = NULL;
370
- kfree(pdn);
364
+ /*
365
+ * At this point we *might* still have a pci_dev that was
366
+ * instantiated from this pci_dn. So defer free()ing it until
367
+ * the pci_dev's release function is called.
368
+ */
369
+ pdev = pci_get_domain_bus_and_slot(pdn->phb->global_number,
370
+ pdn->busno, pdn->devfn);
371
+ if (pdev) {
372
+ /* NB: pdev has a ref to dn */
373
+ pci_dbg(pdev, "marked pdn (from %pOF) as dead\n", dn);
374
+ pdn->flags |= PCI_DN_FLAG_DEAD;
375
+ } else {
376
+ dn->data = NULL;
377
+ kfree(pdn);
378
+ }
379
+
380
+ pci_dev_put(pdev);
371381 }
372382 EXPORT_SYMBOL_GPL(pci_remove_device_node_info);
373383