linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / net / pcmcia / ibmtr_cs.c
index b8fe70b..b9c7e39 100644 (file)
@@ -105,15 +105,15 @@ MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
-static int ibmtr_config(struct pcmcia_device *link);
+static void ibmtr_config(dev_link_t *link);
 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
-static void ibmtr_release(struct pcmcia_device *link);
+static void ibmtr_release(dev_link_t *link);
 static void ibmtr_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
 typedef struct ibmtr_dev_t {
-       struct pcmcia_device    *p_dev;
+    dev_link_t         link;
     struct net_device  *dev;
     dev_node_t          node;
     window_handle_t     sram_win_handle;
@@ -138,11 +138,12 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 ======================================================================*/
 
-static int ibmtr_attach(struct pcmcia_device *link)
+static int ibmtr_attach(struct pcmcia_device *p_dev)
 {
     ibmtr_dev_t *info;
+    dev_link_t *link;
     struct net_device *dev;
-
+    
     DEBUG(0, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
@@ -155,7 +156,7 @@ static int ibmtr_attach(struct pcmcia_device *link)
        return -ENOMEM;
     }
 
-    info->p_dev = link;
+    link = &info->link;
     link->priv = info;
     info->ti = netdev_priv(dev);
 
@@ -166,14 +167,21 @@ static int ibmtr_attach(struct pcmcia_device *link)
     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);
 
-    return ibmtr_config(link);
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT;
+    ibmtr_config(link);
+
+    return 0;
 } /* ibmtr_attach */
 
 /*======================================================================
@@ -185,22 +193,23 @@ static int ibmtr_attach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void ibmtr_detach(struct pcmcia_device *link)
+static void ibmtr_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct ibmtr_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
 
     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
 
-    if (link->dev_node)
+    if (link->dev)
        unregister_netdev(dev);
 
     {
        struct tok_info *ti = netdev_priv(dev);
        del_timer_sync(&(ti->tr_timer));
     }
-
-    ibmtr_release(link);
+    if (link->state & DEV_CONFIG)
+        ibmtr_release(link);
 
     free_netdev(dev);
     kfree(info);
@@ -217,8 +226,9 @@ static void ibmtr_detach(struct pcmcia_device *link)
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
-static int ibmtr_config(struct pcmcia_device *link)
+static void ibmtr_config(dev_link_t *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);
@@ -236,25 +246,29 @@ static int ibmtr_config(struct pcmcia_device *link)
     tuple.TupleDataMax = 64;
     tuple.TupleOffset = 0;
     tuple.DesiredTuple = CISTPL_CONFIG;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
+    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;
+
     link->conf.ConfigIndex = 0x61;
 
     /* Determine if this is PRIMARY or ALTERNATE. */
 
     /* Try PRIMARY card at 0xA20-0xA23 */
     link->io.BasePort1 = 0xA20;
-    i = pcmcia_request_io(link, &link->io);
+    i = pcmcia_request_io(link->handle, &link->io);
     if (i != CS_SUCCESS) {
        /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
        link->io.BasePort1 = 0xA24;
-       CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+       CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
     }
     dev->base_addr = link->io.BasePort1;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
     dev->irq = link->irq.AssignedIRQ;
     ti->irq = link->irq.AssignedIRQ;
     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
@@ -265,7 +279,7 @@ static int ibmtr_config(struct pcmcia_device *link)
     req.Base = 0; 
     req.Size = 0x2000;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
 
     mem.CardOffset = mmiobase;
     mem.Page = 0;
@@ -278,7 +292,7 @@ static int ibmtr_config(struct pcmcia_device *link)
     req.Base = 0;
     req.Size = sramsize * 1024;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
+    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
 
     mem.CardOffset = srambase;
     mem.Page = 0;
@@ -288,20 +302,21 @@ static int ibmtr_config(struct pcmcia_device *link)
     ti->sram_virt = ioremap(req.Base, req.Size);
     ti->sram_phys = req.Base;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
 
     /*  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_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    link->dev = &info->node;
+    link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
        printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
-       link->dev_node = NULL;
+       link->dev = NULL;
        goto failed;
     }
 
@@ -315,13 +330,12 @@ static int ibmtr_config(struct pcmcia_device *link)
     for (i = 0; i < TR_ALEN; i++)
         printk("%02X", dev->dev_addr[i]);
     printk("\n");
-    return 0;
+    return;
 
 cs_failed:
-    cs_error(link, last_fn, last_ret);
+    cs_error(link->handle, last_fn, last_ret);
 failed:
     ibmtr_release(link);
-    return -ENODEV;
 } /* ibmtr_config */
 
 /*======================================================================
@@ -332,41 +346,56 @@ failed:
 
 ======================================================================*/
 
-static void ibmtr_release(struct pcmcia_device *link)
+static void ibmtr_release(dev_link_t *link)
 {
-       ibmtr_dev_t *info = link->priv;
-       struct net_device *dev = info->dev;
+    ibmtr_dev_t *info = link->priv;
+    struct net_device *dev = info->dev;
+
+    DEBUG(0, "ibmtr_release(0x%p)\n", link);
 
-       DEBUG(0, "ibmtr_release(0x%p)\n", link);
+    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);
+    }
 
-       if (link->win) {
-               struct tok_info *ti = netdev_priv(dev);
-               iounmap(ti->mmio);
-               pcmcia_release_window(info->sram_win_handle);
-       }
-       pcmcia_disable_device(link);
+    link->state &= ~DEV_CONFIG;
 }
 
-static int ibmtr_suspend(struct pcmcia_device *link)
+static int ibmtr_suspend(struct pcmcia_device *p_dev)
 {
+       dev_link_t *link = dev_to_instance(p_dev);
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
 
-       if (link->open)
-               netif_device_detach(dev);
+       link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+        }
 
        return 0;
 }
 
-static int ibmtr_resume(struct pcmcia_device *link)
+static int ibmtr_resume(struct pcmcia_device *p_dev)
 {
+       dev_link_t *link = dev_to_instance(p_dev);
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
 
-       if (link->open) {
-               ibmtr_probe(dev);       /* really? */
-               netif_device_attach(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);
+               }
+        }
 
        return 0;
 }