Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
[safe/jmp/linux-2.6] / drivers / net / pcmcia / xirc2ps_cs.c
index 9f33bad..6622f04 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 #include <linux/bitops.h>
+#include <linux/mii.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -208,22 +209,8 @@ enum xirc_cmd {        /* Commands */
 #define XIRCREG45_REV   15 /* Revision Register (rd) */
 #define XIRCREG50_IA   8   /* Individual Address (8-13) */
 
-static char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
+static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
 
-/****************
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 #define KDBG_XIRC KERN_DEBUG   "xirc2ps_cs: "
 #define KERR_XIRC KERN_ERR     "xirc2ps_cs: "
@@ -273,12 +260,12 @@ INT_MODULE_PARM(lockup_hack,      0);  /* anti lockup hack */
 static unsigned maxrx_bytes = 22000;
 
 /* MII management prototypes */
-static void mii_idle(kio_addr_t ioaddr);
-static void mii_putbit(kio_addr_t ioaddr, unsigned data);
-static int  mii_getbit(kio_addr_t ioaddr);
-static void mii_wbits(kio_addr_t ioaddr, unsigned data, int len);
-static unsigned mii_rd(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg);
-static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
+static void mii_idle(unsigned int ioaddr);
+static void mii_putbit(unsigned int ioaddr, unsigned data);
+static int  mii_getbit(unsigned int ioaddr);
+static void mii_wbits(unsigned int ioaddr, unsigned data, int len);
+static unsigned mii_rd(unsigned int ioaddr, u_char phyaddr, u_char phyreg);
+static void mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg,
                   unsigned data, int len);
 
 /*
@@ -289,11 +276,9 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
  * and ejection events.  They are invoked from the event handler.
  */
 
-static int has_ce2_string(dev_link_t * link);
-static void xirc2ps_config(dev_link_t * link);
-static void xirc2ps_release(dev_link_t * link);
-static int xirc2ps_event(event_t event, int priority,
-                        event_callback_args_t * args);
+static int has_ce2_string(struct pcmcia_device * link);
+static int xirc2ps_config(struct pcmcia_device * link);
+static void xirc2ps_release(struct pcmcia_device * link);
 
 /****************
  * The attach() and detach() entry points are used to create and destroy
@@ -301,8 +286,7 @@ static int xirc2ps_event(event_t event, int priority,
  * needed to manage one actual PCMCIA card.
  */
 
-static dev_link_t *xirc2ps_attach(void);
-static void xirc2ps_detach(dev_link_t *);
+static void xirc2ps_detach(struct pcmcia_device *p_dev);
 
 /****************
  * You'll also need to prototype all the functions that will actually
@@ -311,49 +295,34 @@ static void xirc2ps_detach(dev_link_t *);
  * less on other parts of the kernel.
  */
 
-static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-
-static dev_info_t dev_info = "xirc2ps_cs";
+static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);
 
 /****************
  * A linked list of "instances" of the device.  Each actual
  * PCMCIA card corresponds to one device instance, and is described
- * by one dev_link_t structure (defined in ds.h).
+ * by one struct pcmcia_device structure (defined in ds.h).
  *
  * You may not want to use a linked list for this -- for example, the
- * memory card driver uses an array of dev_link_t pointers, where minor
+ * memory card driver uses an array of struct pcmcia_device pointers, where minor
  * device numbers are used to derive the corresponding array index.
  */
 
-static dev_link_t *dev_list;
-
 /****************
- * A dev_link_t structure has fields for most things that are needed
- * to keep track of a socket, but there will usually be some device
- * specific information that also needs to be kept track of.  The
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
  * A driver needs to provide a dev_node_t structure for each device
  * on a card.  In some cases, there is only one device per card (for
  * example, ethernet cards, modems).  In other cases, there may be
  * many actual or logical devices (SCSI adapters, memory cards with
  * multiple partitions).  The dev_node_t structures need to be kept
- * in a linked list starting at the 'dev' field of a dev_link_t
+ * in a linked list starting at the 'dev' field of a struct pcmcia_device
  * structure.  We allocate them in the card's private data structure,
  * because they generally can't be allocated dynamically.
  */
 
 typedef struct local_info_t {
-    dev_link_t link;
+       struct net_device       *dev;
+       struct pcmcia_device    *p_dev;
     dev_node_t node;
-    struct net_device_stats stats;
+
     int card_type;
     int probe_port;
     int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */
@@ -364,21 +333,23 @@ typedef struct local_info_t {
     void __iomem *dingo_ccr; /* only used for CEM56 cards */
     unsigned last_ptr_value; /* last packets transmitted value */
     const char *manf_str;
+    struct work_struct tx_timeout_task;
 } local_info_t;
 
 /****************
  * Some more prototypes
  */
-static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void do_tx_timeout(struct net_device *dev);
-static struct net_device_stats *do_get_stats(struct net_device *dev);
+static netdev_tx_t do_start_xmit(struct sk_buff *skb,
+                                      struct net_device *dev);
+static void xirc_tx_timeout(struct net_device *dev);
+static void xirc2ps_tx_timeout_task(struct work_struct *work);
 static void set_addresses(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
-static int set_card_type(dev_link_t *link, const void *s);
+static int set_card_type(struct pcmcia_device *link);
 static int do_config(struct net_device *dev, struct ifmap *map);
 static int do_open(struct net_device *dev);
 static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static struct ethtool_ops netdev_ethtool_ops;
+static const struct ethtool_ops netdev_ethtool_ops;
 static void hardreset(struct net_device *dev);
 static void do_reset(struct net_device *dev, int full);
 static int init_mii(struct net_device *dev);
@@ -386,28 +357,6 @@ static void do_powerdown(struct net_device *dev);
 static int do_stop(struct net_device *dev);
 
 /*=============== Helper functions =========================*/
-static int
-first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-{
-       int err;
-
-       if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
-                       (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(handle, tuple, parse);
-       return err;
-}
-
-static int
-next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-{
-       int err;
-
-       if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
-                       (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(handle, tuple, parse);
-       return err;
-}
-
 #define SelectPage(pgnr)   outb((pgnr), ioaddr + XIRCREG_PR)
 #define GetByte(reg)      ((unsigned)inb(ioaddr + (reg)))
 #define GetWord(reg)      ((unsigned)inw(ioaddr + (reg)))
@@ -415,11 +364,11 @@ next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
 #define PutWord(reg,value) outw((value), ioaddr+(reg))
 
 /*====== Functions used for debugging =================================*/
-#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
+#if 0 /* reading regs may change system status */
 static void
 PrintRegisters(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
     if (pc_debug > 1) {
        int i, page;
@@ -436,9 +385,9 @@ PrintRegisters(struct net_device *dev)
            printk("\n");
        }
        for (page=0x40 ; page <= 0x5f; page++) {
-           if (page == 0x43 || (page >= 0x46 && page <= 0x4f)
-               || (page >= 0x51 && page <=0x5e))
-               continue;
+               if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
+                   (page >= 0x51 && page <=0x5e))
+                       continue;
            printk(KDBG_XIRC "Register page %2x: ", page);
            SelectPage(page);
            for (i = 8; i < 16; i++)
@@ -447,7 +396,7 @@ PrintRegisters(struct net_device *dev)
        }
     }
 }
-#endif /* PCMCIA_DEBUG */
+#endif /* 0 */
 
 /*============== MII Management functions ===============*/
 
@@ -455,7 +404,7 @@ PrintRegisters(struct net_device *dev)
  * Turn around for read
  */
 static void
-mii_idle(kio_addr_t ioaddr)
+mii_idle(unsigned int ioaddr)
 {
     PutByte(XIRCREG2_GPR2, 0x04|0); /* drive MDCK low */
     udelay(1);
@@ -467,7 +416,7 @@ mii_idle(kio_addr_t ioaddr)
  * Write a bit to MDI/O
  */
 static void
-mii_putbit(kio_addr_t ioaddr, unsigned data)
+mii_putbit(unsigned int ioaddr, unsigned data)
 {
   #if 1
     if (data) {
@@ -500,7 +449,7 @@ mii_putbit(kio_addr_t ioaddr, unsigned data)
  * Get a bit from MDI/O
  */
 static int
-mii_getbit(kio_addr_t ioaddr)
+mii_getbit(unsigned int ioaddr)
 {
     unsigned d;
 
@@ -513,7 +462,7 @@ mii_getbit(kio_addr_t ioaddr)
 }
 
 static void
-mii_wbits(kio_addr_t ioaddr, unsigned data, int len)
+mii_wbits(unsigned int ioaddr, unsigned data, int len)
 {
     unsigned m = 1 << (len-1);
     for (; m; m >>= 1)
@@ -521,7 +470,7 @@ mii_wbits(kio_addr_t ioaddr, unsigned data, int len)
 }
 
 static unsigned
-mii_rd(kio_addr_t ioaddr,      u_char phyaddr, u_char phyreg)
+mii_rd(unsigned int ioaddr,    u_char phyaddr, u_char phyreg)
 {
     int i;
     unsigned data=0, m;
@@ -543,7 +492,8 @@ mii_rd(kio_addr_t ioaddr,   u_char phyaddr, u_char phyreg)
 }
 
 static void
-mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
+mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg, unsigned data,
+       int len)
 {
     int i;
 
@@ -561,6 +511,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
 
 /*============= Main bulk of functions =========================*/
 
+static const struct net_device_ops netdev_ops = {
+       .ndo_open               = do_open,
+       .ndo_stop               = do_stop,
+       .ndo_start_xmit         = do_start_xmit,
+       .ndo_tx_timeout         = xirc_tx_timeout,
+       .ndo_set_config         = do_config,
+       .ndo_do_ioctl           = do_ioctl,
+       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 /****************
  * xirc2ps_attach() creates an "instance" of the driver, allocating
  * local data structures for one device.  The device is registered
@@ -571,62 +534,36 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
  * card insertion event.
  */
 
-static dev_link_t *
-xirc2ps_attach(void)
+static int
+xirc2ps_probe(struct pcmcia_device *link)
 {
-    client_reg_t client_reg;
-    dev_link_t *link;
     struct net_device *dev;
     local_info_t *local;
-    int err;
 
-    DEBUG(0, "attach()\n");
+    dev_dbg(&link->dev, "attach()\n");
 
     /* Allocate the device structure */
     dev = alloc_etherdev(sizeof(local_info_t));
     if (!dev)
-           return NULL;
+           return -ENOMEM;
     local = netdev_priv(dev);
-    link = &local->link;
+    local->dev = dev;
+    local->p_dev = link;
     link->priv = dev;
 
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
     link->irq.Handler = xirc2ps_interrupt;
-    link->irq.Instance = dev;
 
     /* Fill in card specific entries */
-    SET_MODULE_OWNER(dev);
-    dev->hard_start_xmit = &do_start_xmit;
-    dev->set_config = &do_config;
-    dev->get_stats = &do_get_stats;
-    dev->do_ioctl = &do_ioctl;
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    dev->set_multicast_list = &set_multicast_list;
-    dev->open = &do_open;
-    dev->stop = &do_stop;
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = do_tx_timeout;
+    dev->netdev_ops = &netdev_ops;
+    dev->ethtool_ops = &netdev_ethtool_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+    INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
-       cs_error(link->handle, RegisterClient, err);
-       xirc2ps_detach(link);
-       return NULL;
-    }
-
-    return link;
+    return xirc2ps_config(link);
 } /* xirc2ps_attach */
 
 /****************
@@ -637,40 +574,17 @@ xirc2ps_attach(void)
  */
 
 static void
-xirc2ps_detach(dev_link_t * link)
+xirc2ps_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
 
-    DEBUG(0, "detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "detach\n");
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-       if (*linkp == link)
-           break;
-    if (!*linkp) {
-       DEBUG(0, "detach(0x%p): dev_link lost\n", link);
-       return;
-    }
-
-    if (link->dev)
+    if (link->dev_node)
        unregister_netdev(dev);
 
-    /*
-     * If the device is currently configured and active, we won't
-     * actually delete it yet. Instead, it is marked so that when
-     * the release() function is called, that will trigger a proper
-     * detach().
-     */
-    if (link->state & DEV_CONFIG)
-       xirc2ps_release(link);
-
-    /* Break the link with Card Services */
-    if (link->handle)
-       pcmcia_deregister_client(link->handle);
+    xirc2ps_release(link);
 
-    /* Unlink device structure, free it */
-    *linkp = link->next;
     free_netdev(dev);
 } /* xirc2ps_detach */
 
@@ -693,17 +607,25 @@ xirc2ps_detach(dev_link_t * link)
  *
  */
 static int
-set_card_type(dev_link_t *link, const void *s)
+set_card_type(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
-  #ifdef PCMCIA_DEBUG
-    unsigned cisrev = ((const unsigned char *)s)[2];
-  #endif
-    unsigned mediaid= ((const unsigned char *)s)[3];
-    unsigned prodid = ((const unsigned char *)s)[4];
+    u8 *buf;
+    unsigned int cisrev, mediaid, prodid;
+    size_t len;
+
+    len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
+    if (len < 5) {
+           dev_err(&link->dev, "invalid CIS -- sorry\n");
+           return 0;
+    }
+
+    cisrev = buf[2];
+    mediaid = buf[3];
+    prodid = buf[4];
 
-    DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
+    dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
          cisrev, mediaid, prodid);
 
     local->mohawk = 0;
@@ -762,65 +684,100 @@ set_card_type(dev_link_t *link, const void *s)
  * Returns: true if this is a CE2
  */
 static int
-has_ce2_string(dev_link_t * link)
+has_ce2_string(struct pcmcia_device * p_dev)
 {
-    client_handle_t handle = link->handle;
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[256];
-
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = 254;
-    tuple.TupleOffset = 0;
-    tuple.DesiredTuple = CISTPL_VERS_1;
-    if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) {
-       if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2"))
-           return 1;
-    }
-    return 0;
+       if (p_dev->prod_id[2] && strstr(p_dev->prod_id[2], "CE2"))
+               return 1;
+       return 0;
 }
 
+static int
+xirc2ps_config_modem(struct pcmcia_device *p_dev,
+                    cistpl_cftable_entry_t *cf,
+                    cistpl_cftable_entry_t *dflt,
+                    unsigned int vcc,
+                    void *priv_data)
+{
+       unsigned int ioaddr;
+
+       if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {
+               for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
+                       p_dev->io.BasePort2 = cf->io.win[0].base;
+                       p_dev->io.BasePort1 = ioaddr;
+                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                               return 0;
+               }
+       }
+       return -ENODEV;
+}
+
+static int
+xirc2ps_config_check(struct pcmcia_device *p_dev,
+                    cistpl_cftable_entry_t *cf,
+                    cistpl_cftable_entry_t *dflt,
+                    unsigned int vcc,
+                    void *priv_data)
+{
+       int *pass = priv_data;
+
+       if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
+               p_dev->io.BasePort2 = cf->io.win[0].base;
+               p_dev->io.BasePort1 = p_dev->io.BasePort2
+                       + (*pass ? (cf->index & 0x20 ? -24:8)
+                          : (cf->index & 0x20 ?   8:-24));
+               if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       return 0;
+       }
+       return -ENODEV;
+
+}
+
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+                            tuple_t *tuple,
+                            void *priv)
+{
+       struct net_device *dev = priv;
+       int i;
+
+       if (tuple->TupleDataLen != 13)
+               return -EINVAL;
+       if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+               (tuple->TupleData[2] != 6))
+               return -EINVAL;
+       /* another try  (James Lehmer's CE2 version 4.1)*/
+       for (i = 2; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
+
+
 /****************
  * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
  * is received, to configure the PCMCIA socket, and to make the
  * ethernet device available to the system.
  */
-static void
-xirc2ps_config(dev_link_t * link)
+static int
+xirc2ps_config(struct pcmcia_device * link)
 {
-    client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
-    kio_addr_t ioaddr;
-    int err, i;
-    u_char buf[64];
-    cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    unsigned int ioaddr;
+    int err;
+    u8 *buf;
+    size_t len;
 
     local->dingo_ccr = NULL;
 
-    DEBUG(0, "config(0x%p)\n", link);
-
-    /*
-     * This reads the card's CONFIG tuple to find its configuration
-     * registers.
-     */
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
+    dev_dbg(&link->dev, "config\n");
 
     /* Is this a valid card */
-    tuple.DesiredTuple = CISTPL_MANFID;
-    if ((err=first_tuple(handle, &tuple, &parse))) {
+    if (link->has_manf_id == 0) {
        printk(KNOT_XIRC "manfid not found in CIS\n");
        goto failure;
     }
 
-    switch(parse.manfid.manf) {
+    switch (link->manf_id) {
       case MANFID_XIRCOM:
        local->manf_str = "Xircom";
        break;
@@ -839,75 +796,44 @@ xirc2ps_config(dev_link_t * link)
        break;
       default:
        printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
-              (unsigned)parse.manfid.manf);
+              (unsigned)link->manf_id);
        goto failure;
     }
-    DEBUG(0, "found %s card\n", local->manf_str);
+    dev_dbg(&link->dev, "found %s card\n", local->manf_str);
 
-    if (!set_card_type(link, buf)) {
+    if (!set_card_type(link)) {
        printk(KNOT_XIRC "this card is not supported\n");
        goto failure;
     }
 
-    /* get configuration stuff */
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    if ((err=first_tuple(handle, &tuple, &parse)))
-       goto cis_error;
-    link->conf.ConfigBase = parse.config.base;
-    link->conf.Present =    parse.config.rmask[0];
-
     /* get the ethernet address from the CIS */
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    for (err = first_tuple(handle, &tuple, &parse); !err;
-                            err = next_tuple(handle, &tuple, &parse)) {
-       /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
-        * the first one with a length of zero the second correct -
-        * so I skip all entries with length 0 */
-       if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
-           && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
-           break;
-    }
-    if (err) { /* not found: try to get the node-id from tuple 0x89 */
-       tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */
-       if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 &&
-               (err = pcmcia_get_tuple_data(handle, &tuple)) == 0) {
-           if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
-               memcpy(&parse, buf, 8);
-           else
-               err = -1;
-       }
-    }
-    if (err) { /* another try  (James Lehmer's CE2 version 4.1)*/
-       tuple.DesiredTuple = CISTPL_FUNCE;
-       for (err = first_tuple(handle, &tuple, &parse); !err;
-                                err = next_tuple(handle, &tuple, &parse)) {
-           if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
-               && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
-               buf[1] = 4;
-               memcpy(&parse, buf+1, 8);
-               break;
+    err = pcmcia_get_mac_from_cis(link, dev);
+
+    /* not found: try to get the node-id from tuple 0x89 */
+    if (err) {
+           len = pcmcia_get_tuple(link, 0x89, &buf);
+           /* data layout looks like tuple 0x22 */
+           if (buf && len == 8) {
+                   if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
+                           int i;
+                           for (i = 2; i < 6; i++)
+                                   dev->dev_addr[i] = buf[i+2];
+                   } else
+                           err = -1;
            }
-       }
+           kfree(buf);
     }
+
+    if (err)
+       err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
     if (err) {
        printk(KNOT_XIRC "node-id not found in CIS\n");
        goto failure;
     }
-    node_id = (cistpl_lan_node_id_t *)parse.funce.data;
-    if (node_id->nb != 6) {
-       printk(KNOT_XIRC "malformed node-id in CIS\n");
-       goto failure;
-    }
-    for (i=0; i < 6; i++)
-       dev->dev_addr[i] = node_id->id[i];
-
-    /* Configure card */
-    link->state |= DEV_CONFIG;
 
     link->io.IOAddrLines =10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     if (local->modem) {
        int pass;
 
@@ -915,26 +841,15 @@ xirc2ps_config(dev_link_t * link)
            link->conf.Attributes |= CONF_ENABLE_SPKR;
            link->conf.Status |= CCSR_AUDIO_ENA;
        }
-       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED ;
+       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
        link->io.NumPorts2 = 8;
        link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        if (local->dingo) {
            /* Take the Modem IO port from the CIS and scan for a free
             * Ethernet port */
            link->io.NumPorts1 = 16; /* no Mako stuff anymore */
-           tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-           for (err = first_tuple(handle, &tuple, &parse); !err;
-                                err = next_tuple(handle, &tuple, &parse)) {
-               if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {
-                   for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
-                       link->conf.ConfigIndex = cf->index ;
-                       link->io.BasePort2 = cf->io.win[0].base;
-                       link->io.BasePort1 = ioaddr;
-                       if (!(err=pcmcia_request_io(link->handle, &link->io)))
-                           goto port_found;
-                   }
-               }
-           }
+           if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
+                   goto port_found;
        } else {
            link->io.NumPorts1 = 18;
            /* We do 2 passes here: The first one uses the regular mapping and
@@ -942,39 +857,25 @@ xirc2ps_config(dev_link_t * link)
             * mirrored every 32 bytes. Actually we use a mirrored port for
             * the Mako if (on the first pass) the COR bit 5 is set.
             */
-           for (pass=0; pass < 2; pass++) {
-               tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-               for (err = first_tuple(handle, &tuple, &parse); !err;
-                                    err = next_tuple(handle, &tuple, &parse)){
-                   if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8){
-                       link->conf.ConfigIndex = cf->index ;
-                       link->io.BasePort2 = cf->io.win[0].base;
-                       link->io.BasePort1 = link->io.BasePort2
-                                   + (pass ? (cf->index & 0x20 ? -24:8)
-                                           : (cf->index & 0x20 ?   8:-24));
-                       if (!(err=pcmcia_request_io(link->handle, &link->io)))
+           for (pass=0; pass < 2; pass++)
+                   if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
                            goto port_found;
-                   }
-               }
-           }
            /* if special option:
             * try to configure as Ethernet only.
             * .... */
        }
        printk(KNOT_XIRC "no ports available\n");
     } else {
-       link->irq.Attributes |= IRQ_TYPE_EXCLUSIVE;
+       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
        link->io.NumPorts1 = 16;
        for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
            link->io.BasePort1 = ioaddr;
-           if (!(err=pcmcia_request_io(link->handle, &link->io)))
+           if (!(err=pcmcia_request_io(link, &link->io)))
                goto port_found;
        }
        link->io.BasePort1 = 0; /* let CS decide */
-       if ((err=pcmcia_request_io(link->handle, &link->io))) {
-           cs_error(link->handle, RequestIO, err);
+       if ((err=pcmcia_request_io(link, &link->io)))
            goto config_error;
-       }
     }
   port_found:
     if (err)
@@ -984,19 +885,15 @@ xirc2ps_config(dev_link_t * link)
      * Now allocate an interrupt line. Note that this does not
      * actually assign a handler to the interrupt.
      */
-    if ((err=pcmcia_request_irq(link->handle, &link->irq))) {
-       cs_error(link->handle, RequestIRQ, err);
+    if ((err=pcmcia_request_irq(link, &link->irq)))
        goto config_error;
-    }
 
     /****************
      * This actually configures the PCMCIA socket -- setting up
      * the I/O windows and the interrupt mapping.
      */
-    if ((err=pcmcia_request_configuration(link->handle, &link->conf))) {
-       cs_error(link->handle, RequestConfiguration, err);
+    if ((err=pcmcia_request_configuration(link, &link->conf)))
        goto config_error;
-    }
 
     if (local->dingo) {
        conf_reg_t reg;
@@ -1011,17 +908,13 @@ xirc2ps_config(dev_link_t * link)
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_IOBASE_0;
        reg.Value = link->io.BasePort2 & 0xff;
-       if ((err = pcmcia_access_configuration_register(link->handle, &reg))) {
-           cs_error(link->handle, AccessConfigurationRegister, err);
+       if ((err = pcmcia_access_configuration_register(link, &reg)))
            goto config_error;
-       }
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_IOBASE_1;
        reg.Value = (link->io.BasePort2 >> 8) & 0xff;
-       if ((err = pcmcia_access_configuration_register(link->handle, &reg))) {
-           cs_error(link->handle, AccessConfigurationRegister, err);
+       if ((err = pcmcia_access_configuration_register(link, &reg)))
            goto config_error;
-       }
 
        /* There is no config entry for the Ethernet part which
         * is at 0x0800. So we allocate a window into the attribute
@@ -1030,17 +923,14 @@ xirc2ps_config(dev_link_t * link)
        req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
        req.Base = req.Size = 0;
        req.AccessSpeed = 0;
-       if ((err = pcmcia_request_window(&link->handle, &req, &link->win))) {
-           cs_error(link->handle, RequestWindow, err);
+       if ((err = pcmcia_request_window(link, &req, &link->win)))
            goto config_error;
-       }
+
        local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
        mem.CardOffset = 0x0;
        mem.Page = 0;
-       if ((err = pcmcia_map_mem_page(link->win, &mem))) {
-           cs_error(link->handle, MapMemPage, err);
+       if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
            goto config_error;
-       }
 
        /* Setup the CCRs; there are no infos in the CIS about the Ethernet
         * part.
@@ -1098,36 +988,30 @@ xirc2ps_config(dev_link_t * link)
     if (local->dingo)
        do_reset(dev, 1); /* a kludge to make the cem56 work */
 
-    link->dev = &local->node;
-    link->state &= ~DEV_CONFIG_PENDING;
-    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+    link->dev_node = &local->node;
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if ((err=register_netdev(dev))) {
        printk(KNOT_XIRC "register_netdev() failed\n");
-       link->dev = NULL;
+       link->dev_node = NULL;
        goto config_error;
     }
 
     strcpy(local->node.dev_name, dev->name);
 
     /* give some infos about the hardware */
-    printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr",
-        dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq);
-    for (i = 0; i < 6; i++)
-       printk("%c%02X", i?':':' ', dev->dev_addr[i]);
-    printk("\n");
+    printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n",
+          dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq,
+          dev->dev_addr);
 
-    return;
+    return 0;
 
   config_error:
-    link->state &= ~DEV_CONFIG_PENDING;
     xirc2ps_release(link);
-    return;
+    return -ENODEV;
 
-  cis_error:
-    printk(KNOT_XIRC "unable to parse CIS\n");
   failure:
-    link->state &= ~DEV_CONFIG_PENDING;
+    return -ENODEV;
 } /* xirc2ps_config */
 
 /****************
@@ -1136,88 +1020,46 @@ xirc2ps_config(dev_link_t * link)
  * still open, this will be postponed until it is closed.
  */
 static void
-xirc2ps_release(dev_link_t *link)
+xirc2ps_release(struct pcmcia_device *link)
 {
+       dev_dbg(&link->dev, "release\n");
 
-    DEBUG(0, "release(0x%p)\n", link);
-
-    if (link->win) {
-       struct net_device *dev = link->priv;
-       local_info_t *local = netdev_priv(dev);
-       if (local->dingo)
-           iounmap(local->dingo_ccr - 0x0800);
-       pcmcia_release_window(link->win);
-    }
-    pcmcia_release_configuration(link->handle);
-    pcmcia_release_io(link->handle, &link->io);
-    pcmcia_release_irq(link->handle, &link->irq);
-    link->state &= ~DEV_CONFIG;
-
+       if (link->win) {
+               struct net_device *dev = link->priv;
+               local_info_t *local = netdev_priv(dev);
+               if (local->dingo)
+                       iounmap(local->dingo_ccr - 0x0800);
+       }
+       pcmcia_disable_device(link);
 } /* xirc2ps_release */
 
 /*====================================================================*/
 
-/****************
- * The card status event handler.  Mostly, this schedules other
- * stuff to run after an event is received.  A CARD_REMOVAL event
- * also sets some flags to discourage the net drivers from trying
- * to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag
- * to block future accesses to this device.  All the functions that
- * actually access the device should check this flag to make sure
- * the card is still present.
- */
 
-static int
-xirc2ps_event(event_t event, int priority,
-             event_callback_args_t * args)
+static int xirc2ps_suspend(struct pcmcia_device *link)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-
-    DEBUG(0, "event(%d)\n", (int)event);
+       struct net_device *dev = link->priv;
 
-    switch (event) {
-    case CS_EVENT_REGISTRATION_COMPLETE:
-       DEBUG(0, "registration complete\n");
-       break;
-    case CS_EVENT_CARD_REMOVAL:
-       link->state &= ~DEV_PRESENT;
-       if (link->state & DEV_CONFIG)
-           netif_device_detach(dev);
-       break;
-    case CS_EVENT_CARD_INSERTION:
-       link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-       xirc2ps_config(link);
-       break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open) {
+       if (link->open) {
                netif_device_detach(dev);
                do_powerdown(dev);
-           }
-           pcmcia_release_configuration(link->handle);
        }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
+
+       return 0;
+}
+
+static int xirc2ps_resume(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+
+       if (link->open) {
                do_reset(dev,1);
                netif_device_attach(dev);
-           }
        }
-       break;
-    }
-    return 0;
-} /* xirc2ps_event */
+
+       return 0;
+}
+
 
 /*====================================================================*/
 
@@ -1225,11 +1067,11 @@ xirc2ps_event(event_t event, int priority,
  * This is the Interrupt service route.
  */
 static irqreturn_t
-xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+xirc2ps_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *)dev_id;
     local_info_t *lp = netdev_priv(dev);
-    kio_addr_t ioaddr;
+    unsigned int ioaddr;
     u_char saved_page;
     unsigned bytes_rcvd;
     unsigned int_status, eth_status, rx_status, tx_status;
@@ -1247,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        PutByte(XIRCREG_CR, 0);
     }
 
-    DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
+    pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
 
     saved_page = GetByte(XIRCREG_PR);
     /* Read the ISR to see whats the cause for the interrupt.
@@ -1257,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     bytes_rcvd = 0;
   loop_entry:
     if (int_status == 0xff) { /* card may be ejected */
-       DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
+       pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
        goto leave;
     }
     eth_status = GetByte(XIRCREG_ESR);
@@ -1270,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     PutByte(XIRCREG40_TXST0, 0);
     PutByte(XIRCREG40_TXST1, 0);
 
-    DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
+    pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
          dev->name, int_status, eth_status, rx_status, tx_status);
 
     /***** receive section ******/
@@ -1280,21 +1122,21 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        if (bytes_rcvd > maxrx_bytes && (rsr & PktRxOk)) {
            /* too many bytes received during this int, drop the rest of the
             * packets */
-           lp->stats.rx_dropped++;
-           DEBUG(2, "%s: RX drop, too much done\n", dev->name);
+           dev->stats.rx_dropped++;
+           pr_debug("%s: RX drop, too much done\n", dev->name);
        } else if (rsr & PktRxOk) {
            struct sk_buff *skb;
 
            pktlen = GetWord(XIRCREG0_RBC);
            bytes_rcvd += pktlen;
 
-           DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
+           pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
 
            skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
            if (!skb) {
                printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
                       pktlen);
-               lp->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
            } else { /* okay get the packet */
                skb_reserve(skb, 2);
                if (lp->silicon == 0 ) { /* work around a hardware bug */
@@ -1334,7 +1176,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    unsigned i;
                    u_long *p = skb_put(skb, pktlen);
                    register u_long a;
-                   kio_addr_t edpreg = ioaddr+XIRCREG_EDP-2;
+                   unsigned int edpreg = ioaddr+XIRCREG_EDP-2;
                    for (i=0; i < len ; i += 4, p++) {
                        a = inl(edpreg);
                        __asm__("rorl $16,%0\n\t"
@@ -1349,28 +1191,26 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                            (pktlen+1)>>1);
                }
                skb->protocol = eth_type_trans(skb, dev);
-               skb->dev = dev;
                netif_rx(skb);
-               dev->last_rx = jiffies;
-               lp->stats.rx_packets++;
-               lp->stats.rx_bytes += pktlen;
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += pktlen;
                if (!(rsr & PhyPkt))
-                   lp->stats.multicast++;
+                   dev->stats.multicast++;
            }
        } else { /* bad packet */
-           DEBUG(5, "rsr=%#02x\n", rsr);
+           pr_debug("rsr=%#02x\n", rsr);
        }
        if (rsr & PktTooLong) {
-           lp->stats.rx_frame_errors++;
-           DEBUG(3, "%s: Packet too long\n", dev->name);
+           dev->stats.rx_frame_errors++;
+           pr_debug("%s: Packet too long\n", dev->name);
        }
        if (rsr & CRCErr) {
-           lp->stats.rx_crc_errors++;
-           DEBUG(3, "%s: CRC error\n", dev->name);
+           dev->stats.rx_crc_errors++;
+           pr_debug("%s: CRC error\n", dev->name);
        }
        if (rsr & AlignErr) {
-           lp->stats.rx_fifo_errors++; /* okay ? */
-           DEBUG(3, "%s: Alignment error\n", dev->name);
+           dev->stats.rx_fifo_errors++; /* okay ? */
+           pr_debug("%s: Alignment error\n", dev->name);
        }
 
        /* clear the received/dropped/error packet */
@@ -1380,9 +1220,9 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        eth_status = GetByte(XIRCREG_ESR);
     }
     if (rx_status & 0x10) { /* Receive overrun */
-       lp->stats.rx_over_errors++;
+       dev->stats.rx_over_errors++;
        PutByte(XIRCREG_CR, ClearRxOvrun);
-       DEBUG(3, "receive overrun cleared\n");
+       pr_debug("receive overrun cleared\n");
     }
 
     /***** transmit section ******/
@@ -1393,19 +1233,19 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        nn = GetByte(XIRCREG0_PTR);
        lp->last_ptr_value = nn;
        if (nn < n) /* rollover */
-           lp->stats.tx_packets += 256 - n;
+           dev->stats.tx_packets += 256 - n;
        else if (n == nn) { /* happens sometimes - don't know why */
-           DEBUG(0, "PTR not changed?\n");
+           pr_debug("PTR not changed?\n");
        } else
-           lp->stats.tx_packets += lp->last_ptr_value - n;
+           dev->stats.tx_packets += lp->last_ptr_value - n;
        netif_wake_queue(dev);
     }
     if (tx_status & 0x0002) {  /* Execessive collissions */
-       DEBUG(0, "tx restarted due to execssive collissions\n");
+       pr_debug("tx restarted due to execssive collissions\n");
        PutByte(XIRCREG_CR, RestartTx);  /* restart transmitter process */
     }
     if (tx_status & 0x0040)
-       lp->stats.tx_aborted_errors++;
+       dev->stats.tx_aborted_errors++;
 
     /* recalculate our work chunk so that we limit the duration of this
      * ISR to about 1/10 of a second.
@@ -1420,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                maxrx_bytes = 2000;
            else if (maxrx_bytes > 22000)
                maxrx_bytes = 22000;
-           DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
+           pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
                  maxrx_bytes, bytes_rcvd, duration);
        } else if (!duration && maxrx_bytes < 22000) {
            /* now much faster */
            maxrx_bytes += 2000;
            if (maxrx_bytes > 22000)
                maxrx_bytes = 22000;
-           DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
+           pr_debug("set maxrx=%u\n", maxrx_bytes);
        }
     }
 
@@ -1448,27 +1288,36 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 /*====================================================================*/
 
 static void
-do_tx_timeout(struct net_device *dev)
+xirc2ps_tx_timeout_task(struct work_struct *work)
 {
-    local_info_t *lp = netdev_priv(dev);
-    printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
-    lp->stats.tx_errors++;
+       local_info_t *local =
+               container_of(work, local_info_t, tx_timeout_task);
+       struct net_device *dev = local->dev;
     /* reset the card */
     do_reset(dev,1);
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
     netif_wake_queue(dev);
 }
 
-static int
+static void
+xirc_tx_timeout(struct net_device *dev)
+{
+    local_info_t *lp = netdev_priv(dev);
+    dev->stats.tx_errors++;
+    printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
+    schedule_work(&lp->tx_timeout_task);
+}
+
+static netdev_tx_t
 do_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     int okay;
     unsigned freespace;
-    unsigned pktlen = skb? skb->len : 0;
+    unsigned pktlen = skb->len;
 
-    DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
+    pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
          skb, dev, pktlen);
 
 
@@ -1481,9 +1330,8 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
      */
     if (pktlen < ETH_ZLEN)
     {
-        skb = skb_padto(skb, ETH_ZLEN);
-        if (skb == NULL)
-               return 0;
+        if (skb_padto(skb, ETH_ZLEN))
+               return NETDEV_TX_OK;
        pktlen = ETH_ZLEN;
     }
 
@@ -1495,10 +1343,10 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     freespace &= 0x7fff;
     /* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
     okay = pktlen +2 < freespace;
-    DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
+    pr_debug("%s: avail. tx space=%u%s\n",
          dev->name, freespace, okay ? " (okay)":" (not enough)");
     if (!okay) { /* not enough space */
-       return 1;  /* upper layer may decide to requeue this packet */
+       return NETDEV_TX_BUSY;  /* upper layer may decide to requeue this packet */
     }
     /* send the packet */
     PutWord(XIRCREG_EDP, (u_short)pktlen);
@@ -1510,19 +1358,34 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
        PutByte(XIRCREG_CR, TransmitPacket|EnableIntr);
 
     dev_kfree_skb (skb);
-    dev->trans_start = jiffies;
-    lp->stats.tx_bytes += pktlen;
+    dev->stats.tx_bytes += pktlen;
     netif_start_queue(dev);
-    return 0;
+    return NETDEV_TX_OK;
 }
 
-static struct net_device_stats *
-do_get_stats(struct net_device *dev)
-{
-    local_info_t *lp = netdev_priv(dev);
+struct set_address_info {
+       int reg_nr;
+       int page_nr;
+       int mohawk;
+       unsigned int ioaddr;
+};
 
-    /* lp->stats.rx_missed_errors = GetByte(?) */
-    return &lp->stats;
+static void set_address(struct set_address_info *sa_info, char *addr)
+{
+       unsigned int ioaddr = sa_info->ioaddr;
+       int i;
+
+       for (i = 0; i < 6; i++) {
+               if (sa_info->reg_nr > 15) {
+                       sa_info->reg_nr = 8;
+                       sa_info->page_nr++;
+                       SelectPage(sa_info->page_nr);
+               }
+               if (sa_info->mohawk)
+                       PutByte(sa_info->reg_nr++, addr[5 - i]);
+               else
+                       PutByte(sa_info->reg_nr++, addr[i]);
+       }
 }
 
 /****************
@@ -1530,40 +1393,33 @@ do_get_stats(struct net_device *dev)
  * the next 9 addresses are taken from the multicast list and
  * the rest is filled with the individual address.
  */
-static void
-set_addresses(struct net_device *dev)
+static void set_addresses(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
-    local_info_t *lp = netdev_priv(dev);
-    struct dev_mc_list *dmi = dev->mc_list;
-    char *addr;
-    int i,j,k,n;
-
-    SelectPage(k=0x50);
-    for (i=0,j=8,n=0; ; i++, j++) {
-       if (i > 5) {
-           if (++n > 9)
-               break;
-           i = 0;
-       }
-       if (j > 15) {
-           j = 8;
-           k++;
-           SelectPage(k);
+       unsigned int ioaddr = dev->base_addr;
+       local_info_t *lp = netdev_priv(dev);
+       struct netdev_hw_addr *ha;
+       struct set_address_info sa_info;
+       int i;
+
+       /*
+        * Setup the info structure so that by first set_address call it will do
+        * SelectPage with the right page number. Hence these ones here.
+        */
+       sa_info.reg_nr = 15 + 1;
+       sa_info.page_nr = 0x50 - 1;
+       sa_info.mohawk = lp->mohawk;
+       sa_info.ioaddr = ioaddr;
+
+       set_address(&sa_info, dev->dev_addr);
+       i = 0;
+       netdev_for_each_mc_addr(ha, dev) {
+               if (i++ == 9)
+                       break;
+               set_address(&sa_info, ha->addr);
        }
-
-       if (n && n <= dev->mc_count && dmi) {
-           addr = dmi->dmi_addr;
-           dmi = dmi->next;
-       } else
-           addr = dev->dev_addr;
-
-       if (lp->mohawk)
-           PutByte(j, addr[5-i]);
-       else
-           PutByte(j, addr[i]);
-    }
-    SelectPage(0);
+       while (i++ < 9)
+               set_address(&sa_info, dev->dev_addr);
+       SelectPage(0);
 }
 
 /****************
@@ -1575,23 +1431,26 @@ set_addresses(struct net_device *dev)
 static void
 set_multicast_list(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
+    unsigned value;
 
     SelectPage(0x42);
+    value = GetByte(XIRCREG42_SWC1) & 0xC0;
+
     if (dev->flags & IFF_PROMISC) { /* snoop */
-       PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */
-    } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {
-       PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */
-    } else if (dev->mc_count) {
+       PutByte(XIRCREG42_SWC1, value | 0x06); /* set MPE and PME */
+    } else if (netdev_mc_count(dev) > 9 || (dev->flags & IFF_ALLMULTI)) {
+       PutByte(XIRCREG42_SWC1, value | 0x02); /* set MPE */
+    } else if (!netdev_mc_empty(dev)) {
        /* the chip can filter 9 addresses perfectly */
-       PutByte(XIRCREG42_SWC1, 0x00);
+       PutByte(XIRCREG42_SWC1, value | 0x01);
        SelectPage(0x40);
        PutByte(XIRCREG40_CMD0, Offline);
        set_addresses(dev);
        SelectPage(0x40);
        PutByte(XIRCREG40_CMD0, EnableRecv | Online);
     } else { /* standard usage */
-       PutByte(XIRCREG42_SWC1, 0x00);
+       PutByte(XIRCREG42_SWC1, value | 0x00);
     }
     SelectPage(0);
 }
@@ -1601,7 +1460,7 @@ do_config(struct net_device *dev, struct ifmap *map)
 {
     local_info_t *local = netdev_priv(dev);
 
-    DEBUG(0, "do_config(%p)\n", dev);
+    pr_debug("do_config(%p)\n", dev);
     if (map->port != 255 && map->port != dev->if_port) {
        if (map->port > 4)
            return -EINVAL;
@@ -1626,13 +1485,13 @@ static int
 do_open(struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_open(%p)\n", dev);
+    dev_dbg(&link->dev, "do_open(%p)\n", dev);
 
     /* Check that the PCMCIA card is still here. */
     /* Physical device present signature. */
-    if (!DEV_OK(link))
+    if (!pcmcia_dev_present(link))
        return -ENODEV;
 
     /* okay */
@@ -1651,7 +1510,7 @@ static void netdev_get_drvinfo(struct net_device *dev,
        sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-static struct ethtool_ops netdev_ethtool_ops = {
+static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
 };
 
@@ -1659,27 +1518,27 @@ static int
 do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     local_info_t *local = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
-    u16 *data = (u16 *)&rq->ifr_ifru;
+    unsigned int ioaddr = dev->base_addr;
+    struct mii_ioctl_data *data = if_mii(rq);
 
-    DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
+    pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
          dev->name, rq->ifr_ifrn.ifrn_name, cmd,
-         data[0], data[1], data[2], data[3]);
+         data->phy_id, data->reg_num, data->val_in, data->val_out);
 
     if (!local->mohawk)
        return -EOPNOTSUPP;
 
     switch(cmd) {
       case SIOCGMIIPHY:                /* Get the address of the PHY in use. */
-       data[0] = 0;            /* we have only this address */
-       /* fall trough */
+       data->phy_id = 0;       /* we have only this address */
+       /* fall through */
       case SIOCGMIIREG:                /* Read the specified MII register. */
-       data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+       data->val_out = mii_rd(ioaddr, data->phy_id & 0x1f,
+                              data->reg_num & 0x1f);
        break;
       case SIOCSMIIREG:                /* Write the specified MII register */
-       if (!capable(CAP_NET_ADMIN))
-           return -EPERM;
-       mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16);
+       mii_wr(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in,
+              16);
        break;
       default:
        return -EOPNOTSUPP;
@@ -1691,7 +1550,7 @@ static void
 hardreset(struct net_device *dev)
 {
     local_info_t *local = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
     SelectPage(4);
     udelay(1);
@@ -1708,10 +1567,10 @@ static void
 do_reset(struct net_device *dev, int full)
 {
     local_info_t *local = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     unsigned value;
 
-    DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
+    pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
 
     hardreset(dev);
     PutByte(XIRCREG_CR, SoftReset); /* set */
@@ -1749,8 +1608,8 @@ do_reset(struct net_device *dev, int full)
     }
     msleep(40);                             /* wait 40 msec to let it complete */
 
-  #ifdef PCMCIA_DEBUG
-    if (pc_debug) {
+  #if 0
+    {
        SelectPage(0);
        value = GetByte(XIRCREG_ESR);    /* read the ESR */
        printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
@@ -1767,7 +1626,7 @@ do_reset(struct net_device *dev, int full)
        value |= DisableLinkPulse;
     PutByte(XIRCREG1_ECR, value);
   #endif
-    DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
+    pr_debug("%s: ECR is: %#02x\n", dev->name, value);
 
     SelectPage(0x42);
     PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
@@ -1837,6 +1696,7 @@ do_reset(struct net_device *dev, int full)
 
     /* enable receiver and put the mac online */
     if (full) {
+       set_multicast_list(dev);
        SelectPage(0x40);
        PutByte(XIRCREG40_CMD0, EnableRecv | Online);
     }
@@ -1869,7 +1729,7 @@ static int
 init_mii(struct net_device *dev)
 {
     local_info_t *local = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     unsigned control, status, linkpartner;
     int i;
 
@@ -1942,9 +1802,9 @@ static void
 do_powerdown(struct net_device *dev)
 {
 
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "do_powerdown(%p)\n", dev);
+    pr_debug("do_powerdown(%p)\n", dev);
 
     SelectPage(4);
     PutByte(XIRCREG4_GPR1, 0);      /* clear bit 0: power down */
@@ -1954,11 +1814,11 @@ do_powerdown(struct net_device *dev)
 static int
 do_stop(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_stop(%p)\n", dev);
+    dev_dbg(&link->dev, "do_stop(%p)\n", dev);
 
     if (!link)
        return -ENODEV;
@@ -1985,7 +1845,7 @@ static struct pcmcia_device_id xirc2ps_ids[] = {
        PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
        PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
        PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
-       PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2),
+       PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
        PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a),
        PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2),
        PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37),
@@ -2009,10 +1869,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
        .drv            = {
                .name   = "xirc2ps_cs",
        },
-       .attach         = xirc2ps_attach,
-       .event          = xirc2ps_event,
-       .detach         = xirc2ps_detach,
+       .probe          = xirc2ps_probe,
+       .remove         = xirc2ps_detach,
        .id_table       = xirc2ps_ids,
+       .suspend        = xirc2ps_suspend,
+       .resume         = xirc2ps_resume,
 };
 
 static int __init
@@ -2025,7 +1886,6 @@ static void __exit
 exit_xirc2ps_cs(void)
 {
        pcmcia_unregister_driver(&xirc2ps_cs_driver);
-       BUG_ON(dev_list != NULL);
 }
 
 module_init(init_xirc2ps_cs);
@@ -2047,7 +1907,7 @@ static int __init setup_xirc2ps_cs(char *str)
        MAYBE_SET(lockup_hack, 6);
 #undef  MAYBE_SET
 
-       return 0;
+       return 1;
 }
 
 __setup("xirc2ps_cs=", setup_xirc2ps_cs);