?? diva.c
字號:
#define DIVA_ASSIGN 1static voiddiva_led_handler(struct IsdnCardState *cs){ int blink = 0; if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI) ) 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 *ireg; switch (mt) { case CARD_RESET: reset_diva(cs); return(0); case CARD_RELEASE: release_io_diva(cs); return(0); case CARD_INIT: if (cs->subtyp == DIVA_IPACX_PCI) { ireg = (unsigned int *)cs->hw.diva.pci_cfg; *ireg = PITA_INT0_ENABLE; init_ipacx(cs, 3); // init chip and enable interrupts return (0); } if (cs->subtyp == DIVA_IPAC_PCI) { ireg = (unsigned int *)cs->hw.diva.pci_cfg; *ireg = PITA_INT0_ENABLE; } 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) && (cs->subtyp != DIVA_IPAC_PCI) && (cs->subtyp != DIVA_IPACX_PCI) ) diva_led_handler(cs); return(0);}static struct pci_dev *dev_diva __initdata = NULL;static struct pci_dev *dev_diva_u __initdata = NULL;static struct pci_dev *dev_diva201 __initdata = NULL;static struct pci_dev *dev_diva202 __initdata = NULL;#ifdef __ISAPNP__static struct isapnp_device_id diva_ids[] __initdata = { { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), (unsigned long) "Diva picola" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), (unsigned long) "Diva picola" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), (unsigned long) "Diva 2.0" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), (unsigned long) "Diva 2.0" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), (unsigned long) "Diva 2.01" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), (unsigned long) "Diva 2.01" }, { 0, }};static struct isapnp_device_id *pdev = &diva_ids[0];static struct pci_bus *pnp_c __devinitdata = NULL;#endifint __initsetup_diva(struct IsdnCard *card){ int bytecnt = 8; 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) || (val==2)) { 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]; } else {#ifdef __ISAPNP__ if (isapnp_present()) { struct pci_bus *pb; struct pci_dev *pd; while(pdev->card_vendor) { if ((pb = isapnp_find_card(pdev->card_vendor, pdev->card_device, pnp_c))) { pnp_c = pb; pd = NULL; if ((pd = isapnp_find_dev(pnp_c, pdev->vendor, pdev->function, pd))) { printk(KERN_INFO "HiSax: %s detected\n", (char *)pdev->driver_data); pd->prepare(pd); pd->deactivate(pd); pd->activate(pd); card->para[1] = pd->resource[0].start; card->para[0] = pd->irq_resource[0].start; if (!card->para[0] || !card->para[1]) { printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pd->deactivate(pd); return(0); } cs->hw.diva.cfg_reg = card->para[1]; cs->irq = card->para[0]; if (pdev->function == ISAPNP_FUNCTION(0xA1)) { 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; } goto ready; } else { printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); return(0); } } pdev++; pnp_c=NULL; } if (!pdev->card_vendor) { printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); } }#endif#if CONFIG_PCI if (!pci_present()) { printk(KERN_ERR "Diva: no PCI bus present\n"); return(0); } cs->subtyp = 0; if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { if (pci_enable_device(dev_diva)) return(0); cs->subtyp = DIVA_PCI; cs->irq = dev_diva->irq; cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { if (pci_enable_device(dev_diva_u)) return(0); cs->subtyp = DIVA_PCI; cs->irq = dev_diva_u->irq; cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { if (pci_enable_device(dev_diva201)) return(0); cs->subtyp = DIVA_IPAC_PCI; cs->irq = dev_diva201->irq; cs->hw.diva.pci_cfg = (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); cs->hw.diva.cfg_reg = (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { if (pci_enable_device(dev_diva202)) return(0); cs->subtyp = DIVA_IPACX_PCI; cs->irq = dev_diva202->irq; cs->hw.diva.pci_cfg = (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); cs->hw.diva.cfg_reg = (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); } else { printk(KERN_WARNING "Diva: No PCI card found\n"); return(0); } if (!cs->irq) { printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); return(0); } if (!cs->hw.diva.cfg_reg) { printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); return(0); } cs->irq_flags |= SA_SHIRQ;#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 */ if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI) ) { cs->hw.diva.ctrl = 0; cs->hw.diva.isac = 0; cs->hw.diva.hscx = 0; cs->hw.diva.isac_adr = 0; cs->hw.diva.hscx_adr = 0; test_and_set_bit(HW_IPAC, &cs->HW_Flags); bytecnt = 0; } else { cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; bytecnt = 32; } }ready: printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", (cs->subtyp == DIVA_PCI) ? "PCI" : (cs->subtyp == DIVA_ISA) ? "ISA" : (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", cs->hw.diva.cfg_reg, cs->irq); if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI) || (cs->subtyp == DIVA_PCI) ) printk(KERN_INFO "Diva: %s space at %#lx\n", (cs->subtyp == DIVA_PCI) ? "PCI" : (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", cs->hw.diva.pci_cfg); if ((cs->subtyp != DIVA_IPAC_PCI) && (cs->subtyp != DIVA_IPACX_PCI) ) { if (check_region(cs->hw.diva.cfg_reg, bytecnt)) { printk(KERN_WARNING "HiSax: %s config port %lx-%lx 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; cs->irq_func = &diva_irq_ipac_isa; val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); } else if (cs->subtyp == DIVA_IPAC_PCI) { cs->readisac = &MemReadISAC_IPAC; cs->writeisac = &MemWriteISAC_IPAC; cs->readisacfifo = &MemReadISACfifo_IPAC; cs->writeisacfifo = &MemWriteISACfifo_IPAC; cs->BC_Read_Reg = &MemReadHSCX; cs->BC_Write_Reg = &MemWriteHSCX; cs->BC_Send_Data = &Memhscx_fill_fifo; cs->irq_func = &diva_irq_ipac_pci; val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); } else if (cs->subtyp == DIVA_IPACX_PCI) { cs->readisac = &MemReadISAC_IPACX; cs->writeisac = &MemWriteISAC_IPACX; cs->readisacfifo = &MemReadISACfifo_IPACX; cs->writeisacfifo = &MemWriteISACfifo_IPACX; cs->BC_Read_Reg = &MemReadHSCX_IPACX; cs->BC_Write_Reg = &MemWriteHSCX_IPACX; cs->BC_Send_Data = 0; // function located in ipacx module cs->irq_func = &diva_irq_ipacx_pci; printk(KERN_INFO "Diva: IPACX Design Id: %x\n", MemReadISAC_IPACX(cs, IPACX_ID) &0x3F); } else { /* DIVA 2.0 */ 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; cs->irq_func = &diva_interrupt; 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 + -