diff options
| author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2025-12-02 16:04:22 +0000 |
|---|---|---|
| committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2025-12-02 18:46:20 +0000 |
| commit | ed29ffd396e522a45ab1980c12a75b3409b51712 (patch) | |
| tree | cf52879d2e9c68c3c1a8357fb111d344063d7dbe | |
| parent | 44d6df4f65b1441cf9cd9f12cd41edd52205d084 (diff) | |
LinuxKPI: pci: undo the pci_resource_len() check in lkpi_pci_request_region()
Creating non-passthru SR-IOV interfaces on a mlx5en(4) failed.
The problem lies in the pci_resource_len() call but not that the BAR length
is tmeporary 0 but in that we call lkpi_pci_get_bar() with a true argument
which will create the BAR resource for us and report the approriate length
back. However, the later call to bus_alloc_resource_any() will then fail
given the resource already exists.
Restore the previous behaviour and let bus_alloc_resource_any() do the
work. Adjust the return values from -ENODEV to -EBUSY to match callers
expectations.
In linuxkpi_pcim_request_all_regions(), like in linuxkpi_pci_request_regions(),
filter out the -EBUSY errors as "not an error" and try the next bar.
This also seems to be consistent with the expectations of the callers.
PR: 290793
Reported by: David BOYER (jcduss13 gmail.com)
Tested on: mlx5en, iwlwifi, mt7921
Reviewed by: kib
Fixes: 7e21158d44cd "implement [linuxkpi_]pcim_request_all_regions()"
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D53902
| -rw-r--r-- | sys/compat/linuxkpi/common/src/linux_pci.c | 13 |
1 files changed, 3 insertions, 10 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index 8507a59a8df3..fb3f648df496 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -1223,13 +1223,6 @@ lkpi_pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, if (!lkpi_pci_bar_id_valid(bar)) return (-EINVAL); - /* - * If the bar is not valid, return success without adding the BAR; - * otherwise linuxkpi_pcim_request_all_regions() will error. - */ - if (pci_resource_len(pdev, bar) == 0) - return (0); - /* Likewise if it is neither IO nor MEM, nothing to do for us. */ type = pci_resource_type(pdev, bar); if (type < 0) return (0); @@ -1241,7 +1234,7 @@ lkpi_pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, device_printf(pdev->dev.bsddev, "%s: failed to alloc " "bar %d type %d rid %d\n", __func__, bar, type, PCIR_BAR(bar)); - return (-ENODEV); + return (-EBUSY); } /* @@ -1285,7 +1278,7 @@ linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name) for (i = 0; i <= PCIR_MAX_BAR_0; i++) { error = pci_request_region(pdev, i, res_name); - if (error && error != -ENODEV) { + if (error && error != -EBUSY) { pci_release_regions(pdev); return (error); } @@ -1300,7 +1293,7 @@ linuxkpi_pcim_request_all_regions(struct pci_dev *pdev, const char *res_name) for (bar = 0; bar <= PCIR_MAX_BAR_0; bar++) { error = lkpi_pci_request_region(pdev, bar, res_name, true); - if (error != 0) { + if (error != 0 && error != -EBUSY) { device_printf(pdev->dev.bsddev, "%s: bar %d res_name '%s': " "lkpi_pci_request_region returned %d\n", __func__, bar, res_name, error); |
