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

📄 isapnp.c

📁 话带数据中传真解调程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			kfree(dma);			return;		}	}	dma->map = tmp[0];	dma->flags = tmp[1];	dma->res = *res;	ptr = (*res)->dma;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = dma;	else		(*res)->dma = dma;}/* *  Add port resource to resources list. */static void __init isapnp_add_port_resource(struct pnp_dev *dev,						struct isapnp_resources **res,						int dependent, int size){	unsigned char tmp[7];	struct isapnp_port *port, *ptr;	isapnp_peek(tmp, size);	port = isapnp_alloc(sizeof(struct isapnp_port));	if (!port)		return;	if (*res == NULL) {		*res = isapnp_build_resources(dev, dependent);		if (*res == NULL) {			kfree(port);			return;		}	}	port->min = (tmp[2] << 8) | tmp[1];	port->max = (tmp[4] << 8) | tmp[3];	port->align = tmp[5];	port->size = tmp[6];	port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;	port->res = *res;	ptr = (*res)->port;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = port;	else		(*res)->port = port;}/* *  Add fixed port resource to resources list. */static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,						      struct isapnp_resources **res,						      int dependent, int size){	unsigned char tmp[3];	struct isapnp_port *port, *ptr;	isapnp_peek(tmp, size);	port = isapnp_alloc(sizeof(struct isapnp_port));	if (!port)		return;	if (*res == NULL) {		*res = isapnp_build_resources(dev, dependent);		if (*res == NULL) {			kfree(port);			return;		}	}	port->min = port->max = (tmp[1] << 8) | tmp[0];	port->size = tmp[2];	port->align = 0;	port->flags = ISAPNP_PORT_FLAG_FIXED;	port->res = *res;	ptr = (*res)->port;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = port;	else		(*res)->port = port;}/* *  Add memory resource to resources list. */static void __init isapnp_add_mem_resource(struct pnp_dev *dev,					       struct isapnp_resources **res,					       int dependent, int size){	unsigned char tmp[9];	struct isapnp_mem *mem, *ptr;	isapnp_peek(tmp, size);	mem = isapnp_alloc(sizeof(struct isapnp_mem));	if (!mem)		return;	if (*res == NULL) {		*res = isapnp_build_resources(dev, dependent);		if (*res == NULL) {			kfree(mem);			return;		}	}	mem->min = ((tmp[2] << 8) | tmp[1]) << 8;	mem->max = ((tmp[4] << 8) | tmp[3]) << 8;	mem->align = (tmp[6] << 8) | tmp[5];	mem->size = ((tmp[8] << 8) | tmp[7]) << 8;	mem->flags = tmp[0];	mem->res = *res;	ptr = (*res)->mem;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = mem;	else		(*res)->mem = mem;}/* *  Add 32-bit memory resource to resources list. */static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,						 struct isapnp_resources **res,						 int dependent, int size){	unsigned char tmp[17];	struct isapnp_mem32 *mem32, *ptr;	isapnp_peek(tmp, size);	mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));	if (!mem32)		return;	if (*res == NULL) {		*res = isapnp_build_resources(dev, dependent);		if (*res == NULL) {			kfree(mem32);			return;		}	}	memcpy(mem32->data, tmp, 17);	mem32->res = *res;	ptr = (*res)->mem32;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = mem32;	else		(*res)->mem32 = mem32;}/* *  Add 32-bit fixed memory resource to resources list. */static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,						       struct isapnp_resources **res,						       int dependent, int size){	unsigned char tmp[17];	struct isapnp_mem32 *mem32, *ptr;	isapnp_peek(tmp, size);	mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));	if (!mem32)		return;	if (*res == NULL) {		*res = isapnp_build_resources(dev, dependent);		if (*res == NULL) {			kfree(mem32);			return;		}	}	memcpy(mem32->data, tmp, 17);	mem32->res = *res;	ptr = (*res)->mem32;	while (ptr && ptr->next)		ptr = ptr->next;	if (ptr)		ptr->next = mem32;	else		(*res)->mem32 = mem32;}/* *  Parse resource map for logical device. */static int __init isapnp_create_device(struct pnp_bus *card,					   unsigned short size){	int number = 0, skip = 0, dependent = 0, compat = 0;	unsigned char type, tmp[17];	struct pnp_dev *dev, *prev_dev;	struct isapnp_resources *res = NULL;		if ((dev = isapnp_parse_device(card, size, number++)) == NULL)		return 1;	card->devices = dev;	if (isapnp_last_device) {		isapnp_last_device->next = dev;		isapnp_last_device = dev;	} else {		isapnp_devices = isapnp_last_device = dev;	}	while (1) {		if (isapnp_read_tag(&type, &size)<0)			return 1;		if (skip && type != _STAG_LOGDEVID && type != _STAG_END)			goto __skip;		switch (type) {		case _STAG_LOGDEVID:			if (size >= 5 && size <= 6) {				prev_dev = dev;				isapnp_config_prepare(dev);				if ((dev = isapnp_parse_device(card, size, number++)) == NULL)					return 1;				prev_dev->sibling = dev;				isapnp_last_device->next = dev;				isapnp_last_device = dev;				size = 0;				skip = 0;			} else {				skip = 1;			}			res = NULL;			dependent = 0;			compat = 0;			break;		case _STAG_COMPATDEVID:			if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {				isapnp_peek(tmp, 4);				dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0];				dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2];				compat++;				size = 0;			}			break;		case _STAG_IRQ:			if (size < 2 || size > 3)				goto __skip;			isapnp_add_irq_resource(dev, &res, dependent, size);			size = 0;			break;		case _STAG_DMA:			if (size != 2)				goto __skip;			isapnp_add_dma_resource(dev, &res, dependent, size);			size = 0;			break;		case _STAG_STARTDEP:			if (size > 1)				goto __skip;			res = NULL;			dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;			if (size > 0) {				isapnp_peek(tmp, size);				dependent = 0x100 | tmp[0];				size = 0;			}			break;		case _STAG_ENDDEP:			if (size != 0)				goto __skip;			res = NULL;			dependent = 0;			break;		case _STAG_IOPORT:			if (size != 7)				goto __skip;			isapnp_add_port_resource(dev, &res, dependent, size);			size = 0;			break;		case _STAG_FIXEDIO:			if (size != 3)				goto __skip;			isapnp_add_fixed_port_resource(dev, &res, dependent, size);			size = 0;			break;		case _STAG_VENDOR:			break;		case _LTAG_MEMRANGE:			if (size != 9)				goto __skip;			isapnp_add_mem_resource(dev, &res, dependent, size);			size = 0;			break;		case _LTAG_ANSISTR:			if (dev->name[0] == '\0') {				unsigned short size1 = size > 47 ? 47 : size;				isapnp_peek(dev->name, size1);				dev->name[size1] = '\0';				size -= size1;			}			break;		case _LTAG_UNICODESTR:			/* silently ignore */			/* who use unicode for hardware identification? */			break;		case _LTAG_VENDOR:			break;		case _LTAG_MEM32RANGE:			if (size != 17)				goto __skip;			isapnp_add_mem32_resource(dev, &res, dependent, size);			size = 0;			break;		case _LTAG_FIXEDMEM32RANGE:			if (size != 17)				goto __skip;			isapnp_add_fixed_mem32_resource(dev, &res, dependent, size);			size = 0;			break;		case _STAG_END:			if (size > 0)				isapnp_skip_bytes(size);			return 1;		default:			printk("isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->devfn, card->number);		}	      __skip:	      	if (size > 0)		      	isapnp_skip_bytes(size);	}	isapnp_config_prepare(dev);	return 0;}/* *  Parse resource map for ISA PnP card. */ static void __init isapnp_parse_resource_map(struct pnp_bus *card){	unsigned char type, tmp[17];	unsigned short size;		while (1) {		if (isapnp_read_tag(&type, &size)<0)			return;		switch (type) {		case _STAG_PNPVERNO:			if (size != 2)				goto __skip;			isapnp_peek(tmp, 2);			card->pnpver = tmp[0];			card->productver = tmp[1];			size = 0;			break;		case _STAG_LOGDEVID:			if (size >= 5 && size <= 6) {				if (isapnp_create_device(card, size)==1)					return;				size = 0;			}			break;		case _STAG_VENDOR:			break;		case _LTAG_ANSISTR:			if (card->name[0] == '\0') {				unsigned short size1 = size > 47 ? 47 : size;				isapnp_peek(card->name, size1);				card->name[size1] = '\0';				size -= size1;			}			break;		case _LTAG_UNICODESTR:			/* silently ignore */			/* who use unicode for hardware identification? */			break;		case _LTAG_VENDOR:			break;		case _STAG_END:			if (size > 0)				isapnp_skip_bytes(size);			return;		default:			printk("isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number);		}	      __skip:	      	if (size > 0)		      	isapnp_skip_bytes(size);	}}/* *  Compute ISA PnP checksum for first eight bytes. */static unsigned char __init isapnp_checksum(unsigned char *data){	int i, j;	unsigned char checksum = 0x6a, bit, b;		for (i = 0; i < 8; i++) {		b = data[i];		for (j = 0; j < 8; j++) {			bit = 0;			if (b & (1 << j))				bit = 1;			checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);		}	}	return checksum;}/* *  Build device list for all present ISA PnP devices. */static int __init isapnp_build_device_list(void){	int csn;	unsigned char header[9], checksum;	struct pnp_bus *card, *prev = NULL;	isapnp_wait();	isapnp_key();	for (csn = 1; csn <= 10; csn++) {		isapnp_wake(csn);		isapnp_peek(header, 9);		checksum = isapnp_checksum(header);#if 0		printk("vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",			header[0], header[1], header[2], header[3],			header[4], header[5], header[6], header[7], header[8]);		printk("checksum = 0x%x\n", checksum);#endif		if (checksum == 0x00 || checksum != header[8])	/* not valid CSN */			continue;		if ((card = isapnp_alloc(sizeof(struct pnp_bus))) == NULL)			continue;		card->number = csn;		card->vendor = (header[1] << 8) | header[0];		card->device = (header[3] << 8) | header[2];		card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];		isapnp_checksum_value = 0x00;		isapnp_parse_resource_map(card);		if (isapnp_checksum_value != 0x00)			printk("isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);		card->checksum = isapnp_checksum_value;		if (!isapnp_cards)			isapnp_cards = card;		else			prev->next = card;		prev = card;	}	return 0;}/* *  Basic configuration routines. */int isapnp_present(void){	if (isapnp_devices)		return 1;	return 0;}int isapnp_cfg_begin(int csn, int logdev){	if (csn < 1 || csn > 10 || logdev > 10)		return -EINVAL;	MOD_INC_USE_COUNT;	down(&isapnp_cfg_mutex);	isapnp_wait();	isapnp_key();	isapnp_wake(csn);#if 1	/* to avoid malfunction when the isapnptools package is used */	isapnp_set_rdp();	udelay(1000);	/* delay 1000us */	write_address(0x01);	udelay(1000);	/* delay 1000us */#endif	if (logdev >= 0)		isapnp_device(logdev);	return 0;}int isapnp_cfg_end(void){	isapnp_wait();	up(&isapnp_cfg_mutex);	MOD_DEC_USE_COUNT;	return 0;}/* *  Resource manager. */static struct isapnp_port *isapnp_find_port(struct pnp_dev *dev, int index){	struct isapnp_resources *res;	struct isapnp_port *port;		if (!dev || index < 0 || index > 7)		return NULL;	for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {		for (port = res->port; port; port = port->next) {			if (!index)				return port;			index--;		}	}	return NULL;}struct isapnp_irq *isapnp_find_irq(struct pnp_dev *dev, int index){	struct isapnp_resources *res, *resa;	struct isapnp_irq *irq;	int index1, index2, index3;		if (!dev || index < 0 || index > 7)		return NULL;	for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {		index3 = 0;		for (resa = res; resa; resa = resa->alt) {			index1 = index;			index2 = 0;			for (irq = resa->irq; irq; irq = irq->next) {				if (!index1)					return irq;				index1--;				index2++;			}			if (index3 < index2)				index3 = index2;		}		index -= index3;	}	return NULL;}struct isapnp_dma *isapnp_find_dma(struct pnp_dev *dev, int index){	struct isapnp_resources *res;	struct isapnp_dma *dma;		if (!dev || index < 0 || index > 7)		return NULL;	for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {

⌨️ 快捷键说明

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