diff options
Diffstat (limited to 'src/read-cis.c')
-rw-r--r-- | src/read-cis.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/src/read-cis.c b/src/read-cis.c deleted file mode 100644 index 9ee71e2..0000000 --- a/src/read-cis.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * read-cis.c - * - * 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <linux/limits.h> - -#include "cistpl.h" - -#define MAX_TUPLES 0x200 - -#define PATH_TO_SOCKET "/sys/class/pcmcia_socket/" - -/* Bits in attr field */ -#define IS_ATTR 1 -#define IS_INDIRECT 8 - - -static unsigned int functions; -static unsigned char cis_copy[MAX_TUPLES]; -static unsigned int cis_length = MAX_TUPLES; - - -#define SPACE(f) (((tuple_flags *)(&(f)))->space) -#define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link) -#define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space) -#define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) - - -static void read_cis(int attr, unsigned int addr, unsigned int len, void *ptr) -{ - if (cis_length > addr+len) - memcpy(ptr, cis_copy+addr, len); - else - memset(ptr, 0xff, len); - return; -} - -int pcmcia_get_next_tuple(unsigned int function, tuple_t *tuple); - -int pcmcia_get_first_tuple(unsigned int function, tuple_t *tuple) -{ - tuple->TupleLink = tuple->Flags = 0; - { - /* Assume presence of a LONGLINK_C to address 0 */ - tuple->CISOffset = tuple->LinkOffset = 0; - SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1; - } - if ((functions > 1) && - !(tuple->Attributes & TUPLE_RETURN_COMMON)) { - unsigned char req = tuple->DesiredTuple; - tuple->DesiredTuple = CISTPL_LONGLINK_MFC; - if (!pcmcia_get_next_tuple(function, tuple)) { - tuple->DesiredTuple = CISTPL_LINKTARGET; - if (pcmcia_get_next_tuple(function, tuple)) - return -ENODEV; - } else - tuple->CISOffset = tuple->TupleLink = 0; - tuple->DesiredTuple = req; - } - return pcmcia_get_next_tuple(function, tuple); -} - - -static int follow_link(tuple_t *tuple) -{ - char link[5]; - unsigned int ofs; - - if (MFC_FN(tuple->Flags)) { - /* Get indirect link from the MFC tuple */ - read_cis(LINK_SPACE(tuple->Flags), - tuple->LinkOffset, 5, link); - ofs = *(u_int *)(link+1); - SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); - /* Move to the next indirect link */ - tuple->LinkOffset += 5; - MFC_FN(tuple->Flags)--; - } else if (HAS_LINK(tuple->Flags)) { - ofs = tuple->LinkOffset; - SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags); - HAS_LINK(tuple->Flags) = 0; - } else { - return -1; - } - if (SPACE(tuple->Flags)) { - /* This is ugly, but a common CIS error is to code the long - link offset incorrectly, so we check the right spot... */ - read_cis(SPACE(tuple->Flags), ofs, 5, link); - if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && - (strncmp(link+2, "CIS", 3) == 0)) - return ofs; - /* Then, we try the wrong spot... */ - ofs = ofs >> 1; - } - read_cis(SPACE(tuple->Flags), ofs, 5, link); - if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && - (strncmp(link+2, "CIS", 3) == 0)) - return ofs; - return -1; -} - -int pcmcia_get_next_tuple(unsigned int function, tuple_t *tuple) -{ - unsigned char link[2], tmp; - int ofs, i, attr; - - link[1] = tuple->TupleLink; - ofs = tuple->CISOffset + tuple->TupleLink; - attr = SPACE(tuple->Flags); - - for (i = 0; i < MAX_TUPLES; i++) { - if (link[1] == 0xff) { - link[0] = CISTPL_END; - } else { - read_cis(attr, ofs, 2, link); - if (link[0] == CISTPL_NULL) { - ofs++; continue; - } - } - - /* End of chain? Follow long link if possible */ - if (link[0] == CISTPL_END) { - if ((ofs = follow_link(tuple)) < 0) - return -ENODEV; - attr = SPACE(tuple->Flags); - read_cis(attr, ofs, 2, link); - } - - /* Is this a link tuple? Make a note of it */ - if ((link[0] == CISTPL_LONGLINK_A) || - (link[0] == CISTPL_LONGLINK_C) || - (link[0] == CISTPL_LONGLINK_MFC) || - (link[0] == CISTPL_LINKTARGET) || - (link[0] == CISTPL_INDIRECT) || - (link[0] == CISTPL_NO_LINK)) { - switch (link[0]) { - case CISTPL_LONGLINK_A: - HAS_LINK(tuple->Flags) = 1; - LINK_SPACE(tuple->Flags) = attr | IS_ATTR; - read_cis(attr, ofs+2, 4, &tuple->LinkOffset); - break; - case CISTPL_LONGLINK_C: - HAS_LINK(tuple->Flags) = 1; - LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; - read_cis(attr, ofs+2, 4, &tuple->LinkOffset); - break; - case CISTPL_INDIRECT: - HAS_LINK(tuple->Flags) = 1; - LINK_SPACE(tuple->Flags) = IS_ATTR | IS_INDIRECT; - tuple->LinkOffset = 0; - break; - case CISTPL_LONGLINK_MFC: - tuple->LinkOffset = ofs + 3; - LINK_SPACE(tuple->Flags) = attr; - if (function == BIND_FN_ALL) { - /* Follow all the MFC links */ - read_cis(attr, ofs+2, 1, &tmp); - MFC_FN(tuple->Flags) = tmp; - } else { - /* Follow exactly one of the links */ - MFC_FN(tuple->Flags) = 1; - tuple->LinkOffset += function * 5; - } - break; - case CISTPL_NO_LINK: - HAS_LINK(tuple->Flags) = 0; - break; - } - if ((tuple->Attributes & TUPLE_RETURN_LINK) && - (tuple->DesiredTuple == RETURN_FIRST_TUPLE)) - break; - } else - if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) - break; - - if (link[0] == tuple->DesiredTuple) - break; - ofs += link[1] + 2; - } - if (i == MAX_TUPLES) - return -ENODEV; - - tuple->TupleCode = link[0]; - tuple->TupleLink = link[1]; - tuple->CISOffset = ofs + 2; - - return 0; -} - -#define _MIN(a, b) (((a) < (b)) ? (a) : (b)) - -int pcmcia_get_tuple_data(tuple_t *tuple) -{ - unsigned int len; - - if (tuple->TupleLink < tuple->TupleOffset) - return -ENODEV; - len = tuple->TupleLink - tuple->TupleOffset; - tuple->TupleDataLen = tuple->TupleLink; - if (len == 0) - return 0; - - read_cis (SPACE(tuple->Flags), - tuple->CISOffset + tuple->TupleOffset, - _MIN(len, tuple->TupleDataMax), - tuple->TupleData); - - return 0; -} - - -int read_out_cis (unsigned int socket_no, FILE *fd) -{ - char file[PATH_MAX]; - int ret, i; - tuple_t tuple; - unsigned char buf[256]; - - snprintf(file, sizeof(file), PATH_TO_SOCKET "pcmcia_socket%d/cis", - socket_no); - - if (!fd) { - fd = fopen(file, "r"); - if (!fd) - return -EIO; - } - - for (i=0; i<MAX_TUPLES; i++) { - ret = fgetc(fd); - if (ret == EOF) { - cis_length = i + 1; - break; - } - cis_copy[i] = (unsigned char) ret; - } - fclose(fd); - - if (cis_length < 4) - return -EINVAL; - - functions = 1; - - tuple.DesiredTuple = CISTPL_LONGLINK_MFC; - tuple.Attributes = TUPLE_RETURN_COMMON; - - ret = pcmcia_get_first_tuple(BIND_FN_ALL, &tuple); - if (ret) - functions = 1; - - tuple.TupleData = buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - ret = pcmcia_get_tuple_data(&tuple); - if (ret) - return -EBADF; - - functions = tuple.TupleData[0]; - - return 0; -} |