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

📄 elsa.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (!icnt)		printk(KERN_WARNING"ELSA IRQ LOOP\n");	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0xFF);	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0xFF);	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0xFF);	if (cs->hw.elsa.status & ELSA_TIMER_AKTIV) {		if (!TimerRun(cs)) {			/* Timer Restart */			byteout(cs->hw.elsa.timer, 0);			cs->hw.elsa.counter++;		}	}	if (cs->hw.elsa.MFlag) {		val = serial_inp(cs, UART_MCR);		val ^= 0x8;		serial_outp(cs, UART_MCR, val);		val = serial_inp(cs, UART_MCR);		val ^= 0x8;		serial_outp(cs, UART_MCR, val);	}	if (cs->hw.elsa.trig)		byteout(cs->hw.elsa.trig, 0x00);	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0x0);	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0x0);	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0x0);}static voidelsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs){	struct IsdnCardState *cs = dev_id;	u_char ista,val;	int icnt=20;	if (!cs) {		printk(KERN_WARNING "Elsa: Spurious interrupt!\n");		return;	}	val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */	if (!(val & ELSA_PCI_IRQ_MASK))		return;#if ARCOFI_USE	if (cs->hw.elsa.MFlag) {		val = serial_inp(cs, UART_IIR);		if (!(val & UART_IIR_NO_INT)) {			debugl1(cs,"IIR %02x", val);			rs_interrupt_elsa(intno, cs);		}	}#endif	ista = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA);Start_IPAC:	if (cs->debug & L1_DEB_IPAC)		debugl1(cs, "IPAC ISTA %02X", ista);	if (ista & 0x0f) {		val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);		if (ista & 0x01)			val |= 0x01;		if (ista & 0x04)			val |= 0x02;		if (ista & 0x08)			val |= 0x04;		if (val)			hscx_int_main(cs, val);	}	if (ista & 0x20) {		val = 0xfe & readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA + 0x80);		if (val) {			isac_interrupt(cs, val);		}	}	if (ista & 0x10) {		val = 0x01;		isac_interrupt(cs, val);	}	ista  = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA);	if ((ista & 0x3f) && icnt) {		icnt--;		goto Start_IPAC;	}	if (!icnt)		printk(KERN_WARNING "ELSA IRQ LOOP\n");	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xFF);	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xC0);}voidrelease_io_elsa(struct IsdnCardState *cs){	int bytecnt = 8;	del_timer(&cs->hw.elsa.tl);	if (cs->hw.elsa.ctrl)		byteout(cs->hw.elsa.ctrl, 0);	/* LEDs Out */	if (cs->subtyp == ELSA_QS1000PCI) {		byteout(cs->hw.elsa.cfg + 0x4c, 0x01);  /* disable IRQ */		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);		bytecnt = 2;		release_region(cs->hw.elsa.cfg, 0x80);	}	if (cs->subtyp == ELSA_QS3000PCI) {		byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);		release_region(cs->hw.elsa.cfg, 0x80);	}	if ((cs->subtyp == ELSA_PCFPRO) ||		(cs->subtyp == ELSA_QS3000) ||		(cs->subtyp == ELSA_PCF) ||		(cs->subtyp == ELSA_QS3000PCI)) {		bytecnt = 16;		release_modem(cs);	}	if (cs->hw.elsa.base)		release_region(cs->hw.elsa.base, bytecnt);}static voidreset_elsa(struct IsdnCardState *cs){	long flags;	if (cs->hw.elsa.timer) {		/* Wait 1 Timer */		byteout(cs->hw.elsa.timer, 0);		while (TimerRun(cs));		cs->hw.elsa.ctrl_reg |= 0x50;		cs->hw.elsa.ctrl_reg &= ~ELSA_ISDN_RESET;	/* Reset On */		byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);		/* Wait 1 Timer */		byteout(cs->hw.elsa.timer, 0);		while (TimerRun(cs));		cs->hw.elsa.ctrl_reg |= ELSA_ISDN_RESET;	/* Reset Off */		byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);		/* Wait 1 Timer */		byteout(cs->hw.elsa.timer, 0);		while (TimerRun(cs));		if (cs->hw.elsa.trig)			byteout(cs->hw.elsa.trig, 0xff);	}	if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) {		save_flags(flags);		sti();		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x20);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x00);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xc0);		schedule();		restore_flags(flags);		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x0);		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0x3c);		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);		if (cs->subtyp == ELSA_QS1000PCI)			byteout(cs->hw.elsa.cfg + 0x4c, 0x41); /* enable ELSA PCI IRQ */		else if (cs->subtyp == ELSA_QS3000PCI)			byteout(cs->hw.elsa.cfg + 0x4c, 0x43); /* enable ELSA PCI IRQ */	}}static voidinit_arcofi(struct IsdnCardState *cs) {	send_arcofi(cs, ARCOFI_XOP_0, 1, 0);/*	send_arcofi(cs, ARCOFI_XOP_F, 1);*/}#define ARCDEL 500static voidset_arcofi(struct IsdnCardState *cs, int bc) {	long flags;	debugl1(cs,"set_arcofi bc=%d", bc);	save_flags(flags);	sti();	send_arcofi(cs, ARCOFI_XOP_0, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_COP_5, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_COP_6, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_COP_7, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_COP_8, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_COP_9, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_SOP_F, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_XOP_1, bc, 0);	udelay(ARCDEL);	send_arcofi(cs, ARCOFI_XOP_F, bc, 0);	restore_flags(flags);	debugl1(cs,"end set_arcofi bc=%d", bc);}static intcheck_arcofi(struct IsdnCardState *cs){#if ARCOFI_USE	int arcofi_present = 0;	char tmp[40];	char *t;	u_char *p;	if (!cs->mon_tx)		if (!(cs->mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {			if (cs->debug & L1_DEB_WARN)				debugl1(cs, "ISAC MON TX out of buffers!");			return(0);		}	send_arcofi(cs, ARCOFI_VERSION, 0, 1);	if (test_and_clear_bit(HW_MON1_TX_END, &cs->HW_Flags)) {		if (test_and_clear_bit(HW_MON1_RX_END, &cs->HW_Flags)) {			debugl1(cs, "Arcofi response received %d bytes", cs->mon_rxp);			p = cs->mon_rx;			t = tmp;			t += sprintf(tmp, "Arcofi data");			QuickHex(t, p, cs->mon_rxp);			debugl1(cs, tmp);			if ((cs->mon_rxp == 2) && (cs->mon_rx[0] == 0xa0)) {				switch(cs->mon_rx[1]) {					case 0x80:						debugl1(cs, "Arcofi 2160 detected");						arcofi_present = 1;						break;					case 0x82:						debugl1(cs, "Arcofi 2165 detected");						arcofi_present = 2;						break;					case 0x84:						debugl1(cs, "Arcofi 2163 detected");						arcofi_present = 3;						break;					default:						debugl1(cs, "unknown Arcofi response");						break;				}			} else				debugl1(cs, "undefined Monitor response");			cs->mon_rxp = 0;		}	} else if (cs->mon_tx) {		debugl1(cs, "Arcofi not detected");	}	if (arcofi_present) {		if (cs->subtyp==ELSA_QS1000) {			cs->subtyp = ELSA_QS3000;			printk(KERN_INFO				"Elsa: %s detected modem at 0x%x\n",				Elsa_Types[cs->subtyp],				cs->hw.elsa.base+8);			release_region(cs->hw.elsa.base, 8);			if (check_region(cs->hw.elsa.base, 16)) {				printk(KERN_WARNING				"HiSax: %s config port %x-%x already in use\n",				Elsa_Types[cs->subtyp],				cs->hw.elsa.base + 8,				cs->hw.elsa.base + 16);			} else				request_region(cs->hw.elsa.base, 16,					"elsa isdn modem");		} else if (cs->subtyp==ELSA_PCC16) {			cs->subtyp = ELSA_PCF;			printk(KERN_INFO				"Elsa: %s detected modem at 0x%x\n",				Elsa_Types[cs->subtyp],				cs->hw.elsa.base+8);			release_region(cs->hw.elsa.base, 8);			if (check_region(cs->hw.elsa.base, 16)) {				printk(KERN_WARNING				"HiSax: %s config port %x-%x already in use\n",				Elsa_Types[cs->subtyp],				cs->hw.elsa.base + 8,				cs->hw.elsa.base + 16);			} else				request_region(cs->hw.elsa.base, 16,					"elsa isdn modem");		} else			printk(KERN_INFO				"Elsa: %s detected modem at 0x%x\n",				Elsa_Types[cs->subtyp],				cs->hw.elsa.base+8);		init_arcofi(cs);		return(1);	}#endif	return(0);}static voidelsa_led_handler(struct IsdnCardState *cs){	int blink = 0;	if (cs->subtyp == ELSA_PCMCIA)		return;	del_timer(&cs->hw.elsa.tl);	if (cs->hw.elsa.status & ELSA_ASSIGN)		cs->hw.elsa.ctrl_reg |= ELSA_STAT_LED;	else if (cs->hw.elsa.status & ELSA_BAD_PWR)		cs->hw.elsa.ctrl_reg &= ~ELSA_STAT_LED;	else {		cs->hw.elsa.ctrl_reg ^= ELSA_STAT_LED;		blink = 250;	}	if (cs->hw.elsa.status & 0xf000)		cs->hw.elsa.ctrl_reg |= ELSA_LINE_LED;	else if (cs->hw.elsa.status & 0x0f00) {		cs->hw.elsa.ctrl_reg ^= ELSA_LINE_LED;		blink = 500;	} else		cs->hw.elsa.ctrl_reg &= ~ELSA_LINE_LED;	if ((cs->subtyp == ELSA_QS1000PCI) ||		(cs->subtyp == ELSA_QS3000PCI)) {		u_char led = 0xff;		if (cs->hw.elsa.ctrl_reg & ELSA_LINE_LED)			led ^= ELSA_IPAC_LINE_LED;		if (cs->hw.elsa.ctrl_reg & ELSA_STAT_LED)			led ^= ELSA_IPAC_STAT_LED;		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, led);	} else		byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);	if (blink) {		init_timer(&cs->hw.elsa.tl);		cs->hw.elsa.tl.expires = jiffies + ((blink * HZ) / 1000);		add_timer(&cs->hw.elsa.tl);	}}static intElsa_card_msg(struct IsdnCardState *cs, int mt, void *arg){	int len, ret = 0;	u_char *msg;	long flags;	switch (mt) {		case CARD_RESET:			reset_elsa(cs);			return(0);		case CARD_RELEASE:			release_io_elsa(cs);			return(0);		case CARD_SETIRQ:			if ((cs->subtyp == ELSA_QS1000PCI) ||				(cs->subtyp == ELSA_QS3000PCI))				ret = request_irq(cs->irq, &elsa_interrupt_ipac,					I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs);			else				ret = request_irq(cs->irq, &elsa_interrupt,					I4L_IRQ_FLAG, "HiSax", cs);			return(ret);		case CARD_INIT:			cs->debug |= L1_DEB_IPAC;			inithscxisac(cs, 1);			if ((cs->subtyp == ELSA_QS1000) ||			    (cs->subtyp == ELSA_QS3000))			{				byteout(cs->hw.elsa.timer, 0);			}			if (cs->hw.elsa.trig)				byteout(cs->hw.elsa.trig, 0xff);			inithscxisac(cs, 2);			return(0);		case CARD_TEST:			if ((cs->subtyp == ELSA_PCMCIA) ||				(cs->subtyp == ELSA_QS1000PCI)) {				return(0);			} else if (cs->subtyp == ELSA_QS3000PCI) {				ret = 0;			} else {				save_flags(flags);				cs->hw.elsa.counter = 0;				sti();				cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT;				cs->hw.elsa.status |= ELSA_TIMER_AKTIV;				byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);				byteout(cs->hw.elsa.timer, 0);				current->state = TASK_INTERRUPTIBLE;				current->timeout = jiffies + (110 * HZ) / 1000;		/* Timeout 110ms */				schedule();				restore_flags(flags);				cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT;				byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);				cs->hw.elsa.status &= ~ELSA_TIMER_AKTIV;				printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",				       cs->hw.elsa.counter);				if (abs(cs->hw.elsa.counter - 13) < 3) {					printk(KERN_INFO "Elsa: timer and irq OK\n");					ret = 0;				} else {					printk(KERN_WARNING					       "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n",					       cs->hw.elsa.counter, cs->irq);					ret = 1;				}			}#if ARCOFI_USE

⌨️ 快捷键说明

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