| .. | .. |
|---|
| 204 | 204 | return 0; |
|---|
| 205 | 205 | } |
|---|
| 206 | 206 | |
|---|
| 207 | +/** |
|---|
| 208 | + * get_dvsec_vendor0() - Find a related PCI device (function 0) |
|---|
| 209 | + * @dev: PCI device to match |
|---|
| 210 | + * @dev0: The PCI device (function 0) found |
|---|
| 211 | + * @out_pos: The position of PCI device (function 0) |
|---|
| 212 | + * |
|---|
| 213 | + * Returns 0 on success, negative on failure. |
|---|
| 214 | + * |
|---|
| 215 | + * NOTE: If it's successful, the reference of dev0 is increased, |
|---|
| 216 | + * so after using it, the callers must call pci_dev_put() to give |
|---|
| 217 | + * up the reference. |
|---|
| 218 | + */ |
|---|
| 207 | 219 | static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0, |
|---|
| 208 | 220 | int *out_pos) |
|---|
| 209 | 221 | { |
|---|
| .. | .. |
|---|
| 213 | 225 | dev = get_function_0(dev); |
|---|
| 214 | 226 | if (!dev) |
|---|
| 215 | 227 | return -1; |
|---|
| 228 | + } else { |
|---|
| 229 | + dev = pci_dev_get(dev); |
|---|
| 216 | 230 | } |
|---|
| 217 | 231 | pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID); |
|---|
| 218 | | - if (!pos) |
|---|
| 232 | + if (!pos) { |
|---|
| 233 | + pci_dev_put(dev); |
|---|
| 219 | 234 | return -1; |
|---|
| 235 | + } |
|---|
| 220 | 236 | *dev0 = dev; |
|---|
| 221 | 237 | *out_pos = pos; |
|---|
| 222 | 238 | return 0; |
|---|
| .. | .. |
|---|
| 233 | 249 | |
|---|
| 234 | 250 | pci_read_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD, |
|---|
| 235 | 251 | &reset_reload); |
|---|
| 252 | + pci_dev_put(dev0); |
|---|
| 236 | 253 | *val = !!(reset_reload & BIT(0)); |
|---|
| 237 | 254 | return 0; |
|---|
| 238 | 255 | } |
|---|
| .. | .. |
|---|
| 254 | 271 | reset_reload &= ~BIT(0); |
|---|
| 255 | 272 | pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD, |
|---|
| 256 | 273 | reset_reload); |
|---|
| 274 | + pci_dev_put(dev0); |
|---|
| 257 | 275 | return 0; |
|---|
| 258 | 276 | } |
|---|
| 259 | 277 | |
|---|