fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / pcmcia / cistpl.c
index 317ca50..912c03e 100644 (file)
@@ -1,37 +1,17 @@
-/*======================================================================
-
-    PCMCIA Card Information Structure parser
-
-    cistpl.c 1.99 2002/10/24 06:11:48
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999            David A. Hinds
+ */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -79,9 +59,9 @@ static const u_int exponent[] = {
 
 /* Parameters that can be set with 'insmod' */
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
-
-INT_MODULE_PARM(cis_width,     0);             /* 16-bit CIS? */
+/* 16-bit CIS? */
+static int cis_width;
+module_param(cis_width, int, 0444);
 
 void release_cis_mem(struct pcmcia_socket *s)
 {
@@ -97,6 +77,7 @@ void release_cis_mem(struct pcmcia_socket *s)
        s->cis_virt = NULL;
     }
 }
+EXPORT_SYMBOL(release_cis_mem);
 
 /*
  * Map the card memory at "card_offset" into virtual space.
@@ -106,25 +87,38 @@ void release_cis_mem(struct pcmcia_socket *s)
 static void __iomem *
 set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
 {
-    pccard_mem_map *mem = &s->cis_mem;
-    if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) {
-       mem->res = find_mem_region(0, s->map_size, s->map_size, 0,
-                                  "card services", s);
-       if (mem->res == NULL) {
-           printk(KERN_NOTICE "cs: unable to map card memory!\n");
-           return NULL;
+       pccard_mem_map *mem = &s->cis_mem;
+       int ret;
+
+       if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
+               mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
+               if (mem->res == NULL) {
+                       printk(KERN_NOTICE "cs: unable to map card memory!\n");
+                       return NULL;
+               }
+               s->cis_virt = NULL;
        }
-       s->cis_virt = ioremap(mem->res->start, s->map_size);
-    }
-    mem->card_start = card_offset;
-    mem->flags = flags;
-    s->ops->set_mem_map(s, mem);
-    if (s->features & SS_CAP_STATIC_MAP) {
-       if (s->cis_virt)
-           iounmap(s->cis_virt);
-       s->cis_virt = ioremap(mem->static_start, s->map_size);
-    }
-    return s->cis_virt;
+
+       if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
+               s->cis_virt = ioremap(mem->res->start, s->map_size);
+
+       mem->card_start = card_offset;
+       mem->flags = flags;
+
+       ret = s->ops->set_mem_map(s, mem);
+       if (ret) {
+               iounmap(s->cis_virt);
+               s->cis_virt = NULL;
+               return NULL;
+       }
+
+       if (s->features & SS_CAP_STATIC_MAP) {
+               if (s->cis_virt)
+                       iounmap(s->cis_virt);
+               s->cis_virt = ioremap(mem->static_start, s->map_size);
+       }
+
+       return s->cis_virt;
 }
 
 /*======================================================================
@@ -138,13 +132,13 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
 #define IS_ATTR                1
 #define IS_INDIRECT    8
 
-int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                 u_int len, void *ptr)
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
@@ -201,14 +195,16 @@ int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
          *(u_char *)(ptr+2), *(u_char *)(ptr+3));
     return 0;
 }
+EXPORT_SYMBOL(pcmcia_read_cis_mem);
 
-void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
+
+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
                   u_int len, void *ptr)
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
@@ -258,6 +254,8 @@ void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
        }
     }
 }
+EXPORT_SYMBOL(pcmcia_write_cis_mem);
+
 
 /*======================================================================
 
@@ -293,7 +291,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
        ret = read_cb_mem(s, attr, addr, len, ptr);
     else
 #endif
-       ret = read_cis_mem(s, attr, addr, len, ptr);
+       ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
 
        if (ret == 0) {
                /* Copy data into the cache */
@@ -331,7 +329,14 @@ void destroy_cis_cache(struct pcmcia_socket *s)
                list_del(&cis->node);
                kfree(cis);
        }
+
+       /*
+        * If there was a fake CIS, destroy that as well.
+        */
+       kfree(s->fake_cis);
+       s->fake_cis = NULL;
 }
+EXPORT_SYMBOL(destroy_cis_cache);
 
 /*======================================================================
 
@@ -358,7 +363,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
                        read_cb_mem(s, cis->attr, cis->addr, len, buf);
                else
 #endif
-                       read_cis_mem(s, cis->attr, cis->addr, len, buf);
+                       pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
 
                if (memcmp(buf, cis->cache, len) != 0) {
                        kfree(buf);
@@ -376,16 +381,10 @@ int verify_cis_cache(struct pcmcia_socket *s)
     
 ======================================================================*/
 
-int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis)
+int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
 {
-    struct pcmcia_socket *s;
-    if (CHECK_HANDLE(handle))
-       return CS_BAD_HANDLE;
-    s = SOCKET(handle);
-    if (s->fake_cis != NULL) {
-       kfree(s->fake_cis);
-       s->fake_cis = NULL;
-    }
+    kfree(s->fake_cis);
+    s->fake_cis = NULL;
     if (cis->Length > CISTPL_MAX_CIS_SIZE)
        return CS_BAD_SIZE;
     s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
@@ -395,6 +394,7 @@ int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis)
     memcpy(s->fake_cis, cis->Data, cis->Length);
     return CS_SUCCESS;
 }
+EXPORT_SYMBOL(pcmcia_replace_cis);
 
 /*======================================================================
 
@@ -414,14 +414,12 @@ typedef struct tuple_flags {
 #define MFC_FN(f)      (((tuple_flags *)(&(f)))->mfc_fn)
 #define SPACE(f)       (((tuple_flags *)(&(f)))->space)
 
-int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple);
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
 
-int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
 {
-    struct pcmcia_socket *s;
-    if (CHECK_HANDLE(handle))
+    if (!s)
        return CS_BAD_HANDLE;
-    s = SOCKET(handle);
     if (!(s->state & SOCKET_PRESENT))
        return CS_NO_CARD;
     tuple->TupleLink = tuple->Flags = 0;
@@ -443,16 +441,17 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
        !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
        cisdata_t req = tuple->DesiredTuple;
        tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
-       if (pcmcia_get_next_tuple(handle, tuple) == CS_SUCCESS) {
+       if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) {
            tuple->DesiredTuple = CISTPL_LINKTARGET;
-           if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
+           if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS)
                return CS_NO_MORE_ITEMS;
        } else
            tuple->CISOffset = tuple->TupleLink = 0;
        tuple->DesiredTuple = req;
     }
-    return pcmcia_get_next_tuple(handle, tuple);
+    return pccard_get_next_tuple(s, function, tuple);
 }
+EXPORT_SYMBOL(pccard_get_first_tuple);
 
 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
 {
@@ -463,7 +462,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
        /* Get indirect link from the MFC tuple */
        read_cis_cache(s, LINK_SPACE(tuple->Flags),
                       tuple->LinkOffset, 5, link);
-       ofs = le32_to_cpu(*(u_int *)(link+1));
+       ofs = le32_to_cpu(*(__le32 *)(link+1));
        SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
        /* Move to the next indirect link */
        tuple->LinkOffset += 5;
@@ -494,15 +493,13 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
     return -1;
 }
 
-int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
 {
-    struct pcmcia_socket *s;
     u_char link[2], tmp;
     int ofs, i, attr;
-    
-    if (CHECK_HANDLE(handle))
+
+    if (!s)
        return CS_BAD_HANDLE;
-    s = SOCKET(handle);
     if (!(s->state & SOCKET_PRESENT))
        return CS_NO_CARD;
 
@@ -554,14 +551,14 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
            case CISTPL_LONGLINK_MFC:
                tuple->LinkOffset = ofs + 3;
                LINK_SPACE(tuple->Flags) = attr;
-               if (handle->Function == BIND_FN_ALL) {
+               if (function == BIND_FN_ALL) {
                    /* Follow all the MFC links */
                    read_cis_cache(s, attr, ofs+2, 1, &tmp);
                    MFC_FN(tuple->Flags) = tmp;
                } else {
                    /* Follow exactly one of the links */
                    MFC_FN(tuple->Flags) = 1;
-                   tuple->LinkOffset += handle->Function * 5;
+                   tuple->LinkOffset += function * 5;
                }
                break;
            case CISTPL_NO_LINK:
@@ -589,20 +586,18 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
     tuple->CISOffset = ofs + 2;
     return CS_SUCCESS;
 }
+EXPORT_SYMBOL(pccard_get_next_tuple);
 
 /*====================================================================*/
 
 #define _MIN(a, b)             (((a) < (b)) ? (a) : (b))
 
-int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
+int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
 {
-    struct pcmcia_socket *s;
     u_int len;
-    
-    if (CHECK_HANDLE(handle))
-       return CS_BAD_HANDLE;
 
-    s = SOCKET(handle);
+    if (!s)
+       return CS_BAD_HANDLE;
 
     if (tuple->TupleLink < tuple->TupleOffset)
        return CS_NO_MORE_ITEMS;
@@ -615,6 +610,8 @@ int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
                   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
     return CS_SUCCESS;
 }
+EXPORT_SYMBOL(pccard_get_tuple_data);
+
 
 /*======================================================================
 
@@ -673,8 +670,8 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
     if (tuple->TupleDataLen < 5)
        return CS_BAD_TUPLE;
     p = (u_char *)tuple->TupleData;
-    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2;
-    csum->len = le16_to_cpu(*(u_short *)(p + 2));
+    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
+    csum->len = le16_to_cpu(*(__le16 *)(p + 2));
     csum->sum = *(p+4);
     return CS_SUCCESS;
 }
@@ -685,7 +682,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
 {
     if (tuple->TupleDataLen < 4)
        return CS_BAD_TUPLE;
-    link->addr = le32_to_cpu(*(u_int *)tuple->TupleData);
+    link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
     return CS_SUCCESS;
 }
 
@@ -704,7 +701,7 @@ static int parse_longlink_mfc(tuple_t *tuple,
        return CS_BAD_TUPLE;
     for (i = 0; i < link->nfn; i++) {
        link->fn[i].space = *p; p++;
-       link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4;
+       link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
     }
     return CS_SUCCESS;
 }
@@ -791,10 +788,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
 
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
-    u_short *p;
+    __le16 *p;
     if (tuple->TupleDataLen < 4)
        return CS_BAD_TUPLE;
-    p = (u_short *)tuple->TupleData;
+    p = (__le16 *)tuple->TupleData;
     m->manf = le16_to_cpu(p[0]);
     m->card = le16_to_cpu(p[1]);
     return CS_SUCCESS;
@@ -1095,7 +1092,7 @@ static int parse_cftable_entry(tuple_t *tuple,
        break;
     case 0x20:
        entry->mem.nwin = 1;
-       entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+       entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
        entry->mem.win[0].card_addr = 0;
        entry->mem.win[0].host_addr = 0;
        p += 2;
@@ -1103,9 +1100,9 @@ static int parse_cftable_entry(tuple_t *tuple,
        break;
     case 0x40:
        entry->mem.nwin = 1;
-       entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+       entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
        entry->mem.win[0].card_addr =
-           le16_to_cpu(*(u_short *)(p+2)) << 8;
+           le16_to_cpu(*(__le16 *)(p+2)) << 8;
        entry->mem.win[0].host_addr = 0;
        p += 4;
        if (p > q) return CS_BAD_TUPLE;
@@ -1142,7 +1139,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
     p = (u_char *)tuple->TupleData;
     bar->attr = *p;
     p += 2;
-    bar->size = le32_to_cpu(*(u_int *)p);
+    bar->size = le32_to_cpu(*(__le32 *)p);
     return CS_SUCCESS;
 }
 
@@ -1155,7 +1152,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
        return CS_BAD_TUPLE;
     config->last_idx = *(++p);
     p++;
-    config->base = le32_to_cpu(*(u_int *)p);
+    config->base = le32_to_cpu(*(__le32 *)p);
     config->subtuples = tuple->TupleDataLen - 6;
     return CS_SUCCESS;
 }
@@ -1271,7 +1268,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
 
     v2->vers = p[0];
     v2->comply = p[1];
-    v2->dindex = le16_to_cpu(*(u_short *)(p+2));
+    v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
     v2->vspec8 = p[6];
     v2->vspec9 = p[7];
     v2->nhdr = p[8];
@@ -1312,15 +1309,15 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
 
     fmt->type = p[0];
     fmt->edc = p[1];
-    fmt->offset = le32_to_cpu(*(u_int *)(p+2));
-    fmt->length = le32_to_cpu(*(u_int *)(p+6));
+    fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
+    fmt->length = le32_to_cpu(*(__le32 *)(p+6));
 
     return CS_SUCCESS;
 }
 
 /*====================================================================*/
 
-int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
 {
     int ret = CS_SUCCESS;
     
@@ -1401,6 +1398,7 @@ int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
     }
     return ret;
 }
+EXPORT_SYMBOL(pccard_parse_tuple);
 
 /*======================================================================
 
@@ -1408,7 +1406,7 @@ int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
     
 ======================================================================*/
 
-int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
+int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse)
 {
     tuple_t tuple;
     cisdata_t *buf;
@@ -1419,18 +1417,19 @@ int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
        return CS_OUT_OF_RESOURCE;
     tuple.DesiredTuple = code;
     tuple.Attributes = TUPLE_RETURN_COMMON;
-    ret = pcmcia_get_first_tuple(handle, &tuple);
+    ret = pccard_get_first_tuple(s, function, &tuple);
     if (ret != CS_SUCCESS) goto done;
     tuple.TupleData = buf;
     tuple.TupleOffset = 0;
     tuple.TupleDataMax = 255;
-    ret = pcmcia_get_tuple_data(handle, &tuple);
+    ret = pccard_get_tuple_data(s, &tuple);
     if (ret != CS_SUCCESS) goto done;
-    ret = pcmcia_parse_tuple(handle, &tuple, parse);
+    ret = pccard_parse_tuple(&tuple, parse);
 done:
     kfree(buf);
     return ret;
 }
+EXPORT_SYMBOL(pccard_read_tuple);
 
 /*======================================================================
 
@@ -1442,14 +1441,15 @@ done:
     
 ======================================================================*/
 
-int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info)
 {
     tuple_t *tuple;
     cisparse_t *p;
     int ret, reserved, dev_ok = 0, ident_ok = 0;
 
-    if (CHECK_HANDLE(handle))
+    if (!s)
        return CS_BAD_HANDLE;
+
     tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
     if (tuple == NULL)
        return CS_OUT_OF_RESOURCE;
@@ -1462,30 +1462,30 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
     info->Chains = reserved = 0;
     tuple->DesiredTuple = RETURN_FIRST_TUPLE;
     tuple->Attributes = TUPLE_RETURN_COMMON;
-    ret = pcmcia_get_first_tuple(handle, tuple);
+    ret = pccard_get_first_tuple(s, function, tuple);
     if (ret != CS_SUCCESS)
        goto done;
 
     /* First tuple should be DEVICE; we should really have either that
        or a CFTABLE_ENTRY of some sort */
     if ((tuple->TupleCode == CISTPL_DEVICE) ||
-       (read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
-       (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
+       (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
+       (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
        dev_ok++;
 
     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
        tuple, for card identification.  Certain old D-Link and Linksys
        cards have only a broken VERS_2 tuple; hence the bogus test. */
-    if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) ||
-       (read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) ||
-       (read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
+    if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) ||
+       (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) ||
+       (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
        ident_ok++;
 
     if (!dev_ok && !ident_ok)
        goto done;
 
     for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
-       ret = pcmcia_get_next_tuple(handle, tuple);
+       ret = pccard_get_next_tuple(s, function, tuple);
        if (ret != CS_SUCCESS) break;
        if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
            ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
@@ -1501,4 +1501,4 @@ done:
     kfree(p);
     return CS_SUCCESS;
 }
-
+EXPORT_SYMBOL(pccard_validate_cis);