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

📄 rsparser.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
			break;		case SMALL_TAG_IRQ:			if (len < 2 || len > 3)				goto len_err;			pnpbios_parse_irq_option(p, len, option);			break;		case SMALL_TAG_DMA:			if (len != 2)				goto len_err;			pnpbios_parse_dma_option(p, len, option);			break;		case SMALL_TAG_PORT:			if (len != 7)				goto len_err;			pnpbios_parse_port_option(p, len, option);			break;		case SMALL_TAG_VENDOR:			/* do nothing */			break;		case SMALL_TAG_FIXEDPORT:			if (len != 3)				goto len_err;			pnpbios_parse_fixed_port_option(p, len, option);			break;		case SMALL_TAG_STARTDEP:			if (len > 1)				goto len_err;			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;			if (len > 0)				priority = 0x100 | p[1];			option = pnp_register_dependent_option(dev, priority);			if (!option)				return NULL;			break;		case SMALL_TAG_ENDDEP:			if (len != 0)				goto len_err;			if (option_independent == option)				printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n");			option = option_independent;			break;		case SMALL_TAG_END:			if (option_independent != option)				printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_ENDDEP tag\n");			p = p + 2;        		return (unsigned char *)p;			break;		default: /* an unkown tag */			len_err:			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);			break;		}		/* continue to the next tag */		if (p[0] & LARGE_TAG)			p += len + 3;		else			p += len + 1;	}	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");	return NULL;}/* * Compatible Device IDs */#define HEX(id,a) hex[((id)>>a) & 15]#define CHAR(id,a) (0x40 + (((id)>>a) & 31))//void pnpid32_to_pnpid(u32 id, char *str){	const char *hex = "0123456789abcdef";	id = be32_to_cpu(id);	str[0] = CHAR(id, 26);	str[1] = CHAR(id, 21);	str[2] = CHAR(id,16);	str[3] = HEX(id, 12);	str[4] = HEX(id, 8);	str[5] = HEX(id, 4);	str[6] = HEX(id, 0);	str[7] = '\0';	return;}//#undef CHAR#undef HEXstatic unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_dev *dev){	int len, tag;	char id[8];	struct pnp_id *dev_id;	if (!p)		return NULL;	while ((char *)p < (char *)end) {		/* determine the type of tag */		if (p[0] & LARGE_TAG) { /* large tag */			len = (p[2] << 8) | p[1];			tag = p[0];		} else { /* small tag */			len = p[0] & 0x07;			tag = ((p[0]>>3) & 0x0f);		}		switch (tag) {		case LARGE_TAG_ANSISTR:			strncpy(dev->name, p + 3, len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len);			dev->name[len >= PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0';			break;		case SMALL_TAG_COMPATDEVID: /* compatible ID */			if (len != 4)				goto len_err;			dev_id =  kcalloc(1, sizeof (struct pnp_id), GFP_KERNEL);			if (!dev_id)				return NULL;			memset(dev_id, 0, sizeof(struct pnp_id));			pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id);			memcpy(&dev_id->id, id, 7);			pnp_add_id(dev_id, dev);			break;		case SMALL_TAG_END:			p = p + 2;        		return (unsigned char *)p;			break;		default: /* an unkown tag */			len_err:			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);			break;		}		/* continue to the next tag */		if (p[0] & LARGE_TAG)			p += len + 3;		else			p += len + 1;	}	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");	return NULL;}/* * Allocated Resource Encoding */static void pnpbios_encode_mem(unsigned char *p, struct resource * res){	unsigned long base = res->start;	unsigned long len = res->end - res->start + 1;	p[4] = (base >> 8) & 0xff;	p[5] = ((base >> 8) >> 8) & 0xff;	p[6] = (base >> 8) & 0xff;	p[7] = ((base >> 8) >> 8) & 0xff;	p[10] = (len >> 8) & 0xff;	p[11] = ((len >> 8) >> 8) & 0xff;	return;}static void pnpbios_encode_mem32(unsigned char *p, struct resource * res){	unsigned long base = res->start;	unsigned long len = res->end - res->start + 1;	p[4] = base & 0xff;	p[5] = (base >> 8) & 0xff;	p[6] = (base >> 16) & 0xff;	p[7] = (base >> 24) & 0xff;	p[8] = base & 0xff;	p[9] = (base >> 8) & 0xff;	p[10] = (base >> 16) & 0xff;	p[11] = (base >> 24) & 0xff;	p[16] = len & 0xff;	p[17] = (len >> 8) & 0xff;	p[18] = (len >> 16) & 0xff;	p[19] = (len >> 24) & 0xff;	return;}static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource * res){	unsigned long base = res->start;	unsigned long len = res->end - res->start + 1;	p[4] = base & 0xff;	p[5] = (base >> 8) & 0xff;	p[6] = (base >> 16) & 0xff;	p[7] = (base >> 24) & 0xff;	p[8] = len & 0xff;	p[9] = (len >> 8) & 0xff;	p[10] = (len >> 16) & 0xff;	p[11] = (len >> 24) & 0xff;	return;}static void pnpbios_encode_irq(unsigned char *p, struct resource * res){	unsigned long map = 0;	map = 1 << res->start;	p[1] = map & 0xff;	p[2] = (map >> 8) & 0xff;	return;}static void pnpbios_encode_dma(unsigned char *p, struct resource * res){	unsigned long map = 0;	map = 1 << res->start;	p[1] = map & 0xff;	return;}static void pnpbios_encode_port(unsigned char *p, struct resource * res){	unsigned long base = res->start;	unsigned long len = res->end - res->start + 1;	p[2] = base & 0xff;	p[3] = (base >> 8) & 0xff;	p[4] = base & 0xff;	p[5] = (base >> 8) & 0xff;	p[7] = len & 0xff;	return;}static void pnpbios_encode_fixed_port(unsigned char *p, struct resource * res){	unsigned long base = res->start;	unsigned long len = res->end - res->start + 1;	p[1] = base & 0xff;	p[2] = (base >> 8) & 0xff;	p[3] = len & 0xff;	return;}static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char * p, unsigned char * end, struct pnp_resource_table * res){	unsigned int len, tag;	int port = 0, irq = 0, dma = 0, mem = 0;	if (!p)		return NULL;	while ((char *)p < (char *)end) {		/* determine the type of tag */		if (p[0] & LARGE_TAG) { /* large tag */			len = (p[2] << 8) | p[1];			tag = p[0];		} else { /* small tag */			len = p[0] & 0x07;			tag = ((p[0]>>3) & 0x0f);		}		switch (tag) {		case LARGE_TAG_MEM:			if (len != 9)				goto len_err;			pnpbios_encode_mem(p, &res->mem_resource[mem]);			mem++;			break;		case LARGE_TAG_MEM32:			if (len != 17)				goto len_err;			pnpbios_encode_mem32(p, &res->mem_resource[mem]);			mem++;			break;		case LARGE_TAG_FIXEDMEM32:			if (len != 9)				goto len_err;			pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]);			mem++;			break;		case SMALL_TAG_IRQ:			if (len < 2 || len > 3)				goto len_err;			pnpbios_encode_irq(p, &res->irq_resource[irq]);			irq++;			break;		case SMALL_TAG_DMA:			if (len != 2)				goto len_err;			pnpbios_encode_dma(p, &res->dma_resource[dma]);			dma++;			break;		case SMALL_TAG_PORT:			if (len != 7)				goto len_err;			pnpbios_encode_port(p, &res->port_resource[port]);			port++;			break;		case SMALL_TAG_VENDOR:			/* do nothing */			break;		case SMALL_TAG_FIXEDPORT:			if (len != 3)				goto len_err;			pnpbios_encode_fixed_port(p, &res->port_resource[port]);			port++;			break;		case SMALL_TAG_END:			p = p + 2;        		return (unsigned char *)p;			break;		default: /* an unkown tag */			len_err:			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);			break;		}		/* continue to the next tag */		if (p[0] & LARGE_TAG)			p += len + 3;		else			p += len + 1;	}	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");	return NULL;}/* * Core Parsing Functions */intpnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node){	unsigned char * p = (char *)node->data;	unsigned char * end = (char *)(node->data + node->size);	p = pnpbios_parse_allocated_resource_data(p,end,&dev->res);	if (!p)		return -EIO;	p = pnpbios_parse_resource_option_data(p,end,dev);	if (!p)		return -EIO;	p = pnpbios_parse_compatible_ids(p,end,dev);	if (!p)		return -EIO;	return 0;}intpnpbios_read_resources_from_node(struct pnp_resource_table *res,				 struct pnp_bios_node * node){	unsigned char * p = (char *)node->data;	unsigned char * end = (char *)(node->data + node->size);	p = pnpbios_parse_allocated_resource_data(p,end,res);	if (!p)		return -EIO;	return 0;}intpnpbios_write_resources_to_node(struct pnp_resource_table *res,				struct pnp_bios_node * node){	unsigned char * p = (char *)node->data;	unsigned char * end = (char *)(node->data + node->size);	p = pnpbios_encode_allocated_resource_data(p,end,res);	if (!p)		return -EIO;	return 0;}

⌨️ 快捷键说明

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