The 2.4 kernel has a new ISA PnP interface, as
described in Documentation/isapnp.txt. This patch adds
support for this interface to the driver for the
SMC EtherEZ ethernet card.

It has been tested on 2.4.0 and 2.4.0-ac10 (and should
also work with all other 2.4 versions).

Feedback will be appreciated. If you have a SMC EtherEZ
that is not detected as a PnP card, please send me a
cat of your /proc/isapnp.

Alexander Sotirov
[EMAIL PROTECTED]

http://www.mirizma.org/sluncho/hacks/smc-etherez-isapnp.patch

--- linux-2.4.0.orig/drivers/net/smc-ultra.c    Mon Dec 11 15:38:29 2000
+++ linux/drivers/net/smc-ultra.c       Sun Jan 21 23:49:55 2001
@@ -20,6 +20,7 @@
 
                ultra_probe()           Detecting and initializing the card.
                ultra_probe1()
+               ultra_probe_isapnp()
 
                ultra_open()            The card-specific details of starting, stopping
                ultra_reset_8390()      and resetting the 8390 NIC core.
@@ -43,6 +44,13 @@
        Paul Gortmaker  : multiple card support for module users.
        Donald Becker   : 4/17/96 PIO support, minor potential problems avoided.
        Donald Becker   : 6/6/96 correctly set auto-wrap bit.
+       Alexander Sotirov : 1/20/01 Added support for ISAPnP cards
+
+       Note about the ISA PnP support:
+
+       This driver can not autoprobe for more than one SMC EtherEZ PnP card.
+       You have to configure the second card manually through the /proc/isapnp
+       interface and then load the module with an explicit io=0x___ option.
 */
 
 static const char *version =
@@ -55,6 +63,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/isapnp.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -69,6 +78,10 @@
 int ultra_probe(struct net_device *dev);
 static int ultra_probe1(struct net_device *dev, int ioaddr);
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int ultra_probe_isapnp(struct net_device *dev);
+#endif
+
 static int ultra_open(struct net_device *dev);
 static void ultra_reset_8390(struct net_device *dev);
 static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
@@ -85,6 +98,18 @@
                                                         const unsigned char *buf, 
const int start_page);
 static int ultra_close_card(struct net_device *dev);
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static struct { unsigned short card_vendor, card_device, vendor, function; char 
+*name; }
+ultra_device_ids[] __initdata = {
+        {       ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
+                ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
+                "SMC EtherEZ (8416)" },
+        {0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
+#endif
+
 
 #define START_PG               0x00    /* First page of TX buffer */
 
@@ -114,6 +139,14 @@
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+       /* Look for any installed ISAPnP cards */
+       if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
+               return 0;
+
+       printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard 
+ones...\n");
+#endif
+
        for (i = 0; ultra_portlist[i]; i++)
                if (ultra_probe1(dev, ultra_portlist[i]) == 0)
                        return 0;
@@ -245,6 +278,48 @@
        return retval;
 }
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int __init ultra_probe_isapnp(struct net_device *dev)
+{
+        int i;
+
+        for (i = 0; ultra_device_ids[i].vendor != 0; i++) {
+                struct pci_dev *idev = NULL;
+
+                while ((idev = isapnp_find_dev(NULL,
+                                               ultra_device_ids[i].vendor,
+                                               ultra_device_ids[i].function,
+                                               idev))) {
+                        /* Avoid already found cards from previous calls */
+                        if (idev->prepare(idev))
+                                continue;
+                        if (idev->activate(idev))
+                                continue;
+                        /* if no irq, search for next */
+                        if (idev->irq_resource[0].start == 0)
+                                continue;
+                        /* found it */
+                        dev->base_addr = idev->resource[0].start;
+                        dev->irq = idev->irq_resource[0].start;
+                        printk(KERN_INFO "smc-ultra.c: ISAPnP reports %s at i/o %#lx, 
+irq %d.\n",
+                                ultra_device_ids[i].name,
+
+                                dev->base_addr, dev->irq);
+                        if (ultra_probe1(dev, dev->base_addr) != 0) {      /* 
+Shouldn't happen. */
+                                printk(KERN_ERR "smc-ultra.c: Probe of ISAPnP card at 
+%#lx failed.\n", dev->base_addr);                                return -ENXIO;
+                        }
+                        ei_status.priv = (unsigned long)idev;
+                        break;
+                }
+                if (!idev)
+                        continue;
+                return 0;
+        }
+
+        return -ENODEV;
+}
+#endif
+
 static int
 ultra_open(struct net_device *dev)
 {
@@ -465,6 +540,13 @@
                if (dev->priv != NULL) {
                        /* NB: ultra_close_card() does free_irq */
                        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+                       struct pci_dev *idev = (struct pci_dev *)ei_status.priv;
+                       if (idev)
+                               idev->deactivate(idev);
+#endif
+
                        unregister_netdev(dev);
                        release_region(ioaddr, ULTRA_IO_EXTENT);
                        kfree(dev->priv);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to