* [PATCH] fix 3c509.c for MCA drivers
@ 2003-02-03 3:09 James Bottomley
2003-02-08 17:25 ` Marc Zyngier
2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
0 siblings, 2 replies; 12+ messages in thread
From: James Bottomley @ 2003-02-03 3:09 UTC (permalink / raw)
To: linux-kernel; +Cc: jgarzik, mzyngier
[-- Attachment #1: Type: text/plain, Size: 308 bytes --]
The attached fixes the MCA version of the 3c509 and updates it to the
new MCA API.
Someone who knows PNP-ISA should migrate it to a probing API for that
too.
I've put the el3_probe back into Space.c for ISA only otherwise the
driver won't work for ISA (could someone with an ISA card test this).
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 11584 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.956 -> 1.957
# drivers/net/3c509.c 1.29 -> 1.30
# drivers/net/Space.c 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/02 jejb@mulgrave.(none) 1.957
# 3c509 fixes: correct MCA probing, add back ISA probe to Space.c
# --------------------------------------------
#
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c Sun Feb 2 22:04:26 2003
+++ b/drivers/net/3c509.c Sun Feb 2 22:04:26 2003
@@ -103,6 +103,10 @@
static int el3_debug = 2;
#endif
+/* Used to do a global count of all the cards in the system. Must be
+ * a global variable so that the mca/eisa probe routines can increment
+ * it */
+static int el3_cards = 0;
/* To minimize the size of the driver source I only define operating
constants if they are used several times. You'll need the manual
@@ -167,16 +171,15 @@
/* skb send-queue */
int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE];
- char mca_slot;
#ifdef CONFIG_PM
struct pm_dev *pmdev;
#endif
-#ifdef __ISAPNP__
- struct pnp_dev *pnpdev;
-#endif
-#ifdef CONFIG_EISA
- struct eisa_device *edev;
-#endif
+ enum {
+ EL3_MCA,
+ EL3_PNP,
+ EL3_EISA,
+ } type; /* type of device */
+ struct device *dev;
};
static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/
static struct net_device *el3_root_dev;
@@ -200,6 +203,8 @@
static int el3_resume(struct pm_dev *pdev);
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
#endif
+/* generic device remove for all device types */
+static int el3_device_remove (struct device *device);
#ifdef CONFIG_EISA
struct eisa_device_id el3_eisa_ids[] = {
@@ -209,31 +214,46 @@
};
static int el3_eisa_probe (struct device *device);
-static int el3_eisa_remove (struct device *device);
struct eisa_driver el3_eisa_driver = {
.id_table = el3_eisa_ids,
.driver = {
.name = "3c509",
.probe = el3_eisa_probe,
- .remove = __devexit_p (el3_eisa_remove)
+ .remove = __devexit_p (el3_device_remove)
}
};
#endif
#ifdef CONFIG_MCA
-struct el3_mca_adapters_struct {
- char* name;
- int id;
+static int el3_mca_probe(struct device *dev);
+
+static short el3_mca_adapter_ids[] __initdata = {
+ 0x627c,
+ 0x627d,
+ 0x62db,
+ 0x62f6,
+ 0x62f7,
+ 0x0000
+};
+
+static char *el3_mca_adapter_names[] __initdata = {
+ "3Com 3c529 EtherLink III (10base2)",
+ "3Com 3c529 EtherLink III (10baseT)",
+ "3Com 3c529 EtherLink III (test mode)",
+ "3Com 3c529 EtherLink III (TP or coax)",
+ "3Com 3c529 EtherLink III (TP)",
+ NULL
};
-static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = {
- { "3Com 3c529 EtherLink III (10base2)", 0x627c },
- { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
- { "3Com 3c529 EtherLink III (test mode)", 0x62db },
- { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
- { "3Com 3c529 EtherLink III (TP)", 0x62f7 },
- { NULL, 0 },
+static struct mca_driver el3_mca_driver = {
+ .id_table = el3_mca_adapter_ids,
+ .driver = {
+ .name = "3c529",
+ .bus = &mca_bus_type,
+ .probe = el3_mca_probe,
+ .remove = __devexit_p(el3_device_remove),
+ },
};
#endif /* CONFIG_MCA */
@@ -264,12 +284,12 @@
};
static u16 el3_isapnp_phys_addr[8][3];
-#endif /* __ISAPNP__ */
static int nopnp;
+#endif /* __ISAPNP__ */
/* With the driver model introduction for EISA devices, both init
* and cleanup have been split :
- * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove
+ * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove
* - MCA/ISA still use el3_probe
*
* Both call el3_common_init/el3_common_remove. */
@@ -278,10 +298,9 @@
{
struct el3_private *lp = dev->priv;
short i;
-
-#ifdef CONFIG_EISA
- if (!lp->edev) /* EISA devices are not chained */
-#endif
+
+ el3_cards++;
+ if (!lp->dev) /* probed devices are not chained */
{
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
@@ -337,17 +356,13 @@
struct el3_private *lp = dev->priv;
(void) lp; /* Keep gcc quiet... */
-#ifdef CONFIG_MCA
- if(lp->mca_slot!=-1)
- mca_mark_as_unused(lp->mca_slot);
-#endif
#ifdef CONFIG_PM
if (lp->pmdev)
pm_unregister(lp->pmdev);
#endif
#ifdef __ISAPNP__
- if (lp->pnpdev)
- pnp_device_detach(lp->pnpdev);
+ if (lp->type == EL3_PNP)
+ pnp_device_detach(to_pnp_dev(lp->dev));
#endif
unregister_netdev (dev);
@@ -363,76 +378,11 @@
int ioaddr, irq, if_port;
u16 phys_addr[3];
static int current_tag;
- int mca_slot = -1;
#ifdef __ISAPNP__
static int pnp_cards;
struct pnp_dev *idev = NULL;
#endif /* __ISAPNP__ */
-#ifdef CONFIG_MCA
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
- * modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
- * to support standard MCA probing.
- *
- * redone for multi-card detection by ZP Gu (zpg@castle.net)
- * now works as a module
- */
-
- if( MCA_bus ) {
- int slot, j;
- u_char pos4, pos5;
-
- for( j = 0; el3_mca_adapters[j].name != NULL; j ++ ) {
- slot = 0;
- while( slot != MCA_NOTFOUND ) {
- slot = mca_find_unused_adapter(
- el3_mca_adapters[j].id, slot );
- if( slot == MCA_NOTFOUND ) break;
-
- /* if we get this far, an adapter has been
- * detected and is enabled
- */
-
- pos4 = mca_read_stored_pos( slot, 4 );
- pos5 = mca_read_stored_pos( slot, 5 );
-
- ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
- irq = pos5 & 0x0f;
-
- /* probing for a card at a particular IO/IRQ */
- if(dev && ((dev->irq >= 1 && dev->irq != irq) ||
- (dev->base_addr >= 1 && dev->base_addr != ioaddr))) {
- slot++; /* probing next slot */
- continue;
- }
-
- printk("3c509: found %s at slot %d\n",
- el3_mca_adapters[j].name, slot + 1 );
-
- /* claim the slot */
- mca_set_adapter_name(slot, el3_mca_adapters[j].name);
- mca_set_adapter_procfn(slot, NULL, NULL);
- mca_mark_as_used(slot);
-
- if_port = pos4 & 0x03;
- if (el3_debug > 2) {
- printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
- }
- EL3WINDOW(0);
- for (i = 0; i < 3; i++) {
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
- }
-
- mca_slot = slot;
-
- goto found;
- }
- }
- /* if we get here, we didn't find an MCA adapter */
- return -ENODEV;
- }
-#endif /* CONFIG_MCA */
-
#ifdef __ISAPNP__
if (nopnp == 1)
goto no_pnp;
@@ -580,7 +530,7 @@
/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
- found:
+
dev = init_etherdev(NULL, sizeof(struct el3_private));
if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT);
@@ -594,13 +544,80 @@
dev->if_port = if_port;
lp = dev->priv;
#ifdef __ISAPNP__
- lp->pnpdev = idev;
+ lp->dev = &idev->dev;
#endif
- lp->mca_slot = mca_slot;
return el3_common_init (dev);
}
+#ifdef CONFIG_MCA
+static int __init el3_mca_probe(struct device *device) {
+ /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
+ * heavily modified by Chris Beauregard
+ * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
+ * probing.
+ *
+ * redone for multi-card detection by ZP Gu (zpg@castle.net)
+ * now works as a module */
+
+ struct el3_private *lp;
+ short i;
+ int ioaddr, irq, if_port;
+ u16 phys_addr[3];
+ struct net_device *dev = NULL;
+ u_char pos4, pos5;
+ struct mca_device *mdev = to_mca_device(device);
+ int slot = mdev->slot;
+
+ pos4 = mca_device_read_stored_pos(mdev, 4);
+ pos5 = mca_device_read_stored_pos(mdev, 5);
+
+ ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
+ irq = pos5 & 0x0f;
+
+
+ printk("3c529: found %s at slot %d\n",
+ el3_mca_adapter_names[mdev->index], slot + 1);
+
+ /* claim the slot */
+ strncpy(device->name, el3_mca_adapter_names[mdev->index],
+ sizeof(device->name));
+ mca_device_set_claim(mdev, 1);
+
+ if_port = pos4 & 0x03;
+
+ irq = mca_device_transform_irq(mdev, irq);
+ ioaddr = mca_device_transform_ioport(mdev, ioaddr);
+ if (el3_debug > 2) {
+ printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
+ }
+ EL3WINDOW(0);
+ for (i = 0; i < 3; i++) {
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+ }
+
+ dev = init_etherdev(NULL, sizeof(struct el3_private));
+ if (dev == NULL) {
+ release_region(ioaddr, EL3_IO_EXTENT);
+ return -ENOMEM;
+ }
+
+ SET_MODULE_OWNER(dev);
+
+ memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->if_port = if_port;
+ lp = dev->priv;
+ lp->dev = device;
+ lp->type = EL3_MCA;
+ device->driver_data = dev;
+
+ return el3_common_init (dev);
+}
+
+#endif /* CONFIG_MCA */
+
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
{
@@ -642,25 +659,26 @@
dev->irq = irq;
dev->if_port = if_port;
lp = dev->priv;
- lp->mca_slot = -1;
- lp->edev = edev;
+ lp->dev = device;
+ lp->type = EL3_EISA;
eisa_set_drvdata (edev, dev);
return el3_common_init (dev);
}
+#endif
-static int __devexit el3_eisa_remove (struct device *device)
+/* This remove works for all device types.
+ *
+ * The net dev must be stored in the driver_data field */
+static int __devexit el3_device_remove (struct device *device)
{
- struct eisa_device *edev;
struct net_device *dev;
- edev = to_eisa_device (device);
- dev = eisa_get_drvdata (edev);
+ dev = device->driver_data;
el3_common_remove (dev);
return 0;
}
-#endif
/* Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
@@ -1080,7 +1098,7 @@
free_irq(dev->irq, dev);
/* Switching back to window 0 disables the IRQ. */
EL3WINDOW(0);
- if (!lp->edev) {
+ if (lp->type != EL3_EISA) {
/* But we explicitly zero the IRQ line select anyway. Don't do
* it on EISA cards, it prevents the module from getting an
* IRQ after unload+reload... */
@@ -1530,7 +1548,7 @@
static int __init el3_init_module(void)
{
- int el3_cards = 0;
+ el3_cards = 0;
if (debug >= 0)
el3_debug = debug;
@@ -1548,8 +1566,9 @@
if (eisa_driver_register (&el3_eisa_driver) < 0) {
eisa_driver_unregister (&el3_eisa_driver);
}
- else
- el3_cards++; /* Found an eisa card */
+#endif
+#ifdef CONFIG_MCA
+ mca_register_driver(&el3_mca_driver);
#endif
return el3_cards ? 0 : -ENODEV;
}
@@ -1568,6 +1587,9 @@
#ifdef CONFIG_EISA
eisa_driver_unregister (&el3_eisa_driver);
+#endif
+#ifdef CONFIG_MCA
+ mca_unregister_driver(&el3_mca_driver);
#endif
}
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c Sun Feb 2 22:04:26 2003
+++ b/drivers/net/Space.c Sun Feb 2 22:04:26 2003
@@ -224,6 +224,9 @@
#ifdef CONFIG_EL2 /* 3c503 */
{el2_probe, 0},
#endif
+#ifdef CONFIG_EL3
+ {el3_probe, 0},
+#endif
#ifdef CONFIG_HPLAN
{hp_probe, 0},
#endif
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] fix 3c509.c for MCA drivers
2003-02-03 3:09 [PATCH] fix 3c509.c for MCA drivers James Bottomley
@ 2003-02-08 17:25 ` Marc Zyngier
2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
1 sibling, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-02-08 17:25 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, jgarzik
[-- Attachment #1: Type: text/plain, Size: 553 bytes --]
>>>>> "James" == James Bottomley <James.Bottomley@steeleye.com> writes:
James> I've put the el3_probe back into Space.c for ISA only otherwise
James> the driver won't work for ISA (could someone with an ISA card
James> test this).
I've managed to finally get it to compile/work for ISA/ISA-PNP. I
checked the stuff was working properly *without* el3_probe in Space.c.
I also restored the 'ether=' functionality.
Anyway, this part of the code (ISA/ISA-PNP) is a real mess, and I wish
somebody who knows what he's doing would clean it up.
M.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 3c509.patch --]
[-- Type: text/x-patch, Size: 3257 bytes --]
===== drivers/net/3c509.c 1.25.1.5 vs 1.34 =====
--- 1.25.1.5/drivers/net/3c509.c Mon Feb 3 08:35:11 2003
+++ 1.34/drivers/net/3c509.c Sat Feb 8 17:17:14 2003
@@ -338,16 +338,6 @@
dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl;
-#ifdef CONFIG_PM
- /* register power management */
- lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
- if (lp->pmdev) {
- struct pm_dev *p;
- p = lp->pmdev;
- p->data = (struct net_device *)dev;
- }
-#endif
-
return 0;
}
@@ -417,6 +407,13 @@
phys_addr[j] =
htons(read_eeprom(ioaddr, j));
if_port = read_eeprom(ioaddr, 8) >> 14;
+ if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) {
+ release_region(ioaddr, EL3_IO_EXTENT);
+ pnp_device_detach(idev);
+ return -ENOMEM;
+ }
+
+ SET_MODULE_OWNER(dev);
pnp_cards++;
goto found;
}
@@ -497,24 +494,29 @@
}
irq = id_read_eeprom(9) >> 12;
-#if 0 /* Huh ?
- Can someone explain what is this for ? */
- if (dev) { /* Set passed-in IRQ or I/O Addr. */
- if (dev->irq > 1 && dev->irq < 16)
+ if (!(dev = init_etherdev(NULL, sizeof(struct el3_private))))
+ return -ENOMEM;
+
+ SET_MODULE_OWNER(dev);
+
+ /* Set passed-in IRQ or I/O Addr. */
+ if (dev->irq > 1 && dev->irq < 16)
irq = dev->irq;
- if (dev->base_addr) {
+ if (dev->base_addr) {
if (dev->mem_end == 0x3c509 /* Magic key */
&& dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
- ioaddr = dev->base_addr & 0x3f0;
- else if (dev->base_addr != ioaddr)
- return -ENODEV;
- }
+ ioaddr = dev->base_addr & 0x3f0;
+ else if (dev->base_addr != ioaddr) {
+ unregister_netdev (dev);
+ return -ENODEV;
+ }
}
-#endif
- if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
- return -EBUSY;
+ if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
+ unregister_netdev (dev);
+ return -EBUSY;
+ }
/* Set the adaptor tag so that the next card can be found. */
outb(0xd0 + ++current_tag, id_port);
@@ -524,19 +526,15 @@
EL3WINDOW(0);
if (inw(ioaddr) != 0x6d50) {
+ unregister_netdev (dev);
release_region(ioaddr, EL3_IO_EXTENT);
return -ENODEV;
}
/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
-
- dev = init_etherdev(NULL, sizeof(struct el3_private));
- if (dev == NULL) {
- release_region(ioaddr, EL3_IO_EXTENT);
- return -ENOMEM;
- }
- SET_MODULE_OWNER(dev);
+
+ found: /* PNP jumps here... */
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr;
@@ -545,6 +543,16 @@
lp = dev->priv;
#ifdef __ISAPNP__
lp->dev = &idev->dev;
+#endif
+
+#ifdef CONFIG_PM
+ /* register power management */
+ lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+ if (lp->pmdev) {
+ struct pm_dev *p;
+ p = lp->pmdev;
+ p->data = (struct net_device *)dev;
+ }
#endif
return el3_common_init (dev);
===== drivers/net/Space.c 1.11.1.5 vs 1.19 =====
--- 1.11.1.5/drivers/net/Space.c Mon Feb 3 08:35:11 2003
+++ 1.19/drivers/net/Space.c Sat Feb 8 17:18:21 2003
@@ -224,9 +224,6 @@
#ifdef CONFIG_EL2 /* 3c503 */
{el2_probe, 0},
#endif
-#ifdef CONFIG_EL3
- {el3_probe, 0},
-#endif
#ifdef CONFIG_HPLAN
{hp_probe, 0},
#endif
[-- Attachment #3: Type: text/plain, Size: 59 bytes --]
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] EISA/sysfs update
2003-02-03 3:09 [PATCH] fix 3c509.c for MCA drivers James Bottomley
2003-02-08 17:25 ` Marc Zyngier
@ 2003-02-14 10:16 ` Marc Zyngier
2003-02-14 14:32 ` Ivan Kokshaysky
2003-02-14 18:12 ` [PATCH] EISA/sysfs update Christoph Hellwig
1 sibling, 2 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-02-14 10:16 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 609 bytes --]
James, LKML,
Here is the latest round of EISA/sysfs hacking.
>From the changelog :
# EISA/sysfs update.
#
# - Separate bus root code from generic code.
# - Add driver for i82375 PCI/EISA bridge.
# - Hacked parisc eisa driver so it can act as a root device.
# - Add driver for so-called virtual root (for bridge-less systems).
# - Allow multiple roots.
I tested it on alpha (AS1000-4/200 and Jensen) and parisc (C100). The
parisc part really needs more work (I don't like the double probing at
all), but at least it is now useable.
I'd be happy to read any comment about this code.
Thanks,
M.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: EISA/sysfs update --]
[-- Type: text/x-patch, Size: 11621 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.994 -> 1.995
# drivers/parisc/eisa.c 1.4 -> 1.5
# drivers/eisa/eisa-bus.c 1.2 -> 1.3
# drivers/eisa/Kconfig 1.1 -> 1.2
# drivers/eisa/Makefile 1.2 -> 1.3
# include/linux/eisa.h 1.1 -> 1.2
# (new) -> 1.2 drivers/eisa/i82375.c
# (new) -> 1.2 drivers/eisa/virtual_root.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/14 maz@hina.wild-wind.fr.eu.org 1.995
# EISA/sysfs update.
#
# - Separate bus root code from generic code.
# - Add driver for i82375 PCI/EISA bridge.
# - Hacked parisc eisa driver so it can act as a root device.
# - Add driver for so-called virtual root (for bridge-less systems).
# - Allow multiple roots.
# --------------------------------------------
#
diff -Nru a/drivers/eisa/Kconfig b/drivers/eisa/Kconfig
--- a/drivers/eisa/Kconfig Fri Feb 14 11:14:39 2003
+++ b/drivers/eisa/Kconfig Fri Feb 14 11:14:39 2003
@@ -1,6 +1,27 @@
#
-# PCI configuration
+# EISA configuration
#
+config EISA_I82375
+ bool "Intel 82375 PCI/EISA bridge"
+ depends on PCI && EISA
+ default y
+ ---help---
+ Activate this option if your system contains an Intel 82375
+ PCI to EISA bridge.
+
+ 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
diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile
--- a/drivers/eisa/Makefile Fri Feb 14 11:14:39 2003
+++ b/drivers/eisa/Makefile Fri Feb 14 11:14:39 2003
@@ -1,6 +1,11 @@
# Makefile for the Linux device tree
-obj-$(CONFIG_EISA) += eisa-bus.o
+obj-$(CONFIG_EISA) += eisa-bus.o
+obj-${CONFIG_EISA_I82375} += i82375.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
diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- a/drivers/eisa/eisa-bus.c Fri Feb 14 11:14:39 2003
+++ b/drivers/eisa/eisa-bus.c Fri Feb 14 11:14:39 2003
@@ -15,6 +15,8 @@
#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 {
@@ -95,12 +97,6 @@
.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;
@@ -125,7 +121,8 @@
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;
@@ -135,11 +132,11 @@
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... :-( */
@@ -150,7 +147,7 @@
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);
@@ -167,16 +164,18 @@
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);
@@ -187,7 +186,7 @@
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");
@@ -195,20 +194,40 @@
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);
diff -Nru a/drivers/eisa/i82375.c b/drivers/eisa/i82375.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/i82375.c Fri Feb 14 11:14:39 2003
@@ -0,0 +1,61 @@
+/*
+ * Minimalist driver for the Intel 82375 PCI-to-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/pci.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+/* There is only *one* i82375 device per machine, right ? */
+static struct eisa_root_device i82375_root;
+
+static int __devinit i82375_init (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int rc;
+
+ if ((rc = pci_enable_device (pdev))) {
+ printk (KERN_INFO "i82375 : Could not enable device %s\n",
+ pdev->slot_name);
+ return rc;
+ }
+
+ i82375_root.dev = &pdev->dev;
+ i82375_root.dev->driver_data = &i82375_root;
+ i82375_root.bus_base_addr = 0; /* Warning, this is a x86-ism */
+ i82375_root.res = &ioport_resource;
+ i82375_root.slots = EISA_MAX_SLOTS;
+
+ if (eisa_root_register (&i82375_root)) {
+ printk (KERN_INFO "i82375 : Could not register EISA root\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static struct pci_device_id i82375_pci_tbl[] = {
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0, }
+};
+
+static struct pci_driver i82375_driver = {
+ .name = "i82375",
+ .id_table = i82375_pci_tbl,
+ .probe = i82375_init,
+};
+
+static int __init i82375_init_module (void)
+{
+ return pci_module_init (&i82375_driver);
+}
+
+device_initcall(i82375_init_module);
diff -Nru a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/virtual_root.c Fri Feb 14 11:14:39 2003
@@ -0,0 +1,49 @@
+/*
+ * 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);
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c Fri Feb 14 11:14:39 2003
+++ b/drivers/parisc/eisa.c Fri Feb 14 11:14:39 2003
@@ -35,6 +35,7 @@
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/eisa.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -61,6 +62,7 @@
static struct eisa_ba {
struct pci_hba_data hba;
unsigned long eeprom_addr;
+ struct eisa_root_device root;
} eisa_dev;
/* Port ops */
@@ -376,6 +378,20 @@
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 : Maybe we could get rid of io_space and only rely on
+ * lmmio_space, since all operations are already going through
+ * this region... Also get the number of slots from the
+ * enumerator, not a hadcoded value.*/
+ 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;
}
diff -Nru a/include/linux/eisa.h b/include/linux/eisa.h
--- a/include/linux/eisa.h Fri Feb 14 11:14:39 2003
+++ b/include/linux/eisa.h Fri Feb 14 11:14:39 2003
@@ -24,7 +24,8 @@
};
/* 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;
@@ -56,5 +57,19 @@
{
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
[-- Attachment #3: Type: text/plain, Size: 59 bytes --]
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
@ 2003-02-14 14:32 ` Ivan Kokshaysky
2003-02-14 15:32 ` Marc Zyngier
2003-02-14 18:12 ` [PATCH] EISA/sysfs update Christoph Hellwig
1 sibling, 1 reply; 12+ messages in thread
From: Ivan Kokshaysky @ 2003-02-14 14:32 UTC (permalink / raw)
To: Marc Zyngier; +Cc: James Bottomley, linux-kernel
On Fri, Feb 14, 2003 at 11:16:24AM +0100, Marc Zyngier wrote:
> # - Add driver for i82375 PCI/EISA bridge.
I believe this driver will work for any PCI/EISA bridge without
any changes, not only for i82375. Probably we need to look for a
class code rather than a device id.
Also, to get rid of that x86-ism I'd suggest something like
i82375_root.dev = &pdev->dev;
i82375_root.dev->driver_data = &i82375_root;
- i82375_root.bus_base_addr = 0; /* Warning, this is a x86-ism */
- i82375_root.res = &ioport_resource;
+ i82375_root.res = pdev->bus->resource[0];
+ i82375_root.bus_base_addr = pdev->bus->resource[0]->start;
i82375_root.slots = EISA_MAX_SLOTS;
Without that you'll have resource conflicts on multi-hose alphas.
Otherwise, the patch looks good to me.
Ivan.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 14:32 ` Ivan Kokshaysky
@ 2003-02-14 15:32 ` Marc Zyngier
2003-02-14 16:05 ` Ivan Kokshaysky
0 siblings, 1 reply; 12+ messages in thread
From: Marc Zyngier @ 2003-02-14 15:32 UTC (permalink / raw)
To: Ivan Kokshaysky; +Cc: James Bottomley, linux-kernel
>>>>> "Ivan" == Ivan Kokshaysky <ink@jurassic.park.msu.ru> writes:
Ivan> On Fri, Feb 14, 2003 at 11:16:24AM +0100, Marc Zyngier wrote:
>> # - Add driver for i82375 PCI/EISA bridge.
Ivan> I believe this driver will work for any PCI/EISA bridge without
Ivan> any changes, not only for i82375. Probably we need to look for a
Ivan> class code rather than a device id.
Unfortunately, the i82375 appears to be unclassified :
00:07.0 Non-VGA unclassified device: Intel Corp. 82375EB (rev 03)
I'll had PCI_CLASS_BRIDGE_EISA anyway, just in case.
Ivan> Also, to get rid of that x86-ism I'd suggest something like
Ivan> - i82375_root.bus_base_addr = 0; /* Warning, this is a x86-ism */
Ivan> - i82375_root.res = &ioport_resource;
Ivan> + i82375_root.res = pdev->bus->resource[0];
Ivan> + i82375_root.bus_base_addr = pdev->bus->resource[0]->start;
Ivan> i82375_root.slots = EISA_MAX_SLOTS;
Ivan> Without that you'll have resource conflicts on multi-hose alphas.
Applied, thanks.
M.
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 15:32 ` Marc Zyngier
@ 2003-02-14 16:05 ` Ivan Kokshaysky
2003-02-14 16:42 ` Marc Zyngier
2003-02-15 12:20 ` [PATCH] EISA/sysfs update, take #2 Marc Zyngier
0 siblings, 2 replies; 12+ messages in thread
From: Ivan Kokshaysky @ 2003-02-14 16:05 UTC (permalink / raw)
To: Marc Zyngier; +Cc: James Bottomley, linux-kernel
On Fri, Feb 14, 2003 at 04:32:50PM +0100, Marc Zyngier wrote:
> Ivan> I believe this driver will work for any PCI/EISA bridge without
> Ivan> any changes, not only for i82375. Probably we need to look for a
> Ivan> class code rather than a device id.
>
> Unfortunately, the i82375 appears to be unclassified :
>
> 00:07.0 Non-VGA unclassified device: Intel Corp. 82375EB (rev 03)
We have this code in arch/alpha/kernel/pci.c for ages:
...
static void __init
quirk_eisa_bridge(struct pci_dev *dev)
{
dev->class = PCI_CLASS_BRIDGE_EISA << 8;
}
...
struct pci_fixup pcibios_fixups[] __initdata = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
quirk_eisa_bridge },
...
I think it belongs in drivers/pci/quirks.c.
> I'll had PCI_CLASS_BRIDGE_EISA anyway, just in case.
Actually I thought of replacing "i82375" with "pci_eisa" everywhere
in your driver and
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, }
};
Ivan.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 16:05 ` Ivan Kokshaysky
@ 2003-02-14 16:42 ` Marc Zyngier
2003-02-15 12:20 ` [PATCH] EISA/sysfs update, take #2 Marc Zyngier
1 sibling, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-02-14 16:42 UTC (permalink / raw)
To: Ivan Kokshaysky; +Cc: James Bottomley, linux-kernel
>>>>> "Ivan" == Ivan Kokshaysky <ink@jurassic.park.msu.ru> writes:
Ivan> We have this code in arch/alpha/kernel/pci.c for ages:
[...]
Ivan> I think it belongs in drivers/pci/quirks.c.
Indeed, this would be a good thing for x86 boxes.
Ivan> Actually I thought of replacing "i82375" with "pci_eisa" everywhere
Ivan> in your driver and
[..]
Ok, I'll update the patch tonight, and will repost it.
Thanks,
M.
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
2003-02-14 14:32 ` Ivan Kokshaysky
@ 2003-02-14 18:12 ` Christoph Hellwig
2003-02-14 19:37 ` Marc Zyngier
1 sibling, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2003-02-14 18:12 UTC (permalink / raw)
To: Marc Zyngier; +Cc: James Bottomley, linux-kernel
On Fri, Feb 14, 2003 at 11:16:24AM +0100, Marc Zyngier wrote:
> James, LKML,
>
> Here is the latest round of EISA/sysfs hacking.
BTW, could you fix eisa_driver_register to properly return 0 on
sucess instead of 1?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update
2003-02-14 18:12 ` [PATCH] EISA/sysfs update Christoph Hellwig
@ 2003-02-14 19:37 ` Marc Zyngier
0 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-02-14 19:37 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: James Bottomley, linux-kernel
>>>>> "Christoph" == Christoph Hellwig <hch@infradead.org> writes:
Christoph> BTW, could you fix eisa_driver_register to properly return
Christoph> 0 on sucess instead of 1?
Huhhh... Nice catch.
Thanks,
M.
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] EISA/sysfs update, take #2
2003-02-14 16:05 ` Ivan Kokshaysky
2003-02-14 16:42 ` Marc Zyngier
@ 2003-02-15 12:20 ` Marc Zyngier
1 sibling, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-02-15 12:20 UTC (permalink / raw)
To: Ivan Kokshaysky; +Cc: James Bottomley, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 256 bytes --]
Folks,
Here is the updated EISA/sysfs patch, with the corrections discussed
yesterday (using PCI_CLASS_BRIDGE_EISA, moving quirk_eisa_bridge from
alpha to generic code, eisa_driver_register return value, as well as a
3C59x EISA probing fix).
M.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: eisa-drivers.patch --]
[-- Type: text/x-patch, Size: 15388 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.994 -> 1.998
# drivers/net/3c59x.c 1.31 -> 1.32
# drivers/parisc/eisa.c 1.4 -> 1.6
# drivers/pci/quirks.c 1.22 -> 1.23
# arch/alpha/kernel/pci.c 1.22 -> 1.23
# drivers/eisa/eisa-bus.c 1.2 -> 1.4
# drivers/eisa/Kconfig 1.1 -> 1.3
# drivers/eisa/Makefile 1.2 -> 1.4
# include/linux/eisa.h 1.1 -> 1.2
# (new) -> 1.4 drivers/eisa/pci_eisa.c
# (new) -> 1.2 drivers/eisa/virtual_root.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/14 maz@hina.wild-wind.fr.eu.org 1.995
# EISA/sysfs update.
#
# - Separate bus root code from generic code.
# - Add driver for i82375 PCI/EISA bridge.
# - Hacked parisc eisa driver so it can act as a root device.
# - Add driver for so-called virtual root (for bridge-less systems).
# - Allow multiple roots.
# --------------------------------------------
# 03/02/15 maz@hina.wild-wind.fr.eu.org 1.996
# Moved quirk_eisa_bridge from alpha to generic code,
# since the EISA code needs it now.
# --------------------------------------------
# 03/02/15 maz@hina.wild-wind.fr.eu.org 1.997
# Use PCI_CLASS_BRIDGE_EISA instead of i82375 ID.
# A few fixes all over the map.
# --------------------------------------------
# 03/02/15 maz@hina.wild-wind.fr.eu.org 1.998
# 3c59x :
# Prevent driver from returning ENODEV in case it has registered with the EISA
# framework, but no device has been found yet (it happends when the driver is
# built into the kernel, and the EISA bus root has not been discovered yet).
# --------------------------------------------
#
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c Sat Feb 15 12:56:07 2003
+++ b/arch/alpha/kernel/pci.c Sat Feb 15 12:56:07 2003
@@ -57,12 +57,6 @@
*/
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)
{
dev->class = PCI_CLASS_BRIDGE_ISA << 8;
@@ -125,8 +119,6 @@
}
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,
diff -Nru a/drivers/eisa/Kconfig b/drivers/eisa/Kconfig
--- a/drivers/eisa/Kconfig Sat Feb 15 12:56:07 2003
+++ b/drivers/eisa/Kconfig Sat Feb 15 12:56:07 2003
@@ -1,6 +1,28 @@
#
-# 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
diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile
--- a/drivers/eisa/Makefile Sat Feb 15 12:56:07 2003
+++ b/drivers/eisa/Makefile Sat Feb 15 12:56:07 2003
@@ -1,6 +1,11 @@
# 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
diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- a/drivers/eisa/eisa-bus.c Sat Feb 15 12:56:07 2003
+++ b/drivers/eisa/eisa-bus.c Sat Feb 15 12:56:07 2003
@@ -15,6 +15,8 @@
#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 {
@@ -95,12 +97,6 @@
.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;
@@ -109,7 +105,7 @@
if ((r = driver_register (&edrv->driver)) < 0)
return r;
- return 1;
+ return 0;
}
void eisa_driver_unregister (struct eisa_driver *edrv)
@@ -125,7 +121,8 @@
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;
@@ -135,11 +132,11 @@
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... :-( */
@@ -150,7 +147,7 @@
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);
@@ -167,16 +164,18 @@
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);
@@ -187,7 +186,7 @@
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");
@@ -195,20 +194,40 @@
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);
diff -Nru a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/pci_eisa.c Sat Feb 15 12:56:07 2003
@@ -0,0 +1,64 @@
+/*
+ * 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);
diff -Nru a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/virtual_root.c Sat Feb 15 12:56:07 2003
@@ -0,0 +1,49 @@
+/*
+ * 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);
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c Sat Feb 15 12:56:07 2003
+++ b/drivers/net/3c59x.c Sat Feb 15 12:56:07 2003
@@ -1007,6 +1007,7 @@
/* 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. */
@@ -1014,8 +1015,14 @@
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
@@ -1025,7 +1032,7 @@
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 */
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c Sat Feb 15 12:56:07 2003
+++ b/drivers/parisc/eisa.c Sat Feb 15 12:56:07 2003
@@ -35,6 +35,7 @@
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/eisa.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -61,6 +62,7 @@
static struct eisa_ba {
struct pci_hba_data hba;
unsigned long eeprom_addr;
+ struct eisa_root_device root;
} eisa_dev;
/* Port ops */
@@ -376,6 +378,18 @@
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;
}
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c Sat Feb 15 12:56:07 2003
+++ b/drivers/pci/quirks.c Sat Feb 15 12:56:07 2003
@@ -535,6 +535,15 @@
}
}
+/* 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.
*/
@@ -604,6 +613,7 @@
{ 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 }
};
diff -Nru a/include/linux/eisa.h b/include/linux/eisa.h
--- a/include/linux/eisa.h Sat Feb 15 12:56:07 2003
+++ b/include/linux/eisa.h Sat Feb 15 12:56:07 2003
@@ -24,7 +24,8 @@
};
/* 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;
@@ -56,5 +57,19 @@
{
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
[-- Attachment #3: Type: text/plain, Size: 59 bytes --]
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] EISA/sysfs update
@ 2003-04-21 16:48 Marc Zyngier
0 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-04-21 16:48 UTC (permalink / raw)
To: torvalds; +Cc: linux-kernel
Linus,
The included patch cleans up the EISA code :
- Documentation update,
- Remove i386 EISA ID reservation (handled in the generic code),
- Add some preliminary support for EISA-like VLB cards (Adaptec 287x),
- Add some stricter dependancies on EISA_VIRTUAL_ROOT
- Preliminary support for EISA DMA,
- Much more conservative probing,
- EISA IDs list update (Compaq stuff).
Please apply.
M.
diff -ruN linux/Documentation/eisa.txt linux-eisa/Documentation/eisa.txt
--- linux/Documentation/eisa.txt 2003-04-21 18:10:21.000000000 +0200
+++ linux-eisa/Documentation/eisa.txt 2003-04-21 18:21:26.000000000 +0200
@@ -79,8 +79,9 @@
};
id_table : an array of NULL terminated EISA id strings,
- followed by an empty string. Each string can be
- paired with a driver-dependant value (driver_data).
+ followed by an empty string. Each string can
+ optionnaly be paired with a driver-dependant value
+ (driver_data).
driver : a generic driver, such as described in
Documentation/driver-model/driver.txt. Only .name,
@@ -88,19 +89,19 @@
An example is the 3c509 driver :
-struct eisa_device_id el3_eisa_ids[] = {
- { "TCM5092" },
- { "TCM5093" },
- { "" }
+static struct eisa_device_id vortex_eisa_ids[] = {
+ { "TCM5920", EISA_3C592_OFFSET },
+ { "TCM5970", EISA_3C597_OFFSET },
+ { "" }
};
-struct eisa_driver el3_eisa_driver = {
- .id_table = el3_eisa_ids,
- .driver = {
- .name = "3c509",
- .probe = el3_eisa_probe,
- .remove = __devexit_p (el3_device_remove)
- }
+static struct eisa_driver vortex_eisa_driver = {
+ .id_table = vortex_eisa_ids,
+ .driver = {
+ .name = "3c59x",
+ .probe = vortex_eisa_probe,
+ .remove = vortex_eisa_remove
+ }
};
** Device :
diff -ruN linux/arch/i386/kernel/traps.c linux-eisa/arch/i386/kernel/traps.c
--- linux/arch/i386/kernel/traps.c 2003-04-21 18:07:11.000000000 +0200
+++ linux-eisa/arch/i386/kernel/traps.c 2003-04-21 18:19:26.000000000 +0200
@@ -833,7 +833,6 @@
#ifdef CONFIG_EISA
int EISA_bus;
-static struct resource eisa_id = { "EISA ID", 0xc80, 0xc83, IORESOURCE_BUSY };
#endif
void __init trap_init(void)
@@ -841,8 +840,6 @@
#ifdef CONFIG_EISA
if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
EISA_bus = 1;
- if (request_resource(&ioport_resource, &eisa_id) == -EBUSY)
- printk ("EISA port was EBUSY :-(\n");
}
#endif
diff -ruN linux/drivers/eisa/Kconfig linux-eisa/drivers/eisa/Kconfig
--- linux/drivers/eisa/Kconfig 2003-04-21 18:07:58.000000000 +0200
+++ linux-eisa/drivers/eisa/Kconfig 2003-04-21 18:20:23.000000000 +0200
@@ -1,6 +1,17 @@
#
# EISA configuration
#
+config EISA_VLB_PRIMING
+ bool "Vesa Local Bus priming"
+ depends on X86_PC && EISA
+ default n
+ ---help---
+ Activate this option if your system contains a Vesa Local
+ Bus (VLB) card that identify itself as an EISA card (such as
+ the Adaptec AHA-284x).
+
+ When in doubt, say N.
+
config EISA_PCI_EISA
bool "Generic PCI/EISA bridge"
depends on PCI && EISA
@@ -12,9 +23,12 @@
When in doubt, say Y.
+# Using EISA_VIRTUAL_ROOT on something other than an Alpha or
+# an X86_PC may lead to crashes...
+
config EISA_VIRTUAL_ROOT
bool "EISA virtual root device"
- depends on EISA
+ depends on EISA && (ALPHA || X86_PC)
default y
---help---
Activate this option if your system only have EISA bus
diff -ruN linux/drivers/eisa/Makefile linux-eisa/drivers/eisa/Makefile
--- linux/drivers/eisa/Makefile 2003-04-21 18:09:25.000000000 +0200
+++ linux-eisa/drivers/eisa/Makefile 2003-04-21 18:21:18.000000000 +0200
@@ -1,5 +1,8 @@
# Makefile for the Linux device tree
+# Being anal sometimes saves a crash/reboot cycle... ;-)
+EXTRA_CFLAGS := -Werror
+
obj-$(CONFIG_EISA) += eisa-bus.o
obj-${CONFIG_EISA_PCI_EISA} += pci_eisa.o
diff -ruN linux/drivers/eisa/eisa-bus.c linux-eisa/drivers/eisa/eisa-bus.c
--- linux/drivers/eisa/eisa-bus.c 2003-04-21 18:07:49.000000000 +0200
+++ linux-eisa/drivers/eisa/eisa-bus.c 2003-04-21 18:20:17.000000000 +0200
@@ -56,13 +56,22 @@
u16 rev;
int i;
- sig[0] = inb (addr);
-
- if (sig[0] & 0x80)
- return NULL;
-
- for (i = 1; i < 4; i++)
+ for (i = 0; i < 4; i++) {
+#ifdef CONFIG_EISA_VLB_PRIMING
+ /*
+ * This ugly stuff is used to wake up VL-bus cards
+ * (AHA-284x is the only known example), so we can
+ * read the EISA id.
+ *
+ * Thankfully, this only exists on x86...
+ */
+ outb(0x80 + i, addr);
+#endif
sig[i] = inb (addr + i);
+
+ if (!i && (sig[0] & 0x80))
+ return NULL;
+ }
sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
@@ -123,47 +132,28 @@
static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
-static void __init eisa_register_device (struct eisa_root_device *root,
- char *sig, int slot)
+static int __init eisa_register_device (struct eisa_root_device *root,
+ struct eisa_device *edev,
+ char *sig, int slot)
{
- struct eisa_device *edev;
-
- if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL)))
- return;
-
- memset (edev, 0, sizeof (*edev));
- memcpy (edev->id.sig, sig, 7);
+ memcpy (edev->id.sig, sig, EISA_SIG_LEN);
edev->slot = slot;
edev->base_addr = SLOT_ADDRESS (root, slot);
+ edev->dma_mask = 0xffffffff; /* Default DMA mask */
eisa_name_device (edev);
edev->dev.parent = root->dev;
edev->dev.bus = &eisa_bus_type;
+ edev->dev.dma_mask = &edev->dma_mask;
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.name = edev->dev.name;
- if (slot) {
- edev->res.name = edev->dev.name;
- edev->res.start = edev->base_addr;
- edev->res.end = edev->res.start + 0xfff;
- edev->res.flags = IORESOURCE_IO;
-
- if (request_resource (root->res, &edev->res)) {
- printk (KERN_WARNING \
- "Cannot allocate resource for EISA slot %d\n",
- slot);
- kfree (edev);
- return;
- }
- }
-
- if (device_register (&edev->dev)) {
- kfree (edev);
- return;
- }
+ if (device_register (&edev->dev))
+ return -1;
device_create_file (&edev->dev, &dev_attr_signature);
+
+ return 0;
}
static int __init eisa_probe (struct eisa_root_device *root)
@@ -171,54 +161,106 @@
int i, c;
char *str;
unsigned long sig_addr;
+ struct eisa_device *edev;
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);
- else {
- printk (KERN_INFO "EISA: slot %d : %s detected.\n",
- i, str);
+ if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+ printk (KERN_ERR "EISA: Out of memory for slot %d\n",
+ i);
+ continue;
+ }
+
+ memset (edev, 0, sizeof (*edev));
- c++;
- }
+ /* Don't register resource for slot 0, since this is
+ * very likely to fail... :-( Instead, grab the EISA
+ * id, now we can display something in /proc/ioports.
+ */
+
+ if (i) {
+ edev->res.name = NULL;
+ edev->res.start = SLOT_ADDRESS (root, i);
+ edev->res.end = edev->res.start + 0xfff;
+ edev->res.flags = IORESOURCE_IO;
+ } else {
+ edev->res.name = NULL;
+ edev->res.start = SLOT_ADDRESS (root, i) + EISA_VENDOR_ID_OFFSET;
+ edev->res.end = edev->res.start + 3;
+ edev->res.flags = IORESOURCE_BUSY;
+ }
+
+ if (request_resource (root->res, &edev->res)) {
+ printk (KERN_WARNING \
+ "Cannot allocate resource for EISA slot %d\n",
+ i);
+ kfree (edev);
+ continue;
+ }
+
+ sig_addr = SLOT_ADDRESS (root, i) + EISA_VENDOR_ID_OFFSET;
+
+ if (!(str = decode_eisa_sig (sig_addr))) {
+ release_resource (&edev->res);
+ kfree (edev);
+ continue;
+ }
+
+ if (!i)
+ printk (KERN_INFO "EISA: Motherboard %s detected\n",
+ str);
+ else {
+ printk (KERN_INFO "EISA: slot %d : %s detected.\n",
+ i, str);
- eisa_register_device (root, str, i);
- }
+ c++;
+ }
+
+ if (eisa_register_device (root, edev, str, i)) {
+ printk (KERN_ERR "EISA: Failed to register %s\n", str);
+ release_resource (&edev->res);
+ kfree (edev);
+ }
}
printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
return 0;
}
-
-static LIST_HEAD (eisa_root_head);
+static struct resource eisa_root_res = {
+ .name = "EISA root resource",
+ .start = 0,
+ .end = 0xffffffff,
+ .flags = IORESOURCE_IO,
+};
static int eisa_bus_count;
-int eisa_root_register (struct eisa_root_device *root)
+int __init eisa_root_register (struct eisa_root_device *root)
{
- struct list_head *node;
- struct eisa_root_device *tmp_root;
+ int err;
- /* 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... */
- }
+ /* Use our own resources to 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... */
+
+ root->eisa_root_res.name = eisa_root_res.name;
+ root->eisa_root_res.start = root->res->start;
+ root->eisa_root_res.end = root->res->end;
+ root->eisa_root_res.flags = IORESOURCE_BUSY;
+
+ if ((err = request_resource (&eisa_root_res, &root->eisa_root_res)))
+ return err;
root->bus_nr = eisa_bus_count++;
- list_add_tail (&root->node, &eisa_root_head);
- return eisa_probe (root);
+
+ if ((err = eisa_probe (root)))
+ release_resource (&root->eisa_root_res);
+
+ return err;
}
static int __init eisa_init (void)
diff -ruN linux/drivers/eisa/eisa.ids linux-eisa/drivers/eisa/eisa.ids
--- linux/drivers/eisa/eisa.ids 2003-04-21 18:05:41.000000000 +0200
+++ linux-eisa/drivers/eisa/eisa.ids 2003-04-21 18:19:07.000000000 +0200
@@ -162,6 +162,17 @@
CPQ0501 "Compaq DESKPRO/M System Board"
CPQ0509 "Compaq DESKPRO/M System Board with Audio"
CPQ0511 "Compaq SYSTEMPRO/LT System Board"
+CPQ0521 "Compaq DESKPRO XL System Board"
+CPQ0531 "Compaq ProSignia 500 System Board"
+CPQ0541 "Compaq ProSignia 300 System Board"
+CPQ0551 "Compaq ProLiant 2500 Server"
+CPQ0552 "Compaq ProLiant 2500 System Board"
+CPQ0553 "Compaq ProLiant 1600 System Board"
+CPQ0559 "Compaq ProLiant 1500 System Board"
+CPQ0561 "Compaq ProLiant 3000 System Board"
+CPQ0571 "Compaq ProSignia 200 Server"
+CPQ0579 "Compaq ProLiant 800 Server"
+CPQ0589 "Compaq ProLiant 850R"
CPQ0601 "Compaq ProSignia Server"
CPQ0609 "Compaq ProSignia Server"
CPQ0611 "Compaq ProSignia Server"
@@ -169,6 +180,30 @@
CPQ0629 "Compaq ProSignia Server (ASSY # 3154)"
CPQ0631 "Compaq ProLiant 1000 Server"
CPQ0639 "Compaq ProLiant 1000 Server"
+CPQ0671 "Compaq ProSignia 200"
+CPQ0679 "Compaq ProLiant 1850R"
+CPQ0680 "Compaq ProLiant CL1850 System Board"
+CPQ0681 "ProLiant CL380"
+CPQ0685 "Compaq ProLiant DL360"
+CPQ0686 "Compaq ProSignia 780"
+CPQ0687 "Compaq ProSignia 740"
+CPQ0688 "Compaq ProLiant 800 System Board"
+CPQ0689 "Compaq ProLiant 1600 System Board"
+CPQ0690 "Compaq ProLiant ML370"
+CPQ0691 "Compaq ProLiant 800"
+CPQ0692 "Compaq ProLiant DL380"
+CPQ0701 "Compaq ProSignia VS"
+CPQ0709 "Compaq ProLiant 3000 System Board"
+CPQ0711 "Compaq ProSignia VS"
+CPQ0712 "Compaq ProLiant ML530"
+CPQ0714 "Compaq ProLiant ML570"
+CPQ0715 "Compaq ProLiant DL580"
+CPQ0718 "Compaq TaskSmart N2400"
+CPQ071D "Compaq TaskSmart C2500"
+CPQ0808 "Compaq ProLiant 5500"
+CPQ0809 "Compaq ProLiant 6500 System Board"
+CPQ0810 "Compaq ProLiant 6400R System Board"
+CPQ0811 "Compaq ProLiant 1500 System Board"
CPQ1001 "Compaq Portable 486"
CPQ1009 "Compaq Portable 486/66"
CPQ1201 "Compaq DESKPRO 486/25"
@@ -178,6 +213,16 @@
CPQ1501 "Compaq SYSTEMPRO/XL Server"
CPQ1509 "Compaq ProLiant 4000 Server"
CPQ1519 "Compaq ProLiant 2000 Server"
+CPQ1529 "Compaq ProLiant 4500 Server"
+CPQ1561 "Compaq ProLiant 5000 System Board"
+CPQ1563 "Compaq ProLiant 6000 System Board"
+CPQ1565 "Compaq ProLiant 6500 System Board"
+CPQ1601 "Compaq ProLiant 7000"
+CPQ1602 "Compaq ProLiant 6000"
+CPQ1603 "Compaq Standard Peripherals Board"
+CPQ1608 "Compaq ProLiant 8500"
+CPQ1609 "Compaq ProLiant 8000"
+CPQ1669 "Compaq ProLiant 7000 System Board"
CPQ3001 "Compaq Advanced VGA"
CPQ3011 "Compaq QVision 1024/E Video Controller"
CPQ3021 "Compaq QVision 1024/I Video Controller"
@@ -189,27 +234,43 @@
CPQ4002 "Compaq Intelligent Drive Array Controller-2"
CPQ4010 "Compaq 32-Bit Intelligent Drive Array Expansion Controller"
CPQ4020 "Compaq SMART Array Controller"
+CPQ4030 "Compaq SMART-2/E Array Controller"
CPQ4300 "Compaq Advanced ESDI Fixed Disk Controller"
CPQ4401 "Compaq Integrated SCSI-2 Options Port"
CPQ4410 "Compaq Integrated 32-Bit Fast-SCSI-2 Controller"
CPQ4411 "Compaq 32-Bit Fast-SCSI-2 Controller"
CPQ4420 "Compaq 6260 SCSI-2 Controller"
+CPQ4430 "Compaq 32-Bit Fast-Wide SCSI-2/E Controller"
+CPQ4431 "Compaq 32-Bit Fast-Wide SCSI-2/E Controller"
CPQ5000 "Compaq 386/33 System Processor Board used as Secondary"
+CPQ5251 "Compaq 5/133 System Processor Board-2MB"
+CPQ5253 "Compaq 5/166 System Processor Board-2MB"
+CPQ5255 "Compaq 5/133 System Processor Board-1MB"
+CPQ525D "Compaq 5/100 System Processor Board-1MB"
CPQ5281 "Compaq 486/50 System Processor Board used as Secondary"
CPQ5282 "Compaq 486/50 System Processor Board used as Secondary"
CPQ5287 "Compaq 5/66 System Processor Board used as Secondary"
+CPQ528A "Compaq 5/100 System Processor Board w/ Transaction Blaster"
+CPQ528B "Compaq 5/100 System Processor Board"
CPQ528F "Compaq 486DX2/66 System Processor Board used as Secondary"
+CPQ529B "Compaq 5/90 System Processor Board"
+CPQ529F "Compaq 5/133 System Processor Board"
+CPQ52A0 "Compaq System Processor"
CPQ5900 "Compaq 486/33 System Processor Board used as Secondary"
CPQ5A00 "Compaq 486/33 System Processor Board (ASSY # 002013) used as Secondary"
CPQ5B00 "Compaq 486DX2/66 System Processor Board used as Secondary"
CPQ5C00 "Compaq 486/33 System Processor Board used as Secondary"
CPQ6000 "Compaq 32-Bit DualSpeed Token Ring Controller"
CPQ6001 "Compaq 32-Bit DualSpeed Token Ring Controller"
-CPQ6100 "Compaq 32-Bit NetFlex Controller"
+CPQ6002 "Compaq NetFlex-2 TR"
+CPQ6100 "Compaq NetFlex ENET-TR"
CPQ6101 "Compaq NetFlex-2 Controller"
CPQ6200 "Compaq DualPort Ethernet Controller"
+CPQ6300 "Compaq NetFlex-2 DualPort TR"
CPQ7000 "Compaq 32-Bit Server Manager/R Board"
CPQ7001 "Compaq 32-Bit Server Manager/R Board"
+CPQ7100 "Compaq Remote Insight Board"
+CPQ7200 "Compaq StorageWorks Fibre Channel Host Bus Adapter/E"
CPQ9004 "Compaq 386/33 Processor Board"
CPQ9005 "Compaq 386/25 Processor Board"
CPQ9013 "Compaq 486DX2/66 System Processor Board used as Primary"
@@ -232,16 +293,60 @@
CPQ9045 "Compaq 5/60 Processor Board"
CPQ9046 "Compaq 5/60 Processor Board"
CPQ9047 "Compaq 5/60 Processor Board"
+CPQ9251 "Compaq 5/133 System Processor Board-2MB"
+CPQ9253 "Compaq 5/166 System Processor Board-2MB"
+CPQ9255 "Compaq 5/133 System Processor Board-1MB"
+CPQ925D "Compaq 5/100 System Processor Board-1MB"
+CPQ925F "ProLiant 2500 Dual Pentium Pro Processor Board"
+CPQ9267 "Compaq Pentium II Processor Board"
+CPQ9278 "Compaq Processor Board"
+CPQ9279 "Compaq Processor Board"
+CPQ9280 "Compaq Processor Board"
CPQ9281 "Compaq 486/50 System Processor Board used as Primary"
CPQ9282 "Compaq 486/50 System Processor Board used as Primary"
+CPQ9283 "Processor Modules"
+CPQ9285 "Processor Modules"
+CPQ9286 "Compaq Slot-1 Terminator Board"
CPQ9287 "Compaq 5/66 System Processor Board used as Primary"
+CPQ928A "Compaq 5/100 System Processor Board w/ Transaction Blaster"
+CPQ928B "Compaq 5/100 System Processor Board"
CPQ928F "Compaq 486DX2/66 System Processor Board used as Primary"
+CPQ929B "Compaq 5/90 System Processor Board"
+CPQ929F "Compaq 5/133 System Processor Board"
+CPQ92A0 "Compaq ProLiant 1500 Processor Board"
+CPQ92A4 "Compaq System Processor Board"
+CPQ92B0 "Compaq Processor Board"
+CPQ92B1 "Compaq FRC Processor Board"
+CPQ92B2 "Compaq Terminator Board"
+CPQ92B3 "6/200 FlexSMP Dual Processor Board"
+CPQ92B4 "Compaq Processor Board"
+CPQ92B5 "Compaq Terminator Board"
+CPQ92B6 "Compaq Processor Board"
+CPQ92B7 "Compaq Processor(s)"
+CPQ92B8 "Compaq Terminator Board"
+CPQ92B9 "Compaq Terminator Board"
+CPQ9351 "Compaq 5/133 System Processor Board-2MB"
+CPQ9353 "Compaq 5/166 System Processor Board-2MB"
+CPQ9355 "Compaq 5/133 System Processor Board-1MB"
+CPQ935D "Compaq 5/100 System Processor Board-1MB"
CPQ9381 "Compaq 486/50 System Processor Board"
CPQ9382 "Compaq 486/50 System Processor Board"
CPQ9387 "Compaq 5/66 System Processor Board"
+CPQ938A "Compaq 5/100 System Processor Board w/ Transaction Blaster"
+CPQ938B "Compaq 5/100 System Processor Board"
+CPQ939B "Compaq 5/90 System Processor Board"
+CPQ939F "Compaq 5/133 System Processor Board"
+CPQ9451 "Compaq 5/133 System Processor Board-2MB"
+CPQ9453 "Compaq 5/166 System Processor Board-2MB"
+CPQ9455 "Compaq 5/133 System Processor Board-1MB"
+CPQ945D "Compaq 5/100 System Processor Board-1MB"
CPQ9481 "Compaq 486/50 System Processor Board"
CPQ9482 "Compaq 486/50 System Processor Board"
CPQ9487 "Compaq 5/66 System Processor Board"
+CPQ948A "Compaq 5/100 System Processor Board w/ Transaction Blaster"
+CPQ948B "Compaq 5/100 System Processor Board"
+CPQ949B "Compaq 5/90 System Processor Board"
+CPQ949F "Compaq 5/133 System Processor Board"
CPQ9901 "Compaq 486SX/16 Processor Board"
CPQ9902 "Compaq 486SX/16 Processor Board"
CPQ9903 "Compaq 486SX/25 Processor Board"
@@ -261,12 +366,21 @@
CPQ9991 "Compaq 386/33 Desktop Processor Board"
CPQ9999 "Compaq 486/33 System Processor Board used as Primary"
CPQ999A "Compaq 486/33 Desktop Processor Board"
+CPQ9A83 "Compaq DESKPRO XL Processor Board"
+CPQ9AA1 "Compaq ProSignia 500 Processor Board"
+CPQ9AA2 "Compaq ProSignia 300 Processor Board"
CPQA000 "Compaq Enhanced Option Slot Serial Board"
CPQA010 "Compaq Enhanced Option Slot Modem Board"
+CPQA015 "Compaq Integrated Remote Console (IRC)"
CPQA020 "Compaq Integrated CD Rom Adapter"
CPQA030 "Compaq Integrated CD Rom Adapter"
+CPQA040 "Compaq Automatic Server Recovery (ASR)"
+CPQA045 "Compaq Integrated Management Display Information"
CPQF000 "Compaq Fixed Disk Drive Feature"
CPQF100 "Compaq Ethernet 16TP Controller"
+CPQF110 "Compaq Token Ring 16TR Controller"
+CPQF120 "Compaq NetFlex-3/E Controller"
+CPQF140 "Compaq NetFlex-3/E Controller"
CPQFA0D "Compaq SYSTEMPRO 4-Socket System Memory Board"
CPQFA0E "Compaq SYSTEMPRO 6-Socket System Memory Board"
CPQFA0F "Compaq DESKPRO 486/25 System Memory Board"
@@ -274,8 +388,11 @@
CPQFA1B "Compaq DESKPRO 486/50 System Memory Board"
CPQFA1C "Compaq System Memory Expansion Board"
CPQFA1D "Compaq SYSTEMPRO/XL Memory Expansion Board"
+CPQFA1E "Compaq Memory Expansion Board"
CPQFB03 "Compaq Async/Parallel Printer Intf Assy 000990"
CPQFB07 "Compaq DESKPRO 2400 Baud Modem"
+CPQFB09 "Compaq SpeedPaq 144/I Modem"
+CPQFB11 "Compaq Internal 28.8/33.6 Data+Fax Modem"
CPQFC0B "Compaq Advanced Graphics 1024 Board"
CPQFD08 "Compaq 135Mb, 150/250Mb Tape Adapter"
CPQFD13 "Compaq 15MHz ESDI Fixed Disk Controller 001283"
diff -ruN linux/include/linux/eisa.h linux-eisa/include/linux/eisa.h
--- linux/include/linux/eisa.h 2003-04-21 18:11:17.000000000 +0200
+++ linux-eisa/include/linux/eisa.h 2003-04-21 18:22:28.000000000 +0200
@@ -25,13 +25,15 @@
};
/* 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. dma_mask is set by
+ * default to 32 bits.*/
struct eisa_device {
struct eisa_device_id id;
int slot;
unsigned long base_addr;
struct resource res;
+ u64 dma_mask;
struct device dev; /* generic device */
};
@@ -63,12 +65,12 @@
* 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 */
+ struct resource eisa_root_res; /* ditto */
};
int eisa_root_register (struct eisa_root_device *root);
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] EISA/sysfs update
@ 2003-03-05 14:22 Marc Zyngier
0 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2003-03-05 14:22 UTC (permalink / raw)
To: linux-kernel; +Cc: torvalds
[-- Attachment #1: Type: text/plain, Size: 267 bytes --]
LKML, Linus,
Here is the latest round of EISA/sysfs update.
>From the changelog :
# EISA/sysfs update :
# Add documentation,
# Add support for per EISA-id driver data,
# Move virtual_root device to a plateform device,
# Update CREDITS.
Thanks a lot,
M.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: EISA/sysfs update --]
[-- Type: text/x-patch, Size: 9790 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1037 -> 1.1038
# drivers/eisa/eisa-bus.c 1.5 -> 1.6
# CREDITS 1.77 -> 1.78
# drivers/eisa/virtual_root.c 1.1 -> 1.2
# include/linux/eisa.h 1.3 -> 1.4
# (new) -> 1.1 Documentation/eisa.txt
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/03/05 maz@hina.wild-wind.fr.eu.org 1.1038
# EISA/sysfs update :
# Add documentation,
# Add support for per EISA-id driver data,
# Move virtual_root device to a plateform device,
# Update CREDITS.
# --------------------------------------------
#
diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS Wed Mar 5 15:11:17 2003
+++ b/CREDITS Wed Mar 5 15:11:17 2003
@@ -3492,9 +3492,9 @@
N: Marc Zyngier
E: maz@wild-wind.fr.eu.org
+W: http://www.misterjones.org
D: MD driver
-S: 11 rue Victor HUGO
-S: 95560 Montsoult
+D: EISA/sysfs subsystem
S: France
# Don't add your name here, unless you really _are_ after Marc
diff -Nru a/Documentation/eisa.txt b/Documentation/eisa.txt
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/Documentation/eisa.txt Wed Mar 5 15:11:17 2003
@@ -0,0 +1,164 @@
+EISA bus support (Marc Zyngier <maz@wild-wind.fr.eu.org>)
+
+This document groups random notes about porting EISA drivers to the
+new EISA/sysfs API.
+
+Starting from version 2.5.59, the EISA bus is almost given the same
+status as other much more mainstream busses such as PCI or USB. This
+has been possible through sysfs, which defines a nice enough set of
+abstractions to manage busses, devices and drivers.
+
+Although the new API is quite simple to use, converting existing
+drivers to the new infrastructure is not an easy task (mostly because
+detection code is generally also used to probe ISA cards). Moreover,
+most EISA drivers are among the oldest Linux drivers so, as you can
+imagine, some dust has settled here over the years.
+
+The EISA infrastructure is made up of three parts :
+
+ - The bus code implements most of the generic code. It is shared
+ among all the architectures that the EISA code runs on. It
+ implements bus probing (detecting EISA cards avaible on the bus),
+ allocates I/O resources, allows fancy naming through sysfs, and
+ offers interfaces for driver to register.
+
+ - The bus root driver implements the glue between the bus hardware
+ and the generic bus code. It is responsible for discovering the
+ device implementing the bus, and setting it up to be latter probed
+ by the bus code. This can go from something as simple as reserving
+ an I/O region on x86, to the rather more complex, like the hppa
+ EISA code. This is the part to implement in order to have EISA
+ running on an "new" platform.
+
+ - The driver offers the bus a list of devices that it manages, and
+ implements the necessary callbacks to probe and release devices
+ whenever told to.
+
+Every function/structure below lives in <linux/eisa.h>, which depends
+heavily on <linux/device.h>.
+
+** Bus root driver :
+
+int eisa_root_register (struct eisa_root_device *root);
+
+The eisa_root_register function is used to declare a device as the
+root of an EISA bus. The eisa_root_device structure holds a reference
+to this device, as well as some parameters for probing purposes.
+
+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 */
+};
+
+node : used for eisa_root_register internal purpose
+dev : pointer to the root device
+res : root device I/O resource
+bus_base_addr : slot 0 address on this bus
+slots : max slot number to probe
+bus_nr : unique bus id, set by eisa_root_register
+
+** Driver :
+
+int eisa_driver_register (struct eisa_driver *edrv);
+void eisa_driver_unregister (struct eisa_driver *edrv);
+
+Clear enough ?
+
+struct eisa_device_id {
+ char sig[EISA_SIG_LEN];
+ unsigned long driver_data;
+};
+
+struct eisa_driver {
+ const struct eisa_device_id *id_table;
+ struct device_driver driver;
+};
+
+id_table : an array of NULL terminated EISA id strings,
+ followed by an empty string. Each string can be
+ paired with a driver-dependant value (driver_data).
+
+driver : a generic driver, such as described in
+ Documentation/driver-model/driver.txt. Only .name,
+ .probe and .remove members are mandatory.
+
+An example is the 3c509 driver :
+
+struct eisa_device_id el3_eisa_ids[] = {
+ { "TCM5092" },
+ { "TCM5093" },
+ { "" }
+};
+
+struct eisa_driver el3_eisa_driver = {
+ .id_table = el3_eisa_ids,
+ .driver = {
+ .name = "3c509",
+ .probe = el3_eisa_probe,
+ .remove = __devexit_p (el3_device_remove)
+ }
+};
+
+** Device :
+
+The sysfs framework calls .probe and .remove functions upon device
+discovery and removal (note that the .remove function is only called
+when driver is built as a module).
+
+Both functions are passed a pointer to a 'struct device', which is
+encapsulated in a 'struct eisa_device' described as follows :
+
+struct eisa_device {
+ struct eisa_device_id id;
+ int slot;
+ unsigned long base_addr;
+ struct resource res;
+ struct device dev; /* generic device */
+};
+
+id : EISA id, as read from device. id.driver_data is set from the
+ matching driver EISA id.
+slot : slot number which the device was detected on
+res : I/O resource allocated to this device
+dev : generic device (see Documentation/driver-model/device.txt)
+
+You can get the 'struct eisa_device' from 'struct device' using the
+'to_eisa_device' macro.
+
+** Misc stuff :
+
+void eisa_set_drvdata (struct eisa_device *edev, void *data);
+
+Stores data into the device's driver_data area.
+
+void *eisa_get_drvdata (struct eisa_device *edev):
+
+Gets the pointer previously stored into the device's driver_data area.
+
+** Random notes :
+
+Converting an EISA driver to the new API mostly involves *deleting*
+code (since probing is now in the core EISA code). Unfortunately, most
+drivers share their probing routine between ISA, MCA and EISA. Special
+care must be taken when ripping out the EISA code, so other busses
+won't suffer from these surgical strikes...
+
+You *must not* expect any EISA device to be detected when returning
+from eisa_driver_register, since the chances are that the bus has not
+yet been probed. In fact, that's what happens most of the time (the
+bus root driver usually kicks in rather late in the boot process).
+Unfortunately, most drivers are doing the probing by themselves, and
+expect to have explored the whole machine when they exit their probe
+routine.
+
+** Thanks :
+
+I'd like to thank the following people for their help :
+- Xavier Benigni for lending me a wonderful Alpha Jensen,
+- James Bottomley, Jeff Garzik for getting this stuff into the kernel,
+- Andries Brouwer for contributing numerous EISA ids,
+- Catrin Jones for coping with too many machines at home
diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- a/drivers/eisa/eisa-bus.c Wed Mar 5 15:11:17 2003
+++ b/drivers/eisa/eisa-bus.c Wed Mar 5 15:11:17 2003
@@ -83,8 +83,10 @@
return 0;
while (strlen (eids->sig)) {
- if (!strcmp (eids->sig, edev->id.sig))
+ if (!strcmp (eids->sig, edev->id.sig)) {
+ edev->id.driver_data = eids->driver_data;
return 1;
+ }
eids++;
}
diff -Nru a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
--- a/drivers/eisa/virtual_root.c Wed Mar 5 15:11:17 2003
+++ b/drivers/eisa/virtual_root.c Wed Mar 5 15:11:17 2003
@@ -13,14 +13,19 @@
#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",
+/* The default EISA device parent (virtual root device).
+ * Now use a platform device, since that's the obvious choice. */
+
+static struct platform_device eisa_root_dev = {
+ .name = "eisa",
+ .id = 0,
+ .dev = {
+ .name = "Virtual EISA Bridge",
+ },
};
static struct eisa_root_device eisa_bus_root = {
- .dev = &eisa_root_dev,
+ .dev = &eisa_root_dev.dev,
.bus_base_addr = 0,
.res = &ioport_resource,
.slots = EISA_MAX_SLOTS,
@@ -30,16 +35,16 @@
{
int r;
- if ((r = device_register (&eisa_root_dev))) {
+ if ((r = platform_device_register (&eisa_root_dev))) {
return r;
}
- eisa_root_dev.driver_data = &eisa_bus_root;
+ eisa_root_dev.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);
+ platform_device_unregister (&eisa_root_dev);
return -1;
}
diff -Nru a/include/linux/eisa.h b/include/linux/eisa.h
--- a/include/linux/eisa.h Wed Mar 5 15:11:17 2003
+++ b/include/linux/eisa.h Wed Mar 5 15:11:17 2003
@@ -20,7 +20,8 @@
/* The EISA signature, in ASCII form, null terminated */
struct eisa_device_id {
- char sig[EISA_SIG_LEN];
+ char sig[EISA_SIG_LEN];
+ unsigned long driver_data;
};
/* There is not much we can say about an EISA device, apart from
[-- Attachment #3: Type: text/plain, Size: 58 bytes --]
--
Places change, faces change. Life is so very strange.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2003-04-21 16:37 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-03 3:09 [PATCH] fix 3c509.c for MCA drivers James Bottomley
2003-02-08 17:25 ` Marc Zyngier
2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
2003-02-14 14:32 ` Ivan Kokshaysky
2003-02-14 15:32 ` Marc Zyngier
2003-02-14 16:05 ` Ivan Kokshaysky
2003-02-14 16:42 ` Marc Zyngier
2003-02-15 12:20 ` [PATCH] EISA/sysfs update, take #2 Marc Zyngier
2003-02-14 18:12 ` [PATCH] EISA/sysfs update Christoph Hellwig
2003-02-14 19:37 ` Marc Zyngier
2003-03-05 14:22 Marc Zyngier
2003-04-21 16:48 Marc Zyngier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®