mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] EISA/sysfs update
@ 2003-03-05 14:22 Marc Zyngier
  0 siblings, 0 replies; 9+ 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] 9+ messages in thread
* [PATCH] EISA/sysfs update
@ 2003-04-21 16:48 Marc Zyngier
  0 siblings, 0 replies; 9+ 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] 9+ messages in thread
* [PATCH] fix 3c509.c for MCA drivers
@ 2003-02-03  3:09 James Bottomley
  2003-02-14 10:16 ` [PATCH] EISA/sysfs update Marc Zyngier
  0 siblings, 1 reply; 9+ 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] 9+ messages in thread

end of thread, other threads:[~2003-04-21 16:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-05 14:22 [PATCH] EISA/sysfs update Marc Zyngier
  -- strict thread matches above, loose matches on Subject: below --
2003-04-21 16:48 Marc Zyngier
2003-02-03  3:09 [PATCH] fix 3c509.c for MCA drivers James Bottomley
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-14 18:12   ` Christoph Hellwig
2003-02-14 19:37     ` 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®