Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102520462
D32447.id.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
D32447.id.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
@@ -311,19 +311,27 @@
return (SYS_RES_MEMORY);
}
+struct resource_list_entry *linux_pci_reserve_bar(struct pci_dev *pdev,
+ struct resource_list *rl, int type, int rid);
+
static inline struct resource_list_entry *
-linux_pci_get_rle(struct pci_dev *pdev, int type, int rid)
+linux_pci_get_rle(struct pci_dev *pdev, int type, int rid, bool reserve_bar)
{
struct pci_devinfo *dinfo;
struct resource_list *rl;
+ struct resource_list_entry *rle;
dinfo = device_get_ivars(pdev->dev.bsddev);
rl = &dinfo->resources;
- return resource_list_find(rl, type, rid);
+ rle = resource_list_find(rl, type, rid);
+ /* Reserve resources for this BAR if needed. */
+ if (rle == NULL && reserve_bar)
+ rle = linux_pci_reserve_bar(pdev, rl, type, rid);
+ return (rle);
}
static inline struct resource_list_entry *
-linux_pci_get_bar(struct pci_dev *pdev, int bar)
+linux_pci_get_bar(struct pci_dev *pdev, int bar, bool reserve)
{
int type;
@@ -331,7 +339,7 @@
if (type < 0)
return (NULL);
bar = PCIR_BAR(bar);
- return (linux_pci_get_rle(pdev, type, bar));
+ return (linux_pci_get_rle(pdev, type, bar, reserve));
}
static inline struct device *
@@ -521,7 +529,7 @@
struct pci_devres *dr;
struct pci_mmio_region *mmio, *p;
- if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
+ if ((rle = linux_pci_get_bar(pdev, bar, false)) == NULL)
return;
/*
@@ -779,7 +787,7 @@
pci_release_msi(pdev->dev.bsddev);
return avail;
}
- rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
+ rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false);
pdev->dev.irq_start = rle->start;
pdev->dev.irq_end = rle->start + avail;
for (i = 0; i < nreq; i++)
@@ -832,7 +840,7 @@
if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0)
return error;
- rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
+ rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false);
pdev->dev.irq_start = rle->start;
pdev->dev.irq_end = rle->start + avail;
pdev->irq = rle->start;
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
@@ -409,7 +409,7 @@
PCI_GET_ID(parent, dev, PCI_ID_RID, &rid);
pdev->devfn = rid;
pdev->pdrv = pdrv;
- rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0);
+ rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0, false);
if (rle != NULL)
pdev->dev.irq = rle->start;
else
@@ -665,6 +665,25 @@
return (_linux_pci_register_driver(pdrv, dc));
}
+struct resource_list_entry *
+linux_pci_reserve_bar(struct pci_dev *pdev, struct resource_list *rl,
+ int type, int rid)
+{
+ device_t dev;
+ struct resource *res;
+
+ KASSERT(type == SYS_RES_IOPORT || type == SYS_RES_MEMORY,
+ ("trying to reserve non-BAR type %d", type));
+
+ dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ?
+ device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev;
+ res = pci_reserve_map(device_get_parent(dev), dev, type, &rid, 0, ~0,
+ 1, 1, 0);
+ if (res == NULL)
+ return (NULL);
+ return (resource_list_find(rl, type, rid));
+}
+
unsigned long
pci_resource_start(struct pci_dev *pdev, int bar)
{
@@ -672,7 +691,7 @@
rman_res_t newstart;
device_t dev;
- if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
+ if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL)
return (0);
dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ?
device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev;
@@ -689,7 +708,7 @@
{
struct resource_list_entry *rle;
- if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
+ if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL)
return (0);
return (rle->count);
}
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -5365,7 +5365,7 @@
}
#endif /* DDB */
-static struct resource *
+struct resource *
pci_reserve_map(device_t dev, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int num,
u_int flags)
diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h
--- a/sys/dev/pci/pci_private.h
+++ b/sys/dev/pci/pci_private.h
@@ -163,6 +163,10 @@
struct pci_map *pci_add_bar(device_t dev, int reg, pci_addr_t value,
pci_addr_t size);
+struct resource *pci_reserve_map(device_t dev, device_t child, int type,
+ int *rid, rman_res_t start, rman_res_t end,
+ rman_res_t count, u_int num, u_int flags);
+
struct resource *pci_alloc_multi_resource(device_t dev, device_t child,
int type, int *rid, rman_res_t start, rman_res_t end,
rman_res_t count, u_long num, u_int flags);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 14, 12:33 PM (27 m, 24 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14629321
Default Alt Text
D32447.id.diff (4 KB)
Attached To
Mode
D32447: LinuxKPI: Support lazy BAR allocation
Attached
Detach File
Event Timeline
Log In to Comment