pcmcia: pcmcia_config_loop() ConfigIndex unification
[linux-2.6.git] / drivers / net / pcmcia / smc91c92_cs.c
index b46b7e1..1e59503 100644 (file)
@@ -80,14 +80,14 @@ INT_MODULE_PARM(if_port, 0);
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 static const char *version =
-"smc91c92_cs.c 0.09 1996/8/4 Donald Becker, becker@scyld.com.\n";
+"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 #else
 #define DEBUG(n, args...)
 #endif
 
 #define DRV_NAME       "smc91c92_cs"
-#define DRV_VERSION    "1.122"
+#define DRV_VERSION    "1.123"
 
 /*====================================================================*/
 
@@ -104,7 +104,7 @@ static const char *version =
 #define MEMORY_WAIT_TIME               8
 
 struct smc_private {
-    dev_link_t                 link;
+       struct pcmcia_device    *p_dev;
     spinlock_t                 lock;
     u_short                    manfid;
     u_short                    cardid;
@@ -279,15 +279,15 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
 /*====================================================================*/
 
 static void smc91c92_detach(struct pcmcia_device *p_dev);
-static void smc91c92_config(dev_link_t *link);
-static void smc91c92_release(dev_link_t *link);
+static int smc91c92_config(struct pcmcia_device *link);
+static void smc91c92_release(struct pcmcia_device *link);
 
 static int smc_open(struct net_device *dev);
 static int smc_close(struct net_device *dev);
 static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void smc_tx_timeout(struct net_device *dev);
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t smc_interrupt(int irq, void *dev_id);
 static void smc_rx(struct net_device *dev);
 static struct net_device_stats *smc_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -295,11 +295,11 @@ static int s9k_config(struct net_device *dev, struct ifmap *map);
 static void smc_set_xcvr(struct net_device *dev, int if_port);
 static void smc_reset(struct net_device *dev);
 static void media_check(u_long arg);
-static void mdio_sync(kio_addr_t addr);
+static void mdio_sync(unsigned int addr);
 static int mdio_read(struct net_device *dev, int phy_id, int loc);
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
 static int smc_link_ok(struct net_device *dev);
-static struct ethtool_ops ethtool_ops;
+static const struct ethtool_ops ethtool_ops;
 
 /*======================================================================
 
@@ -309,10 +309,9 @@ static struct ethtool_ops ethtool_ops;
 
 ======================================================================*/
 
-static int smc91c92_attach(struct pcmcia_device *p_dev)
+static int smc91c92_probe(struct pcmcia_device *link)
 {
     struct smc_private *smc;
-    dev_link_t *link;
     struct net_device *dev;
 
     DEBUG(0, "smc91c92_attach()\n");
@@ -322,14 +321,14 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
     if (!dev)
        return -ENOMEM;
     smc = netdev_priv(dev);
-    link = &smc->link;
+    smc->p_dev = link;
     link->priv = dev;
 
     spin_lock_init(&smc->lock);
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &smc_interrupt;
     link->irq.Instance = dev;
@@ -337,7 +336,6 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     /* The SMC91c92-specific entries in the device structure. */
-    SET_MODULE_OWNER(dev);
     dev->hard_start_xmit = &smc_start_xmit;
     dev->get_stats = &smc_get_stats;
     dev->set_config = &s9k_config;
@@ -357,13 +355,7 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
     smc->mii_if.phy_id_mask = 0x1f;
     smc->mii_if.reg_num_mask = 0x1f;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    smc91c92_config(link);
-
-    return 0;
+    return smc91c92_config(link);
 } /* smc91c92_attach */
 
 /*======================================================================
@@ -375,18 +367,16 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
 
 ======================================================================*/
 
-static void smc91c92_detach(struct pcmcia_device *p_dev)
+static void smc91c92_detach(struct pcmcia_device *link)
 {
-    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
 
     DEBUG(0, "smc91c92_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
        unregister_netdev(dev);
 
-    if (link->state & DEV_CONFIG)
-       smc91c92_release(link);
+    smc91c92_release(link);
 
     free_netdev(dev);
 } /* smc91c92_detach */
@@ -414,7 +404,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
 
 /*====================================================================*/
 
-static int first_tuple(client_handle_t handle, tuple_t *tuple,
+static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
                cisparse_t *parse)
 {
        int i;
@@ -425,7 +415,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
        return pcmcia_parse_tuple(handle, tuple, parse);
 }
 
-static int next_tuple(client_handle_t handle, tuple_t *tuple,
+static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
                cisparse_t *parse)
 {
        int i;
@@ -447,7 +437,7 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
 
 ======================================================================*/
 
-static int mhz_3288_power(dev_link_t *link)
+static int mhz_3288_power(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
@@ -469,28 +459,35 @@ static int mhz_3288_power(dev_link_t *link)
     return 0;
 }
 
-static int mhz_mfc_config(dev_link_t *link)
+static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cf,
+                               void *priv_data)
+{
+       int k;
+       p_dev->io.BasePort2 = cf->io.win[0].base;
+       for (k = 0; k < 0x400; k += 0x10) {
+               if (k & 0x80)
+                       continue;
+               p_dev->io.BasePort1 = k ^ 0x300;
+               if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       return 0;
+       }
+       return -ENODEV;
+}
+
+static int mhz_mfc_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
     struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_cftable_entry_t *cf;
-    u_char *buf;
     win_req_t req;
     memreq_t mem;
-    int i, k;
+    int i;
 
     cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
     if (!cfg_mem)
         return CS_OUT_OF_RESOURCE;
 
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    cf = &parse->cftable_entry;
-    buf = cfg_mem->buf;
-
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
@@ -499,27 +496,9 @@ static int mhz_mfc_config(dev_link_t *link)
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
 
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-    i = first_tuple(link->handle, tuple, parse);
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
-    while (i == CS_SUCCESS) {
-       link->conf.ConfigIndex = cf->index;
-       link->io.BasePort2 = cf->io.win[0].base;
-       for (k = 0; k < 0x400; k += 0x10) {
-           if (k & 0x80) continue;
-           link->io.BasePort1 = k ^ 0x300;
-           i = pcmcia_request_io(link->handle, &link->io);
-           if (i == CS_SUCCESS) break;
-       }
-       if (i == CS_SUCCESS) break;
-       i = next_tuple(link->handle, tuple, parse);
-    }
-    if (i != CS_SUCCESS)
+    if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
        goto free_cfg_mem;
     dev->base_addr = link->io.BasePort1;
 
@@ -527,7 +506,7 @@ static int mhz_mfc_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;
-    i = pcmcia_request_window(&link->handle, &req, &link->win);
+    i = pcmcia_request_window(&link, &req, &link->win);
     if (i != CS_SUCCESS)
        goto free_cfg_mem;
     smc->base = ioremap(req.Base, req.Size);
@@ -543,12 +522,11 @@ static int mhz_mfc_config(dev_link_t *link)
 
 free_cfg_mem:
     kfree(cfg_mem);
-    return i;
+    return -ENODEV;
 }
 
-static int mhz_setup(dev_link_t *link)
+static int mhz_setup(struct pcmcia_device *link)
 {
-    client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     struct smc_cfg_mem *cfg_mem;
     tuple_t *tuple;
@@ -571,13 +549,13 @@ static int mhz_setup(dev_link_t *link)
     /* Read the station address from the CIS.  It is stored as the last
        (fourth) string in the Version 1 Version/ID tuple. */
     tuple->DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
+    if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
        rc = -1;
        goto free_cfg_mem;
     }
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(handle, tuple, parse) != CS_SUCCESS)
-       first_tuple(handle, tuple, parse);
+    if (next_tuple(link, tuple, parse) != CS_SUCCESS)
+       first_tuple(link, tuple, parse);
     if (parse->version_1.ns > 3) {
        station_addr = parse->version_1.str + parse->version_1.ofs[3];
        if (cvt_ascii_address(dev, station_addr) == 0) {
@@ -588,11 +566,11 @@ static int mhz_setup(dev_link_t *link)
 
     /* Another possibility: for the EM3288, in a special tuple */
     tuple->DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) {
+    if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) {
        rc = -1;
        goto free_cfg_mem;
     }
-    if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) {
+    if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) {
        rc = -1;
        goto free_cfg_mem;
     }
@@ -616,12 +594,12 @@ free_cfg_mem:
 
 ======================================================================*/
 
-static void mot_config(dev_link_t *link)
+static void mot_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
-    kio_addr_t iouart = link->io.BasePort2;
+    unsigned int ioaddr = dev->base_addr;
+    unsigned int iouart = link->io.BasePort2;
 
     /* Set UART base address and force map with COR bit 1 */
     writeb(iouart & 0xff,        smc->base + MOT_UART + CISREG_IOBASE_0);
@@ -637,10 +615,10 @@ static void mot_config(dev_link_t *link)
     mdelay(100);
 }
 
-static int mot_setup(dev_link_t *link)
+static int mot_setup(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     int i, wait, loop;
     u_int addr;
 
@@ -671,52 +649,30 @@ static int mot_setup(dev_link_t *link)
 
 /*====================================================================*/
 
-static int smc_config(dev_link_t *link)
+static int smc_configcheck(struct pcmcia_device *p_dev,
+                          cistpl_cftable_entry_t *cf,
+                          void *priv_data)
+{
+       p_dev->io.BasePort1 = cf->io.win[0].base;
+       p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+       return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
+static int smc_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_cftable_entry_t *cf;
-    u_char *buf;
     int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-       return CS_OUT_OF_RESOURCE;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    cf = &parse->cftable_entry;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
     link->io.NumPorts1 = 16;
-    i = first_tuple(link->handle, tuple, parse);
-    while (i != CS_NO_MORE_ITEMS) {
-       if (i == CS_SUCCESS) {
-           link->conf.ConfigIndex = cf->index;
-           link->io.BasePort1 = cf->io.win[0].base;
-           link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-           i = pcmcia_request_io(link->handle, &link->io);
-           if (i == CS_SUCCESS) break;
-       }
-       i = next_tuple(link->handle, tuple, parse);
-    }
-    if (i == CS_SUCCESS)
-       dev->base_addr = link->io.BasePort1;
+    i = pcmcia_loop_config(link, smc_configcheck, NULL);
+    if (!i)
+           dev->base_addr = link->io.BasePort1;
 
-    kfree(cfg_mem);
     return i;
 }
 
-static int smc_setup(dev_link_t *link)
+static int smc_setup(struct pcmcia_device *link)
 {
-    client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     struct smc_cfg_mem *cfg_mem;
     tuple_t *tuple;
@@ -739,11 +695,11 @@ static int smc_setup(dev_link_t *link)
 
     /* Check for a LAN function extension tuple */
     tuple->DesiredTuple = CISTPL_FUNCE;
-    i = first_tuple(handle, tuple, parse);
+    i = first_tuple(link, tuple, parse);
     while (i == CS_SUCCESS) {
        if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
            break;
-       i = next_tuple(handle, tuple, parse);
+       i = next_tuple(link, tuple, parse);
     }
     if (i == CS_SUCCESS) {
        node_id = (cistpl_lan_node_id_t *)parse->funce.data;
@@ -755,15 +711,12 @@ static int smc_setup(dev_link_t *link)
        }
     }
     /* Try the third string in the Version 1 Version/ID tuple. */
-    tuple->DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    station_addr = parse->version_1.str + parse->version_1.ofs[2];
-    if (cvt_ascii_address(dev, station_addr) == 0) {
-       rc = 0;
-       goto free_cfg_mem;
+    if (link->prod_id[2]) {
+       station_addr = link->prod_id[2];
+       if (cvt_ascii_address(dev, station_addr) == 0) {
+               rc = 0;
+               goto free_cfg_mem;
+       }
     }
 
     rc = -1;
@@ -774,10 +727,10 @@ free_cfg_mem:
 
 /*====================================================================*/
 
-static int osi_config(dev_link_t *link)
+static int osi_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    static const kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+    static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
     int i, j;
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -794,22 +747,21 @@ static int osi_config(dev_link_t *link)
 
     for (i = j = 0; j < 4; j++) {
        link->io.BasePort2 = com[j];
-       i = pcmcia_request_io(link->handle, &link->io);
+       i = pcmcia_request_io(link, &link->io);
        if (i == CS_SUCCESS) break;
     }
     if (i != CS_SUCCESS) {
        /* Fallback: turn off hard decode */
        link->conf.ConfigIndex = 0x03;
        link->io.NumPorts2 = 0;
-       i = pcmcia_request_io(link->handle, &link->io);
+       i = pcmcia_request_io(link, &link->io);
     }
     dev->base_addr = link->io.BasePort1 + 0x10;
     return i;
 }
 
-static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
 {
-    client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     struct smc_cfg_mem *cfg_mem;
     tuple_t *tuple;
@@ -830,12 +782,12 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
 
     /* Read the station address from tuple 0x90, subtuple 0x04 */
     tuple->DesiredTuple = 0x90;
-    i = pcmcia_get_first_tuple(handle, tuple);
+    i = pcmcia_get_first_tuple(link, tuple);
     while (i == CS_SUCCESS) {
-       i = pcmcia_get_tuple_data(handle, tuple);
+       i = pcmcia_get_tuple_data(link, tuple);
        if ((i != CS_SUCCESS) || (buf[0] == 0x04))
            break;
-       i = pcmcia_get_next_tuple(handle, tuple);
+       i = pcmcia_get_next_tuple(link, tuple);
     }
     if (i != CS_SUCCESS) {
        rc = -1;
@@ -868,51 +820,47 @@ free_cfg_mem:
    return rc;
 }
 
-static int smc91c92_suspend(struct pcmcia_device *p_dev)
+static int smc91c92_suspend(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *dev = link->priv;
 
-       if ((link->state & DEV_CONFIG) && (link->open))
+       if (link->open)
                netif_device_detach(dev);
 
        return 0;
 }
 
-static int smc91c92_resume(struct pcmcia_device *p_dev)
+static int smc91c92_resume(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *dev = link->priv;
        struct smc_private *smc = netdev_priv(dev);
        int i;
 
-       if (link->state & DEV_CONFIG) {
-               if ((smc->manfid == MANFID_MEGAHERTZ) &&
-                   (smc->cardid == PRODID_MEGAHERTZ_EM3288))
-                       mhz_3288_power(link);
-               if (smc->manfid == MANFID_MOTOROLA)
-                       mot_config(link);
-               if ((smc->manfid == MANFID_OSITECH) &&
-                   (smc->cardid != PRODID_OSITECH_SEVEN)) {
-                       /* Power up the card and enable interrupts */
-                       set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
-                       set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
-               }
-               if (((smc->manfid == MANFID_OSITECH) &&
-                    (smc->cardid == PRODID_OSITECH_SEVEN)) ||
-                   ((smc->manfid == MANFID_PSION) &&
-                    (smc->cardid == PRODID_PSION_NET100))) {
-                       /* Download the Seven of Diamonds firmware */
-                       for (i = 0; i < sizeof(__Xilinx7OD); i++) {
-                               outb(__Xilinx7OD[i], link->io.BasePort1+2);
-                               udelay(50);
-                       }
-               }
-               if (link->open) {
-                       smc_reset(dev);
-                       netif_device_attach(dev);
+       if ((smc->manfid == MANFID_MEGAHERTZ) &&
+           (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+               mhz_3288_power(link);
+       if (smc->manfid == MANFID_MOTOROLA)
+               mot_config(link);
+       if ((smc->manfid == MANFID_OSITECH) &&
+           (smc->cardid != PRODID_OSITECH_SEVEN)) {
+               /* Power up the card and enable interrupts */
+               set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
+               set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
+       }
+       if (((smc->manfid == MANFID_OSITECH) &&
+            (smc->cardid == PRODID_OSITECH_SEVEN)) ||
+           ((smc->manfid == MANFID_PSION) &&
+            (smc->cardid == PRODID_PSION_NET100))) {
+               /* Download the Seven of Diamonds firmware */
+               for (i = 0; i < sizeof(__Xilinx7OD); i++) {
+                       outb(__Xilinx7OD[i], link->io.BasePort1+2);
+                       udelay(50);
                }
        }
+       if (link->open) {
+               smc_reset(dev);
+               netif_device_attach(dev);
+       }
 
        return 0;
 }
@@ -925,10 +873,10 @@ static int smc91c92_resume(struct pcmcia_device *p_dev)
 
 ======================================================================*/
 
-static int check_sig(dev_link_t *link)
+static int check_sig(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     int width;
     u_short s;
 
@@ -963,9 +911,9 @@ static int check_sig(dev_link_t *link)
            };
            printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
 
-           smc91c92_suspend(link->handle);
-           pcmcia_modify_configuration(link->handle, &mod);
-           smc91c92_resume(link->handle);
+           smc91c92_suspend(link);
+           pcmcia_modify_configuration(link, &mod);
+           smc91c92_resume(link);
            return check_sig(link);
     }
     return -ENODEV;
@@ -980,51 +928,22 @@ static int check_sig(dev_link_t *link)
 ======================================================================*/
 
 #define CS_EXIT_TEST(ret, svc, label) \
-if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; }
+if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; }
 
-static void smc91c92_config(dev_link_t *link)
+static int smc91c92_config(struct pcmcia_device *link)
 {
-    client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    u_char *buf;
     char *name;
     int i, j, rev;
-    kio_addr_t ioaddr;
+    unsigned int ioaddr;
     u_long mir;
+    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "smc91c92_config(0x%p)\n", link);
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-       goto config_failed;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 64;
-
-    tuple->DesiredTuple = CISTPL_CONFIG;
-    i = first_tuple(handle, tuple, parse);
-    CS_EXIT_TEST(i, ParseTuple, config_failed);
-    link->conf.ConfigBase = parse->config.base;
-    link->conf.Present = parse->config.rmask[0];
-
-    tuple->DesiredTuple = CISTPL_MANFID;
-    tuple->Attributes = TUPLE_RETURN_COMMON;
-    if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
-       smc->manfid = parse->manfid.manf;
-       smc->cardid = parse->manfid.card;
-    }
-
-    /* Configure card */
-    link->state |= DEV_CONFIG;
+    smc->manfid = link->manf_id;
+    smc->cardid = link->card_id;
 
     if ((smc->manfid == MANFID_OSITECH) &&
        (smc->cardid != PRODID_OSITECH_SEVEN)) {
@@ -1039,9 +958,9 @@ static void smc91c92_config(dev_link_t *link)
     }
     CS_EXIT_TEST(i, RequestIO, config_failed);
 
-    i = pcmcia_request_irq(link->handle, &link->irq);
+    i = pcmcia_request_irq(link, &link->irq);
     CS_EXIT_TEST(i, RequestIRQ, config_failed);
-    i = pcmcia_request_configuration(link->handle, &link->conf);
+    i = pcmcia_request_configuration(link, &link->conf);
     CS_EXIT_TEST(i, RequestConfiguration, config_failed);
 
     if (smc->manfid == MANFID_MOTOROLA)
@@ -1120,23 +1039,21 @@ static void smc91c92_config(dev_link_t *link)
        SMC_SELECT_BANK(0);
     }
 
-    link->dev = &smc->node;
-    link->state &= ~DEV_CONFIG_PENDING;
-    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+    link->dev_node = &smc->node;
+    SET_NETDEV_DEV(dev, &handle_to_dev(link));
 
     if (register_netdev(dev) != 0) {
        printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
-       link->dev = NULL;
+       link->dev_node = NULL;
        goto config_undo;
     }
 
     strcpy(smc->node.dev_name, dev->name);
 
     printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
-          "hw_addr ", dev->name, name, (rev & 0x0f), dev->base_addr,
-          dev->irq);
-    for (i = 0; i < 6; i++)
-       printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
+          "hw_addr %s\n",
+          dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
+          print_mac(mac, dev->dev_addr));
 
     if (rev > 0) {
        if (mir & 0x3ff)
@@ -1155,16 +1072,13 @@ static void smc91c92_config(dev_link_t *link)
            printk(KERN_NOTICE "  No MII transceivers found!\n");
        }
     }
-    kfree(cfg_mem);
-    return;
+    return 0;
 
 config_undo:
     unregister_netdev(dev);
 config_failed:                 /* CS_EXIT_TEST() calls jump to here... */
     smc91c92_release(link);
-    link->state &= ~DEV_CONFIG_PENDING;
-    kfree(cfg_mem);
-
+    return -ENODEV;
 } /* smc91c92_config */
 
 /*======================================================================
@@ -1175,7 +1089,7 @@ config_failed:                    /* CS_EXIT_TEST() calls jump to here... */
 
 ======================================================================*/
 
-static void smc91c92_release(dev_link_t *link)
+static void smc91c92_release(struct pcmcia_device *link)
 {
        DEBUG(0, "smc91c92_release(0x%p)\n", link);
        if (link->win) {
@@ -1183,7 +1097,7 @@ static void smc91c92_release(dev_link_t *link)
                struct smc_private *smc = netdev_priv(dev);
                iounmap(smc->base);
        }
-       pcmcia_disable_device(link->handle);
+       pcmcia_disable_device(link);
 }
 
 /*======================================================================
@@ -1198,7 +1112,7 @@ static void smc91c92_release(dev_link_t *link)
 #define MDIO_DATA_WRITE1       (MDIO_DIR_WRITE | MDIO_DATA_OUT)
 #define MDIO_DATA_READ         0x02
 
-static void mdio_sync(kio_addr_t addr)
+static void mdio_sync(unsigned int addr)
 {
     int bits;
     for (bits = 0; bits < 32; bits++) {
@@ -1209,7 +1123,7 @@ static void mdio_sync(kio_addr_t addr)
 
 static int mdio_read(struct net_device *dev, int phy_id, int loc)
 {
-    kio_addr_t addr = dev->base_addr + MGMT;
+    unsigned int addr = dev->base_addr + MGMT;
     u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
     int i, retval = 0;
 
@@ -1229,7 +1143,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int loc)
 
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
 {
-    kio_addr_t addr = dev->base_addr + MGMT;
+    unsigned int addr = dev->base_addr + MGMT;
     u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
     int i;
 
@@ -1255,7 +1169,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
 #ifdef PCMCIA_DEBUG
 static void smc_dump(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_short i, w, save;
     save = inw(ioaddr + BANK_SELECT);
     for (w = 0; w < 4; w++) {
@@ -1272,7 +1186,7 @@ static void smc_dump(struct net_device *dev)
 static int smc_open(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    dev_link_t *link = &smc->link;
+    struct pcmcia_device *link = smc->p_dev;
 
 #ifdef PCMCIA_DEBUG
     DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
@@ -1281,7 +1195,7 @@ static int smc_open(struct net_device *dev)
 #endif
 
     /* Check that the PCMCIA card is still here. */
-    if (!DEV_OK(link))
+    if (!pcmcia_dev_present(link))
        return -ENODEV;
     /* Physical device present signature. */
     if (check_sig(link) < 0) {
@@ -1309,8 +1223,8 @@ static int smc_open(struct net_device *dev)
 static int smc_close(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    dev_link_t *link = &smc->link;
-    kio_addr_t ioaddr = dev->base_addr;
+    struct pcmcia_device *link = smc->p_dev;
+    unsigned int ioaddr = dev->base_addr;
 
     DEBUG(0, "%s: smc_close(), status %4.4x.\n",
          dev->name, inw(ioaddr + BANK_SELECT));
@@ -1347,7 +1261,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
 {
     struct smc_private *smc = netdev_priv(dev);
     struct sk_buff *skb = smc->saved_skb;
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_char packet_no;
 
     if (!skb) {
@@ -1411,7 +1325,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
 static void smc_tx_timeout(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
     printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
           "Tx_status %2.2x status %4.4x.\n",
@@ -1426,9 +1340,10 @@ static void smc_tx_timeout(struct net_device *dev)
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_short num_pages;
     short time_out, ir;
+    unsigned long flags;
 
     netif_stop_queue(dev);
 
@@ -1456,6 +1371,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
     /* A packet is now waiting. */
     smc->packets_waiting++;
 
+    spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(2);        /* Paranoia, we should always be in window 2 */
 
     /* need MC_RESET to keep the memory consistent. errata? */
@@ -1472,6 +1388,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
            /* Acknowledge the interrupt, send the packet. */
            outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
            smc_hardware_send_packet(dev);      /* Send the packet now.. */
+           spin_unlock_irqrestore(&smc->lock, flags);
            return 0;
        }
     }
@@ -1479,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
     /* Otherwise defer until the Tx-space-allocated interrupt. */
     DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
+    spin_unlock_irqrestore(&smc->lock, flags);
 
     return 0;
 }
@@ -1492,7 +1410,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static void smc_tx_err(struct net_device * dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     int saved_packet = inw(ioaddr + PNR_ARR) & 0xff;
     int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f;
     int tx_status;
@@ -1536,7 +1454,7 @@ static void smc_tx_err(struct net_device * dev)
 static void smc_eph_irq(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_short card_stats, ephs;
 
     SMC_SELECT_BANK(0);
@@ -1567,11 +1485,11 @@ static void smc_eph_irq(struct net_device *dev)
 
 /*====================================================================*/
 
-static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smc_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = dev_id;
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr;
+    unsigned int ioaddr;
     u_short saved_bank, saved_pointer, mask, status;
     unsigned int handled = 1;
     char bogus_cnt = INTR_WORK;                /* Work we are willing to do. */
@@ -1584,6 +1502,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
          irq, ioaddr);
 
+    spin_lock(&smc->lock);
     smc->watchdog = 0;
     saved_bank = inw(ioaddr + BANK_SELECT);
     if ((saved_bank & 0xff00) != 0x3300) {
@@ -1681,6 +1600,7 @@ irq_done:
        readb(smc->base+MEGAHERTZ_ISR);
     }
 #endif
+    spin_unlock(&smc->lock);
     return IRQ_RETVAL(handled);
 }
 
@@ -1689,7 +1609,7 @@ irq_done:
 static void smc_rx(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     int rx_status;
     int packet_length; /* Caution: not frame length, rather words
                           to transfer from the chip. */
@@ -1730,7 +1650,6 @@ static void smc_rx(struct net_device *dev)
             (packet_length+1)>>1);
        skb->protocol = eth_type_trans(skb, dev);
        
-       skb->dev = dev;
        netif_rx(skb);
        dev->last_rx = jiffies;
        smc->stats.rx_packets++;
@@ -1795,14 +1714,13 @@ static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
 
 static void set_rx_mode(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
     u_int multicast_table[ 2 ] = { 0, };
     unsigned long flags;
     u_short rx_cfg_setting;
 
     if (dev->flags & IFF_PROMISC) {
-       printk(KERN_NOTICE "%s: setting Rx mode to promiscuous.\n", dev->name);
        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
     } else if (dev->flags & IFF_ALLMULTI)
        rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti;
@@ -1862,7 +1780,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map)
 static void smc_set_xcvr(struct net_device *dev, int if_port)
 {
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_short saved_bank;
 
     saved_bank = inw(ioaddr + BANK_SELECT);
@@ -1885,7 +1803,7 @@ static void smc_set_xcvr(struct net_device *dev, int if_port)
 
 static void smc_reset(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
     int i;
 
@@ -1905,7 +1823,7 @@ static void smc_reset(struct net_device *dev)
     /* Set the Window 1 control, configuration and station addr registers.
        No point in writing the I/O base register ;-> */
     SMC_SELECT_BANK(1);
-    /* Automatically release succesfully transmitted packets,
+    /* Automatically release successfully transmitted packets,
        Accept link errors, counter and Tx error interrupts. */
     outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
         ioaddr + CONTROL);
@@ -1962,9 +1880,12 @@ static void media_check(u_long arg)
 {
     struct net_device *dev = (struct net_device *) arg;
     struct smc_private *smc = netdev_priv(dev);
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     u_short i, media, saved_bank;
     u_short link;
+    unsigned long flags;
+
+    spin_lock_irqsave(&smc->lock, flags);
 
     saved_bank = inw(ioaddr + BANK_SELECT);
 
@@ -1989,7 +1910,7 @@ static void media_check(u_long arg)
     if (smc->watchdog++ && ((i>>8) & i)) {
        if (!smc->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-       smc_interrupt(dev->irq, smc, NULL);
+       smc_interrupt(dev->irq, dev);
        smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
@@ -1997,6 +1918,7 @@ static void media_check(u_long arg)
        smc->media.expires = jiffies + HZ/100;
        add_timer(&smc->media);
        SMC_SELECT_BANK(saved_bank);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return;
     }
 
@@ -2070,11 +1992,12 @@ reschedule:
     smc->media.expires = jiffies + HZ;
     add_timer(&smc->media);
     SMC_SELECT_BANK(saved_bank);
+    spin_unlock_irqrestore(&smc->lock, flags);
 }
 
 static int smc_link_ok(struct net_device *dev)
 {
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
 
     if (smc->cfg & CFG_MII_SELECT) {
@@ -2088,7 +2011,7 @@ static int smc_link_ok(struct net_device *dev)
 static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
     u16 tmp;
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
     ecmd->supported = (SUPPORTED_TP | SUPPORTED_AUI |
        SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full);
@@ -2110,7 +2033,7 @@ static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
     u16 tmp;
-    kio_addr_t ioaddr = dev->base_addr;
+    unsigned int ioaddr = dev->base_addr;
 
     if (ecmd->speed != SPEED_10)
        return -EINVAL;
@@ -2153,51 +2076,51 @@ static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
 static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct smc_private *smc = netdev_priv(dev);
-       kio_addr_t ioaddr = dev->base_addr;
+       unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
 
-       SMC_SELECT_BANK(3);
        spin_lock_irq(&smc->lock);
+       SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_gset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_get_ecmd(dev, ecmd);
-       spin_unlock_irq(&smc->lock);
        SMC_SELECT_BANK(saved_bank);
+       spin_unlock_irq(&smc->lock);
        return ret;
 }
 
 static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct smc_private *smc = netdev_priv(dev);
-       kio_addr_t ioaddr = dev->base_addr;
+       unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
 
-       SMC_SELECT_BANK(3);
        spin_lock_irq(&smc->lock);
+       SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_sset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_set_ecmd(dev, ecmd);
-       spin_unlock_irq(&smc->lock);
        SMC_SELECT_BANK(saved_bank);
+       spin_unlock_irq(&smc->lock);
        return ret;
 }
 
 static u32 smc_get_link(struct net_device *dev)
 {
        struct smc_private *smc = netdev_priv(dev);
-       kio_addr_t ioaddr = dev->base_addr;
+       unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        u32 ret;
 
-       SMC_SELECT_BANK(3);
        spin_lock_irq(&smc->lock);
+       SMC_SELECT_BANK(3);
        ret = smc_link_ok(dev);
-       spin_unlock_irq(&smc->lock);
        SMC_SELECT_BANK(saved_bank);
+       spin_unlock_irq(&smc->lock);
        return ret;
 }
 
@@ -2217,7 +2140,7 @@ static int smc_nway_reset(struct net_device *dev)
 {
        struct smc_private *smc = netdev_priv(dev);
        if (smc->cfg & CFG_MII_SELECT) {
-               kio_addr_t ioaddr = dev->base_addr;
+               unsigned int ioaddr = dev->base_addr;
                u16 saved_bank = inw(ioaddr + BANK_SELECT);
                int res;
 
@@ -2230,7 +2153,7 @@ static int smc_nway_reset(struct net_device *dev)
                return -EOPNOTSUPP;
 }
 
-static struct ethtool_ops ethtool_ops = {
+static const struct ethtool_ops ethtool_ops = {
        .begin = check_if_running,
        .get_drvinfo = smc_get_drvinfo,
        .get_settings = smc_get_settings,
@@ -2249,7 +2172,7 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
        struct mii_ioctl_data *mii = if_mii(rq);
        int rc = 0;
        u16 saved_bank;
-       kio_addr_t ioaddr = dev->base_addr;
+       unsigned int ioaddr = dev->base_addr;
 
        if (!netif_running(dev))
                return -EINVAL;
@@ -2300,7 +2223,7 @@ static struct pcmcia_driver smc91c92_cs_driver = {
        .drv            = {
                .name   = "smc91c92_cs",
        },
-       .probe          = smc91c92_attach,
+       .probe          = smc91c92_probe,
        .remove         = smc91c92_detach,
        .id_table       = smc91c92_ids,
        .suspend        = smc91c92_suspend,