Page MenuHomeFreeBSD

D26360.id76773.diff
No OneTemporary

D26360.id76773.diff

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

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)

Event Timeline