Currently pci_iov_add_virtfn() scans the SR-IOV BARs, adds the VF to the bus and also creates the sysfs links between the newly added VF and its parent PF. With pdev->no_vf_scan fencing off the entire pci_iov_add_virtfn() call s390 as the sole pdev->no_vf_scan user thus ends up missing these sysfs links which are required for example by QEMU/libvirt. Instead of duplicating the code refactor pci_iov_add_virtfn() to make sysfs link creation callable separately.
Unified · Split
| @@ -133,12 +133,35 @@ static void pci_read_vf_config_common(struct pci_dev *virtfn) · 132 unmodified lines | |||
| 133 | &physfn->sriov->subsystem_device); | 133 | &physfn->sriov->subsystem_device); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | int pci_iov_sysfs_link(struct pci_dev *dev, | ||
| 137 | struct pci_dev *virtfn, int id) | ||
| 138 | { | ||
| 139 | char buf[VIRTFN_ID_LEN]; | ||
| 140 | int rc; | ||
| 141 | |||
| 142 | sprintf(buf, "virtfn%u", id); | ||
| 143 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); | ||
| 144 | if (rc) | ||
| 145 | goto failed; | ||
| 146 | rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn"); | ||
| 147 | if (rc) | ||
| 148 | goto failed1; | ||
| 149 | |||
| 150 | kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | |||
| 154 | failed1: | ||
| 155 | sysfs_remove_link(&dev->dev.kobj, buf); | ||
| 156 | failed: | ||
| 157 | return rc; | ||
| 158 | } | ||
| 159 | |||
| 136 | int pci_iov_add_virtfn(struct pci_dev *dev, int id) | 160 | int pci_iov_add_virtfn(struct pci_dev *dev, int id) |
| 137 | { | 161 | { |
| 138 | int i; | 162 | int i; |
| 139 | int rc = -ENOMEM; | 163 | int rc = -ENOMEM; |
| 140 | u64 size; | 164 | u64 size; |
| 141 | char buf[VIRTFN_ID_LEN]; | ||
| 142 | struct pci_dev *virtfn; | 165 | struct pci_dev *virtfn; |
| 143 | struct resource *res; | 166 | struct resource *res; |
| 144 | struct pci_sriov *iov = dev->sriov; | 167 | struct pci_sriov *iov = dev->sriov; |
| @@ -182,23 +205,14 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id) · 37 unmodified lines | |||
| 182 | } | 205 | } |
| 183 | 206 | ||
| 184 | pci_device_add(virtfn, virtfn->bus); | 207 | pci_device_add(virtfn, virtfn->bus); |
| 185 | 208 | rc = pci_iov_sysfs_link(dev, virtfn, id); | |
| 186 | sprintf(buf, "virtfn%u", id); | ||
| 187 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); | ||
| 188 | if (rc) | 209 | if (rc) |
| 189 | goto failed1; | 210 | goto failed1; |
| 190 | rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn"); | ||
| 191 | if (rc) | ||
| 192 | goto failed2; | ||
| 193 | |||
| 194 | kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); | ||
| 195 | 211 | ||
| 196 | pci_bus_add_device(virtfn); | 212 | pci_bus_add_device(virtfn); |
| 197 | 213 | ||
| 198 | return 0; | 214 | return 0; |
| 199 | 215 | ||
| 200 | failed2: | ||
| 201 | sysfs_remove_link(&dev->dev.kobj, buf); | ||
| 202 | failed1: | 216 | failed1: |
| 203 | pci_stop_and_remove_bus_device(virtfn); | 217 | pci_stop_and_remove_bus_device(virtfn); |
| 204 | pci_dev_put(dev); | 218 | pci_dev_put(dev); |
| @@ -2048,6 +2048,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id); · 2047 unmodified lines | |||
| 2048 | 2048 | ||
| 2049 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | 2049 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); |
| 2050 | void pci_disable_sriov(struct pci_dev *dev); | 2050 | void pci_disable_sriov(struct pci_dev *dev); |
| 2051 | |||
| 2052 | int pci_iov_sysfs_link(struct pci_dev *dev, struct pci_dev *virtfn, int id); | ||
| 2051 | int pci_iov_add_virtfn(struct pci_dev *dev, int id); | 2053 | int pci_iov_add_virtfn(struct pci_dev *dev, int id); |
| 2052 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id); | 2054 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id); |
| 2053 | int pci_num_vf(struct pci_dev *dev); | 2055 | int pci_num_vf(struct pci_dev *dev); |
| @@ -2073,6 +2075,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id) · 19 unmodified lines | |||
| 2073 | } | 2075 | } |
| 2074 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 2076 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
| 2075 | { return -ENODEV; } | 2077 | { return -ENODEV; } |
| 2078 | |||
| 2079 | static inline int pci_iov_sysfs_link(struct pci_dev *dev, | ||
| 2080 | struct pci_dev *virtfn, int id) | ||
| 2081 | { | ||
| 2082 | return -ENODEV; | ||
| 2083 | } | ||
| 2076 | static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id) | 2084 | static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id) |
| 2077 | { | 2085 | { |
| 2078 | return -ENOSYS; | 2086 | return -ENOSYS; |