summaryrefslogtreecommitdiff
path: root/src/read-cis.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/read-cis.c')
-rw-r--r--src/read-cis.c275
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;
-}