.. | .. |
---|
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 | |
---|