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

📄 isapnp.c

📁 话带数据中传真解调程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	unsigned long *value1, *value2;	struct isapnp_dma *dma;	if (!cfg || idx < 0 || idx > 1)		return -EINVAL;	if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO))	/* don't touch */		return 0;      __again:      	dma = cfg->dma[idx];      	if (!dma)      		return -EINVAL;      	value1 = &cfg->result.dma_resource[idx].start;      	value2 = &cfg->result.dma_resource[idx].end;	if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {		for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);		if (i >= 8)			return -ENOENT;		cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;		if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))			return 0;	}	do {		for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);		if (i >= 8) {			if (dma->res && dma->res->alt) {				if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)					return err;				goto __again;			}			return -ENOENT;		} else {			*value1 = *value2 = i;		}	} while (isapnp_check_dma(cfg, *value1, idx));	return 0;}static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx){	int i, tmp;	unsigned int raddr, rsize;	struct pnp_dev *dev;	struct isapnp_mem *xmem;	for (i = 0; i < 8; i++) {		raddr = (unsigned int)isapnp_reserve_mem[i << 1];		rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1];		if (addr >= raddr && addr < raddr + rsize)			return 1;		if (addr + size > raddr && addr + size < (raddr + rsize) - 1)			return 1;//		if (__check_region(&iomem_resource, addr, size))		if (check_region(addr, size))			return 1;	}	for (dev = isapnp_devices; dev; dev = dev->next) {		if (dev->active) {			for (tmp = 0; tmp < 4; tmp++) {				if (dev->resource[tmp].flags) {					raddr = dev->resource[tmp + 8].start;					rsize = (dev->resource[tmp + 8].end - raddr) + 1;					if (addr >= raddr && addr < raddr + rsize)						return 1;					if (addr + size > raddr && addr + size < (raddr + rsize) - 1)						return 1;				}			}		}	}	for (i = 0; i < 4; i++) {		unsigned int flags = cfg->request->resource[i + 8].flags;		if (i == idx)			continue;		if (!flags)			continue;		tmp = cfg->result.resource[i + 8].start;		if (flags & IORESOURCE_AUTO) {		/* auto */			xmem = cfg->mem[i];			if (!xmem)				return 1;			if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)				continue;			if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)				return 1;			continue;		}		if (addr == tmp)			return 1;		xmem = isapnp_find_mem(cfg->request, i);		if (!xmem)			return 1;		if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)			return 1;	}	return 0;}static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx){	int err;	unsigned long *value1, *value2;	struct isapnp_mem *mem;	if (!cfg || idx < 0 || idx > 3)		return -EINVAL;	if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */		return 0;      __again:      	mem = cfg->mem[idx];      	if (!mem)      		return -EINVAL;      	value1 = &cfg->result.resource[idx].start;      	value2 = &cfg->result.resource[idx].end;	if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {		cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;		*value1 = mem->min;		*value2 = mem->min + mem->size - 1;		if (!isapnp_check_mem(cfg, *value1, mem->size, idx))			return 0;	}	do {		*value1 += mem->align;		*value2 = *value1 + mem->size - 1;		if (*value1 >= 8 || !mem->align) {			if (mem->res && mem->res->alt) {				if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)					return err;				goto __again;			}			return -ENOENT;		}	} while (isapnp_check_mem(cfg, *value1, mem->size, idx));	return 0;}static int isapnp_check_valid(struct isapnp_cfgtmp *cfg){	int tmp;		for (tmp = 0; tmp < 8; tmp++)		if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)			return -EAGAIN;	for (tmp = 0; tmp < 2; tmp++)		if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)			return -EAGAIN;	for (tmp = 0; tmp < 2; tmp++)		if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)			return -EAGAIN;	for (tmp = 0; tmp < 4; tmp++)		if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)			return -EAGAIN;	return 0;}static int isapnp_config_activate(struct pnp_dev *dev){	struct isapnp_cfgtmp cfg;	int tmp, fauto, err;		if (!dev)		return -EINVAL;	if (dev->active)		return -EBUSY;	memset(&cfg, 0, sizeof(cfg));	cfg.request = dev;	memcpy(&cfg.result, dev, sizeof(struct pnp_dev));	/* check if all values are set, otherwise try auto-configuration */	for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {		if (dev->resource[tmp].flags & IORESOURCE_AUTO)			fauto++;	}	for (tmp = 0; !fauto && tmp < 2; tmp++) {		if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)			fauto++;	}	for (tmp = 0; !fauto && tmp < 2; tmp++) {		if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)			fauto++;	}	for (tmp = 0; !fauto && tmp < 4; tmp++) {		if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)			fauto++;	}	if (!fauto)		goto __skip_auto;	/* set variables to initial values */	if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0)		return err;	/* find first valid configuration */	fauto = 0;	do {		for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)			if ((err = isapnp_valid_port(&cfg, tmp))<0)				return err;		for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)			if ((err = isapnp_valid_irq(&cfg, tmp))<0)				return err;		for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)			if ((err = isapnp_valid_dma(&cfg, tmp))<0)				return err;		for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)			if ((err = isapnp_valid_mem(&cfg, tmp))<0)				return err;	} while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);	if (fauto >= 20)		return -EAGAIN;      __skip_auto:      	/* we have valid configuration, try configure hardware */      	isapnp_cfg_begin(dev->bus->number, dev->devfn);	dev->active = 1;	dev->irq_resource[0] = cfg.result.irq_resource[0];	dev->irq_resource[1] = cfg.result.irq_resource[1];	dev->dma_resource[0] = cfg.result.dma_resource[0];	dev->dma_resource[1] = cfg.result.dma_resource[1];	for (tmp = 0; tmp < 12; tmp++) {		dev->resource[tmp] = cfg.result.resource[tmp];	}		for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)		isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);	for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {		int irq = dev->irq_resource[tmp].start;		if (irq == 2)			irq = 9;		isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);	}	for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)		isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);	for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)		isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);	isapnp_activate(dev->devfn);	isapnp_cfg_end();	return 0;}static int isapnp_config_deactivate(struct pnp_dev *dev){	if (!dev || !dev->active)		return -EINVAL;      	isapnp_cfg_begin(dev->bus->number, dev->devfn);	isapnp_deactivate(dev->devfn);	dev->active = 0;	isapnp_cfg_end();	return 0;}void isapnp_resource_change(struct resource *resource,			    unsigned long start,			    unsigned long size){	if (resource == NULL)		return;	resource->flags &= ~IORESOURCE_AUTO;	resource->start = start;	resource->end = start + size - 1;}/* *  Inititialization. */#ifdef MODULEstatic void isapnp_free_port(struct isapnp_port *port){	struct isapnp_port *next;	while (port) {		next = port->next;		kfree(port);		port = next;	}}static void isapnp_free_irq(struct isapnp_irq *irq){	struct isapnp_irq *next;	while (irq) {		next = irq->next;		kfree(irq);		irq = next;	}}static void isapnp_free_dma(struct isapnp_dma *dma){	struct isapnp_dma *next;	while (dma) {		next = dma->next;		kfree(dma);		dma = next;	}}static void isapnp_free_mem(struct isapnp_mem *mem){	struct isapnp_mem *next;	while (mem) {		next = mem->next;		kfree(mem);		mem = next;	}}static void isapnp_free_mem32(struct isapnp_mem32 *mem32){	struct isapnp_mem32 *next;	while (mem32) {		next = mem32->next;		kfree(mem32);		mem32 = next;	}}static void isapnp_free_resources(struct isapnp_resources *resources, int alt){	struct isapnp_resources *next;	while (resources) {		next = alt ? resources->alt : resources->next;		isapnp_free_port(resources->port);		isapnp_free_irq(resources->irq);		isapnp_free_dma(resources->dma);		isapnp_free_mem(resources->mem);		isapnp_free_mem32(resources->mem32);		if (!alt && resources->alt)			isapnp_free_resources(resources->alt, 1);		kfree(resources);		resources = next;	}}static void isapnp_free_device(struct pnp_dev *dev){	struct pnp_dev *next;	while (dev) {		next = dev->sibling;		isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);		kfree(dev);		dev = next;	}}#endif /* MODULE */static void isapnp_free_all_resources(void){#ifdef MODULE	struct pnp_bus *card, *cardnext;#endif#ifdef ISAPNP_REGION_OK//	release_resource(pidxr_res);        release_region(_PIDXR, 1);#endif//	release_resource(pnpwrp_res);        release_region(_PNPWRP, 1);	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff)//		release_resource(isapnp_rdp_res);		release_region(isapnp_rdp, 1);#ifdef MODULE	for (card = isapnp_cards; card; card = cardnext) {		cardnext = card->next;		isapnp_free_device(card->devices);		kfree(card);	}#ifdef CONFIG_PROC_FS	isapnp_proc_done();#endif#endif}static int __init isapnp_do_reserve_irq(int irq){	int i;		if (irq < 0 || irq > 15)		return -EINVAL;	for (i = 0; i < 16; i++) {		if (isapnp_reserve_irq[i] == irq)			return 0;	}	for (i = 0; i < 16; i++) {		if (isapnp_reserve_irq[i] < 0) {			isapnp_reserve_irq[i] = irq;#ifdef ISAPNP_DEBUG			printk("IRQ %i is reserved now.\n", irq);#endif			return 0;		}	}	return -ENOMEM;}#ifdef CONFIG_PCIstruct pnp_dev *pnp_find_slot(unsigned int bus, unsigned int devfn){        struct pnp_dev *dev;        for(dev=isapnp_devices; dev; dev=dev->next)                if (dev->bus->number == bus && dev->devfn == devfn)                        break;        return dev;}static void __init isapnp_pci_init(void){	int devfn;	struct pnp_dev *dev;		for (devfn = 0; devfn < 255; devfn++) {		dev = pnp_find_slot(0, devfn);		if (dev != NULL)			break;	}	if (dev == NULL)		return;	while (dev) {#ifdef ISAPNP_DEBUG		printk("PCI: reserved IRQ: %i\n", dev->irq);#endif		if (dev->irq > 0)			isapnp_do_reserve_irq(dev->irq);		dev = dev->next;	}}#endif /* CONFIG_PCI */EXPORT_SYMBOL(isapnp_present);EXPORT_SYMBOL(isapnp_cfg_begin);EXPORT_SYMBOL(isapnp_cfg_end);EXPORT_SYMBOL(isapnp_read_byte);EXPORT_SYMBOL(isapnp_read_word);EXPORT_SYMBOL(isapnp_read_dword);EXPORT_SYMBOL(isapnp_write_byte);EXPORT_SYMBOL(isapnp_write_word);EXPORT_SYMBOL(isapnp_write_dword);EXPORT_SYMBOL(isapnp_wake);EXPORT_SYMBOL(isapnp_device);EXPORT_SYMBOL(isapnp_activate);EXPORT_SYMBOL(isapnp_deactivate);EXPORT_SYMBOL(isapnp_find_card);EXPORT_SYMBOL(isapnp_find_dev);EXPORT_SYMBOL(isapnp_resource_change);int __init isapnp_init(void){	int cards;	struct pnp_bus *card;	struct pnp_dev *dev;	if (isapnp_disable) {		isapnp_detected = 0;		printk("isapnp: ISA Plug & Play support disabled\n");		return 0;	}#ifdef ISAPNP_REGION_OK	request_region(_PIDXR, 1, "isapnp index");//	pidxr_res=request_region(_PIDXR, 1, "isapnp index");//	if(!pidxr_res) {//		printk("isapnp: Index Register 0x%x already used\n", _PIDXR);//		return -EBUSY;//	}#endif	request_region(_PNPWRP, 1, "isapnp write");//	pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write");//	if(!pnpwrp_res) {//		printk("isapnp: Write Data Register 0x%x already used\n", _PNPWRP);//		return -EBUSY;//	}		/*	 *	Print a message. The existing ISAPnP code is hanging machines	 *	so let the user know where.	 */	 	printk("isapnp: Scanning for Pnp cards...\n");	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {		isapnp_rdp |= 3;		request_region(isapnp_rdp, 1, "isapnp read");//		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");//		if(!isapnp_rdp_res) {//			printk("isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);//			return -EBUSY;//		}		isapnp_set_rdp();	}	isapnp_detected = 1;	if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {		cards = isapnp_isolate();		if (cards < 0 || 		    (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {			isapnp_free_all_resources();			isapnp_detected = 0;			printk("isapnp: No Plug & Play device found\n");			return 0;		}		request_region(isapnp_rdp, 1, "isapnp read");//		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");	}	isapnp_build_device_list();	cards = 0;	for (card = isapnp_cards; card; card = card->next)		cards++;	if (isapnp_verbose) {		for (card = isapnp_cards; card; card = card->next) {			printk( "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");			if (isapnp_verbose < 2)				continue;			for (dev = card->devices; dev; dev = dev->next)				printk("isapnp:   Device '%s'\n", dev->name[0]?card->name:"Unknown");		}	}	if (cards) {		printk("isapnp: %i Plug & Play card%s detected total\n", cards, cards>1?"s":"");	} else {		printk("isapnp: No Plug & Play card found\n");	}#ifdef CONFIG_PCI	if (!isapnp_skip_pci_scan)		isapnp_pci_init();#endif#ifdef CONFIG_PROC_FS	isapnp_proc_init();#endif	return 0;}#ifdef MODULEint init_module(void){	return isapnp_init();}void cleanup_module(void){	if (isapnp_detected)		isapnp_free_all_resources();}#endif

⌨️ 快捷键说明

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