Page MenuHomeFreeBSD

D32447.id.diff
No OneTemporary

D32447.id.diff

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

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)

Event Timeline