Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[safe/jmp/linux-2.6] / drivers / net / pcmcia / ibmtr_cs.c
index 90da35d..67ee985 100644 (file)
 #define PCMCIA
 #include "../tokenring/ibmtr.c"
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ibmtr_cs.c 1.10   1996/01/06 05:19:00 (Steve Kipisz)\n"
-"           2.2.7  1999/05/03 12:00:00 (Mike Phillips)\n"
-"           2.4.2  2001/30/28 Midnight (Burt Silverman)\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -105,23 +94,16 @@ MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
-static void ibmtr_config(dev_link_t *link);
+static int ibmtr_config(struct pcmcia_device *link);
 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
-static void ibmtr_release(dev_link_t *link);
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args);
-
-static dev_info_t dev_info = "ibmtr_cs";
-
-static dev_link_t *ibmtr_attach(void);
+static void ibmtr_release(struct pcmcia_device *link);
 static void ibmtr_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
 typedef struct ibmtr_dev_t {
-    dev_link_t         link;
+       struct pcmcia_device    *p_dev;
     struct net_device  *dev;
-    dev_node_t          node;
     window_handle_t     sram_win_handle;
     struct tok_info    *ti;
 } ibmtr_dev_t;
@@ -132,10 +114,16 @@ static void netdev_get_drvinfo(struct net_device *dev,
        strcpy(info->driver, "ibmtr_cs");
 }
 
-static struct ethtool_ops netdev_ethtool_ops = {
+static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
 };
 
+static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
+       ibmtr_dev_t *info = dev_id;
+       struct net_device *dev = info->dev;
+       return tok_interrupt(irq, dev);
+};
+
 /*======================================================================
 
     ibmtr_attach() creates an "instance" of the driver, allocating
@@ -144,63 +132,38 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 ======================================================================*/
 
-static dev_link_t *ibmtr_attach(void)
+static int __devinit ibmtr_attach(struct pcmcia_device *link)
 {
     ibmtr_dev_t *info;
-    dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
-    
-    DEBUG(0, "ibmtr_attach()\n");
+
+    dev_dbg(&link->dev, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL); 
-    if (!info) return NULL;
-    memset(info,0,sizeof(*info));
+    info = kzalloc(sizeof(*info), GFP_KERNEL);
+    if (!info) return -ENOMEM;
     dev = alloc_trdev(sizeof(struct tok_info));
-    if (!dev) { 
-       kfree(info); 
-       return NULL;
-    } 
+    if (!dev) {
+       kfree(info);
+       return -ENOMEM;
+    }
 
-    link = &info->link;
+    info->p_dev = link;
     link->priv = info;
     info->ti = netdev_priv(dev);
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &tok_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Instance = info->dev = dev;
-    
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+    info->dev = dev;
 
-    /* Register with Card Services */
-    link->next = NULL;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        cs_error(link->handle, RegisterClient, ret);
-       goto out_detach;
-    }
-
-out:
-    return link;
+    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-out_detach:
-    ibmtr_detach(link->handle);
-    link = NULL;
-    goto out;
+    return ibmtr_config(link);
 } /* ibmtr_attach */
 
 /*======================================================================
@@ -212,23 +175,25 @@ out_detach:
 
 ======================================================================*/
 
-static void ibmtr_detach(struct pcmcia_device *p_dev)
+static void ibmtr_detach(struct pcmcia_device *link)
 {
-    dev_link_t *link = dev_to_instance(p_dev);
     struct ibmtr_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
+     struct tok_info *ti = netdev_priv(dev);
 
-    DEBUG(0, "ibmtr_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "ibmtr_detach\n");
+    
+    /* 
+     * When the card removal interrupt hits tok_interrupt(), 
+     * bail out early, so we don't crash the machine 
+     */
+    ti->sram_phys |= 1;
 
-    if (link->dev)
-       unregister_netdev(dev);
+    unregister_netdev(dev);
+    
+    del_timer_sync(&(ti->tr_timer));
 
-    {
-       struct tok_info *ti = netdev_priv(dev);
-       del_timer_sync(&(ti->tr_timer));
-    }
-    if (link->state & DEV_CONFIG)
-        ibmtr_release(link);
+    ibmtr_release(link);
 
     free_netdev(dev);
     kfree(info);
@@ -242,36 +207,16 @@ static void ibmtr_detach(struct pcmcia_device *p_dev)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-static void ibmtr_config(dev_link_t *link)
+static int __devinit ibmtr_config(struct pcmcia_device *link)
 {
-    client_handle_t handle = link->handle;
     ibmtr_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
     struct tok_info *ti = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
     win_req_t req;
     memreq_t mem;
-    int i, last_ret, last_fn;
-    u_char buf[64];
-
-    DEBUG(0, "ibmtr_config(0x%p)\n", link);
+    int i, ret;
 
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
-    link->conf.ConfigBase = parse.config.base;
-
-    /* Configure card */
-    link->state |= DEV_CONFIG;
+    dev_dbg(&link->dev, "ibmtr_config\n");
 
     link->conf.ConfigIndex = 0x61;
 
@@ -279,17 +224,21 @@ static void ibmtr_config(dev_link_t *link)
 
     /* Try PRIMARY card at 0xA20-0xA23 */
     link->io.BasePort1 = 0xA20;
-    i = pcmcia_request_io(link->handle, &link->io);
-    if (i != CS_SUCCESS) {
+    i = pcmcia_request_io(link, &link->io);
+    if (i != 0) {
        /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
        link->io.BasePort1 = 0xA24;
-       CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+       ret = pcmcia_request_io(link, &link->io);
+       if (ret)
+               goto failed;
     }
     dev->base_addr = link->io.BasePort1;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
-    dev->irq = link->irq.AssignedIRQ;
-    ti->irq = link->irq.AssignedIRQ;
+    ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
+    if (ret)
+           goto failed;
+    dev->irq = link->irq;
+    ti->irq = link->irq;
     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
 
     /* Allocate the MMIO memory window */
@@ -298,11 +247,15 @@ static void ibmtr_config(dev_link_t *link)
     req.Base = 0; 
     req.Size = 0x2000;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+           goto failed;
 
     mem.CardOffset = mmiobase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+           goto failed;
     ti->mmio = ioremap(req.Base, req.Size);
 
     /* Allocate the SRAM memory window */
@@ -311,50 +264,47 @@ static void ibmtr_config(dev_link_t *link)
     req.Base = 0;
     req.Size = sramsize * 1024;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
+    ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
+    if (ret)
+           goto failed;
 
     mem.CardOffset = srambase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
+    ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+    if (ret)
+           goto failed;
 
     ti->sram_base = mem.CardOffset >> 12;
     ti->sram_virt = ioremap(req.Base, req.Size);
     ti->sram_phys = req.Base;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /*  Set up the Token-Ring Controller Configuration Register and
         turn on the card.  Check the "Local Area Network Credit Card
         Adapters Technical Reference"  SC30-3585 for this info.  */
     ibmtr_hw_setup(dev, mmiobase);
 
-    link->dev = &info->node;
-    link->state &= ~DEV_CONFIG_PENDING;
-    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
        printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
-       link->dev = NULL;
        goto failed;
     }
 
-    strcpy(info->node.dev_name, dev->name);
-
-    printk(KERN_INFO "%s: port %#3lx, irq %d,",
-           dev->name, dev->base_addr, dev->irq);
-    printk (" mmio %#5lx,", (u_long)ti->mmio);
-    printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
-    printk ("\n" KERN_INFO "  hwaddr=");
-    for (i = 0; i < TR_ALEN; i++)
-        printk("%02X", dev->dev_addr[i]);
-    printk("\n");
-    return;
+    printk(KERN_INFO
+          "%s: port %#3lx, irq %d,  mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
+           dev->name, dev->base_addr, dev->irq,
+          (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
+          dev->dev_addr);
+    return 0;
 
-cs_failed:
-    cs_error(link->handle, last_fn, last_ret);
 failed:
     ibmtr_release(link);
+    return -ENODEV;
 } /* ibmtr_config */
 
 /*======================================================================
@@ -365,86 +315,46 @@ failed:
 
 ======================================================================*/
 
-static void ibmtr_release(dev_link_t *link)
+static void ibmtr_release(struct pcmcia_device *link)
 {
-    ibmtr_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
-
-    DEBUG(0, "ibmtr_release(0x%p)\n", link);
+       ibmtr_dev_t *info = link->priv;
+       struct net_device *dev = info->dev;
 
-    pcmcia_release_configuration(link->handle);
-    pcmcia_release_io(link->handle, &link->io);
-    pcmcia_release_irq(link->handle, &link->irq);
-    if (link->win) {
-       struct tok_info *ti = netdev_priv(dev);
-       iounmap(ti->mmio);
-       pcmcia_release_window(link->win);
-       pcmcia_release_window(info->sram_win_handle);
-    }
+       dev_dbg(&link->dev, "ibmtr_release\n");
 
-    link->state &= ~DEV_CONFIG;
+       if (link->win) {
+               struct tok_info *ti = netdev_priv(dev);
+               iounmap(ti->mmio);
+               pcmcia_release_window(link, info->sram_win_handle);
+       }
+       pcmcia_disable_device(link);
 }
 
-static int ibmtr_suspend(struct pcmcia_device *p_dev)
+static int ibmtr_suspend(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
 
-       link->state |= DEV_SUSPEND;
-        if (link->state & DEV_CONFIG) {
-               if (link->open)
-                       netif_device_detach(dev);
-               pcmcia_release_configuration(link->handle);
-        }
+       if (link->open)
+               netif_device_detach(dev);
 
        return 0;
 }
 
-static int ibmtr_resume(struct pcmcia_device *p_dev)
+static int __devinit ibmtr_resume(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
 
-       link->state &= ~DEV_SUSPEND;
-        if (link->state & DEV_CONFIG) {
-               pcmcia_request_configuration(link->handle, &link->conf);
-               if (link->open) {
-                       ibmtr_probe(dev);       /* really? */
-                       netif_device_attach(dev);
-               }
-        }
+       if (link->open) {
+               ibmtr_probe(dev);       /* really? */
+               netif_device_attach(dev);
+       }
 
        return 0;
 }
 
 
-/*======================================================================
-
-    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.
-
-======================================================================*/
-
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-
-    DEBUG(1, "ibmtr_event(0x%06x)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT;
-       ibmtr_config(link);
-       break;
-    }
-    return 0;
-} /* ibmtr_event */
-
 /*====================================================================*/
 
 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
@@ -484,8 +394,6 @@ static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
 
     /* 0x40 will release the card for use */
     outb(0x40, dev->base_addr);
-
-    return;
 }
 
 static struct pcmcia_device_id ibmtr_ids[] = {
@@ -500,8 +408,7 @@ static struct pcmcia_driver ibmtr_cs_driver = {
        .drv            = {
                .name   = "ibmtr_cs",
        },
-       .attach         = ibmtr_attach,
-       .event          = ibmtr_event,
+       .probe          = ibmtr_attach,
        .remove         = ibmtr_detach,
        .id_table       = ibmtr_ids,
        .suspend        = ibmtr_suspend,