📄 c4.c
字号:
if (data->configuration.len > 0 && data->configuration.data) { retval = c4_send_config(card, &data->configuration); if (retval) { printk(KERN_ERR "%s: failed to set config!!\n", card->name); c4_reset(card); return retval; } } c4_send_init(card); return 0;}void c4_reset_ctr(struct capi_ctr *ctrl){ avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; avmctrl_info *cinfo; int i; c4_reset(card); for (i=0; i < 4; i++) { cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); if (cinfo->capi_ctrl) cinfo->capi_ctrl->reseted(cinfo->capi_ctrl); }}static void c4_remove_ctr(struct capi_ctr *ctrl){ avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; avmctrl_info *cinfo; int i; c4_reset(card); for (i=0; i < 4; i++) { cinfo = &card->ctrlinfo[i]; if (cinfo->capi_ctrl) { di->detach_ctr(cinfo->capi_ctrl); cinfo->capi_ctrl = NULL; } } free_irq(card->irq, card); iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); release_region(card->port, AVMB1_PORTLEN); ctrl->driverdata = 0; kfree(card->ctrlinfo); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT;}/* ------------------------------------------------------------- */void c4_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp){ avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; struct sk_buff *skb; int want = rp->level3cnt; int nconn; void *p; if (ctrl->cnr == card->cardnr) { if (want > 0) nconn = want; else nconn = ctrl->profile.nbchannel * 4 * -want; if (nconn == 0) nconn = ctrl->profile.nbchannel * 4; skb = alloc_skb(23, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost register appl.\n", card->name); return; } p = skb->data; _put_byte(&p, 0); _put_byte(&p, 0); _put_byte(&p, SEND_REGISTER); _put_word(&p, appl); _put_word(&p, 1024 * (nconn+1)); _put_word(&p, nconn); _put_word(&p, rp->datablkcnt); _put_word(&p, rp->datablklen); skb_put(skb, (__u8 *)p - (__u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); c4_dispatch_tx(card); } ctrl->appl_registered(ctrl, appl);}/* ------------------------------------------------------------- */void c4_release_appl(struct capi_ctr *ctrl, __u16 appl){ avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; struct sk_buff *skb; void *p; if (ctrl->cnr == card->cardnr) { skb = alloc_skb(7, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost release appl.\n", card->name); return; } p = skb->data; _put_byte(&p, 0); _put_byte(&p, 0); _put_byte(&p, SEND_RELEASE); _put_word(&p, appl); skb_put(skb, (__u8 *)p - (__u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); c4_dispatch_tx(card); }}/* ------------------------------------------------------------- */static void c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb){ avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; skb_queue_tail(&card->dma->send_queue, skb); c4_dispatch_tx(card);}/* ------------------------------------------------------------- */static char *c4_procinfo(struct capi_ctr *ctrl){ avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); if (!cinfo) return ""; sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx", cinfo->cardname[0] ? cinfo->cardname : "-", cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", cinfo->card ? cinfo->card->port : 0x0, cinfo->card ? cinfo->card->irq : 0, cinfo->card ? cinfo->card->membase : 0 ); return cinfo->infobuf;}static int c4_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl){ avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; __u8 flag; int len = 0; char *s; len += sprintf(page+len, "%-16s %s\n", "name", card->name); len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); switch (card->cardtype) { case avm_b1isa: s = "B1 ISA"; break; case avm_b1pci: s = "B1 PCI"; break; case avm_b1pcmcia: s = "B1 PCMCIA"; break; case avm_m1: s = "M1"; break; case avm_m2: s = "M2"; break; case avm_t1isa: s = "T1 ISA (HEMA)"; break; case avm_t1pci: s = "T1 PCI"; break; case avm_c4: s = "C4"; break; default: s = "???"; break; } len += sprintf(page+len, "%-16s %s\n", "type", s); if ((s = cinfo->version[VER_DRIVER]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); if ((s = cinfo->version[VER_CARDTYPE]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); if ((s = cinfo->version[VER_SERIAL]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); if (card->cardtype != avm_m1) { flag = ((__u8 *)(ctrl->profile.manu))[3]; if (flag) len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", "protocol", (flag & 0x01) ? " DSS1" : "", (flag & 0x02) ? " CT1" : "", (flag & 0x04) ? " VN3" : "", (flag & 0x08) ? " NI1" : "", (flag & 0x10) ? " AUSTEL" : "", (flag & 0x20) ? " ESS" : "", (flag & 0x40) ? " 1TR6" : "" ); } if (card->cardtype != avm_m1) { flag = ((__u8 *)(ctrl->profile.manu))[5]; if (flag) len += sprintf(page+len, "%-16s%s%s%s%s\n", "linetype", (flag & 0x01) ? " point to point" : "", (flag & 0x02) ? " point to multipoint" : "", (flag & 0x08) ? " leased line without D-channel" : "", (flag & 0x04) ? " leased line with D-channel" : "" ); } len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); if (off+count >= len) *eof = 1; if (len < off) return 0; *start = page + off; return ((count < len-off) ? count : len-off);}/* ------------------------------------------------------------- */static int c4_add_card(struct capi_driver *driver, struct capicardparams *p){ unsigned long base, page_offset; avmctrl_info *cinfo; avmcard *card; int retval; int i; MOD_INC_USE_COUNT; card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); if (!card) { printk(KERN_WARNING "%s: no memory.\n", driver->name); MOD_DEC_USE_COUNT; return -ENOMEM; } memset(card, 0, sizeof(avmcard)); card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC); if (!card->dma) { printk(KERN_WARNING "%s: no memory.\n", driver->name); kfree(card); MOD_DEC_USE_COUNT; return -ENOMEM; } memset(card->dma, 0, sizeof(avmcard_dmainfo)); cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info)*4, GFP_ATOMIC); if (!cinfo) { printk(KERN_WARNING "%s: no memory.\n", driver->name); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT; return -ENOMEM; } memset(cinfo, 0, sizeof(avmctrl_info)*4); card->ctrlinfo = cinfo; for (i=0; i < 4; i++) { cinfo = &card->ctrlinfo[i]; cinfo->card = card; } sprintf(card->name, "c4-%x", p->port); card->port = p->port; card->irq = p->irq; card->membase = p->membase; card->cardtype = avm_c4; if (check_region(card->port, AVMB1_PORTLEN)) { printk(KERN_WARNING "%s: ports 0x%03x-0x%03x in use.\n", driver->name, card->port, card->port + AVMB1_PORTLEN); kfree(card->ctrlinfo); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT; return -EBUSY; } base = card->membase & PAGE_MASK; page_offset = card->membase - base; card->mbase = ioremap_nocache(base, page_offset + 128); if (card->mbase) { card->mbase += page_offset; } else { printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n", driver->name, card->membase); kfree(card->ctrlinfo); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT; return -EIO; } if ((retval = c4_detect(card)) != 0) { printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", driver->name, card->port, retval); iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); kfree(card->ctrlinfo); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT; return -EIO; } c4_reset(card); request_region(p->port, AVMB1_PORTLEN, card->name); retval = request_irq(card->irq, c4_interrupt, SA_SHIRQ, card->name, card); if (retval) { printk(KERN_ERR "%s: unable to get IRQ %d.\n", driver->name, card->irq); iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); release_region(card->port, AVMB1_PORTLEN); kfree(card->ctrlinfo); kfree(card->dma); kfree(card); MOD_DEC_USE_COUNT; return -EBUSY; } for (i=0; i < 4; i++) { cinfo = &card->ctrlinfo[i]; cinfo->card = card; cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); if (!cinfo->capi_ctrl) { printk(KERN_ERR "%s: attach controller failed (%d).\n", driver->name, i); for (i--; i >= 0; i--) { cinfo = &card->ctrlinfo[i]; di->detach_ctr(cinfo->capi_ctrl); } iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); kfree(card->dma); kfree(card->ctrlinfo); kfree(card); MOD_DEC_USE_COUNT; return -EBUSY; } if (i == 0) card->cardnr = cinfo->capi_ctrl->cnr; } skb_queue_head_init(&card->dma->send_queue); printk(KERN_INFO "%s: AVM C4 at i/o %#x, irq %d, mem %#lx\n", driver->name, card->port, card->irq, card->membase); return 0;}/* ------------------------------------------------------------- */static struct capi_driver c4_driver = { name: "c4", revision: "0.0", load_firmware: c4_load_firmware, reset_ctr: c4_reset_ctr, remove_ctr: c4_remove_ctr, register_appl: c4_register_appl, release_appl: c4_release_appl, send_message: c4_send_message, procinfo: c4_procinfo, ctr_read_proc: c4_read_proc, driver_read_proc: 0, /* use standard driver_read_proc */ add_card: 0, /* no add_card function */};static int ncards = 0;static int __init c4_init(void){ struct capi_driver *driver = &c4_driver; struct pci_dev *dev = NULL; char *p; int retval; MOD_INC_USE_COUNT; if ((p = strchr(revision, ':'))) { strncpy(driver->revision, p + 1, sizeof(driver->revision)); p = strchr(driver->revision, '$'); *p = 0; } printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); di = attach_capi_driver(driver); if (!di) { printk(KERN_ERR "%s: failed to attach capi_driver\n", driver->name); MOD_DEC_USE_COUNT; return -EIO; }#ifdef CONFIG_PCI if (!pci_present()) { printk(KERN_ERR "%s: no PCI bus present\n", driver->name); detach_capi_driver(driver); MOD_DEC_USE_COUNT; return -EIO; } while ((dev = pci_find_subsys( PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, dev))) { struct capicardparams param; param.port = pci_resource_start(dev, 1); param.irq = dev->irq; param.membase = pci_resource_start(dev, 0); retval = pci_enable_device (dev); if (retval != 0) { printk(KERN_ERR "%s: failed to enable AVM-C4 at i/o %#x, irq %d, mem %#x err=%d\n", driver->name, param.port, param.irq, param.membase, retval); detach_capi_driver(driver); MOD_DEC_USE_COUNT; return -EIO; } printk(KERN_INFO "%s: PCI BIOS reports AVM-C4 at i/o %#x, irq %d, mem %#x\n", driver->name, param.port, param.irq, param.membase); retval = c4_add_card(driver, ¶m); if (retval != 0) { printk(KERN_ERR "%s: no AVM-C4 at i/o %#x, irq %d detected, mem %#x\n", driver->name, param.port, param.irq, param.membase); detach_capi_driver(driver); MOD_DEC_USE_COUNT; return retval; } ncards++; } if (ncards) { printk(KERN_INFO "%s: %d C4 card(s) detected\n", driver->name, ncards); MOD_DEC_USE_COUNT; return 0; } printk(KERN_ERR "%s: NO C4 card detected\n", driver->name); detach_capi_driver(driver); MOD_DEC_USE_COUNT; return -ESRCH;#else printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name); MOD_DEC_USE_COUNT; return -EIO;#endif}static void __exit c4_exit(void){ detach_capi_driver(&c4_driver);}module_init(c4_init);module_exit(c4_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -