Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / drivers / isdn / hisax / teles_cs.c
index 4e5c14c..3e3e182 100644 (file)
@@ -75,8 +75,8 @@ module_param(protocol, int, 0);
    handler.
 */
 
-static void teles_cs_config(dev_link_t *link);
-static void teles_cs_release(dev_link_t *link);
+static int teles_cs_config(struct pcmcia_device *link);
+static void teles_cs_release(struct pcmcia_device *link);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -89,10 +89,10 @@ static void teles_detach(struct pcmcia_device *p_dev);
 /*
    A linked list of "instances" of the teles_cs device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
+   by one struct pcmcia_device structure (defined in ds.h).
 
    You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
+   memory card driver uses an array of struct pcmcia_device pointers, where minor
    device numbers are used to derive the corresponding array index.
 */
 
@@ -102,7 +102,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
    example, ethernet cards, modems).  In other cases, there may be
    many actual or logical devices (SCSI adapters, memory cards with
    multiple partitions).  The dev_node_t structures need to be kept
-   in a linked list starting at the 'dev' field of a dev_link_t
+   in a linked list starting at the 'dev' field of a struct pcmcia_device
    structure.  We allocate them in the card's private data structure,
    because they generally shouldn't be allocated dynamically.
    In this case, we also provide a flag to indicate if a device is
@@ -112,7 +112,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
 */
 
 typedef struct local_info_t {
-    dev_link_t          link;
+       struct pcmcia_device    *p_dev;
     dev_node_t          node;
     int                 busy;
     int                        cardnr;
@@ -130,19 +130,19 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static int teles_attach(struct pcmcia_device *p_dev)
+static int teles_probe(struct pcmcia_device *link)
 {
-    dev_link_t *link;
     local_info_t *local;
 
     DEBUG(0, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) return -ENOMEM;
-    memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
-    link = &local->link; link->priv = local;
+
+    local->p_dev = link;
+    link->priv = local;
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
@@ -161,16 +161,9 @@ static int teles_attach(struct pcmcia_device *p_dev)
     link->io.IOAddrLines = 5;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    teles_cs_config(link);
-
-    return 0;
+    return teles_cs_config(link);
 } /* teles_attach */
 
 /*======================================================================
@@ -182,20 +175,16 @@ static int teles_attach(struct pcmcia_device *p_dev)
 
 ======================================================================*/
 
-static void teles_detach(struct pcmcia_device *p_dev)
+static void teles_detach(struct pcmcia_device *link)
 {
-    dev_link_t *link = dev_to_instance(p_dev);
-    local_info_t *info = link->priv;
-
-    DEBUG(0, "teles_detach(0x%p)\n", link);
+       local_info_t *info = link->priv;
 
-    if (link->state & DEV_CONFIG) {
-           info->busy = 1;
-           teles_cs_release(link);
-    }
+       DEBUG(0, "teles_detach(0x%p)\n", link);
 
-    kfree(info);
+       info->busy = 1;
+       teles_cs_release(link);
 
+       kfree(info);
 } /* teles_detach */
 
 /*======================================================================
@@ -205,7 +194,7 @@ static void teles_detach(struct pcmcia_device *p_dev)
     device available to the system.
 
 ======================================================================*/
-static int get_tuple(client_handle_t handle, tuple_t *tuple,
+static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
                      cisparse_t *parse)
 {
     int i = pcmcia_get_tuple_data(handle, tuple);
@@ -213,7 +202,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
     return pcmcia_parse_tuple(handle, tuple, parse);
 }
 
-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 = pcmcia_get_first_tuple(handle, tuple);
@@ -221,7 +210,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
     return get_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 = pcmcia_get_next_tuple(handle, tuple);
@@ -229,9 +218,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
     return get_tuple(handle, tuple, parse);
 }
 
-static void teles_cs_config(dev_link_t *link)
+static int teles_cs_config(struct pcmcia_device *link)
 {
-    client_handle_t handle;
     tuple_t tuple;
     cisparse_t parse;
     local_info_t *dev;
@@ -241,52 +229,31 @@ static void teles_cs_config(dev_link_t *link)
     IsdnCard_t icard;
 
     DEBUG(0, "teles_config(0x%p)\n", link);
-    handle = link->handle;
     dev = link->priv;
 
-    /*
-       This reads the card's CONFIG tuple to find its configuration
-       registers.
-    */
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = 255;
-    tuple.TupleOffset = 0;
-    tuple.Attributes = 0;
-    i = first_tuple(handle, &tuple, &parse);
-    if (i != CS_SUCCESS) {
-        last_fn = ParseTuple;
-       goto cs_failed;
-    }
-    link->conf.ConfigBase = parse.config.base;
-    link->conf.Present = parse.config.rmask[0];
-
-    /* Configure card */
-    link->state |= DEV_CONFIG;
-
     tuple.TupleData = (cisdata_t *)buf;
     tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
     tuple.Attributes = 0;
     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    i = first_tuple(handle, &tuple, &parse);
+    i = first_tuple(link, &tuple, &parse);
     while (i == CS_SUCCESS) {
         if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
             printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
             link->conf.ConfigIndex = cf->index;
             link->io.BasePort1 = cf->io.win[0].base;
-            i = pcmcia_request_io(link->handle, &link->io);
+            i = pcmcia_request_io(link, &link->io);
             if (i == CS_SUCCESS) break;
         } else {
           printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
           link->conf.ConfigIndex = cf->index;
           for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
             link->io.BasePort1 = j;
-            i = pcmcia_request_io(link->handle, &link->io);
+            i = pcmcia_request_io(link, &link->io);
             if (i == CS_SUCCESS) break;
           }
           break;
         }
-        i = next_tuple(handle, &tuple, &parse);
+        i = next_tuple(link, &tuple, &parse);
     }
 
     if (i != CS_SUCCESS) {
@@ -294,14 +261,14 @@ static void teles_cs_config(dev_link_t *link)
        goto cs_failed;
     }
 
-    i = pcmcia_request_irq(link->handle, &link->irq);
+    i = pcmcia_request_irq(link, &link->irq);
     if (i != CS_SUCCESS) {
         link->irq.AssignedIRQ = 0;
        last_fn = RequestIRQ;
         goto cs_failed;
     }
 
-    i = pcmcia_request_configuration(link->handle, &link->conf);
+    i = pcmcia_request_configuration(link, &link->conf);
     if (i != CS_SUCCESS) {
       last_fn = RequestConfiguration;
       goto cs_failed;
@@ -312,14 +279,11 @@ static void teles_cs_config(dev_link_t *link)
     sprintf(dev->node.dev_name, "teles");
     dev->node.major = dev->node.minor = 0x0;
 
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
 
     /* Finally, report what we've done */
-    printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
-           dev->node.dev_name, link->conf.ConfigIndex,
-           link->conf.Vcc/10, link->conf.Vcc%10);
-    if (link->conf.Vpp1)
-        printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+    printk(KERN_INFO "%s: index 0x%02x:",
+           dev->node.dev_name, link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
         printk(", irq %d", link->irq.AssignedIRQ);
     if (link->io.NumPorts1)
@@ -330,8 +294,6 @@ static void teles_cs_config(dev_link_t *link)
                link->io.BasePort2+link->io.NumPorts2-1);
     printk("\n");
 
-    link->state &= ~DEV_CONFIG_PENDING;
-
     icard.para[0] = link->irq.AssignedIRQ;
     icard.para[1] = link->io.BasePort1;
     icard.protocol = protocol;
@@ -342,13 +304,16 @@ static void teles_cs_config(dev_link_t *link)
        printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
                i, link->io.BasePort1);
        teles_cs_release(link);
-    } else
-       ((local_info_t*)link->priv)->cardnr = i;
+       return -ENODEV;
+    }
+
+    ((local_info_t*)link->priv)->cardnr = i;
+    return 0;
 
-    return;
 cs_failed:
-    cs_error(link->handle, last_fn, i);
+    cs_error(link, last_fn, i);
     teles_cs_release(link);
+    return -ENODEV;
 } /* teles_cs_config */
 
 /*======================================================================
@@ -359,7 +324,7 @@ cs_failed:
 
 ======================================================================*/
 
-static void teles_cs_release(dev_link_t *link)
+static void teles_cs_release(struct pcmcia_device *link)
 {
     local_info_t *local = link->priv;
 
@@ -371,39 +336,23 @@ static void teles_cs_release(dev_link_t *link)
            HiSax_closecard(local->cardnr);
        }
     }
-    /* Unlink the device chain */
-    link->dev = NULL;
-
-    /* Don't bother checking to see if these succeed or not */
-    if (link->win)
-        pcmcia_release_window(link->win);
-    pcmcia_release_configuration(link->handle);
-    pcmcia_release_io(link->handle, &link->io);
-    pcmcia_release_irq(link->handle, &link->irq);
-    link->state &= ~DEV_CONFIG;
+
+    pcmcia_disable_device(link);
 } /* teles_cs_release */
 
-static int teles_suspend(struct pcmcia_device *p_dev)
+static int teles_suspend(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        local_info_t *dev = link->priv;
 
-       link->state |= DEV_SUSPEND;
         dev->busy = 1;
-       if (link->state & DEV_CONFIG)
-               pcmcia_release_configuration(link->handle);
 
        return 0;
 }
 
-static int teles_resume(struct pcmcia_device *p_dev)
+static int teles_resume(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        local_info_t *dev = link->priv;
 
-       link->state &= ~DEV_SUSPEND;
-       if (link->state & DEV_CONFIG)
-               pcmcia_request_configuration(link->handle, &link->conf);
         dev->busy = 0;
 
        return 0;
@@ -421,7 +370,7 @@ static struct pcmcia_driver teles_cs_driver = {
        .drv            = {
                .name   = "teles_cs",
        },
-       .probe          = teles_attach,
+       .probe          = teles_probe,
        .remove         = teles_detach,
        .id_table       = teles_ids,
        .suspend        = teles_suspend,