⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eicon_mod.c

📁 MIZI Research, Inc.发布的嵌入式Linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		/* *** */#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 + -