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

📄 isapnp_proc.c

📁 话带数据中传真解调程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = next = 0; i < 2; i++) {		tmp = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1));		if (!(tmp >> 8))			continue;		if (!next) {			isapnp_printf(buffer, "%sActive IRQ ", space);			next = 1;		}		isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp >> 8);		if (tmp & 0xff)			isapnp_printf(buffer, " [0x%x]", tmp & 0xff);	}	if (next)		isapnp_printf(buffer, "\n");	for (i = next = 0; i < 2; i++) {		tmp = isapnp_read_byte(ISAPNP_CFG_DMA + i);		if (tmp == 4)			continue;		if (!next) {			isapnp_printf(buffer, "%sActive DMA ", space);			next = 1;		}		isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp);	}	if (next)		isapnp_printf(buffer, "\n");	for (i = next = 0; i < 4; i++) {		tmp = isapnp_read_dword(ISAPNP_CFG_MEM + (i << 3));		if (!tmp)			continue;		if (!next) {			isapnp_printf(buffer, "%sActive memory ", space);			next = 1;		}		isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp);	}	if (next)		isapnp_printf(buffer, "\n");	isapnp_cfg_end();}static void isapnp_print_device(isapnp_info_buffer_t *buffer, struct pnp_dev *dev){	int block, block1;	char *space = "    ";	struct isapnp_resources *res, *resa;	if (!dev)		return;	isapnp_printf(buffer, "  Logical device %i '", dev->devfn);	isapnp_print_devid(buffer, dev->vendor, dev->device);	isapnp_printf(buffer, ":%s'", dev->name[0]?dev->name:"Unknown");	isapnp_printf(buffer, "\n");#if 0	isapnp_cfg_begin(dev->bus->number, dev->devfn);	for (block = 0; block < 128; block++)		if ((block % 16) == 15)			isapnp_printf(buffer, "%02x\n", isapnp_read_byte(block));		else			isapnp_printf(buffer, "%02x:", isapnp_read_byte(block));	isapnp_cfg_end();#endif	if (dev->regs)		isapnp_printf(buffer, "%sSupported registers 0x%x\n", space, dev->regs);	isapnp_print_compatible(buffer, dev);	isapnp_print_configuration(buffer, dev);	for (res = (struct isapnp_resources *)dev->sysdata, block = 0; res; res = res->next, block++) {		isapnp_printf(buffer, "%sResources %i\n", space, block);		isapnp_print_resources(buffer, "      ", res);		for (resa = res->alt, block1 = 1; resa; resa = resa->alt, block1++) {			isapnp_printf(buffer, "%s  Alternate resources %i:%i\n", space, block, block1);			isapnp_print_resources(buffer, "        ", resa);		}	}}/* *  Main read routine */ static void isapnp_info_read(isapnp_info_buffer_t *buffer){	struct pnp_bus *card;	struct pnp_dev *dev;		for (card = isapnp_cards; card;              card = card->next) {		isapnp_printf(buffer, "Card %i '", card->number);		isapnp_print_devid(buffer, card->vendor, card->device);		isapnp_printf(buffer, ":%s'", card->name[0]?card->name:"Unknown");		if (card->pnpver)			isapnp_printf(buffer, " PnP version %x.%x", card->pnpver >> 4, card->pnpver & 0x0f);		if (card->productver)			isapnp_printf(buffer, " Product version %x.%x", card->productver >> 4, card->productver & 0x0f);		isapnp_printf(buffer,"\n");		for (dev = card->devices; dev; dev = dev->sibling)			isapnp_print_device(buffer, dev);	}}/* * */static struct pnp_bus *isapnp_info_card;static struct pnp_dev *isapnp_info_device;static char *isapnp_get_str(char *dest, char *src, int len){	int c;	while (*src == ' ' || *src == '\t')		src++;	if (*src == '"' || *src == '\'') {		c = *src++;		while (--len > 0 && *src && *src != c) {			*dest++ = *src++;		}		if (*src == c)			src++;	} else {		while (--len > 0 && *src && *src != ' ' && *src != '\t') {			*dest++ = *src++;		}	}	*dest = 0;	while (*src == ' ' || *src == '\t')		src++;	return src;}static unsigned char isapnp_get_hex(unsigned char c){	if (c >= '0' || c <= '9')		return c - '0';	if (c >= 'a' || c <= 'f')		return (c - 'a') + 10;	if (c >= 'A' || c <= 'F')		return (c - 'A') + 10;	return 0;}static unsigned int isapnp_parse_id(const char *id){	if (strlen(id) != 7) {		printk("isapnp: wrong PnP ID\n");		return 0;	}	return (ISAPNP_VENDOR(id[0], id[1], id[2])<<16) |			(isapnp_get_hex(id[3])<<4) |			(isapnp_get_hex(id[4])<<0) |			(isapnp_get_hex(id[5])<<12) |			(isapnp_get_hex(id[6])<<8);}static int isapnp_set_card(char *line){	int idx, idx1;	unsigned int id;	char index[16], value[32];	isapnp_info_card = NULL;	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = idx1 = simple_strtoul(index, NULL, 0);	id = isapnp_parse_id(value);	isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, NULL);	while (isapnp_info_card && idx1-- > 0)		isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, isapnp_info_card);	if (isapnp_info_card == NULL) {		printk("isapnp: card '%s' order %i not found\n", value, idx);		return 1;	}	if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) {		printk("isapnp: configuration start sequence for device '%s' failed\n", value);		isapnp_info_card = NULL;		return 1;	}	return 0;}static int isapnp_select_csn(char *line){	int csn;	char index[16], value[32];	isapnp_info_device = NULL;	isapnp_get_str(index, line, sizeof(index));	csn = simple_strtoul(index, NULL, 0);	for (isapnp_info_card = isapnp_cards; isapnp_info_card; isapnp_info_card = isapnp_info_card->next)		if (isapnp_info_card->number == csn)			break;	if (isapnp_info_card == NULL) {		printk("isapnp: cannot find CSN %i\n", csn);		return 1;	}	if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) {		printk("isapnp: configuration start sequence for device '%s' failed\n", value);		isapnp_info_card = NULL;		return 1;	}	return 0;}static int isapnp_set_device(char *line){	int idx, idx1;	unsigned int id;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = idx1 = simple_strtoul(index, NULL, 0);	id = isapnp_parse_id(value);	isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, NULL);	while (isapnp_info_device && idx-- > 0)		isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, isapnp_info_device);	if (isapnp_info_device == NULL) {		printk("isapnp: device '%s' order %i not found\n", value, idx);		return 1;	}	isapnp_device(isapnp_info_device->devfn);	return 0;}static int isapnp_autoconfigure(void){	if (isapnp_info_device == NULL) {		printk("isapnp: device is not set\n");		return 0;	}	if (isapnp_info_device->active)		isapnp_info_device->deactivate(isapnp_info_device);	if (isapnp_info_device->prepare(isapnp_info_device) < 0) {		printk("isapnp: cannot prepare device for the activation");		return 0;	}	if (isapnp_info_device->activate(isapnp_info_device) < 0) {		printk("isapnp: cannot activate device");		return 0;	}	return 0;}static int isapnp_set_port(char *line){	int idx, port;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = simple_strtoul(index, NULL, 0);	port = simple_strtoul(value, NULL, 0);	if (idx < 0 || idx > 7) {		printk("isapnp: wrong port index %i\n", idx);		return 1;	}	if (port < 0 || port > 0xffff) {		printk("isapnp: wrong port value 0x%x\n", port);		return 1;	}	isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port);	if (!isapnp_info_device->resource[idx].flags)		return 0;	if (isapnp_info_device->resource[idx].flags & IORESOURCE_AUTO) {		isapnp_info_device->resource[idx].start = port;		isapnp_info_device->resource[idx].end += port - 1;		isapnp_info_device->resource[idx].flags &= ~IORESOURCE_AUTO;	} else {		isapnp_info_device->resource[idx].end -= isapnp_info_device->resource[idx].start;		isapnp_info_device->resource[idx].start = port;		isapnp_info_device->resource[idx].end += port;	}	return 0;}static void isapnp_set_irqresource(struct resource *res, int irq){	res->start = res->end = irq;	res->flags = IORESOURCE_IRQ;} static int isapnp_set_irq(char *line){	int idx, irq;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = simple_strtoul(index, NULL, 0);	irq = simple_strtoul(value, NULL, 0);	if (idx < 0 || idx > 1) {		printk("isapnp: wrong IRQ index %i\n", idx);		return 1;	}	if (irq == 2)		irq = 9;	if (irq < 0 || irq > 15) {		printk("isapnp: wrong IRQ value %i\n", irq);		return 1;	}	isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq);	isapnp_set_irqresource(isapnp_info_device->irq_resource + idx, irq);	return 0;} static void isapnp_set_dmaresource(struct resource *res, int dma){	res->start = res->end = dma;	res->flags = IORESOURCE_DMA;} static int isapnp_set_dma(char *line){	int idx, dma;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = simple_strtoul(index, NULL, 0);	dma = simple_strtoul(value, NULL, 0);	if (idx < 0 || idx > 1) {		printk("isapnp: wrong DMA index %i\n", idx);		return 1;	}	if (dma < 0 || dma > 7) {		printk("isapnp: wrong DMA value %i\n", dma);		return 1;	}	isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma);	isapnp_set_dmaresource(isapnp_info_device->dma_resource + idx, dma);	return 0;} static int isapnp_set_mem(char *line){	int idx;	unsigned int mem;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	idx = simple_strtoul(index, NULL, 0);	mem = simple_strtoul(value, NULL, 0);	if (idx < 0 || idx > 3) {		printk("isapnp: wrong memory index %i\n", idx);		return 1;	}	mem >>= 8;	isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff);	if (!isapnp_info_device->resource[idx + 8].flags)		return 0;	if (isapnp_info_device->resource[idx + 8].flags & IORESOURCE_AUTO) {		isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00;		isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1;		isapnp_info_device->resource[idx + 8].flags &= ~IORESOURCE_AUTO;	} else {		isapnp_info_device->resource[idx + 8].end -= isapnp_info_device->resource[idx + 8].start;		isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00;		isapnp_info_device->resource[idx + 8].end += mem & ~0x00ffff00;	}	return 0;} static int isapnp_poke(char *line, int what){	int reg;	unsigned int val;	char index[16], value[32];	line = isapnp_get_str(index, line, sizeof(index));	isapnp_get_str(value, line, sizeof(value));	reg = simple_strtoul(index, NULL, 0);	val = simple_strtoul(value, NULL, 0);	if (reg < 0 || reg > 127) {		printk("isapnp: wrong register %i\n", reg);		return 1;	}	switch (what) {	case 1:		isapnp_write_word(reg, val);		break;	case 2:		isapnp_write_dword(reg, val);		break;	default:		isapnp_write_byte(reg, val);		break;	}	return 0;} static int isapnp_decode_line(char *line){	char cmd[32];	line = isapnp_get_str(cmd, line, sizeof(cmd));	if (!strcmp(cmd, "card"))		return isapnp_set_card(line);	if (!strcmp(cmd, "csn"))		return isapnp_select_csn(line);	if (!isapnp_info_card) {		printk("isapnp: card is not selected\n");		return 1;	}	if (!strncmp(cmd, "dev", 3))		return isapnp_set_device(line);	if (!isapnp_info_device) {		printk("isapnp: device is not selected\n");		return 1;	}	if (!strncmp(cmd, "auto", 4))		return isapnp_autoconfigure();	if (!strncmp(cmd, "act", 3)) {		isapnp_activate(isapnp_info_device->devfn);		isapnp_info_device->active = 1;		return 0;	}	if (!strncmp(cmd, "deact", 5)) {		isapnp_deactivate(isapnp_info_device->devfn);		isapnp_info_device->active = 0;		return 0;	}	if (!strcmp(cmd, "port"))		return isapnp_set_port(line);	if (!strcmp(cmd, "irq"))		return isapnp_set_irq(line);	if (!strcmp(cmd, "dma"))		return isapnp_set_dma(line);	if (!strncmp(cmd, "mem", 3))		return isapnp_set_mem(line);	if (!strcmp(cmd, "poke"))		return isapnp_poke(line, 0);	if (!strcmp(cmd, "pokew"))		return isapnp_poke(line, 1);	if (!strcmp(cmd, "poked"))		return isapnp_poke(line, 2);	printk("isapnp: wrong command '%s'\n", cmd);	return 1;}/* *  Main write routine */static void isapnp_info_write(isapnp_info_buffer_t *buffer){	int c, idx, idx1 = 0;	char line[128];	if (buffer->size <= 0)		return;	isapnp_info_card = NULL;	isapnp_info_device = NULL;	for (idx = 0; idx < buffer->size; idx++) {		c = buffer->buffer[idx];		if (c == '\n') {			line[idx1] = '\0';			if (line[0] != '#') {				if (isapnp_decode_line(line))					goto __end;			}			idx1 = 0;			continue;		}		if (idx1 >= sizeof(line)-1) {			printk("isapnp: line too long, aborting\n");			return;		}		line[idx1++] = c;	}      __end:	if (isapnp_info_card)		isapnp_cfg_end();}

⌨️ 快捷键说明

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