Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[safe/jmp/linux-2.6] / drivers / net / pcmcia / smc91c92_cs.c
index 37e05d3..7b6fe89 100644 (file)
@@ -79,14 +79,6 @@ MODULE_FIRMWARE(FIRMWARE_NAME);
 */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-static const char *version =
-"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.123"
@@ -111,7 +103,6 @@ struct smc_private {
     u_short                    manfid;
     u_short                    cardid;
 
-    dev_node_t                 node;
     struct sk_buff             *saved_skb;
     int                                packets_waiting;
     void                       __iomem *base;
@@ -126,12 +117,6 @@ struct smc_private {
     int                                rx_ovrn;
 };
 
-struct smc_cfg_mem {
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255];
-};
-
 /* Special definitions for Megahertz multifunction cards */
 #define MEGAHERTZ_ISR          0x0380
 
@@ -288,7 +273,8 @@ 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 netdev_tx_t smc_start_xmit(struct sk_buff *skb,
+                                       struct net_device *dev);
 static irqreturn_t smc_interrupt(int irq, void *dev_id);
 static void smc_rx(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -328,7 +314,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
     struct smc_private *smc;
     struct net_device *dev;
 
-    DEBUG(0, "smc91c92_attach()\n");
+    dev_dbg(&link->dev, "smc91c92_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct smc_private));
@@ -336,16 +322,11 @@ static int smc91c92_probe(struct pcmcia_device *link)
        return -ENOMEM;
     smc = netdev_priv(dev);
     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_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &smc_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -376,10 +357,9 @@ static void smc91c92_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "smc91c92_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_detach\n");
 
-    if (link->dev_node)
-       unregister_netdev(dev);
+    unregister_netdev(dev);
 
     smc91c92_release(link);
 
@@ -407,34 +387,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
     return 0;
 }
 
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-               cisparse_t *parse)
-{
-       int i;
-
-       i = pcmcia_get_first_tuple(handle, tuple);
-       if (i != 0)
-               return i;
-       i = pcmcia_get_tuple_data(handle, tuple);
-       if (i != 0)
-               return i;
-       return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-               cisparse_t *parse)
-{
-       int i;
-
-       if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
-                       (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
-               return i;
-       return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
 
     Configuration stuff for Megahertz cards
 
@@ -489,19 +442,12 @@ 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;
     win_req_t req;
     memreq_t mem;
     int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-           return -ENOMEM;
-
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes =
-       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
     link->io.IOAddrLines = 16;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -509,91 +455,81 @@ static int mhz_mfc_config(struct pcmcia_device *link)
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
     if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
-       goto free_cfg_mem;
+           return -ENODEV;
+
     dev->base_addr = link->io.BasePort1;
 
     /* Allocate a memory window, for accessing the ISR */
     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, &req, &link->win);
+    i = pcmcia_request_window(link, &req, &link->win);
     if (i != 0)
-       goto free_cfg_mem;
+           return -ENODEV;
+
     smc->base = ioremap(req.Base, req.Size);
     mem.CardOffset = mem.Page = 0;
     if (smc->manfid == MANFID_MOTOROLA)
        mem.CardOffset = link->conf.ConfigBase;
-    i = pcmcia_map_mem_page(link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, &mem);
 
-    if ((i == 0)
-       && (smc->manfid == MANFID_MEGAHERTZ)
-       && (smc->cardid == PRODID_MEGAHERTZ_EM3288))
-       mhz_3288_power(link);
+    if ((i == 0) &&
+       (smc->manfid == MANFID_MEGAHERTZ) &&
+       (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+           mhz_3288_power(link);
 
-free_cfg_mem:
-    kfree(cfg_mem);
-    return -ENODEV;
+    return 0;
 }
 
-static int mhz_setup(struct pcmcia_device *link)
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+                             tuple_t *tuple,
+                             void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    u_char *buf, *station_addr;
-    int rc;
+       struct net_device *dev = priv;
+       cisparse_t parse;
+       u8 *buf;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-       return -1;
+       if (pcmcia_parse_tuple(tuple, &parse))
+               return -EINVAL;
+
+       buf = parse.version_1.str + parse.version_1.ofs[3];
 
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
+       if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0))
+               return 0;
 
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
+       return -EINVAL;
+};
+
+static int mhz_setup(struct pcmcia_device *link)
+{
+    struct net_device *dev = link->priv;
+    size_t len;
+    u8 *buf;
+    int rc;
 
     /* 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(link, tuple, parse) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
+    if ((link->prod_id[3]) &&
+       (cvt_ascii_address(dev, link->prod_id[3]) == 0))
+           return 0;
+
+    /* Workarounds for broken cards start here. */
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(link, tuple, parse) != 0)
-       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) {
-               rc = 0;
-               goto free_cfg_mem;
-       }
-    }
+    if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+           return 0;
 
     /* Another possibility: for the EM3288, in a special tuple */
-    tuple->DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(link, tuple) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    if (pcmcia_get_tuple_data(link, tuple) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    buf[12] = '\0';
-    if (cvt_ascii_address(dev, buf) == 0) {
-       rc = 0;
-       goto free_cfg_mem;
-   }
     rc = -1;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
-}
+    len = pcmcia_get_tuple(link, 0x81, &buf);
+    if (buf && len >= 13) {
+           buf[12] = '\0';
+           if (cvt_ascii_address(dev, buf) == 0)
+                   rc = 0;
+    }
+    kfree(buf);
+
+    return rc;
+};
 
 /*======================================================================
 
@@ -683,58 +619,21 @@ static int smc_config(struct pcmcia_device *link)
     return i;
 }
 
+
 static int smc_setup(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_lan_node_id_t *node_id;
-    u_char *buf, *station_addr;
-    int i, rc;
-
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-           return -ENOMEM;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
 
     /* Check for a LAN function extension tuple */
-    tuple->DesiredTuple = CISTPL_FUNCE;
-    i = first_tuple(link, tuple, parse);
-    while (i == 0) {
-       if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
-           break;
-       i = next_tuple(link, tuple, parse);
-    }
-    if (i == 0) {
-       node_id = (cistpl_lan_node_id_t *)parse->funce.data;
-       if (node_id->nb == 6) {
-           for (i = 0; i < 6; i++)
-               dev->dev_addr[i] = node_id->id[i];
-           rc = 0;
-           goto free_cfg_mem;
-       }
-    }
+    if (!pcmcia_get_mac_from_cis(link, dev))
+           return 0;
+
     /* Try the third string in the Version 1 Version/ID tuple. */
     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;
-       }
+           if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+                   return 0;
     }
-
-    rc = -1;
-free_cfg_mem:
-    kfree(cfg_mem);
-    return rc;
+    return -1;
 }
 
 /*====================================================================*/
@@ -747,8 +646,6 @@ static int osi_config(struct pcmcia_device *link)
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes =
-       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
     link->io.NumPorts1 = 64;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -793,41 +690,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
        return err;
 }
 
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+                         tuple_t *tuple,
+                         void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    u_char *buf;
-    int i, rc;
+       struct net_device *dev = priv;
+       int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-        return -1;
+       if (tuple->TupleDataLen < 8)
+               return -EINVAL;
+       if (tuple->TupleData[0] != 0x04)
+               return -EINVAL;
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
 
-    tuple = &cfg_mem->tuple;
-    buf = cfg_mem->buf;
 
-    tuple->Attributes = TUPLE_RETURN_COMMON;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+    struct net_device *dev = link->priv;
+    int rc;
 
     /* Read the station address from tuple 0x90, subtuple 0x04 */
-    tuple->DesiredTuple = 0x90;
-    i = pcmcia_get_first_tuple(link, tuple);
-    while (i == 0) {
-       i = pcmcia_get_tuple_data(link, tuple);
-       if ((i != 0) || (buf[0] == 0x04))
-           break;
-       i = pcmcia_get_next_tuple(link, tuple);
-    }
-    if (i != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    for (i = 0; i < 6; i++)
-       dev->dev_addr[i] = buf[i+2];
+    if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+           return -1;
 
     if (((manfid == MANFID_OSITECH) &&
         (cardid == PRODID_OSITECH_SEVEN)) ||
@@ -835,20 +722,17 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
         (cardid == PRODID_PSION_NET100))) {
        rc = osi_load_firmware(link);
        if (rc)
-               goto free_cfg_mem;
+               return rc;
     } else if (manfid == MANFID_OSITECH) {
        /* Make sure both functions are powered up */
        set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
        /* Now, turn on the interrupt for both card functions */
        set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
-       DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
+       dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
              inw(link->io.BasePort1 + OSITECH_AUI_PWR),
              inw(link->io.BasePort1 + OSITECH_RESET_ISR));
     }
-    rc = 0;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
+    return 0;
 }
 
 static int smc91c92_suspend(struct pcmcia_device *link)
@@ -958,12 +842,6 @@ static int check_sig(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_EXIT_TEST(ret, svc, label)  \
-if (ret != 0) {                                \
-       cs_error(link, svc, ret);       \
-       goto label;                     \
-}
-
 static int smc91c92_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
@@ -973,7 +851,7 @@ static int smc91c92_config(struct pcmcia_device *link)
     unsigned int ioaddr;
     u_long mir;
 
-    DEBUG(0, "smc91c92_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_config\n");
 
     smc->manfid = link->manf_id;
     smc->cardid = link->card_id;
@@ -989,17 +867,20 @@ static int smc91c92_config(struct pcmcia_device *link)
     } else {
        i = smc_config(link);
     }
-    CS_EXIT_TEST(i, RequestIO, config_failed);
+    if (i)
+           goto config_failed;
 
-    i = pcmcia_request_irq(link, &link->irq);
-    CS_EXIT_TEST(i, RequestIRQ, config_failed);
+    i = pcmcia_request_irq(link, smc_interrupt);
+    if (i)
+           goto config_failed;
     i = pcmcia_request_configuration(link, &link->conf);
-    CS_EXIT_TEST(i, RequestConfiguration, config_failed);
+    if (i)
+           goto config_failed;
 
     if (smc->manfid == MANFID_MOTOROLA)
        mot_config(link);
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
 
     if ((if_port >= 0) && (if_port <= 2))
        dev->if_port = if_port;
@@ -1023,7 +904,7 @@ static int smc91c92_config(struct pcmcia_device *link)
 
     if (i != 0) {
        printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
-       goto config_undo;
+       goto config_failed;
     }
 
     smc->duplex = 0;
@@ -1072,17 +953,13 @@ static int smc91c92_config(struct pcmcia_device *link)
        SMC_SELECT_BANK(0);
     }
 
-    link->dev_node = &smc->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
-       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 %pM\n",
           dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
@@ -1099,7 +976,7 @@ static int smc91c92_config(struct pcmcia_device *link)
 
     if (smc->cfg & CFG_MII_SELECT) {
        if (smc->mii_if.phy_id != -1) {
-           DEBUG(0, "  MII transceiver at index %d, status %x.\n",
+           dev_dbg(&link->dev, "  MII transceiver at index %d, status %x.\n",
                  smc->mii_if.phy_id, j);
        } else {
            printk(KERN_NOTICE "  No MII transceivers found!\n");
@@ -1109,8 +986,9 @@ static int smc91c92_config(struct pcmcia_device *link)
 
 config_undo:
     unregister_netdev(dev);
-config_failed:                 /* CS_EXIT_TEST() calls jump to here... */
+config_failed:
     smc91c92_release(link);
+    free_netdev(dev);
     return -ENODEV;
 } /* smc91c92_config */
 
@@ -1124,7 +1002,7 @@ config_failed:                    /* CS_EXIT_TEST() calls jump to here... */
 
 static void smc91c92_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "smc91c92_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "smc91c92_release\n");
        if (link->win) {
                struct net_device *dev = link->priv;
                struct smc_private *smc = netdev_priv(dev);
@@ -1221,10 +1099,10 @@ static int smc_open(struct net_device *dev)
     struct smc_private *smc = netdev_priv(dev);
     struct pcmcia_device *link = smc->p_dev;
 
-#ifdef PCMCIA_DEBUG
-    DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
          dev->name, dev, inw(dev->base_addr + BANK_SELECT));
-    if (pc_debug > 1) smc_dump(dev);
+#ifdef PCMCIA_DEBUG
+    smc_dump(dev);
 #endif
 
     /* Check that the PCMCIA card is still here. */
@@ -1259,7 +1137,7 @@ static int smc_close(struct net_device *dev)
     struct pcmcia_device *link = smc->p_dev;
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "%s: smc_close(), status %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
          dev->name, inw(ioaddr + BANK_SELECT));
 
     netif_stop_queue(dev);
@@ -1326,7 +1204,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
        u_char *buf = skb->data;
        u_int length = skb->len; /* The chip will pad to ethernet min. */
 
-       DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
+       pr_debug("%s: Trying to xmit packet of length %d.\n",
              dev->name, length);
        
        /* send the packet length: +6 for status word, length, and ctl */
@@ -1350,7 +1228,6 @@ static void smc_hardware_send_packet(struct net_device * dev)
     dev_kfree_skb_irq(skb);
     dev->trans_start = jiffies;
     netif_start_queue(dev);
-    return;
 }
 
 /*====================================================================*/
@@ -1365,12 +1242,13 @@ static void smc_tx_timeout(struct net_device *dev)
           dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
     dev->stats.tx_errors++;
     smc_reset(dev);
-    dev->trans_start = jiffies;
+    dev->trans_start = jiffies; /* prevent tx timeout */
     smc->saved_skb = NULL;
     netif_wake_queue(dev);
 }
 
-static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
+                                       struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
@@ -1380,7 +1258,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
     netif_stop_queue(dev);
 
-    DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
+    pr_debug("%s: smc_start_xmit(length = %d) called,"
          " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
 
     if (smc->saved_skb) {
@@ -1399,7 +1277,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev_kfree_skb (skb);
        smc->saved_skb = NULL;
        dev->stats.tx_dropped++;
-       return 0;               /* Do not re-queue this packet. */
+       return NETDEV_TX_OK;            /* Do not re-queue this packet. */
     }
     /* A packet is now waiting. */
     smc->packets_waiting++;
@@ -1422,16 +1300,16 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
            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;
+           return NETDEV_TX_OK;
        }
     }
 
     /* Otherwise defer until the Tx-space-allocated interrupt. */
-    DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
+    pr_debug("%s: memory allocation deferred.\n", dev->name);
     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
     spin_unlock_irqrestore(&smc->lock, flags);
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 /*======================================================================
@@ -1479,7 +1357,6 @@ static void smc_tx_err(struct net_device * dev)
     smc->packets_waiting--;
 
     outw(saved_packet, ioaddr + PNR_ARR);
-    return;
 }
 
 /*====================================================================*/
@@ -1492,7 +1369,7 @@ static void smc_eph_irq(struct net_device *dev)
 
     SMC_SELECT_BANK(0);
     ephs = inw(ioaddr + EPH);
-    DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
+    pr_debug("%s: Ethernet protocol handler interrupt, status"
          " %4.4x.\n", dev->name, ephs);
     /* Could be a counter roll-over warning: update stats. */
     card_stats = inw(ioaddr + COUNTER);
@@ -1532,7 +1409,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
 
     ioaddr = dev->base_addr;
 
-    DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
+    pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
          irq, ioaddr);
 
     spin_lock(&smc->lock);
@@ -1541,7 +1418,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
     if ((saved_bank & 0xff00) != 0x3300) {
        /* The device does not exist -- the card could be off-line, or
           maybe it has been ejected. */
-       DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
+       pr_debug("%s: SMC91c92 interrupt %d for non-existent"
              "/ejected device.\n", dev->name, irq);
        handled = 0;
        goto irq_done;
@@ -1555,7 +1432,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
 
     do { /* read the status flag, and mask it */
        status = inw(ioaddr + INTERRUPT) & 0xff;
-       DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
+       pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
              status, mask);
        if ((status & mask) == 0) {
            if (bogus_cnt == INTR_WORK)
@@ -1600,7 +1477,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
            smc_eph_irq(dev);
     } while (--bogus_cnt);
 
-    DEBUG(3, "  Restoring saved registers mask %2.2x bank %4.4x"
+    pr_debug("  Restoring saved registers mask %2.2x bank %4.4x"
          " pointer %4.4x.\n", mask, saved_bank, saved_pointer);
 
     /* restore state register */
@@ -1608,7 +1485,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
     outw(saved_pointer, ioaddr + POINTER);
     SMC_SELECT_BANK(saved_bank);
 
-    DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
+    pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
 
 irq_done:
 
@@ -1659,7 +1536,7 @@ static void smc_rx(struct net_device *dev)
     rx_status = inw(ioaddr + DATA_1);
     packet_length = inw(ioaddr + DATA_1) & 0x07ff;
 
-    DEBUG(2, "%s: Receive status %4.4x length %d.\n",
+    pr_debug("%s: Receive status %4.4x length %d.\n",
          dev->name, rx_status, packet_length);
 
     if (!(rx_status & RS_ERRORS)) {            
@@ -1670,7 +1547,7 @@ static void smc_rx(struct net_device *dev)
        skb = dev_alloc_skb(packet_length+2);
        
        if (skb == NULL) {
-           DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
+           pr_debug("%s: Low memory, packet dropped.\n", dev->name);
            dev->stats.rx_dropped++;
            outw(MC_RELEASE, ioaddr + MMU_CMD);
            return;
@@ -1699,29 +1576,6 @@ static void smc_rx(struct net_device *dev)
     }
     /* Let the MMU free the memory of this packet. */
     outw(MC_RELEASE, ioaddr + MMU_CMD);
-
-    return;
-}
-
-/*======================================================================
-
-    Calculate values for the hardware multicast filter hash table.
-
-======================================================================*/
-
-static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
-                              u_char *multicast_table)
-{
-    struct dev_mc_list *mc_addr;
-
-    for (mc_addr = addrs;  mc_addr && count-- > 0;  mc_addr = mc_addr->next) {
-       u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version          /* Verify multicast address. */
-       if ((mc_addr->dmi_addr[0] & 1) == 0)
-           continue;
-#endif
-       multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
-    }
 }
 
 /*======================================================================
@@ -1739,18 +1593,25 @@ static void set_rx_mode(struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
-    u_int multicast_table[ 2 ] = { 0, };
+    unsigned char multicast_table[8];
     unsigned long flags;
     u_short rx_cfg_setting;
+    int i;
+
+    memset(multicast_table, 0, sizeof(multicast_table));
 
     if (dev->flags & IFF_PROMISC) {
        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
     } else if (dev->flags & IFF_ALLMULTI)
        rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti;
     else {
-       if (dev->mc_count)  {
-           fill_multicast_tbl(dev->mc_count, dev->mc_list,
-                              (u_char *)multicast_table);
+       if (!netdev_mc_empty(dev)) {
+           struct netdev_hw_addr *ha;
+
+           netdev_for_each_mc_addr(ha, dev) {
+               u_int position = ether_crc(6, ha->addr);
+               multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
+           }
        }
        rx_cfg_setting = RxStripCRC | RxEnable;
     }
@@ -1758,14 +1619,12 @@ static void set_rx_mode(struct net_device *dev)
     /* Load MC table and Rx setting into the chip without interrupts. */
     spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(3);
-    outl(multicast_table[0], ioaddr + MULTICAST0);
-    outl(multicast_table[1], ioaddr + MULTICAST4);
+    for (i = 0; i < 8; i++)
+       outb(multicast_table[i], ioaddr + MULTICAST0 + i);
     SMC_SELECT_BANK(0);
     outw(rx_cfg_setting, ioaddr + RCR);
     SMC_SELECT_BANK(2);
     spin_unlock_irqrestore(&smc->lock, flags);
-
-    return;
 }
 
 /*======================================================================
@@ -1830,7 +1689,7 @@ static void smc_reset(struct net_device *dev)
     struct smc_private *smc = netdev_priv(dev);
     int i;
 
-    DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
+    pr_debug("%s: smc91c92 reset called.\n", dev->name);
 
     /* The first interaction must be a write to bring the chip out
        of sleep mode. */
@@ -1928,23 +1787,30 @@ static void media_check(u_long arg)
     SMC_SELECT_BANK(1);
     media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
 
+    SMC_SELECT_BANK(saved_bank);
+    spin_unlock_irqrestore(&smc->lock, flags);
+
     /* Check for pending interrupt with watchdog flag set: with
        this, we can limp along even if the interrupt is blocked */
     if (smc->watchdog++ && ((i>>8) & i)) {
        if (!smc->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+       local_irq_save(flags);
        smc_interrupt(dev->irq, dev);
+       local_irq_restore(flags);
        smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
        smc->fast_poll--;
        smc->media.expires = jiffies + HZ/100;
        add_timer(&smc->media);
-       SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irqrestore(&smc->lock, flags);
        return;
     }
 
+    spin_lock_irqsave(&smc->lock, flags);
+
+    saved_bank = inw(ioaddr + BANK_SELECT);
+
     if (smc->cfg & CFG_MII_SELECT) {
        if (smc->mii_if.phy_id < 0)
            goto reschedule;
@@ -2102,15 +1968,16 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        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);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2120,15 +1987,16 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        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);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2138,27 +2006,16 @@ static u32 smc_get_link(struct net_device *dev)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        u32 ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        ret = smc_link_ok(dev);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 smc_get_msglevel(struct net_device *dev)
-{
-       return pc_debug;
-}
-
-static void smc_set_msglevel(struct net_device *dev, u32 val)
-{
-       pc_debug = val;
-}
-#endif
-
 static int smc_nway_reset(struct net_device *dev)
 {
        struct smc_private *smc = netdev_priv(dev);
@@ -2182,10 +2039,6 @@ static const struct ethtool_ops ethtool_ops = {
        .get_settings = smc_get_settings,
        .set_settings = smc_set_settings,
        .get_link = smc_get_link,
-#ifdef PCMCIA_DEBUG
-       .get_msglevel = smc_get_msglevel,
-       .set_msglevel = smc_set_msglevel,
-#endif
        .nway_reset = smc_nway_reset,
 };
 
@@ -2196,16 +2049,17 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
        int rc = 0;
        u16 saved_bank;
        unsigned int ioaddr = dev->base_addr;
+       unsigned long flags;
 
        if (!netif_running(dev))
                return -EINVAL;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        saved_bank = inw(ioaddr + BANK_SELECT);
        SMC_SELECT_BANK(3);
        rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return rc;
 }