* Quirks.
*/
-static void __init
-quirk_eisa_bridge(struct pci_dev *dev)
-{
- dev->class = PCI_CLASS_BRIDGE_EISA << 8;
-}
-
static void __init
quirk_isa_bridge(struct pci_dev *dev)
{
}
struct pci_fixup pcibios_fixups[] __initdata = {
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
- quirk_eisa_bridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
quirk_isa_bridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229,
#
-# PCI configuration
+# EISA configuration
#
+config EISA_PCI_EISA
+ bool "Generic PCI/EISA bridge"
+ depends on PCI && EISA
+ default y
+ ---help---
+ Activate this option if your system contains a PCI to EISA
+ bridge. If your system have both PCI and EISA slots, you
+ certainly need this option.
+
+ When in doubt, say Y.
+
+config EISA_VIRTUAL_ROOT
+ bool "EISA virtual root device"
+ depends on EISA
+ default y
+ ---help---
+ Activate this option if your system only have EISA bus
+ (no PCI slots). The Alpha Jensen is an example of such
+ a system.
+
+ When in doubt, say Y.
+
config EISA_NAMES
bool "EISA device name database"
depends on EISA
# Makefile for the Linux device tree
-obj-$(CONFIG_EISA) += eisa-bus.o
+obj-$(CONFIG_EISA) += eisa-bus.o
+obj-${CONFIG_EISA_PCI_EISA} += pci_eisa.o
+
+# virtual_root.o should be the last EISA root device to initialize,
+# so leave it at the end of the list.
+obj-${CONFIG_EISA_VIRTUAL_ROOT} += virtual_root.o
clean-files:= devlist.h
#include <linux/ioport.h>
#include <asm/io.h>
+#define SLOT_ADDRESS(r,n) (r->bus_base_addr + (0x1000 * n))
+
#define EISA_DEVINFO(i,s) { .id = { .sig = i }, .name = s }
struct eisa_device_info {
.match = eisa_bus_match,
};
-/* The default EISA device parent (virtual root device). */
-static struct device eisa_bus_root = {
- .name = "EISA Bridge",
- .bus_id = "eisa",
-};
-
int eisa_driver_register (struct eisa_driver *edrv)
{
int r;
if ((r = driver_register (&edrv->driver)) < 0)
return r;
- return 1;
+ return 0;
}
void eisa_driver_unregister (struct eisa_driver *edrv)
static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
-static void __init eisa_register_device (char *sig, int slot)
+static void __init eisa_register_device (struct eisa_root_device *root,
+ char *sig, int slot)
{
struct eisa_device *edev;
memset (edev, 0, sizeof (*edev));
memcpy (edev->id.sig, sig, 7);
edev->slot = slot;
- edev->base_addr = 0x1000 * slot;
+ edev->base_addr = SLOT_ADDRESS (root, slot);
eisa_name_device (edev);
- edev->dev.parent = &eisa_bus_root;
+ edev->dev.parent = root->dev;
edev->dev.bus = &eisa_bus_type;
- sprintf (edev->dev.bus_id, "00:%02X", slot);
+ sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
/* Don't register resource for slot 0, since this will surely
* fail... :-( */
edev->res.end = edev->res.start + 0xfff;
edev->res.flags = IORESOURCE_IO;
- if (request_resource (&ioport_resource, &edev->res)) {
+ if (request_resource (root->res, &edev->res)) {
printk (KERN_WARNING \
"Cannot allocate resource for EISA slot %d\n",
slot);
device_create_file (&edev->dev, &dev_attr_signature);
}
-static int __init eisa_probe (void)
+static int __init eisa_probe (struct eisa_root_device *root)
{
int i, c;
char *str;
- unsigned long slot_addr;
+ unsigned long sig_addr;
- printk (KERN_INFO "EISA: Probing bus...\n");
- for (c = 0, i = 0; i <= EISA_MAX_SLOTS; i++) {
- slot_addr = (0x1000 * i) + EISA_VENDOR_ID_OFFSET;
- if ((str = decode_eisa_sig (slot_addr))) {
+ printk (KERN_INFO "EISA: Probing bus %d at %s\n",
+ root->bus_nr, root->dev->name);
+
+ for (c = 0, i = 0; i <= root->slots; i++) {
+ sig_addr = SLOT_ADDRESS (root, i) + EISA_VENDOR_ID_OFFSET;
+ if ((str = decode_eisa_sig (sig_addr))) {
if (!i)
printk (KERN_INFO "EISA: Motherboard %s detected\n",
str);
c++;
}
- eisa_register_device (str, i);
+ eisa_register_device (root, str, i);
}
}
printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
return 0;
}
+
+static LIST_HEAD (eisa_root_head);
+
+static int eisa_bus_count;
+
+int eisa_root_register (struct eisa_root_device *root)
+{
+ struct list_head *node;
+ struct eisa_root_device *tmp_root;
+
+ /* Check if this bus base address has been already
+ * registered. This prevents the virtual root device from
+ * registering after the real one has, for example... */
+
+ list_for_each (node, &eisa_root_head) {
+ tmp_root = list_entry (node, struct eisa_root_device, node);
+ if (tmp_root->bus_base_addr == root->bus_base_addr)
+ return -1; /* Space already taken, buddy... */
+ }
+
+ root->bus_nr = eisa_bus_count++;
+ list_add_tail (&root->node, &eisa_root_head);
+ return eisa_probe (root);
+}
+
static int __init eisa_init (void)
{
int r;
if ((r = bus_register (&eisa_bus_type)))
return r;
-
- if ((r = device_register (&eisa_bus_root))) {
- bus_unregister (&eisa_bus_type);
- return r;
- }
printk (KERN_INFO "EISA bus registered\n");
- return eisa_probe ();
+ return 0;
}
postcore_initcall (eisa_init);
--- /dev/null
+/*
+ * Minimalist driver for a generic PCI-to-EISA bridge.
+ *
+ * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ *
+ * This code is released under the GPL version 2.
+ *
+ * Ivan Kokshaysky <ink@jurassic.park.msu.ru> :
+ * Generalisation from i82375 to PCI_CLASS_BRIDGE_EISA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/eisa.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+/* There is only *one* pci_eisa device per machine, right ? */
+static struct eisa_root_device pci_eisa_root;
+
+static int __devinit pci_eisa_init (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int rc;
+
+ if ((rc = pci_enable_device (pdev))) {
+ printk (KERN_ERR "pci_eisa : Could not enable device %s\n",
+ pdev->slot_name);
+ return rc;
+ }
+
+ pci_eisa_root.dev = &pdev->dev;
+ pci_eisa_root.dev->driver_data = &pci_eisa_root;
+ pci_eisa_root.res = pdev->bus->resource[0];
+ pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start;
+ pci_eisa_root.slots = EISA_MAX_SLOTS;
+
+ if (eisa_root_register (&pci_eisa_root)) {
+ printk (KERN_ERR "pci_eisa : Could not register EISA root\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static struct pci_device_id pci_eisa_pci_tbl[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 },
+ { 0, }
+};
+
+static struct pci_driver pci_eisa_driver = {
+ .name = "pci_eisa",
+ .id_table = pci_eisa_pci_tbl,
+ .probe = pci_eisa_init,
+};
+
+static int __init pci_eisa_init_module (void)
+{
+ return pci_module_init (&pci_eisa_driver);
+}
+
+device_initcall(pci_eisa_init_module);
--- /dev/null
+/*
+ * Virtual EISA root driver.
+ * Acts as a placeholder if we don't have a proper EISA bridge.
+ *
+ * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ *
+ * This code is released under the GPL version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/eisa.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+/* The default EISA device parent (virtual root device). */
+static struct device eisa_root_dev = {
+ .name = "Virtual EISA Bridge",
+ .bus_id = "eisa",
+};
+
+static struct eisa_root_device eisa_bus_root = {
+ .dev = &eisa_root_dev,
+ .bus_base_addr = 0,
+ .res = &ioport_resource,
+ .slots = EISA_MAX_SLOTS,
+};
+
+static int virtual_eisa_root_init (void)
+{
+ int r;
+
+ if ((r = device_register (&eisa_root_dev))) {
+ return r;
+ }
+
+ eisa_root_dev.driver_data = &eisa_bus_root;
+
+ if (eisa_root_register (&eisa_bus_root)) {
+ /* A real bridge may have been registered before
+ * us. So quietly unregister. */
+ device_unregister (&eisa_root_dev);
+ return -1;
+ }
+
+ return 0;
+}
+
+device_initcall (virtual_eisa_root_init);
/* returns count found (>= 0), or negative on error */
static int __init vortex_eisa_init (void)
{
+ int eisa_found = 0;
int orig_cards_found = vortex_cards_found;
/* Now check all slots of the EISA bus. */
return 0;
#ifdef CONFIG_EISA
- if (eisa_driver_register (&vortex_eisa_driver) < 0) {
- eisa_driver_unregister (&vortex_eisa_driver);
+ if (eisa_driver_register (&vortex_eisa_driver) >= 0) {
+ /* Because of the way EISA bus is probed, we cannot assume
+ * any device have been found when we exit from
+ * eisa_driver_register (the bus root driver may not be
+ * initialized yet). So we blindly assume something was
+ * found, and let the sysfs magic happend... */
+
+ eisa_found = 1;
}
#endif
compaq_device_id, vortex_cards_found++);
}
- return vortex_cards_found - orig_cards_found;
+ return vortex_cards_found - orig_cards_found + eisa_found;
}
/* returns count (>= 0), or negative on error */
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/eisa.h>
#include <asm/byteorder.h>
#include <asm/io.h>
static struct eisa_ba {
struct pci_hba_data hba;
unsigned long eeprom_addr;
+ struct eisa_root_device root;
} eisa_dev;
/* Port ops */
eisa_eeprom_init(eisa_dev.eeprom_addr);
eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space);
init_eisa_pic();
+
+ /* FIXME : Get the number of slots from the enumerator, not a
+ * hadcoded value. Also don't enumerate the bus twice. */
+ eisa_dev.root.dev = &dev->dev;
+ dev->dev.driver_data = &eisa_dev.root;
+ eisa_dev.root.bus_base_addr = 0;
+ eisa_dev.root.res = &eisa_dev.hba.io_space;
+ eisa_dev.root.slots = EISA_MAX_SLOTS;
+ if (eisa_root_register (&eisa_dev.root)) {
+ printk(KERN_ERR "EISA: Failed to register EISA root\n");
+ return -1;
+ }
return 0;
}
}
}
+/* This was originally an Alpha specific thing, but it really fits here.
+ * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
+ */
+
+static void __init quirk_eisa_bridge(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_EISA << 8;
+}
+
/*
* The main table of quirks.
*/
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge },
{ 0 }
};
};
/* There is not much we can say about an EISA device, apart from
- * signature, slot number, and base address */
+ * signature, slot number, and base address. */
+
struct eisa_device {
struct eisa_device_id id;
int slot;
edev->dev.driver_data = data;
}
+/* The EISA root device. There's rumours about machines with multiple
+ * busses (PA-RISC ?), so we try to handle that. */
+
+struct eisa_root_device {
+ struct list_head node;
+ struct device *dev; /* Pointer to bridge device */
+ struct resource *res;
+ unsigned long bus_base_addr;
+ int slots; /* Max slot number */
+ int bus_nr; /* Set by eisa_root_register */
+};
+
+int eisa_root_register (struct eisa_root_device *root);
+
#endif