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

📄 diva.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		goto Start_IPAC;	}	if (!icnt)		printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n");	writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF);	writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0);}voidrelease_io_diva(struct IsdnCardState *cs){	int bytecnt;	if (cs->subtyp != DIVA_IPAC_ISA) {		del_timer(&cs->hw.diva.tl);		if (cs->hw.diva.cfg_reg)			byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */	}	if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA))		bytecnt = 8;	else		bytecnt = 32;	if (cs->hw.diva.cfg_reg) {		release_region(cs->hw.diva.cfg_reg, bytecnt);	}}static voidreset_diva(struct IsdnCardState *cs){	long flags;	save_flags(flags);	sti();	if (cs->subtyp == DIVA_IPAC_ISA) {		writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0);		schedule();	} else {		cs->hw.diva.ctrl_reg = 0;        /* Reset On */		byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		cs->hw.diva.ctrl_reg |= DIVA_RESET;  /* Reset Off */		byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + (10 * HZ) / 1000;	/* Timeout 10ms */		schedule();		if (cs->subtyp == DIVA_ISA)			cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A;		else			cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A;		byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);	}	restore_flags(flags);}#define DIVA_ASSIGN 1static voiddiva_led_handler(struct IsdnCardState *cs){	int blink = 0;	if (cs->subtyp == DIVA_IPAC_ISA)		return;	del_timer(&cs->hw.diva.tl);	if (cs->hw.diva.status & DIVA_ASSIGN)		cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?			DIVA_ISA_LED_A : DIVA_PCI_LED_A;	else {		cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?			DIVA_ISA_LED_A : DIVA_PCI_LED_A;		blink = 250;	}	if (cs->hw.diva.status & 0xf000)		cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?			DIVA_ISA_LED_B : DIVA_PCI_LED_B;	else if (cs->hw.diva.status & 0x0f00) {		cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?			DIVA_ISA_LED_B : DIVA_PCI_LED_B;		blink = 500;	} else		cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ?			DIVA_ISA_LED_B : DIVA_PCI_LED_B);	byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);	if (blink) {		init_timer(&cs->hw.diva.tl);		cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000);		add_timer(&cs->hw.diva.tl);	}}static intDiva_card_msg(struct IsdnCardState *cs, int mt, void *arg){	u_int irq_flag = I4L_IRQ_FLAG;	switch (mt) {		case CARD_RESET:			reset_diva(cs);			return(0);		case CARD_RELEASE:			release_io_diva(cs);			return(0);		case CARD_SETIRQ:			if (cs->subtyp == DIVA_PCI)				irq_flag |= SA_SHIRQ;			if (cs->subtyp == DIVA_IPAC_ISA) {				return(request_irq(cs->irq, &diva_interrupt_ipac,						irq_flag, "HiSax", cs));			} else {				return(request_irq(cs->irq, &diva_interrupt,						irq_flag, "HiSax", cs));			}		case CARD_INIT:			inithscxisac(cs, 3);			return(0);		case CARD_TEST:			return(0);		case (MDL_REMOVE | REQUEST):			cs->hw.diva.status = 0;			break;		case (MDL_ASSIGN | REQUEST):			cs->hw.diva.status |= DIVA_ASSIGN;			break;		case MDL_INFO_SETUP:			if ((long)arg)				cs->hw.diva.status |=  0x0200;			else				cs->hw.diva.status |=  0x0100;			break;		case MDL_INFO_CONN:			if ((long)arg)				cs->hw.diva.status |=  0x2000;			else				cs->hw.diva.status |=  0x1000;			break;		case MDL_INFO_REL:			if ((long)arg) {				cs->hw.diva.status &=  ~0x2000;				cs->hw.diva.status &=  ~0x0200;			} else {				cs->hw.diva.status &=  ~0x1000;				cs->hw.diva.status &=  ~0x0100;			}			break;	}	if (cs->subtyp != DIVA_IPAC_ISA)		diva_led_handler(cs);	return(0);}static 	int pci_index __initdata = 0;__initfunc(intsetup_diva(struct IsdnCard *card)){	int bytecnt;	u_char val;	struct IsdnCardState *cs = card->cs;	char tmp[64];	strcpy(tmp, Diva_revision);	printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));	if (cs->typ != ISDN_CTYPE_DIEHLDIVA)		return(0);	cs->hw.diva.status = 0;	if (card->para[1]) {		cs->hw.diva.ctrl_reg = 0;		cs->hw.diva.cfg_reg = card->para[1];		val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,			cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);		printk(KERN_INFO "Diva: IPAC version %x\n", val);		if (val == 1) {			cs->subtyp = DIVA_IPAC_ISA;			cs->hw.diva.ctrl = 0;			cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;			cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;			cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;			cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;			test_and_set_bit(HW_IPAC, &cs->HW_Flags);		} else {			cs->subtyp = DIVA_ISA;			cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;			cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;			cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;			cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;			cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;		}		cs->irq = card->para[0];		bytecnt = 8;	} else {#if CONFIG_PCI		u_char pci_bus, pci_device_fn, pci_irq;		u_int pci_ioaddr;		cs->subtyp = 0;		for (; pci_index < 0xff; pci_index++) {			if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL,			   PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn)			   == PCIBIOS_SUCCESSFUL)				cs->subtyp = DIVA_PCI;			else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL,			   PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn)			   == PCIBIOS_SUCCESSFUL)			   	cs->subtyp = DIVA_PCI;			else				break;			/* get IRQ */			pcibios_read_config_byte(pci_bus, pci_device_fn,				PCI_INTERRUPT_LINE, &pci_irq);			/* get IO address */			pcibios_read_config_dword(pci_bus, pci_device_fn,				PCI_BASE_ADDRESS_2, &pci_ioaddr);			if (cs->subtyp)				break;		}		if (!cs->subtyp) {			printk(KERN_WARNING "Diva: No PCI card found\n");			return(0);		}		pci_index++;		if (!pci_irq) {			printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");			return(0);		}		if (!pci_ioaddr) {			printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");			return(0);		}		pci_ioaddr &= ~3; /* remove io/mem flag */		cs->hw.diva.cfg_reg = pci_ioaddr;		cs->hw.diva.ctrl = pci_ioaddr + DIVA_PCI_CTRL;		cs->hw.diva.isac = pci_ioaddr + DIVA_PCI_ISAC_DATA;		cs->hw.diva.hscx = pci_ioaddr + DIVA_HSCX_DATA;		cs->hw.diva.isac_adr = pci_ioaddr + DIVA_PCI_ISAC_ADR;		cs->hw.diva.hscx_adr = pci_ioaddr + DIVA_HSCX_ADR;		cs->irq = pci_irq;		bytecnt = 32;#else		printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n");		printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");		return (0);#endif /* CONFIG_PCI */	}	printk(KERN_INFO		"Diva: %s card configured at 0x%x IRQ %d\n",		(cs->subtyp == DIVA_PCI) ? "PCI" :		(cs->subtyp == DIVA_ISA) ? "ISA" : "IPAC",		cs->hw.diva.cfg_reg, cs->irq);	if (check_region(cs->hw.diva.cfg_reg, bytecnt)) {		printk(KERN_WARNING		       "HiSax: %s config port %x-%x already in use\n",		       CardType[card->typ],		       cs->hw.diva.cfg_reg,		       cs->hw.diva.cfg_reg + bytecnt);		return (0);	} else {		request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn");	}	reset_diva(cs);	cs->BC_Read_Reg  = &ReadHSCX;	cs->BC_Write_Reg = &WriteHSCX;	cs->BC_Send_Data = &hscx_fill_fifo;	cs->cardmsg = &Diva_card_msg;	if (cs->subtyp == DIVA_IPAC_ISA) {		cs->readisac  = &ReadISAC_IPAC;		cs->writeisac = &WriteISAC_IPAC;		cs->readisacfifo  = &ReadISACfifo_IPAC;		cs->writeisacfifo = &WriteISACfifo_IPAC;		val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);		printk(KERN_INFO "Diva: IPAC version %x\n", val);	} else {		cs->hw.diva.tl.function = (void *) diva_led_handler;		cs->hw.diva.tl.data = (long) cs;		init_timer(&cs->hw.diva.tl);		cs->readisac  = &ReadISAC;		cs->writeisac = &WriteISAC;		cs->readisacfifo  = &ReadISACfifo;		cs->writeisacfifo = &WriteISACfifo;		ISACVersion(cs, "Diva:");		if (HscxVersion(cs, "Diva:")) {			printk(KERN_WARNING		       "Diva: wrong HSCX versions check IO address\n");			release_io_diva(cs);			return (0);		}	}	return (1);}

⌨️ 快捷键说明

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