patch-2.2.17 linux/drivers/sound/emu10k1/emu_wrapper.c

Next file: linux/drivers/sound/emu10k1/emu_wrapper.h
Previous file: linux/drivers/sound/emu10k1/efxmgr.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.16/drivers/sound/emu10k1/emu_wrapper.c linux/drivers/sound/emu10k1/emu_wrapper.c
@@ -0,0 +1,166 @@
+#include "emu_wrapper.h"
+#include <asm/page.h>
+#include <asm/io.h>
+
+static LIST_HEAD(pci_drivers);
+
+struct pci_driver_mapping {
+        struct pci_dev *dev;
+        struct pci_driver *drv;
+        void *driver_data;
+};
+
+#define PCI_MAX_MAPPINGS 16
+static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };
+
+void * pci_compat_get_driver_data (struct pci_dev *dev)
+{
+        int i;
+        
+        for (i = 0; i < PCI_MAX_MAPPINGS; i++)
+                if (drvmap[i].dev == dev)
+                        return drvmap[i].driver_data;
+        
+        return NULL;
+}
+
+void pci_compat_set_driver_data (struct pci_dev *dev, void *driver_data)
+{
+        int i;
+        
+        for (i = 0; i < PCI_MAX_MAPPINGS; i++)
+                if (drvmap[i].dev == dev) {
+                        drvmap[i].driver_data = driver_data;
+                        return;
+                } 
+}
+
+const struct pci_device_id *
+pci_compat_match_device(const struct pci_device_id *ids, struct pci_dev *dev)
+{
+        u16 subsystem_vendor, subsystem_device;
+
+        pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
+        pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &subsystem_device);
+
+        while (ids->vendor || ids->subvendor || ids->class_mask) {
+                if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
+                    (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
+                    (ids->subvendor == PCI_ANY_ID || ids->subvendor == subsystem_vendor) &&
+                    (ids->subdevice == PCI_ANY_ID || ids->subdevice == subsystem_device) &&
+                    !((ids->class ^ dev->class) & ids->class_mask))
+                        return ids;
+                ids++;
+        }
+        return NULL;
+}
+
+static int
+pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
+{
+        const struct pci_device_id *id;
+	int found, i;
+
+        if (drv->id_table) {
+                id = pci_compat_match_device(drv->id_table, dev);
+                if (!id)
+                        return 0;
+        } else
+                id = NULL;
+
+	found = 0;
+	for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+		if (!drvmap[i].dev) {
+			drvmap[i].dev = dev;
+			drvmap[i].drv = drv;
+			found = 1;
+		}
+
+        if (drv->probe(dev, id) >= 0) { 
+		if(found)
+			return 1;
+	} else {
+               drvmap[i - 1].dev = NULL; 
+        }
+        return 0;
+}
+
+int
+pci_compat_register_driver(struct pci_driver *drv)
+{
+        struct pci_dev *dev;
+        int count = 0, found, i;
+#ifdef CONFIG_PCI
+        list_add_tail(&drv->node, &pci_drivers);
+        pci_for_each_dev(dev) {
+                found = 0;
+                for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+                        if (drvmap[i].dev == dev)
+                                found = 1;
+                if (!found)
+                        count += pci_announce_device(drv, dev);
+        }
+#endif        
+        return count;
+}
+
+void
+pci_compat_unregister_driver(struct pci_driver *drv)
+{
+        struct pci_dev *dev;
+        int i, found;
+#ifdef CONFIG_PCI
+        list_del(&drv->node);
+        pci_for_each_dev(dev) {
+                found = 0;
+                for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+                        if (drvmap[i].dev == dev)
+                                found = 1;
+                if (found) {
+                        if (drv->remove)
+                                drv->remove(dev);
+                        drvmap[i].dev = NULL;
+                }
+        }
+#endif        
+}
+
+unsigned long pci_compat_get_size (struct pci_dev *dev, int n_base)
+{
+        u32 l, sz;
+        int reg = PCI_BASE_ADDRESS_0 + (n_base << 2);
+
+        /* XXX temporarily disable I/O and memory decoding for this device? */
+
+        pci_read_config_dword (dev, reg, &l);
+        if (l == 0xffffffff)
+                return 0;
+
+        pci_write_config_dword (dev, reg, ~0);
+        pci_read_config_dword (dev, reg, &sz);
+        pci_write_config_dword (dev, reg, l);
+
+        if (!sz || sz == 0xffffffff)
+                return 0;
+        if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
+                sz = ~(sz & PCI_BASE_ADDRESS_MEM_MASK);
+        } else {
+                sz = ~(sz & PCI_BASE_ADDRESS_IO_MASK) & 0xffff;
+        }
+
+        return sz + 1;
+}
+
+int pci_compat_enable_device(struct pci_dev *dev)
+{
+        return 0;
+}
+
+void *compat_request_region (unsigned long start, unsigned long n, const char *name)
+{
+        if (check_region (start, n) != 0)
+                return NULL;
+        request_region (start, n, name);
+        return (void *) 1;
+}
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)