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

📄 cistpl.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (has_ha)	    for (j = 0; j < asz; j++, p++) {		if (p == q) return NULL;		ha += *p << (j*8);	    }	mem->win[i].len = len << 8;	mem->win[i].card_addr = ca << 8;	mem->win[i].host_addr = ha << 8;    }    return p;}/*====================================================================*/static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq){    if (p == q) return NULL;    irq->IRQInfo1 = *p; p++;    if (irq->IRQInfo1 & IRQ_INFO2_VALID) {	if (p+2 > q) return NULL;	irq->IRQInfo2 = (p[1]<<8) + p[0];	p += 2;    }    return p;}/*====================================================================*/static int parse_cftable_entry(tuple_t *tuple,			       cistpl_cftable_entry_t *entry){    u_char *p, *q, features;    p = tuple->TupleData;    q = p + tuple->TupleDataLen;    entry->index = *p & 0x3f;    entry->flags = 0;    if (*p & 0x40)	entry->flags |= CISTPL_CFTABLE_DEFAULT;    if (*p & 0x80) {	if (++p == q) return CS_BAD_TUPLE;	if (*p & 0x10)	    entry->flags |= CISTPL_CFTABLE_BVDS;	if (*p & 0x20)	    entry->flags |= CISTPL_CFTABLE_WP;	if (*p & 0x40)	    entry->flags |= CISTPL_CFTABLE_RDYBSY;	if (*p & 0x80)	    entry->flags |= CISTPL_CFTABLE_MWAIT;	entry->interface = *p & 0x0f;    } else	entry->interface = 0;    /* Process optional features */    if (++p == q) return CS_BAD_TUPLE;    features = *p; p++;    /* Power options */    if ((features & 3) > 0) {	p = parse_power(p, q, &entry->vcc);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vcc.present = 0;    if ((features & 3) > 1) {	p = parse_power(p, q, &entry->vpp1);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vpp1.present = 0;    if ((features & 3) > 2) {	p = parse_power(p, q, &entry->vpp2);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vpp2.present = 0;    /* Timing options */    if (features & 0x04) {	p = parse_timing(p, q, &entry->timing);	if (p == NULL) return CS_BAD_TUPLE;    } else {	entry->timing.wait = 0;	entry->timing.ready = 0;	entry->timing.reserved = 0;    }        /* I/O window options */    if (features & 0x08) {	p = parse_io(p, q, &entry->io);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->io.nwin = 0;        /* Interrupt options */    if (features & 0x10) {	p = parse_irq(p, q, &entry->irq);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->irq.IRQInfo1 = 0;    switch (features & 0x60) {    case 0x00:	entry->mem.nwin = 0;	break;    case 0x20:	entry->mem.nwin = 1;	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;	entry->mem.win[0].card_addr = 0;	entry->mem.win[0].host_addr = 0;	p += 2;	if (p > q) return CS_BAD_TUPLE;	break;    case 0x40:	entry->mem.nwin = 1;	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;	entry->mem.win[0].card_addr =	    le16_to_cpu(*(u_short *)(p+2)) << 8;	entry->mem.win[0].host_addr = 0;	p += 4;	if (p > q) return CS_BAD_TUPLE;	break;    case 0x60:	p = parse_mem(p, q, &entry->mem);	if (p == NULL) return CS_BAD_TUPLE;	break;    }    /* Misc features */    if (features & 0x80) {	if (p == q) return CS_BAD_TUPLE;	entry->flags |= (*p << 8);	while (*p & 0x80)	    if (++p == q) return CS_BAD_TUPLE;	p++;    }    entry->subtuples = q-p;        return CS_SUCCESS;}/*====================================================================*/#ifdef CONFIG_CARDBUSstatic int parse_bar(tuple_t *tuple, cistpl_bar_t *bar){    u_char *p;    if (tuple->TupleDataLen < 6)	return CS_BAD_TUPLE;    p = (u_char *)tuple->TupleData;    bar->attr = *p;    p += 2;    bar->size = le32_to_cpu(*(u_int *)p);    return CS_SUCCESS;}static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config){    u_char *p;        p = (u_char *)tuple->TupleData;    if ((*p != 3) || (tuple->TupleDataLen < 6))	return CS_BAD_TUPLE;    config->last_idx = *(++p);    p++;    config->base = le32_to_cpu(*(u_int *)p);    config->subtuples = tuple->TupleDataLen - 6;    return CS_SUCCESS;}static int parse_cftable_entry_cb(tuple_t *tuple,				  cistpl_cftable_entry_cb_t *entry){    u_char *p, *q, features;    p = tuple->TupleData;    q = p + tuple->TupleDataLen;    entry->index = *p & 0x3f;    entry->flags = 0;    if (*p & 0x40)	entry->flags |= CISTPL_CFTABLE_DEFAULT;    /* Process optional features */    if (++p == q) return CS_BAD_TUPLE;    features = *p; p++;    /* Power options */    if ((features & 3) > 0) {	p = parse_power(p, q, &entry->vcc);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vcc.present = 0;    if ((features & 3) > 1) {	p = parse_power(p, q, &entry->vpp1);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vpp1.present = 0;    if ((features & 3) > 2) {	p = parse_power(p, q, &entry->vpp2);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->vpp2.present = 0;    /* I/O window options */    if (features & 0x08) {	if (p == q) return CS_BAD_TUPLE;	entry->io = *p; p++;    } else	entry->io = 0;        /* Interrupt options */    if (features & 0x10) {	p = parse_irq(p, q, &entry->irq);	if (p == NULL) return CS_BAD_TUPLE;    } else	entry->irq.IRQInfo1 = 0;    if (features & 0x20) {	if (p == q) return CS_BAD_TUPLE;	entry->mem = *p; p++;    } else	entry->mem = 0;    /* Misc features */    if (features & 0x80) {	if (p == q) return CS_BAD_TUPLE;	entry->flags |= (*p << 8);	if (*p & 0x80) {	    if (++p == q) return CS_BAD_TUPLE;	    entry->flags |= (*p << 16);	}	while (*p & 0x80)	    if (++p == q) return CS_BAD_TUPLE;	p++;    }    entry->subtuples = q-p;        return CS_SUCCESS;}#endif/*====================================================================*/static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo){    u_char *p, *q;    int n;    p = (u_char *)tuple->TupleData;    q = p + tuple->TupleDataLen;    for (n = 0; n < CISTPL_MAX_DEVICES; n++) {	if (p > q-6) break;	geo->geo[n].buswidth = p[0];	geo->geo[n].erase_block = 1 << (p[1]-1);	geo->geo[n].read_block  = 1 << (p[2]-1);	geo->geo[n].write_block = 1 << (p[3]-1);	geo->geo[n].partition   = 1 << (p[4]-1);	geo->geo[n].interleave  = 1 << (p[5]-1);	p += 6;    }    geo->ngeo = n;    return CS_SUCCESS;}/*====================================================================*/static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2){    u_char *p, *q;    if (tuple->TupleDataLen < 10)	return CS_BAD_TUPLE;        p = tuple->TupleData;    q = p + tuple->TupleDataLen;    v2->vers = p[0];    v2->comply = p[1];    v2->dindex = le16_to_cpu(*(u_short *)(p+2));    v2->vspec8 = p[6];    v2->vspec9 = p[7];    v2->nhdr = p[8];    p += 9;    return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);}/*====================================================================*/static int parse_org(tuple_t *tuple, cistpl_org_t *org){    u_char *p, *q;    int i;        p = tuple->TupleData;    q = p + tuple->TupleDataLen;    if (p == q) return CS_BAD_TUPLE;    org->data_org = *p;    if (++p == q) return CS_BAD_TUPLE;    for (i = 0; i < 30; i++) {	org->desc[i] = *p;	if (*p == '\0') break;	if (++p == q) return CS_BAD_TUPLE;    }    return CS_SUCCESS;}/*====================================================================*/static int parse_format(tuple_t *tuple, cistpl_format_t *fmt){    u_char *p;    if (tuple->TupleDataLen < 10)	return CS_BAD_TUPLE;    p = tuple->TupleData;    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));    return CS_SUCCESS;}/*====================================================================*/int parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse){    int ret = CS_SUCCESS;        if (tuple->TupleDataLen > tuple->TupleDataMax)	return CS_BAD_TUPLE;    switch (tuple->TupleCode) {    case CISTPL_DEVICE:    case CISTPL_DEVICE_A:	ret = parse_device(tuple, &parse->device);	break;#ifdef CONFIG_CARDBUS    case CISTPL_BAR:	ret = parse_bar(tuple, &parse->bar);	break;    case CISTPL_CONFIG_CB:	ret = parse_config_cb(tuple, &parse->config);	break;    case CISTPL_CFTABLE_ENTRY_CB:	ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb);	break;#endif    case CISTPL_CHECKSUM:	ret = parse_checksum(tuple, &parse->checksum);	break;    case CISTPL_LONGLINK_A:    case CISTPL_LONGLINK_C:	ret = parse_longlink(tuple, &parse->longlink);	break;    case CISTPL_LONGLINK_MFC:	ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);	break;    case CISTPL_VERS_1:	ret = parse_vers_1(tuple, &parse->version_1);	break;    case CISTPL_ALTSTR:	ret = parse_altstr(tuple, &parse->altstr);	break;    case CISTPL_JEDEC_A:    case CISTPL_JEDEC_C:	ret = parse_jedec(tuple, &parse->jedec);	break;    case CISTPL_MANFID:	ret = parse_manfid(tuple, &parse->manfid);	break;    case CISTPL_FUNCID:	ret = parse_funcid(tuple, &parse->funcid);	break;    case CISTPL_FUNCE:	ret = parse_funce(tuple, &parse->funce);	break;    case CISTPL_CONFIG:	ret = parse_config(tuple, &parse->config);	break;    case CISTPL_CFTABLE_ENTRY:	ret = parse_cftable_entry(tuple, &parse->cftable_entry);	break;    case CISTPL_DEVICE_GEO:    case CISTPL_DEVICE_GEO_A:	ret = parse_device_geo(tuple, &parse->device_geo);	break;    case CISTPL_VERS_2:	ret = parse_vers_2(tuple, &parse->vers_2);	break;    case CISTPL_ORG:	ret = parse_org(tuple, &parse->org);	break;    case CISTPL_FORMAT:    case CISTPL_FORMAT_A:	ret = parse_format(tuple, &parse->format);	break;    case CISTPL_NO_LINK:    case CISTPL_LINKTARGET:	ret = CS_SUCCESS;	break;    default:	ret = CS_UNSUPPORTED_FUNCTION;	break;    }    return ret;}/*======================================================================    This is used internally by Card Services to look up CIS stuff.    ======================================================================*/int read_tuple(client_handle_t handle, cisdata_t code, void *parse){    tuple_t tuple;    cisdata_t buf[255];    int ret;        tuple.DesiredTuple = code;    tuple.Attributes = TUPLE_RETURN_COMMON;    ret = CardServices(GetFirstTuple, handle, &tuple, NULL);    if (ret != CS_SUCCESS) return ret;    tuple.TupleData = buf;    tuple.TupleOffset = 0;    tuple.TupleDataMax = sizeof(buf);    ret = CardServices(GetTupleData, handle, &tuple, NULL);    if (ret != CS_SUCCESS) return ret;    ret = CardServices(ParseTuple, handle, &tuple, parse);    return ret;}/*======================================================================    This tries to determine if a card has a sensible CIS.  It returns    the number of tuples in the CIS, or 0 if the CIS looks bad.  The    checks include making sure several critical tuples are present and    valid; seeing if the total number of tuples is reasonable; and    looking for tuples that use reserved codes.    ======================================================================*/int validate_cis(client_handle_t handle, cisinfo_t *info){    tuple_t tuple;    cisparse_t p;    int ret, reserved, dev_ok = 0, ident_ok = 0;    if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    info->Chains = reserved = 0;    tuple.DesiredTuple = RETURN_FIRST_TUPLE;    tuple.Attributes = TUPLE_RETURN_COMMON;    ret = get_first_tuple(handle, &tuple);    if (ret != CS_SUCCESS)	return CS_SUCCESS;    /* 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))	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))	ident_ok++;    if (!dev_ok && !ident_ok)	return CS_SUCCESS;    for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {	ret = get_next_tuple(handle, &tuple);	if (ret != CS_SUCCESS) break;	if (((tuple.TupleCode > 0x23) && (tuple.TupleCode < 0x40)) ||	    ((tuple.TupleCode > 0x47) && (tuple.TupleCode < 0x80)) ||	    ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff)))	    reserved++;    }    if ((info->Chains == MAX_TUPLES) || (reserved > 5) ||	((!dev_ok || !ident_ok) && (info->Chains > 10)))	info->Chains = 0;    return CS_SUCCESS;}

⌨️ 快捷键说明

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