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

📄 eicon_mod.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: eicon_mod.c,v 1.37 2000/09/02 11:16:47 armin Exp $ * * ISDN lowlevel-module for Eicon active cards. *  * Copyright 1997      by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998-2000 by Armin Schindler (mac@melware.de)  * Copyright 1999,2000 Cytronics & Melware (info@melware.de) *  * Thanks to    Eicon Technology GmbH & Co. oHG for *              documents, informations and hardware. * *		Deutsche Mailbox Saar-Lor-Lux GmbH *		for sponsoring and testing fax *		capabilities with Diva Server cards. *		(dor@deutschemailbox.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  * */#define DRIVERNAME "Eicon active ISDN driver"#define DRIVERRELEASE "2.0"#define DRIVERPATCH ".15"#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#ifdef CONFIG_MCA#include <linux/mca.h>#endif /* CONFIG_MCA */#include "eicon.h"#include "../avmb1/capicmd.h"  /* this should be moved in a common place */#undef N_DATA#include "adapter.h"#include "uxio.h"#define INCLUDE_INLINE_FUNCSstatic eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains                                                     start of card-list   */static char *eicon_revision = "$Revision: 1.37 $";extern char *eicon_pci_revision;extern char *eicon_isa_revision;extern char *eicon_idi_revision;extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile,			unsigned int command, unsigned long arg);extern void eicon_pci_init_conf(eicon_card *card);void mod_inc_use_count(void);void mod_dec_use_count(void);extern char *file_check(void);#ifdef MODULE#define MOD_USE_COUNT (GET_USE_COUNT (&__this_module))#endif#define EICON_CTRL_VERSION 2 ulong DebugVar;spinlock_t eicon_lock;DESCRIPTOR idi_d[32];/* Parameters to be set by insmod */#ifdef CONFIG_ISDN_DRV_EICON_ISAstatic int   membase      = -1;static int   irq          = -1;#endifstatic char *id           = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";MODULE_DESCRIPTION(             "Driver for Eicon active ISDN cards");MODULE_AUTHOR(                  "Armin Schindler");MODULE_SUPPORTED_DEVICE(        "ISDN subsystem");MODULE_PARM_DESC(id,   		"ID-String of first card");MODULE_PARM(id,           	"s");#ifdef CONFIG_ISDN_DRV_EICON_ISAMODULE_PARM_DESC(membase,	"Base address of first ISA card");MODULE_PARM_DESC(irq,    	"IRQ of first card");MODULE_PARM(membase,    	"i");MODULE_PARM(irq,          	"i");#endifchar *eicon_ctype_name[] = {        "ISDN-S",        "ISDN-SX",        "ISDN-SCOM",        "ISDN-QUADRO",        "ISDN-S2M",        "DIVA Server BRI/PCI",        "DIVA Server 4BRI/PCI",        "DIVA Server 4BRI/PCI",        "DIVA Server PRI/PCI"};static char *eicon_getrev(const char *revision){	char *rev;	char *p;	if ((p = strchr(revision, ':'))) {		rev = p + 2;		p = strchr(rev, '$');		*--p = 0;	} else rev = "?.??";	return rev;}static eicon_chan *find_channel(eicon_card *card, int channel){	if ((channel >= 0) && (channel < card->nchannels))        	return &(card->bch[channel]);	eicon_log(card, 1, "eicon: Invalid channel %d\n", channel);	return NULL;}#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI/* * Find pcicard with given card number  */static inline eicon_card *eicon_findnpcicard(int driverid){        eicon_card *p = cards;        while (p) {                if ((p->regname[strlen(p->regname)-1] == (driverid + '0')) &&			(p->bus == EICON_BUS_PCI))                        return p;                p = p->next;        }        return (eicon_card *) 0;}#endif#endif /* CONFIG_PCI */static voideicon_rcv_dispatch(struct eicon_card *card){	switch (card->bus) {		case EICON_BUS_ISA:		case EICON_BUS_MCA:		case EICON_BUS_PCI:			eicon_io_rcv_dispatch(card);			break;		default:			eicon_log(card, 1,			       "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);	}}static voideicon_ack_dispatch(struct eicon_card *card){	switch (card->bus) {		case EICON_BUS_ISA:		case EICON_BUS_MCA:		case EICON_BUS_PCI:			eicon_io_ack_dispatch(card);			break;		default:			eicon_log(card, 1,		       		"eicon_ack_dispatch: Illegal bustype %d\n", card->bus);	}}static voideicon_transmit(struct eicon_card *card){	switch (card->bus) {		case EICON_BUS_ISA:		case EICON_BUS_MCA:		case EICON_BUS_PCI:			eicon_io_transmit(card);			break;		default:			eicon_log(card, 1,			       "eicon_transmit: Illegal bustype %d\n", card->bus);	}}static inteicon_command(eicon_card * card, isdn_ctrl * c){        ulong a;        eicon_chan *chan;	eicon_cdef cdef;#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI	dia_start_t dstart;        int idi_length = 0;#endif#endif	isdn_ctrl cmd;	int ret = 0;	unsigned long flags; 	eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n",		c->command, c->arg, (ulong) *c->parm.num);        switch (c->command) {		case ISDN_CMD_IOCTL:			memcpy(&a, c->parm.num, sizeof(ulong));			switch (c->arg) {				case EICON_IOCTL_GETVER:					return(EICON_CTRL_VERSION);				case EICON_IOCTL_GETTYPE:					if (card->bus == EICON_BUS_PCI) {						copy_to_user((char *)a, &card->hwif.pci.master, sizeof(int));					}					return(card->type);				case EICON_IOCTL_GETMMIO:					switch (card->bus) {						case EICON_BUS_ISA:						case EICON_BUS_MCA:							return (int)card->hwif.isa.shmem;						default:							eicon_log(card, 1,							       "eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}#ifdef CONFIG_ISDN_DRV_EICON_ISA				case EICON_IOCTL_SETMMIO:					if (card->flags & EICON_FLAGS_LOADED)						return -EBUSY;					switch (card->bus) {						case EICON_BUS_ISA:							if (eicon_isa_find_card(a,								card->hwif.isa.irq,								card->regname) < 0)								return -EFAULT;							card->hwif.isa.shmem = (eicon_isa_shmem *)a;							return 0;						case EICON_BUS_MCA:#if CONFIG_MCA							if (eicon_mca_find_card(								0, a,								card->hwif.isa.irq,								card->regname) < 0)								return -EFAULT;							card->hwif.isa.shmem = (eicon_isa_shmem *)a;							return 0;#endif /* CONFIG_MCA */						default:							eicon_log(card, 1,						      		"eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}					#endif				case EICON_IOCTL_GETIRQ:					switch (card->bus) {						case EICON_BUS_ISA:						case EICON_BUS_MCA:							return card->hwif.isa.irq;						default:							eicon_log(card, 1,							       "eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}				case EICON_IOCTL_SETIRQ:					if (card->flags & EICON_FLAGS_LOADED)						return -EBUSY;					if ((a < 2) || (a > 15))						return -EFAULT;					switch (card->bus) {						case EICON_BUS_ISA:						case EICON_BUS_MCA:							card->hwif.isa.irq = a;							return 0;						default:							eicon_log(card, 1,						      		"eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}					#ifdef CONFIG_ISDN_DRV_EICON_ISA				case EICON_IOCTL_LOADBOOT:					if (card->flags & EICON_FLAGS_RUNNING)						return -EBUSY;  					switch (card->bus) {						case EICON_BUS_ISA:						case EICON_BUS_MCA:							ret = eicon_isa_bootload(								&(card->hwif.isa),								&(((eicon_codebuf *)a)->isa));							break;						default:							eicon_log(card, 1,							       "eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}					return ret;#endif#ifdef CONFIG_ISDN_DRV_EICON_ISA				case EICON_IOCTL_LOADISA:					if (card->flags & EICON_FLAGS_RUNNING)						return -EBUSY;  					switch (card->bus) {						case EICON_BUS_ISA:						case EICON_BUS_MCA:							ret = eicon_isa_load(								&(card->hwif.isa),								&(((eicon_codebuf *)a)->isa));							if (!ret) {                                                                card->flags |= EICON_FLAGS_LOADED;                                                                card->flags |= EICON_FLAGS_RUNNING;								if (card->hwif.isa.channels > 1) {									cmd.command = ISDN_STAT_ADDCH;									cmd.driver = card->myid;									cmd.arg = card->hwif.isa.channels - 1;									card->interface.statcallb(&cmd);								}								cmd.command = ISDN_STAT_RUN;    								cmd.driver = card->myid;        								cmd.arg = 0;                    								card->interface.statcallb(&cmd);							}							break;						default:							eicon_log(card, 1,							       "eicon: Illegal BUS type %d\n",							       card->bus);							ret = -ENODEV;					}					return ret;#endif				case EICON_IOCTL_MANIF:					if (!card->flags & EICON_FLAGS_RUNNING)						return -ENODEV;					if (!card->d)						return -ENODEV;					if (!card->d->features & DI_MANAGE)						return -ENODEV;					ret = eicon_idi_manage(						card, 						(eicon_manifbuf *)a);					return ret;				case EICON_IOCTL_GETXLOG:					return -ENODEV;				case EICON_IOCTL_ADDCARD:					if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef))))						return -EFAULT;					if (!(eicon_addcard(0, cdef.membase, cdef.irq, cdef.id, 0)))						return -EIO;					return 0;				case EICON_IOCTL_DEBUGVAR:					DebugVar = a;					eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar);					return 0;#ifdef MODULE				case EICON_IOCTL_FREEIT:					while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT;					mod_inc_use_count();					return 0;#endif				case EICON_IOCTL_LOADPCI:					eicon_log(card, 1, "Eicon: Wrong version of load-utility,\n");					eicon_log(card, 1, "Eicon: re-compile eiconctrl !\n");					eicon_log(card, 1, "Eicon: Maybe update of utility is necessary !\n");					return -EINVAL;				default:	#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI					if (c->arg < EICON_IOCTL_DIA_OFFSET)						return -EINVAL;					if (copy_from_user(&dstart, (char *)a, sizeof(dstart)))						return -1;					if (!(card = eicon_findnpcicard(dstart.card_id)))						return -EINVAL;					ret = do_ioctl(NULL, NULL,						c->arg - EICON_IOCTL_DIA_OFFSET,						(unsigned long) a);					if (((c->arg - EICON_IOCTL_DIA_OFFSET)==DIA_IOCTL_START) && (!ret)) {						if (card->type != EICON_CTYPE_MAESTRAQ) {							DIVA_DIDD_Read(idi_d, sizeof(idi_d));                                                        for(idi_length = 0; idi_length < 32; idi_length++) {                                                          if (idi_d[idi_length].type == 0) break;                                                        }                                                        if ((idi_length < 1) || (idi_length >= 32)) {					                  eicon_log(card, 1, "eicon: invalid idi table length.\n");                                                          break;                                                        }							card->d = &idi_d[idi_length - 1];							card->flags |= EICON_FLAGS_LOADED;							card->flags |= EICON_FLAGS_RUNNING;							eicon_pci_init_conf(card);							if (card->d->channels > 1) {								cmd.command = ISDN_STAT_ADDCH;								cmd.driver = card->myid;								cmd.arg = card->d->channels - 1;								card->interface.statcallb(&cmd);							}							cmd.command = ISDN_STAT_RUN;    							cmd.driver = card->myid;        							cmd.arg = 0;                    							card->interface.statcallb(&cmd);							eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x)\n",								(card->type == EICON_CTYPE_MAESTRA) ? "BRI" : "PRI",								card->d->channels, card->d->features);						} else {							int i;							DIVA_DIDD_Read(idi_d, sizeof(idi_d));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -