summaryrefslogtreecommitdiffstats
path: root/sys/pci/pci_compat.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2000-05-28 16:35:57 +0000
committerpeter <peter@FreeBSD.org>2000-05-28 16:35:57 +0000
commiteda3ab65365eda15e04a893a46c7244b53638c94 (patch)
treea75cd25e9649785a73bedb6d5cbf9fc20d6a036a /sys/pci/pci_compat.c
parentdeeb13a8dbcfd2933374a20e990791e83cd77096 (diff)
downloadFreeBSD-src-eda3ab65365eda15e04a893a46c7244b53638c94.zip
FreeBSD-src-eda3ab65365eda15e04a893a46c7244b53638c94.tar.gz
Encapsulate the old PCI compatability support and APIs completely under
"options COMPAT_OLDPCI". This option already existed, but now also tidies up the declarations in #include <pci/pci*.h>. It is amazing how much stuff was using the old pre-FreeBSD 3.x names and going silently undetected.
Diffstat (limited to 'sys/pci/pci_compat.c')
-rw-r--r--sys/pci/pci_compat.c100
1 files changed, 96 insertions, 4 deletions
diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c
index 59372d7..4635342 100644
--- a/sys/pci/pci_compat.c
+++ b/sys/pci/pci_compat.c
@@ -29,10 +29,12 @@
#include "opt_bus.h"
-/* for compatibility to FreeBSD-2.2 version of PCI code */
+/* for compatibility to FreeBSD-2.2 and 3.x versions of PCI code */
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -43,6 +45,7 @@
#include <sys/rman.h>
#include <machine/resource.h>
+#include <sys/pciio.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@@ -55,8 +58,6 @@
#endif
-#ifdef PCI_COMPAT
-
/* ------------------------------------------------------------------------- */
u_long
@@ -235,4 +236,95 @@ pci_get_bus_from_tag(pcici_t tag)
return tag->bus;
}
-#endif /* PCI_COMPAT */
+/*
+ * A simple driver to wrap the old pci driver mechanism for back-compat.
+ */
+
+static int
+pci_compat_probe(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ const char *name;
+ int error;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ /*
+ * Do the wrapped probe.
+ */
+ error = ENXIO;
+ if (dvp && dvp->pd_probe) {
+ name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor);
+ if (name) {
+ device_set_desc_copy(dev, name);
+ /* Allow newbus drivers to match "better" */
+ error = -200;
+ }
+ }
+
+ return error;
+}
+
+static int
+pci_compat_attach(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ int unit;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ unit = device_get_unit(dev);
+ if (unit > *dvp->pd_count)
+ *dvp->pd_count = unit;
+ if (dvp->pd_attach)
+ dvp->pd_attach(cfg, unit);
+ device_printf(dev, "driver is using old-style compatability shims\n");
+ return 0;
+}
+
+static device_method_t pci_compat_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pci_compat_probe),
+ DEVMETHOD(device_attach, pci_compat_attach),
+
+ { 0, 0 }
+};
+
+/*
+ * Create a new style driver around each old pci driver.
+ */
+int
+compat_pci_handler(module_t mod, int type, void *data)
+{
+ struct pci_device *dvp = (struct pci_device *)data;
+ driver_t *driver;
+ devclass_t pci_devclass = devclass_find("pci");
+
+ switch (type) {
+ case MOD_LOAD:
+ driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
+ if (!driver)
+ return ENOMEM;
+ bzero(driver, sizeof(driver_t));
+ driver->name = dvp->pd_name;
+ driver->methods = pci_compat_methods;
+ driver->size = sizeof(struct pci_devinfo *);
+ driver->priv = dvp;
+ devclass_add_driver(pci_devclass, driver);
+ break;
+ case MOD_UNLOAD:
+ printf("%s: module unload not supported!\n", dvp->pd_name);
+ return EOPNOTSUPP;
+ default:
+ break;
+ }
+ return 0;
+}
OpenPOWER on IntegriCloud