aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2025-12-02 16:04:22 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2025-12-02 18:46:20 +0000
commited29ffd396e522a45ab1980c12a75b3409b51712 (patch)
treecf52879d2e9c68c3c1a8357fb111d344063d7dbe
parent44d6df4f65b1441cf9cd9f12cd41edd52205d084 (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.c13
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);