Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161704905
D26360.id76773.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D26360.id76773.diff
View Options
Index: sys/dev/pci/pci.c
===================================================================
--- sys/dev/pci/pci.c
+++ sys/dev/pci/pci.c
@@ -80,6 +80,8 @@
#include "pcib_if.h"
#include "pci_if.h"
+#define PCI_MAX_FUNC_ALIASES 255
+
#define PCIR_IS_BIOS(cfg, reg) \
(((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
@@ -502,6 +504,81 @@
return (retval);
}
+static pcicfgregs *
+pci_dev_to_cfg(device_t dev)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ bool found;
+
+ found = false;
+
+ STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
+ if (dinfo->cfg.dev == dev) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return (NULL);
+
+ cfg = &dinfo->cfg;
+
+ return (cfg);
+}
+
+int
+pci_add_dma_alias(device_t dev, uint8_t devfn_from, uint8_t nr_devfns)
+{
+ pcicfgregs *cfg;
+
+ if (nr_devfns == 0)
+ return (EINVAL);
+
+ if ((devfn_from + nr_devfns - 1) > PCI_MAX_FUNC_ALIASES)
+ return (EINVAL);
+
+ cfg = pci_dev_to_cfg(dev);
+ if (cfg == NULL)
+ return (ENODEV);
+
+ mtx_lock_spin(&cfg->dma_aliases_mtx);
+ bit_nset(cfg->dma_aliases, devfn_from, nr_devfns);
+ mtx_unlock_spin(&cfg->dma_aliases_mtx);
+
+ return (0);
+}
+
+int
+pci_for_each_dma_alias(device_t dev, int (*fn)(device_t dev,
+ uint8_t alias, void *data), void *data)
+{
+ pcicfgregs *cfg;
+ int n;
+
+ cfg = pci_dev_to_cfg(dev);
+ if (cfg == NULL)
+ return (ENODEV);
+
+ if (cfg->dma_aliases == NULL)
+ return (ENOENT);
+
+ mtx_lock_spin(&cfg->dma_aliases_mtx);
+ bit_ffs_at(cfg->dma_aliases, 0, PCI_MAX_FUNC_ALIASES, &n);
+ mtx_unlock_spin(&cfg->dma_aliases_mtx);
+
+ while (n >= 0) {
+ fn(dev, n, data);
+
+ mtx_lock_spin(&cfg->dma_aliases_mtx);
+ bit_ffs_at(cfg->dma_aliases, n + 1, PCI_MAX_FUNC_ALIASES, &n);
+ mtx_unlock_spin(&cfg->dma_aliases_mtx);
+ }
+
+ return (0);
+}
+
/* return base address of memory or port map */
static pci_addr_t
@@ -705,6 +782,10 @@
cfg->iov = NULL;
+ mtx_init(&cfg->dma_aliases_mtx, "alias bit set", NULL, MTX_SPIN);
+ cfg->dma_aliases = bit_alloc(PCI_MAX_FUNC_ALIASES, M_DEVBUF,
+ M_WAITOK | M_ZERO);
+
pci_fixancient(cfg);
pci_hdrtypedata(pcib, b, s, f, cfg);
@@ -2717,6 +2798,8 @@
free(pm, M_DEVBUF);
}
STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
+ mtx_destroy(&dinfo->cfg.dma_aliases_mtx);
+ free(&dinfo->cfg.dma_aliases, M_DEVBUF);
free(dinfo, M_DEVBUF);
/* increment the generation count */
Index: sys/dev/pci/pcivar.h
===================================================================
--- sys/dev/pci/pcivar.h
+++ sys/dev/pci/pcivar.h
@@ -31,6 +31,7 @@
#ifndef _PCIVAR_H_
#define _PCIVAR_H_
+#include <sys/bitstring.h>
#include <sys/queue.h>
#include <sys/_eventhandler.h>
@@ -212,6 +213,9 @@
uint32_t flags; /* flags defined above */
+ bitstr_t *dma_aliases; /* PCI function aliases for IOMMU. */
+ struct mtx dma_aliases_mtx; /* protection for aliases bitstr */
+
struct pcicfg_bridge bridge; /* Bridges */
struct pcicfg_pp pp; /* Power management */
struct pcicfg_vpd vpd; /* Vital product data */
@@ -694,6 +698,10 @@
void pci_print_faulted_dev(void);
+int pci_add_dma_alias(device_t dev, uint8_t devfn_from, uint8_t nr_devfns);
+int pci_for_each_dma_alias(device_t dev, int (*fn)(device_t dev,
+ uint8_t alias, void *data), void *data);
+
#endif /* _SYS_BUS_H_ */
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jul 7, 2:58 AM (3 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34742473
Default Alt Text
D26360.id76773.diff (3 KB)
Attached To
Mode
D26360: PCI function address aliasing support
Attached
Detach File
Event Timeline
Log In to Comment