📄 eicon_mod.c
字号:
} /* *** */#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;}static void __exitunregister_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; }}static voideicon_freecard(eicon_card *card) { int i; for(i = 0; i < (card->nchannels + 1); i++) { skb_queue_purge(&card->bch[i].e.X); skb_queue_purge(&card->bch[i].e.R); } skb_queue_purge(&card->sndq); skb_queue_purge(&card->rcvq); skb_queue_purge(&card->rackq); skb_queue_purge(&card->sackq); skb_queue_purge(&card->statq);#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 */ registered = 1; if (registered) { /* Init OK, next card ... */ q = p; p = p->next; } else { /* registering failed, remove card from list, free memory */ printk(KERN_ERR "eicon: Initialization of %s failed\n", p->interface.id); if (q) { q->next = p->next; eicon_freecard(p); p = q->next; } else { cards = p->next; eicon_freecard(p); p = cards; } failed++; } } return (added - failed);}static int __initeicon_init(void){ int card_count = 0; char tmprev[50]; DebugVar = 1; eicon_lock = (spinlock_t) SPIN_LOCK_UNLOCKED; printk(KERN_INFO "%s Rev: ", DRIVERNAME); strcpy(tmprev, eicon_revision); printk("%s/", eicon_getrev(tmprev)); strcpy(tmprev, eicon_pci_revision);#ifdef CONFIG_ISDN_DRV_EICON_PCI printk("%s/", eicon_getrev(tmprev));#else printk("---/");#endif strcpy(tmprev, eicon_isa_revision);#ifdef CONFIG_ISDN_DRV_EICON_ISA printk("%s/", eicon_getrev(tmprev));#else printk("---/");#endif strcpy(tmprev, eicon_idi_revision); printk("%s\n", eicon_getrev(tmprev)); printk(KERN_INFO "%s Release: %s%s\n", DRIVERNAME, DRIVERRELEASE, DRIVERPATCH);#ifdef CONFIG_ISDN_DRV_EICON_ISA#ifdef CONFIG_MCA /* Check if we have MCA-bus */ if (!MCA_bus) { printk(KERN_INFO "eicon: No MCA bus, ISDN-interfaces not probed.\n"); } else { eicon_log(NULL, 8, "eicon_mca_find_card, irq=%d.\n", irq); if (!eicon_mca_find_card(0, membase, irq, id)) card_count++; };#else card_count = eicon_addcard(0, membase, irq, id, 0);#endif /* CONFIG_MCA */#endif /* CONFIG_ISDN_DRV_EICON_ISA */ #ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI DivasCardsDiscover(); card_count += eicon_pci_find_card(id);#endif#endif if (!cards) {#ifdef MODULE#ifndef CONFIG_ISDN_DRV_EICON_PCI#ifndef CONFIG_ISDN_DRV_EICON_ISA printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n"); printk(KERN_INFO "Eicon: Driver not loaded !\n");#else printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n");#endif#else printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n");#endif#endif /* MODULE */ return -ENODEV; } else printk(KERN_INFO "Eicon: %d card%s added\n", card_count, (card_count>1)?"s":""); return 0;}#ifdef CONFIG_ISDN_DRV_EICON_PCIvoid DIVA_DIDD_Write(DESCRIPTOR *, int);EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);EXPORT_SYMBOL_NOVERS(DivasPrintf);#elseint DivasCardNext;card_t DivasCards[1];#endifstatic void __exiteicon_exit(void){#if CONFIG_PCI #ifdef CONFIG_ISDN_DRV_EICON_PCI card_t *pCard; word wCardIndex; extern int Divas_major; int iTmp = 0;#endif#endif eicon_card *card = cards; eicon_card *last; while (card) {#ifdef CONFIG_ISDN_DRV_EICON_ISA#ifdef CONFIG_MCA if (MCA_bus) { mca_mark_as_unused (card->mca_slot); mca_set_adapter_procfn(card->mca_slot, NULL, NULL); };#endif /* CONFIG_MCA */#endif unregister_card(card); card = card->next; } card = cards; while (card) { last = card; card = card->next; eicon_freecard(last); }#if CONFIG_PCI #ifdef CONFIG_ISDN_DRV_EICON_PCI pCard = DivasCards; for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++) { if ((pCard->hw) && (pCard->hw->in_use)) { (*pCard->card_reset)(pCard); UxIsrRemove(pCard->hw, pCard); UxCardHandleFree(pCard->hw); if(pCard->e_tbl != NULL) { kfree(pCard->e_tbl); } if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B) { release_region(pCard->hw->io_base,0x20); release_region(pCard->hw->reset_base,0x80); } // If this is a 4BRI ... if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q) { // Skip over the next 3 virtual adapters wCardIndex += 3; // But free their handles for (iTmp = 0; iTmp < 3; iTmp++) { pCard++; UxCardHandleFree(pCard->hw); if(pCard->e_tbl != NULL) { kfree(pCard->e_tbl); } } } } pCard++; } unregister_chrdev(Divas_major, "Divas");#endif#endif /* CONFIG_PCI */ printk(KERN_INFO "%s unloaded\n", DRIVERNAME);}#ifndef MODULEstatic int __initeicon_setup(char *line){ int i, argc; int ints[5]; char *str; str = get_options(line, 4, ints); argc = ints[0]; i = 1;#ifdef CONFIG_ISDN_DRV_EICON_ISA if (argc) { membase = irq = -1; if (argc) { membase = ints[i]; i++; argc--; } if (argc) { irq = ints[i]; i++; argc--; } if (strlen(str)) { strcpy(id, str); } else { strcpy(id, "eicon"); } printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)\n", id, membase, irq); }#else printk(KERN_INFO "Eicon ISDN active driver setup\n");#endif return(1);}__setup("eicon=", eicon_setup);#endif /* MODULE */#ifdef CONFIG_ISDN_DRV_EICON_ISA#ifdef CONFIG_MCAstruct eicon_mca_adapters_struct { char * name; int adf_id;};/* possible MCA-brands of eicon cards */struct eicon_mca_adapters_struct eicon_mca_adapters[] = { { "ISDN-P/2 Adapter", 0x6abb }, { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 }, { "DIVA /MCA", 0x6336 }, { NULL, 0 },};int eicon_mca_find_card(int type, /* type-idx of eicon-card */ int membase, int irq, char * id) /* name of eicon-isdn-dev */{ int j, curr_slot = 0; eicon_log(NULL, 8, "eicon_mca_find_card type: %d, membase: %#x, irq %d \n", type, membase, irq); /* find a no-driver-assigned eicon card */ for (j=0; eicon_mca_adapters[j].adf_id != 0; j++) { for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++) { curr_slot = mca_find_unused_adapter( eicon_mca_adapters[j].adf_id, curr_slot); if (curr_slot != MCA_NOTFOUND) { /* check if pre-set parameters match these of the card, check cards memory */ if (!(int) eicon_mca_probe(curr_slot, j, membase, irq, id)) { return 0; /* means: adapter parms did match */ }; }; break; /* MCA_NOTFOUND-branch: no matching adapter of THIS flavor found, next flavor */ }; }; /* all adapter flavors checked without match, finito with: */ return -ENODEV;};/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999 */int eicon_info(char * buf, int slot, void *d){ int len = 0; struct eicon_card *dev; dev = (struct eicon_card *) d; if (dev == NULL) return len; len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type); len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq); len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem); return len;};int eicon_mca_probe(int slot, /* slot-nr where the card was detected */ int a_idx, /* idx-nr of probed card in eicon_mca_adapters */ int membase, int irq, char * id) /* name of eicon-isdn-dev */{ unsigned char adf_pos0; int cards_irq, cards_membase, cards_io; int type = EICON_CTYPE_S; int irq_array[]={0,3,4,2}; int irq_array1[]={3,4,0,0,2,10,11,12}; adf_pos0 = mca_read_stored_pos(slot,2); eicon_log(NULL, 8, "eicon_mca_probe irq=%d, membase=%d\n", irq, membase); switch (a_idx) { case 0: /* P/2-Adapter (== PRI/S2M ? ) */ cards_membase= 0xC0000+((adf_pos0>>4)*0x4000); if (membase == -1) { membase = cards_membase; } else { if (membase != cards_membase) return -ENODEV; }; cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; if (irq == -1) { irq = cards_irq; } else { if (irq != cards_irq) return -ENODEV; }; cards_io= 0xC00 + ((adf_pos0>>4)*0x10); type = EICON_CTYPE_ISAPRI; break; case 1: /* [S|SX|SCOM]/2 */ cards_membase= 0xC0000+((adf_pos0>>4)*0x2000); if (membase == -1) { membase = cards_membase; } else { if (membase != cards_membase) return -ENODEV; }; cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; if (irq == -1) { irq = cards_irq; } else { if (irq != cards_irq) return -ENODEV; }; cards_io= 0xC00 + ((adf_pos0>>4)*0x10); type = EICON_CTYPE_SCOM; break; case 2: /* DIVA/MCA */ cards_io = 0x200+ ((adf_pos0>>4)* 0x20); cards_irq = irq_array1[(adf_pos0 & 0x7)]; if (irq == -1) { irq = cards_irq; } else { if (irq != cards_irq) return -ENODEV; }; type = 0; break; default: return -ENODEV; }; /* matching membase & irq */ if ( 1 == eicon_addcard(type, membase, irq, id, 0)) { mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name); mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards); mca_mark_as_used(slot); cards->mca_slot = slot; /* card->io noch setzen oder ?? */ cards->mca_io = cards_io; cards->hwif.isa.io = cards_io; /* reset card */ outb_p(0,cards_io+1); eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.\n", cards->mca_slot+1); return 0 ; /* eicon_addcard added a card */ } else { return -ENODEV; };};#endif /* CONFIG_MCA */#endif /* CONFIG_ISDN_DRV_EICON_ISA */module_init(eicon_init);module_exit(eicon_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -