⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cistpl.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 3 页
字号:
    socket_info_t *s;    u_char link[2], tmp;    int ofs, i, attr;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    s = SOCKET(handle);    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    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_cache(s, 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(s, tuple)) < 0)		return CS_NO_MORE_ITEMS;	    attr = SPACE(tuple->Flags);	    read_cis_cache(s, 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_cache(s, 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_cache(s, 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 (handle->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;		}		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) {	DEBUG(1, "cs: overrun in get_next_tuple for socket %d\n",	      handle->Socket);	return CS_NO_MORE_ITEMS;    }        tuple->TupleCode = link[0];    tuple->TupleLink = link[1];    tuple->CISOffset = ofs + 2;    return CS_SUCCESS;}/*====================================================================*/#define _MIN(a, b)		(((a) < (b)) ? (a) : (b))int get_tuple_data(client_handle_t handle, tuple_t *tuple){    socket_info_t *s;    u_int len;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    s = SOCKET(handle);    if (tuple->TupleLink < tuple->TupleOffset)	return CS_NO_MORE_ITEMS;    len = tuple->TupleLink - tuple->TupleOffset;    tuple->TupleDataLen = tuple->TupleLink;    if (len == 0)	return CS_SUCCESS;    read_cis_cache(s, SPACE(tuple->Flags),		   tuple->CISOffset + tuple->TupleOffset,		   _MIN(len, tuple->TupleDataMax), tuple->TupleData);    return CS_SUCCESS;}/*======================================================================    Parsing routines for individual tuples    ======================================================================*/static int parse_device(tuple_t *tuple, cistpl_device_t *device){    int i;    u_char scale;    u_char *p, *q;    p = (u_char *)tuple->TupleData;    q = p + tuple->TupleDataLen;    device->ndev = 0;    for (i = 0; i < CISTPL_MAX_DEVICES; i++) {		if (*p == 0xff) break;	device->dev[i].type = (*p >> 4);	device->dev[i].wp = (*p & 0x08) ? 1 : 0;	switch (*p & 0x07) {	case 0: device->dev[i].speed = 0;   break;	case 1: device->dev[i].speed = 250; break;	case 2: device->dev[i].speed = 200; break;	case 3: device->dev[i].speed = 150; break;	case 4: device->dev[i].speed = 100; break;	case 7:	    if (++p == q) return CS_BAD_TUPLE;	    device->dev[i].speed = SPEED_CVT(*p);	    while (*p & 0x80)		if (++p == q) return CS_BAD_TUPLE;	    break;	default:	    return CS_BAD_TUPLE;	}	if (++p == q) return CS_BAD_TUPLE;	if (*p == 0xff) break;	scale = *p & 7;	if (scale == 7) return CS_BAD_TUPLE;	device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));	device->ndev++;	if (++p == q) break;    }        return CS_SUCCESS;}/*====================================================================*/static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum){    u_char *p;    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->sum = *(p+4);    return CS_SUCCESS;}/*====================================================================*/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);    return CS_SUCCESS;}/*====================================================================*/static int parse_longlink_mfc(tuple_t *tuple,			      cistpl_longlink_mfc_t *link){    u_char *p;    int i;        p = (u_char *)tuple->TupleData;        link->nfn = *p; p++;    if (tuple->TupleDataLen <= link->nfn*5)	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;    }    return CS_SUCCESS;}/*====================================================================*/static int parse_strings(u_char *p, u_char *q, int max,			 char *s, u_char *ofs, u_char *found){    int i, j, ns;    if (p == q) return CS_BAD_TUPLE;    ns = 0; j = 0;    for (i = 0; i < max; i++) {	if (*p == 0xff) break;	ofs[i] = j;	ns++;	for (;;) {	    s[j++] = (*p == 0xff) ? '\0' : *p;	    if ((*p == '\0') || (*p == 0xff)) break;	    if (++p == q) return CS_BAD_TUPLE;	}	if ((*p == 0xff) || (++p == q)) break;    }    if (found) {	*found = ns;	return CS_SUCCESS;    } else {	return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE;    }}/*====================================================================*/static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1){    u_char *p, *q;        p = (u_char *)tuple->TupleData;    q = p + tuple->TupleDataLen;        vers_1->major = *p; p++;    vers_1->minor = *p; p++;    if (p >= q) return CS_BAD_TUPLE;    return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,			 vers_1->str, vers_1->ofs, &vers_1->ns);}/*====================================================================*/static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr){    u_char *p, *q;        p = (u_char *)tuple->TupleData;    q = p + tuple->TupleDataLen;        return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,			 altstr->str, altstr->ofs, &altstr->ns);}/*====================================================================*/static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec){    u_char *p, *q;    int nid;    p = (u_char *)tuple->TupleData;    q = p + tuple->TupleDataLen;    for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {	if (p > q-2) break;	jedec->id[nid].mfr = p[0];	jedec->id[nid].info = p[1];	p += 2;    }    jedec->nid = nid;    return CS_SUCCESS;}/*====================================================================*/static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m){    u_short *p;    if (tuple->TupleDataLen < 4)	return CS_BAD_TUPLE;    p = (u_short *)tuple->TupleData;    m->manf = le16_to_cpu(p[0]);    m->card = le16_to_cpu(p[1]);    return CS_SUCCESS;}/*====================================================================*/static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f){    u_char *p;    if (tuple->TupleDataLen < 2)	return CS_BAD_TUPLE;    p = (u_char *)tuple->TupleData;    f->func = p[0];    f->sysinit = p[1];    return CS_SUCCESS;}/*====================================================================*/static int parse_funce(tuple_t *tuple, cistpl_funce_t *f){    u_char *p;    int i;    if (tuple->TupleDataLen < 1)	return CS_BAD_TUPLE;    p = (u_char *)tuple->TupleData;    f->type = p[0];    for (i = 1; i < tuple->TupleDataLen; i++)	f->data[i-1] = p[i];    return CS_SUCCESS;}/*====================================================================*/static int parse_config(tuple_t *tuple, cistpl_config_t *config){    int rasz, rmsz, i;    u_char *p;    p = (u_char *)tuple->TupleData;    rasz = *p & 0x03;    rmsz = (*p & 0x3c) >> 2;    if (tuple->TupleDataLen < rasz+rmsz+4)	return CS_BAD_TUPLE;    config->last_idx = *(++p);    p++;    config->base = 0;    for (i = 0; i <= rasz; i++)	config->base += p[i] << (8*i);    p += rasz+1;    for (i = 0; i < 4; i++)	config->rmask[i] = 0;    for (i = 0; i <= rmsz; i++)	config->rmask[i>>2] += p[i] << (8*(i%4));    config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);    return CS_SUCCESS;}/*======================================================================    The following routines are all used to parse the nightmarish    config table entries.    ======================================================================*/static u_char *parse_power(u_char *p, u_char *q,			   cistpl_power_t *pwr){    int i;    u_int scale;    if (p == q) return NULL;    pwr->present = *p;    pwr->flags = 0;    p++;    for (i = 0; i < 7; i++)	if (pwr->present & (1<<i)) {	    if (p == q) return NULL;	    pwr->param[i] = POWER_CVT(*p);	    scale = POWER_SCALE(*p);	    while (*p & 0x80) {		if (++p == q) return NULL;		if ((*p & 0x7f) < 100)		    pwr->param[i] += (*p & 0x7f) * scale / 100;		else if (*p == 0x7d)		    pwr->flags |= CISTPL_POWER_HIGHZ_OK;		else if (*p == 0x7e)		    pwr->param[i] = 0;		else if (*p == 0x7f)		    pwr->flags |= CISTPL_POWER_HIGHZ_REQ;		else		    return NULL;	    }	    p++;	}    return p;}/*====================================================================*/static u_char *parse_timing(u_char *p, u_char *q,			    cistpl_timing_t *timing){    u_char scale;    if (p == q) return NULL;    scale = *p;    if ((scale & 3) != 3) {	if (++p == q) return NULL;	timing->wait = SPEED_CVT(*p);	timing->waitscale = exponent[scale & 3];    } else	timing->wait = 0;    scale >>= 2;    if ((scale & 7) != 7) {	if (++p == q) return NULL;	timing->ready = SPEED_CVT(*p);	timing->rdyscale = exponent[scale & 7];    } else	timing->ready = 0;    scale >>= 3;    if (scale != 7) {	if (++p == q) return NULL;	timing->reserved = SPEED_CVT(*p);	timing->rsvscale = exponent[scale];    } else	timing->reserved = 0;    p++;    return p;}/*====================================================================*/static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io){    int i, j, bsz, lsz;    if (p == q) return NULL;    io->flags = *p;    if (!(*p & 0x80)) {	io->nwin = 1;	io->win[0].base = 0;	io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));	return p+1;    }        if (++p == q) return NULL;    io->nwin = (*p & 0x0f) + 1;    bsz = (*p & 0x30) >> 4;    if (bsz == 3) bsz++;    lsz = (*p & 0xc0) >> 6;    if (lsz == 3) lsz++;    p++;        for (i = 0; i < io->nwin; i++) {	io->win[i].base = 0;	io->win[i].len = 1;	for (j = 0; j < bsz; j++, p++) {	    if (p == q) return NULL;	    io->win[i].base += *p << (j*8);	}	for (j = 0; j < lsz; j++, p++) {	    if (p == q) return NULL;	    io->win[i].len += *p << (j*8);	}    }    return p;}/*====================================================================*/static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem){    int i, j, asz, lsz, has_ha;    u_int len, ca, ha;    if (p == q) return NULL;    mem->nwin = (*p & 0x07) + 1;    lsz = (*p & 0x18) >> 3;    asz = (*p & 0x60) >> 5;    has_ha = (*p & 0x80);    if (++p == q) return NULL;        for (i = 0; i < mem->nwin; i++) {	len = ca = ha = 0;	for (j = 0; j < lsz; j++, p++) {	    if (p == q) return NULL;	    len += *p << (j*8);	}	for (j = 0; j < asz; j++, p++) {	    if (p == q) return NULL;	    ca += *p << (j*8);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -