Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162630178
D52068.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D52068.diff
View Options
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -355,7 +355,6 @@
TAILQ_HEAD(, pci_mmio_region) mmio;
};
-int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name);
int pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv,
unsigned int flags);
bool pci_device_is_present(struct pci_dev *pdev);
@@ -369,7 +368,9 @@
void linuxkpi_pci_iounmap(struct pci_dev *pdev, void *res);
int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask,
const char *name);
+int linuxkpi_pci_request_region(struct pci_dev *, int, const char *);
int linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name);
+int linuxkpi_pcim_request_all_regions(struct pci_dev *, const char *);
void linuxkpi_pci_release_region(struct pci_dev *pdev, int bar);
void linuxkpi_pci_release_regions(struct pci_dev *pdev);
int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries,
@@ -562,12 +563,16 @@
return (pdev->bus->self);
}
+#define pci_request_region(pdev, bar, res_name) \
+ linuxkpi_pci_request_region(pdev, bar, res_name)
#define pci_release_region(pdev, bar) \
linuxkpi_pci_release_region(pdev, bar)
-#define pci_release_regions(pdev) \
- linuxkpi_pci_release_regions(pdev)
#define pci_request_regions(pdev, res_name) \
linuxkpi_pci_request_regions(pdev, res_name)
+#define pci_release_regions(pdev) \
+ linuxkpi_pci_release_regions(pdev)
+#define pcim_request_all_regions(pdev, name) \
+ linuxkpi_pcim_request_all_regions(pdev, name)
static inline void
lkpi_pci_disable_msix(struct pci_dev *pdev)
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -1159,8 +1159,9 @@
return (rle->count);
}
-int
-pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
+static int
+lkpi_pci_request_region(struct pci_dev *pdev, int bar, const char *res_name,
+ bool managed)
{
struct resource *res;
struct pci_devres *dr;
@@ -1168,9 +1169,20 @@
int rid;
int type;
+ 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 (-ENODEV);
+ return (0);
+
rid = PCIR_BAR(bar);
res = bus_alloc_resource_any(pdev->dev.bsddev, type, &rid,
RF_ACTIVE|RF_SHAREABLE);
@@ -1183,11 +1195,16 @@
/*
* It seems there is an implicit devres tracking on these if the device
- * is managed; otherwise the resources are not automatiaclly freed on
- * FreeBSD/LinuxKPI tough they should be/are expected to be by Linux
- * drivers.
+ * is managed (lkpi_pci_devres_find() case); otherwise the resources are
+ * not automatically freed on FreeBSD/LinuxKPI though they should be/are
+ * expected to be by Linux drivers.
+ * Otherwise if we are called from a pcim-function with the managed
+ * argument set, we need to track devres independent of pdev->managed.
*/
- dr = lkpi_pci_devres_find(pdev);
+ if (managed)
+ dr = lkpi_pci_devres_get_alloc(pdev);
+ else
+ dr = lkpi_pci_devres_find(pdev);
if (dr != NULL) {
dr->region_mask |= (1 << bar);
dr->region_table[bar] = res;
@@ -1203,6 +1220,12 @@
return (0);
}
+int
+linuxkpi_pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
+{
+ return (lkpi_pci_request_region(pdev, bar, res_name, false));
+}
+
int
linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name)
{
@@ -1219,6 +1242,24 @@
return (0);
}
+int
+linuxkpi_pcim_request_all_regions(struct pci_dev *pdev, const char *res_name)
+{
+ int bar, error;
+
+ for (bar = 0; bar <= PCIR_MAX_BAR_0; bar++) {
+ error = lkpi_pci_request_region(pdev, bar, res_name, true);
+ if (error != 0) {
+ device_printf(pdev->dev.bsddev, "%s: bar %d res_name '%s': "
+ "lkpi_pci_request_region returned %d\n", __func__,
+ bar, res_name, error);
+ pci_release_regions(pdev);
+ return (error);
+ }
+ }
+ return (0);
+}
+
void
linuxkpi_pci_release_region(struct pci_dev *pdev, int bar)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 16, 6:40 AM (11 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35126580
Default Alt Text
D52068.diff (4 KB)
Attached To
Mode
D52068: LinuxKPI: pci: implement [linuxkpi_]pcim_request_all_regions()
Attached
Detach File
Event Timeline
Log In to Comment