📄 eicon_mod.c
字号:
int j; int qloop;#ifdef CONFIG_ISDN_DRV_EICON_ISA char qid[5];#endif eicon_card *card; qloop = (Type == EICON_CTYPE_QUADRO)?2:0; for (i = 0; i <= qloop; i++) { if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) { eicon_log(card, 1, "eicon: (%s) Could not allocate card-struct.\n", id); return; } memset((char *) card, 0, sizeof(eicon_card)); skb_queue_head_init(&card->sndq); skb_queue_head_init(&card->rcvq); skb_queue_head_init(&card->rackq); skb_queue_head_init(&card->sackq); skb_queue_head_init(&card->statq); card->statq_entries = 0; card->snd_tq.routine = (void *) (void *) eicon_transmit; card->snd_tq.data = card; card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch; card->rcv_tq.data = card; card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch; card->ack_tq.data = card; card->interface.maxbufsize = 4000; card->interface.command = if_command; card->interface.writebuf_skb = if_sendbuf; card->interface.writecmd = if_writecmd; card->interface.readstat = if_readstatus; card->interface.features = ISDN_FEATURE_L2_X75I | ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS | ISDN_FEATURE_L3_TRANS | ISDN_FEATURE_P_UNKNOWN; card->interface.hl_hdrlen = 20; card->ptype = ISDN_PTYPE_UNKNOWN; strncpy(card->interface.id, id, sizeof(card->interface.id) - 1); card->myid = -1; card->type = Type; switch (Type) {#ifdef CONFIG_ISDN_DRV_EICON_ISA#if CONFIG_MCA /* only needed for MCA */ case EICON_CTYPE_S: case EICON_CTYPE_SX: case EICON_CTYPE_SCOM: if (MCA_bus) { if (membase == -1) membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; card->bus = EICON_BUS_MCA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)membase; card->hwif.isa.physmem = (unsigned long)membase; card->hwif.isa.master = 1; card->hwif.isa.irq = irq; card->hwif.isa.type = Type; card->nchannels = 2; card->interface.channels = 1; } else { printk(KERN_WARNING "eicon (%s): no MCA bus detected.\n", card->interface.id); kfree(card); return; } break;#endif /* CONFIG_MCA */ case EICON_CTYPE_QUADRO: if (membase == -1) membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; card->bus = EICON_BUS_ISA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET); card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET); card->hwif.isa.master = 0; strcpy(card->interface.id, id); if (id[strlen(id) - 1] == 'a') { card->interface.id[strlen(id) - 1] = 'a' + i + 1; } else { sprintf(qid, "_%c",'2' + i); strcat(card->interface.id, qid); } printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.\n", card->interface.id); if (i == 0) { eicon_card *p = cards; while(p) { if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) { p->qnext = card; break; } p = p->next; } if (!p) { eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n"); kfree(card); return; } } else { cards->qnext = card; } card->hwif.isa.irq = irq; card->hwif.isa.type = Type; card->nchannels = 2; card->interface.channels = 1; break;#endif#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI case EICON_CTYPE_MAESTRA: card->bus = EICON_BUS_PCI; card->interface.features |= ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | ISDN_FEATURE_L2_MODEM | ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_TRANSDSP | ISDN_FEATURE_L3_FCLASS2; card->hwif.pci.card = (void *)card; card->hwif.pci.master = card_id; card->hwif.pci.irq = irq; card->hwif.pci.type = Type; card->flags = 0; card->nchannels = 2; card->interface.channels = 1; break; case EICON_CTYPE_MAESTRAQ: card->bus = EICON_BUS_PCI; card->interface.features |= ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | ISDN_FEATURE_L2_MODEM | ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_TRANSDSP | ISDN_FEATURE_L3_FCLASS2; card->hwif.pci.card = (void *)card; card->hwif.pci.master = card_id; card->hwif.pci.irq = irq; card->hwif.pci.type = Type; card->flags = 0; card->nchannels = 2; card->interface.channels = 1; break; case EICON_CTYPE_MAESTRAP: card->bus = EICON_BUS_PCI; card->interface.features |= ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | ISDN_FEATURE_L2_MODEM | ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_TRANSDSP | ISDN_FEATURE_L3_FCLASS2; card->hwif.pci.card = (void *)card; card->hwif.pci.master = card_id; card->hwif.pci.irq = irq; card->hwif.pci.type = Type; card->flags = 0; card->nchannels = 30; card->interface.channels = 1; break;#endif#endif#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_ISABRI: if (membase == -1) membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; card->bus = EICON_BUS_ISA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)membase; card->hwif.isa.physmem = (unsigned long)membase; card->hwif.isa.master = 1; card->hwif.isa.irq = irq; card->hwif.isa.type = Type; card->nchannels = 2; card->interface.channels = 1; break; case EICON_CTYPE_ISAPRI: if (membase == -1) membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; card->bus = EICON_BUS_ISA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)membase; card->hwif.isa.physmem = (unsigned long)membase; card->hwif.isa.master = 1; card->hwif.isa.irq = irq; card->hwif.isa.type = Type; card->nchannels = 30; card->interface.channels = 1; break;#endif default: eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type); kfree(card); return; } if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1) , GFP_KERNEL))) { eicon_log(card, 1, "eicon: (%s) Could not allocate bch-struct.\n", id); kfree(card); return; } for (j=0; j< (card->nchannels + 1); j++) { memset((char *)&card->bch[j], 0, sizeof(eicon_chan)); card->bch[j].statectrl = 0; card->bch[j].l2prot = ISDN_PROTO_L2_X75I; card->bch[j].l3prot = ISDN_PROTO_L3_TRANS; card->bch[j].e.D3Id = 0; card->bch[j].e.B2Id = 0; card->bch[j].e.Req = 0; card->bch[j].No = j; card->bch[j].tskb1 = NULL; card->bch[j].tskb2 = NULL; skb_queue_head_init(&card->bch[j].e.X); skb_queue_head_init(&card->bch[j].e.R); }#ifdef CONFIG_ISDN_DRV_EICON_PCI /* *** Diva Server *** */ if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2 , GFP_KERNEL))) { eicon_log(card, 1, "eicon: (%s) Could not allocate DBUFFER-struct.\n", id); kfree(card); kfree(card->bch); return; } if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) { eicon_log(card, 1, "eicon: (%s) Could not allocate BUFFERS-struct.\n", id); kfree(card); kfree(card->bch); kfree(card->dbuf); return; } if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) { eicon_log(card, 1, "eicon: (%s) Could not allocate BUFFERSP-struct.\n", id); kfree(card); kfree(card->bch); kfree(card->dbuf); kfree(card->sbuf); return; } for (j=0; j< (card->nchannels + 1); j++) { memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER)); card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j]; memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS)); card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)]; memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS)); card->bch[j].de.X = (BUFFERS *)&card->sbuf[j]; memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS)); card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)]; memset((char *)&card->sbufp[j], 0, 270); card->bch[j].de.X->P = (char *)&card->sbufp[j * 270]; memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270); card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270]; } /* *** */#endif /* CONFIG_ISDN_DRV_EICON_PCI */ card->next = cards; cards = card; }}/* * register card at linklevel */static inteicon_registercard(eicon_card * card){ switch (card->bus) {#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA: /* TODO something to print */ break;#ifdef CONFIG_MCA case EICON_BUS_MCA: eicon_isa_printpar(&card->hwif.isa); break;#endif /* CONFIG_MCA */#endif case EICON_BUS_PCI: break; default: eicon_log(card, 1, "eicon_registercard: Illegal BUS type %d\n", card->bus); return -1; } if (!register_isdn(&card->interface)) { printk(KERN_WARNING "eicon_registercard: Unable to register %s\n", card->interface.id); return -1; } card->myid = card->interface.channels; sprintf(card->regname, "%s", card->interface.id); return 0;}#ifdef MODULEstatic voidunregister_card(eicon_card * card){ isdn_ctrl cmd; cmd.command = ISDN_STAT_UNLOAD; cmd.driver = card->myid; card->interface.statcallb(&cmd); switch (card->bus) {#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA:#ifdef CONFIG_MCA case EICON_BUS_MCA:#endif /* CONFIG_MCA */ eicon_isa_release(&card->hwif.isa); break;#endif case EICON_BUS_PCI: break; default: eicon_log(card, 1, "eicon: Invalid BUS type %d\n", card->bus); break; }}#endif /* MODULE */static voideicon_freecard(eicon_card *card) { int i; struct sk_buff *skb; for(i = 0; i < (card->nchannels + 1); i++) { while((skb = skb_dequeue(&card->bch[i].e.X))) dev_kfree_skb(skb); while((skb = skb_dequeue(&card->bch[i].e.R))) dev_kfree_skb(skb); } while((skb = skb_dequeue(&card->sndq))) dev_kfree_skb(skb); while((skb = skb_dequeue(&card->rcvq))) dev_kfree_skb(skb); while((skb = skb_dequeue(&card->rackq))) dev_kfree_skb(skb); while((skb = skb_dequeue(&card->sackq))) dev_kfree_skb(skb); while((skb = skb_dequeue(&card->statq))) dev_kfree_skb(skb);#ifdef CONFIG_ISDN_DRV_EICON_PCI kfree(card->sbufp); kfree(card->sbuf); kfree(card->dbuf);#endif kfree(card->bch); kfree(card);}inteicon_addcard(int Type, int membase, int irq, char *id, int card_id){ eicon_card *p; eicon_card *q = NULL; int registered; int added = 0; int failed = 0;#ifdef CONFIG_ISDN_DRV_EICON_ISA if (!Type) /* ISA */ if ((Type = eicon_isa_find_card(membase, irq, id)) < 0) return 0;#endif eicon_alloccard(Type, membase, irq, id, card_id); p = cards; while (p) { registered = 0; if (!p->interface.statcallb) { /* Not yet registered. * Try to register and activate it. */ added++; switch (p->bus) {#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA: case EICON_BUS_MCA: if (eicon_registercard(p)) break; registered = 1; break;#endif case EICON_BUS_PCI:#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI if (eicon_registercard(p)) break; registered = 1; break;#endif#endif default: printk(KERN_ERR "eicon: addcard: Invalid BUS type %d\n", p->bus); } } else /* Card already registered */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -