📄 netjet.c
字号:
if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); restore_flags(flags); } else { st->l1.bcs->tx_skb = skb; st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); restore_flags(flags); } break; case (PH_PULL | INDICATION): if (st->l1.bcs->tx_skb) { printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n"); break; } save_flags(flags); cli(); st->l1.bcs->tx_skb = skb; st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); restore_flags(flags); break; case (PH_PULL | REQUEST): if (!st->l1.bcs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (PH_ACTIVATE | REQUEST): test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc); l1_msg_b(st, pr, arg); break; case (PH_DEACTIVATE | REQUEST): l1_msg_b(st, pr, arg); break; case (PH_DEACTIVATE | CONFIRM): test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); mode_tiger(st->l1.bcs, 0, st->l1.bc); st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); break; }}voidclose_tigerstate(struct BCState *bcs){ mode_tiger(bcs, 0, bcs->channel); if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { if (bcs->hw.tiger.rcvbuf) { kfree(bcs->hw.tiger.rcvbuf); bcs->hw.tiger.rcvbuf = NULL; } if (bcs->hw.tiger.sendbuf) { kfree(bcs->hw.tiger.sendbuf); bcs->hw.tiger.sendbuf = NULL; } discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { dev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } }}static intopen_tigerstate(struct IsdnCardState *cs, struct BCState *bcs){ if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for tiger.rcvbuf\n"); return (1); } if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for tiger.sendbuf\n"); return (1); } skb_queue_head_init(&bcs->rqueue); skb_queue_head_init(&bcs->squeue); } bcs->tx_skb = NULL; bcs->hw.tiger.sendcnt = 0; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); bcs->event = 0; bcs->tx_cnt = 0; return (0);}intsetstack_tiger(struct PStack *st, struct BCState *bcs){ bcs->channel = st->l1.bc; if (open_tigerstate(st->l1.hardware, bcs)) return (-1); st->l1.bcs = bcs; st->l2.l2l1 = tiger_l2l1; setstack_manager(st); bcs->st = st; setstack_l1_B(st); return (0);} __initfunc(voidinittiger(struct IsdnCardState *cs)){ if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int), GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.send\n"); return; } cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE/2 - 1; cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1; cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send; cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq; cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end; memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int)); debugl1(cs, "tiger: send buf %x - %x", (u_int)cs->bcs[0].hw.tiger.send, (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1)); outl(virt_to_bus(cs->bcs[0].hw.tiger.send), cs->hw.njet.base + NETJET_DMA_READ_START); outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq), cs->hw.njet.base + NETJET_DMA_READ_IRQ); outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), cs->hw.njet.base + NETJET_DMA_READ_END); if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int), GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.rec\n"); return; } debugl1(cs, "tiger: rec buf %x - %x", (u_int)cs->bcs[0].hw.tiger.rec, (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1)); cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec; memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int)); outl(virt_to_bus(cs->bcs[0].hw.tiger.rec), cs->hw.njet.base + NETJET_DMA_WRITE_START); outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE/2 - 1), cs->hw.njet.base + NETJET_DMA_WRITE_IRQ); outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1), cs->hw.njet.base + NETJET_DMA_WRITE_END); debugl1(cs, "tiger: dmacfg %x/%x pulse=%d", inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); cs->hw.njet.last_is0 = 0; cs->bcs[0].BC_SetStack = setstack_tiger; cs->bcs[1].BC_SetStack = setstack_tiger; cs->bcs[0].BC_Close = close_tigerstate; cs->bcs[1].BC_Close = close_tigerstate;}voidreleasetiger(struct IsdnCardState *cs){ if (cs->bcs[0].hw.tiger.send) { kfree(cs->bcs[0].hw.tiger.send); cs->bcs[0].hw.tiger.send = NULL; } if (cs->bcs[1].hw.tiger.send) { cs->bcs[1].hw.tiger.send = NULL; } if (cs->bcs[0].hw.tiger.rec) { kfree(cs->bcs[0].hw.tiger.rec); cs->bcs[0].hw.tiger.rec = NULL; } if (cs->bcs[1].hw.tiger.rec) { cs->bcs[1].hw.tiger.rec = NULL; }}static voidnetjet_interrupt(int intno, void *dev_id, struct pt_regs *regs){ struct IsdnCardState *cs = dev_id; u_char val, sval; long flags; if (!cs) { printk(KERN_WARNING "NETjet: Spurious interrupt!\n"); return; } if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) & NETJET_ISACIRQ)) { val = ReadISAC(cs, ISAC_ISTA); if (cs->debug & L1_DEB_ISAC) debugl1(cs, "tiger: i1 %x %x", sval, val); if (val) { isac_interrupt(cs, val); WriteISAC(cs, ISAC_MASK, 0xFF); WriteISAC(cs, ISAC_MASK, 0x0); } } save_flags(flags); cli(); if ((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT0))) { if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { restore_flags(flags); return; } cs->hw.njet.irqstat0 = sval; restore_flags(flags);/* debugl1(cs, "tiger: ist0 %x %x %x %x/%x pulse=%d", sval, bytein(cs->hw.njet.base + NETJET_DMACTRL), bytein(cs->hw.njet.base + NETJET_IRQMASK0), inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), bytein(cs->hw.njet.base + NETJET_PULSE_CNT));*//* cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;*/ byteout(cs->hw.njet.base + NETJET_IRQSTAT0, cs->hw.njet.irqstat0);/* byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);*/ if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) read_tiger(cs); if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) write_tiger(cs); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else restore_flags(flags);/* if (!testcnt--) { cs->hw.njet.dmactrl = 0; byteout(cs->hw.njet.base + NETJET_DMACTRL, cs->hw.njet.dmactrl); byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); }*/}static voidreset_netjet(struct IsdnCardState *cs){ long flags; save_flags(flags); sti(); cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); current->state = TASK_INTERRUPTIBLE; current->timeout = jiffies + (10 * HZ) / 1000; /* Timeout 10ms */ schedule(); cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); current->state = TASK_INTERRUPTIBLE; current->timeout = jiffies + (10 * HZ) / 1000; /* Timeout 10ms */ schedule(); restore_flags(flags); cs->hw.njet.auxd = 0; cs->hw.njet.dmactrl = 0; byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);}voidrelease_io_netjet(struct IsdnCardState *cs){ byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); releasetiger(cs); release_region(cs->hw.njet.base, 256);}static intNETjet_card_msg(struct IsdnCardState *cs, int mt, void *arg){ switch (mt) { case CARD_RESET: reset_netjet(cs); return(0); case CARD_RELEASE: release_io_netjet(cs); return(0); case CARD_SETIRQ: return(request_irq(cs->irq, &netjet_interrupt, I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs)); case CARD_INIT: inittiger(cs); clear_pending_isac_ints(cs); initisac(cs); /* Reenable all IRQ */ cs->writeisac(cs, ISAC_MASK, 0); return(0); case CARD_TEST: return(0); } return(0);}static int pci_index __initdata = 0;__initfunc(intsetup_netjet(struct IsdnCard *card)){ int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64];#if CONFIG_PCI u_char pci_bus, pci_device_fn, pci_irq; u_int pci_ioaddr, found;#endif strcpy(tmp, NETjet_revision); printk(KERN_INFO "HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_NETJET) return(0);#if CONFIG_PCI found = 0; for (; pci_index < 0xff; pci_index++) { if (pcibios_find_device(PCI_VENDOR_TRAVERSE_TECH, PCI_NETJET_ID, pci_index, &pci_bus, &pci_device_fn) == PCIBIOS_SUCCESSFUL) found = 1; 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_0, &pci_ioaddr); if (found) break; } if (!found) { printk(KERN_WARNING "NETjet: No PCI card found\n"); return(0); } pci_index++; if (!pci_irq) { printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n"); return(0); } if (!pci_ioaddr) { printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n"); return(0); } pci_ioaddr &= ~3; /* remove io/mem flag */ cs->hw.njet.base = pci_ioaddr; cs->hw.njet.auxa = pci_ioaddr + NETJET_AUXDATA; cs->hw.njet.isac = pci_ioaddr | NETJET_ISAC_OFF; cs->irq = pci_irq; bytecnt = 256;#else printk(KERN_WARNING "NETjet: NO_PCI_BIOS\n"); printk(KERN_WARNING "NETjet: unable to config NETJET PCI\n"); return (0);#endif /* CONFIG_PCI */ printk(KERN_INFO "NETjet: PCI card configured at 0x%x IRQ %d\n", cs->hw.njet.base, cs->irq); if (check_region(cs->hw.njet.base, bytecnt)) { printk(KERN_WARNING "HiSax: %s config port %x-%x already in use\n", CardType[card->typ], cs->hw.njet.base, cs->hw.njet.base + bytecnt); return (0); } else { request_region(cs->hw.njet.base, bytecnt, "netjet isdn"); } reset_netjet(cs); cs->readisac = &ReadISAC; cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; cs->BC_Read_Reg = &dummyrr; cs->BC_Write_Reg = &dummywr; cs->BC_Send_Data = &fill_dma; cs->cardmsg = &NETjet_card_msg; ISACVersion(cs, "NETjet:"); return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -