@@ -60,18 +60,35 @@ static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, in
6060 return 0 ;
6161}
6262
63- int zpci_iov_setup_virtfn (struct zpci_bus * zbus , struct pci_dev * virtfn , int vfn )
63+ /**
64+ * zpci_iov_find_parent_pf - Find the parent PF, if any, of the given function
65+ * @zbus: The bus that the PCI function is on, or would be added on
66+ * @zdev: The PCI function
67+ *
68+ * Finds the parent PF, if it exists and is configured, of the given PCI function
69+ * and increments its refcount. Th PF is searched for on the provided bus so the
70+ * caller has to ensure that this is the correct bus to search. This function may
71+ * be used before adding the PCI function to a zbus.
72+ *
73+ * Return: Pointer to the struct pci_dev of the parent PF or NULL if it not
74+ * found. If the function is not a VF or has no RequesterID information,
75+ * NULL is returned as well.
76+ */
77+ struct pci_dev * zpci_iov_find_parent_pf (struct zpci_bus * zbus , struct zpci_dev * zdev )
6478{
65- int i , cand_devfn ;
66- struct zpci_dev * zdev ;
79+ int i , vfid , devfn , cand_devfn ;
6780 struct pci_dev * pdev ;
68- int vfid = vfn - 1 ; /* Linux' vfid's start at 0 vfn at 1*/
69- int rc = 0 ;
7081
7182 if (!zbus -> multifunction )
72- return 0 ;
73-
74- /* If the parent PF for the given VF is also configured in the
83+ return NULL ;
84+ /* Non-VFs and VFs without RID available don't have a parent */
85+ if (!zdev -> vfn || !zdev -> rid_available )
86+ return NULL ;
87+ /* Linux vfid starts at 0 vfn at 1 */
88+ vfid = zdev -> vfn - 1 ;
89+ devfn = zdev -> rid & ZPCI_RID_MASK_DEVFN ;
90+ /*
91+ * If the parent PF for the given VF is also configured in the
7592 * instance, it must be on the same zbus.
7693 * We can then identify the parent PF by checking what
7794 * devfn the VF would have if it belonged to that PF using the PF's
@@ -85,15 +102,26 @@ int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn
85102 if (!pdev )
86103 continue ;
87104 cand_devfn = pci_iov_virtfn_devfn (pdev , vfid );
88- if (cand_devfn == virtfn -> devfn ) {
89- rc = zpci_iov_link_virtfn (pdev , virtfn , vfid );
90- /* balance pci_get_slot() */
91- pci_dev_put (pdev );
92- break ;
93- }
105+ if (cand_devfn == devfn )
106+ return pdev ;
94107 /* balance pci_get_slot() */
95108 pci_dev_put (pdev );
96109 }
97110 }
111+ return NULL ;
112+ }
113+
114+ int zpci_iov_setup_virtfn (struct zpci_bus * zbus , struct pci_dev * virtfn , int vfn )
115+ {
116+ struct zpci_dev * zdev = to_zpci (virtfn );
117+ struct pci_dev * pdev_pf ;
118+ int rc = 0 ;
119+
120+ pdev_pf = zpci_iov_find_parent_pf (zbus , zdev );
121+ if (pdev_pf ) {
122+ /* Linux' vfids start at 0 while zdev->vfn starts at 1 */
123+ rc = zpci_iov_link_virtfn (pdev_pf , virtfn , zdev -> vfn - 1 );
124+ pci_dev_put (pdev_pf );
125+ }
98126 return rc ;
99127}
0 commit comments