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

📄 elsa.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				if (!arg)					return(0);				msg = arg;				len = *msg;				msg++;				modem_write_cmd(cs, msg, len);			}			break;#endif	}	if (cs->typ == ISDN_CTYPE_ELSA) {		int pwr = bytein(cs->hw.elsa.ale);		if (pwr & 0x08)			cs->hw.elsa.status |= ELSA_BAD_PWR;		else			cs->hw.elsa.status &= ~ELSA_BAD_PWR;	}	elsa_led_handler(cs);	return(ret);}static unsigned charprobe_elsa_adr(unsigned int adr, int typ){	int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0,	 pc_2 = 0, pfp_1 = 0, pfp_2 = 0;	long flags;	/* In case of the elsa pcmcia card, this region is in use,	   reserved for us by the card manager. So we do not check it	   here, it would fail. */	if (typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(adr, 8)) {		printk(KERN_WARNING		       "Elsa: Probing Port 0x%x: already in use\n",		       adr);		return (0);	}	save_flags(flags);	cli();	for (i = 0; i < 16; i++) {		in1 = inb(adr + ELSA_CONFIG);	/* 'toggelt' bei */		in2 = inb(adr + ELSA_CONFIG);	/* jedem Zugriff */		p16_1 += 0x04 & in1;		p16_2 += 0x04 & in2;		p8_1 += 0x02 & in1;		p8_2 += 0x02 & in2;		pc_1 += 0x01 & in1;		pc_2 += 0x01 & in2;		pfp_1 += 0x40 & in1;		pfp_2 += 0x40 & in2;	}	restore_flags(flags);	printk(KERN_INFO "Elsa: Probing IO 0x%x", adr);	if (65 == ++p16_1 * ++p16_2) {		printk(" PCC-16/PCF found\n");		return (ELSA_PCC16);	} else if (1025 == ++pfp_1 * ++pfp_2) {		printk(" PCF-Pro found\n");		return (ELSA_PCFPRO);	} else if (33 == ++p8_1 * ++p8_2) {		printk(" PCC8 found\n");		return (ELSA_PCC8);	} else if (17 == ++pc_1 * ++pc_2) {		printk(" PC found\n");		return (ELSA_PC);	} else {		printk(" failed\n");		return (0);	}}static unsigned intprobe_elsa(struct IsdnCardState *cs){	int i;	unsigned int CARD_portlist[] =	{0x160, 0x170, 0x260, 0x360, 0};	for (i = 0; CARD_portlist[i]; i++) {		if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ)))			break;	}	return (CARD_portlist[i]);}static 	struct pci_dev *dev_qs1000 __devinitdata = NULL;static 	struct pci_dev *dev_qs3000 __devinitdata = NULL;int __devinitsetup_elsa(struct IsdnCard *card){	long flags;	int bytecnt;	u_char val;	struct IsdnCardState *cs = card->cs;	char tmp[64];	strcpy(tmp, Elsa_revision);	printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp));	cs->hw.elsa.ctrl_reg = 0;	cs->hw.elsa.status = 0;	cs->hw.elsa.MFlag = 0;	if (cs->typ == ISDN_CTYPE_ELSA) {		cs->hw.elsa.base = card->para[0];		printk(KERN_INFO "Elsa: Microlink IO probing\n");		if (cs->hw.elsa.base) {			if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base,							  cs->typ))) {				printk(KERN_WARNING				     "Elsa: no Elsa Microlink at 0x%x\n",				       cs->hw.elsa.base);				return (0);			}		} else			cs->hw.elsa.base = probe_elsa(cs);		if (cs->hw.elsa.base) {			cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;			cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;			cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;			cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;			cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC;			cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;			cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;			cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;			val = bytein(cs->hw.elsa.cfg);			if (cs->subtyp == ELSA_PC) {				const u_char CARD_IrqTab[8] =				{7, 3, 5, 9, 0, 0, 0, 0};				cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];			} else if (cs->subtyp == ELSA_PCC8) {				const u_char CARD_IrqTab[8] =				{7, 3, 5, 9, 0, 0, 0, 0};				cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];			} else {				const u_char CARD_IrqTab[8] =				{15, 10, 15, 3, 11, 5, 11, 9};				cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];			}			val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;			if (val < 3)				val |= 8;			val += 'A' - 3;			if (val == 'B' || val == 'C')				val ^= 1;			if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))				val = 'C';			printk(KERN_INFO			       "Elsa: %s found at 0x%x Rev.:%c IRQ %d\n",			       Elsa_Types[cs->subtyp],			       cs->hw.elsa.base,			       val, cs->irq);			val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;			if (val) {				printk(KERN_WARNING				   "Elsa: Microlink S0 bus power bad\n");				cs->hw.elsa.status |= ELSA_BAD_PWR;			}		} else {			printk(KERN_WARNING			       "No Elsa Microlink found\n");			return (0);		}	} else if (cs->typ == ISDN_CTYPE_ELSA_PNP) {		cs->hw.elsa.base = card->para[1];		cs->irq = card->para[0];		cs->subtyp = ELSA_QS1000;		cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;		cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;		cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;		cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;		cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;		cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;		cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;		printk(KERN_INFO		       "Elsa: %s defined at 0x%x IRQ %d\n",		       Elsa_Types[cs->subtyp],		       cs->hw.elsa.base,		       cs->irq);	} else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) {		cs->hw.elsa.base = card->para[1];		cs->irq = card->para[0];		val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID);		if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */			cs->subtyp = ELSA_PCMCIA_IPAC;			cs->hw.elsa.ale = cs->hw.elsa.base + 0;			cs->hw.elsa.isac = cs->hw.elsa.base + 2;			cs->hw.elsa.hscx = cs->hw.elsa.base + 2;			test_and_set_bit(HW_IPAC, &cs->HW_Flags);		} else {			cs->subtyp = ELSA_PCMCIA;			cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;			cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM;			cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;		}		cs->hw.elsa.timer = 0;		cs->hw.elsa.trig = 0;		cs->hw.elsa.ctrl = 0;		printk(KERN_INFO		       "Elsa: %s defined at 0x%x IRQ %d\n",		       Elsa_Types[cs->subtyp],		       cs->hw.elsa.base,		       cs->irq);	} else if (cs->typ == ISDN_CTYPE_ELSA_PCI) {#if CONFIG_PCI		if (!pci_present()) {			printk(KERN_ERR "Elsa: no PCI bus present\n");			return(0);		}		cs->subtyp = 0;		if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA,			PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {			if (pci_enable_device(dev_qs1000))				return(0);			cs->subtyp = ELSA_QS1000PCI;			cs->irq = dev_qs1000->irq;			cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);			cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);		} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,			PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {			if (pci_enable_device(dev_qs3000))				return(0);			cs->subtyp = ELSA_QS3000PCI;			cs->irq = dev_qs3000->irq;			cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);			cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);		} else {			printk(KERN_WARNING "Elsa: No PCI card found\n");			return(0);		}		if (!cs->irq) {			printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");			return(0);		}		if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) {			printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");			return(0);		}		if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) {			printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n");			printk(KERN_WARNING "Elsa: If your system hangs now, read\n");			printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n");			printk(KERN_WARNING "Elsa: Waiting 5 sec to sync discs\n");			save_flags(flags);			sti();			HZDELAY(500);	/* wait 500*10 ms */			restore_flags(flags);		}		cs->hw.elsa.ale  = cs->hw.elsa.base;		cs->hw.elsa.isac = cs->hw.elsa.base +1;		cs->hw.elsa.hscx = cs->hw.elsa.base +1; 		test_and_set_bit(HW_IPAC, &cs->HW_Flags);		cs->hw.elsa.timer = 0;		cs->hw.elsa.trig  = 0;		cs->irq_flags |= SA_SHIRQ;		printk(KERN_INFO		       "Elsa: %s defined at 0x%x/0x%x IRQ %d\n",		       Elsa_Types[cs->subtyp],		       cs->hw.elsa.base,		       cs->hw.elsa.cfg,		       cs->irq);#else		printk(KERN_WARNING "Elsa: Elsa PCI and NO_PCI_BIOS\n");		printk(KERN_WARNING "Elsa: unable to config Elsa PCI\n");		return (0);#endif /* CONFIG_PCI */	} else 		return (0);	switch (cs->subtyp) {		case ELSA_PC:		case ELSA_PCC8:		case ELSA_PCC16:		case ELSA_QS1000:		case ELSA_PCMCIA:		case ELSA_PCMCIA_IPAC:			bytecnt = 8;			break;		case ELSA_PCFPRO:		case ELSA_PCF:		case ELSA_QS3000PCI:			bytecnt = 16;			break;		case ELSA_QS1000PCI:			bytecnt = 2;			break;		default:			printk(KERN_WARNING			       "Unknown ELSA subtype %d\n", cs->subtyp);			return (0);	}	/* In case of the elsa pcmcia card, this region is in use,	   reserved for us by the card manager. So we do not check it	   here, it would fail. */	if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(cs->hw.elsa.base, bytecnt)) {		printk(KERN_WARNING		       "HiSax: %s config port %x-%x already in use\n",		       CardType[card->typ],		       cs->hw.elsa.base,		       cs->hw.elsa.base + bytecnt);		return (0);	} else {		request_region(cs->hw.elsa.base, bytecnt, "elsa isdn");	}	if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) {		if (check_region(cs->hw.elsa.cfg, 0x80)) {			printk(KERN_WARNING			       "HiSax: %s pci port %x-%x already in use\n",				CardType[card->typ],				cs->hw.elsa.cfg,				cs->hw.elsa.cfg + 0x80);			release_region(cs->hw.elsa.base, bytecnt);			return (0);		} else {			request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci");		}	}#if ARCOFI_USE	init_arcofi(cs);#endif	cs->hw.elsa.tl.function = (void *) elsa_led_handler;	cs->hw.elsa.tl.data = (long) cs;	init_timer(&cs->hw.elsa.tl);	/* Teste Timer */	if (cs->hw.elsa.timer) {		byteout(cs->hw.elsa.trig, 0xff);		byteout(cs->hw.elsa.timer, 0);		if (!TimerRun(cs)) {			byteout(cs->hw.elsa.timer, 0);	/* 2. Versuch */			if (!TimerRun(cs)) {				printk(KERN_WARNING				       "Elsa: timer do not start\n");				release_io_elsa(cs);				return (0);			}		}		save_flags(flags);		sti();		HZDELAY(1);	/* wait >=10 ms */		restore_flags(flags);		if (TimerRun(cs)) {			printk(KERN_WARNING "Elsa: timer do not run down\n");			release_io_elsa(cs);			return (0);		}		printk(KERN_INFO "Elsa: timer OK; resetting card\n");	}	cs->BC_Read_Reg = &ReadHSCX;	cs->BC_Write_Reg = &WriteHSCX;	cs->BC_Send_Data = &hscx_fill_fifo;	cs->cardmsg = &Elsa_card_msg;	reset_elsa(cs);	if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) {		cs->readisac = &ReadISAC_IPAC;		cs->writeisac = &WriteISAC_IPAC;		cs->readisacfifo = &ReadISACfifo_IPAC;		cs->writeisacfifo = &WriteISACfifo_IPAC;		cs->irq_func = &elsa_interrupt_ipac;		val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ID);		printk(KERN_INFO "Elsa: IPAC version %x\n", val);	} else {		cs->readisac = &ReadISAC;		cs->writeisac = &WriteISAC;		cs->readisacfifo = &ReadISACfifo;		cs->writeisacfifo = &WriteISACfifo;		cs->irq_func = &elsa_interrupt;		ISACVersion(cs, "Elsa:");		if (HscxVersion(cs, "Elsa:")) {			printk(KERN_WARNING				"Elsa: wrong HSCX versions check IO address\n");			release_io_elsa(cs);			return (0);		}	}	if (cs->subtyp == ELSA_PC) {		val = readitac(cs, ITAC_SYS);		printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]);		writeitac(cs, ITAC_ISEN, 0);		writeitac(cs, ITAC_RFIE, 0);		writeitac(cs, ITAC_XFIE, 0);		writeitac(cs, ITAC_SCIE, 0);		writeitac(cs, ITAC_STIE, 0);	}	return (1);}

⌨️ 快捷键说明

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