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

📄 b1capi.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static __u16 capi_get_version(__u16 contr, struct capi_version *verp){	if (contr == 0) {		*verp = driver_version;		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return 0x2002;	memcpy((void *) verp, &CARD(contr)->cversion,	       sizeof(capi_version));	return CAPI_NOERROR;}static __u16 capi_get_serial(__u16 contr, __u8 serial[CAPI_SERIAL_LEN]){	if (contr == 0) {		strncpy(serial, driver_serial, 8);		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return 0x2002;	memcpy((void *) serial, CARD(contr)->version[VER_SERIAL],	       CAPI_SERIAL_LEN);	serial[CAPI_SERIAL_LEN - 1] = 0;	return CAPI_NOERROR;}static __u16 capi_get_profile(__u16 contr, struct capi_profile *profp){	if (contr == 0) {		profp->ncontroller = ncards;		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return 0x2002;	memcpy((void *) profp, CARD(contr)->version[VER_PROFILE],	       sizeof(struct capi_profile));	return CAPI_NOERROR;}static int capi_manufacturer(unsigned int cmd, void *data){	unsigned long flags;	avmb1_loadandconfigdef ldef;	avmb1_extcarddef cdef;	avmb1_resetdef rdef;	avmb1_getdef gdef;	avmb1_card *card;	int rc;	switch (cmd) {	case AVMB1_ADDCARD:	case AVMB1_ADDCARD_WITH_TYPE:		if (cmd == AVMB1_ADDCARD) {		   if ((rc = copy_from_user((void *) &cdef, data,					    sizeof(avmb1_carddef))))			   return rc;		   cdef.cardtype = AVM_CARDTYPE_B1;		} else {		   if ((rc = copy_from_user((void *) &cdef, data,					    sizeof(avmb1_extcarddef))))			   return rc;		}		if ((rc = avmb1_probecard(cdef.port, cdef.irq, cdef.cardtype)) != 0)			return rc;                if (cdef.cardtype == AVM_CARDTYPE_T1) {			int i;		        for (i=0; i < CAPI_MAXCONTR; i++) {	        	    	if (   cards[i].cardstate != CARD_FREE				    && cards[i].cardtype == AVM_CARDTYPE_T1				    && cards[i].cardnr == cdef.cardnr) {					printk(KERN_ERR						"b1capi: T1-HEMA-card-%d already at 0x%x\n",						cdef.cardnr, cards[i].port);					return -EBUSY;				}                        }			rc = T1_detectandinit(cdef.port,cdef.irq,cdef.cardnr);			if (rc) {			        printk(KERN_NOTICE "b1capi: NO T1-HEMA-card-%d at 0x%x (%d)\n",					  cdef.cardnr, cdef.port, rc);				return -EIO;                        }			printk(KERN_NOTICE "b1capi: T1-HEMA-card-%d at 0x%x\n",				  cdef.cardnr, cdef.port);		}		rc = avmb1_addcard(cdef.port, cdef.irq, cdef.cardtype);		if (rc < 0)			return rc;		/* don't want to change interface t		   addcard/probecard/registercard */                if (cdef.cardtype == AVM_CARDTYPE_T1) {			int i;		        for (i=0; i < CAPI_MAXCONTR; i++) {	        	    	if (cards[i].cnr == rc) {					cards[i].cardnr = cdef.cardnr;					break;				}                        }		}		return rc;	case AVMB1_LOAD:	case AVMB1_LOAD_AND_CONFIG:		if (cmd == AVMB1_LOAD) {			if ((rc = copy_from_user((void *) &ldef, data,						sizeof(avmb1_loaddef))))				return rc;			ldef.t4config.len = 0;			ldef.t4config.data = 0;		} else {			if ((rc = copy_from_user((void *) &ldef, data,					    	sizeof(avmb1_loadandconfigdef))))				return rc;		}		if (!VALID_CARD(ldef.contr))			return -ESRCH;		if (ldef.t4file.len <= 0) {			printk(KERN_DEBUG "b1capi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);			return -EINVAL;		}		card = CARD(ldef.contr);		save_flags(flags);		cli();		if (card->cardstate != CARD_DETECTED) {			restore_flags(flags);			if (loaddebug)				printk(KERN_DEBUG "b1capi: load: contr=%d not in detect state\n", ldef.contr);			return -EBUSY;		}		card->cardstate = CARD_LOADING;		restore_flags(flags);		if (loaddebug) {			printk(KERN_DEBUG "b1capi: load: reseting contr %d\n",				ldef.contr);		}		B1_reset(card->port);		if (loaddebug) {			printk(KERN_DEBUG "b1capi: loading contr %d\n",				ldef.contr);		}		if ((rc = B1_load_t4file(card->port, &ldef.t4file))) {			B1_reset(card->port);			printk(KERN_ERR "b1capi: failed to load t4file!!\n");			card->cardstate = CARD_DETECTED;			return rc;		}		B1_disable_irq(card->port);		if (ldef.t4config.len > 0) { /* load config */		        if (loaddebug) {				printk(KERN_DEBUG "b1capi: loading config to contr %d\n",				   			ldef.contr);		   	}			if ((rc = B1_load_config(card->port, &ldef.t4config))) {				B1_reset(card->port);				printk(KERN_ERR "b1capi: failed to load config!!\n");				card->cardstate = CARD_DETECTED;				return rc;			}		}		if (loaddebug) {			printk(KERN_DEBUG "b1capi: load: ready contr %d: checking\n",				ldef.contr);		}		if (!B1_loaded(card->port)) {			card->cardstate = CARD_DETECTED;			printk(KERN_ERR "b1capi: failed to load t4file.\n");			return -EIO;		}		/*		 * enable interrupt		 */		card->cardstate = CARD_INITSTATE;		save_flags(flags);		cli();		B1_setinterrupt(card->port, card->irq, card->cardtype);		restore_flags(flags);		if (loaddebug) {			printk(KERN_DEBUG "b1capi: load: irq enabled contr %d\n",				ldef.contr);		}		/*		 * init card		 */                if (card->cardtype == AVM_CARDTYPE_T1)		   B1_send_init(card->port, AVM_NAPPS,					    AVM_NNCCI_PER_CHANNEL*30,				   	    card->cnr - 1);		else		   B1_send_init(card->port, AVM_NAPPS,					    AVM_NNCCI_PER_CHANNEL*2,				   	    card->cnr - 1);		if (loaddebug) {			printk(KERN_DEBUG "b1capi: load: waiting for init reply contr %d\n",				ldef.contr);		}		while (card->cardstate != CARD_RUNNING) {			current->timeout = jiffies + HZ / 10;	/* 0.1 sec */			current->state = TASK_INTERRUPTIBLE;			schedule();			if (current->signal & ~current->blocked)				return -EINTR;		}		return 0;	case AVMB1_RESETCARD:		if ((rc = copy_from_user((void *) &rdef, data,					 sizeof(avmb1_resetdef))))			return rc;		return avmb1_resetcard(rdef.contr);	case AVMB1_GET_CARDINFO:		if ((rc = copy_from_user((void *) &gdef, data,					 sizeof(avmb1_getdef))))			return rc;		if (!VALID_CARD(gdef.contr))			return -ESRCH;		card = CARD(gdef.contr);		gdef.cardstate = card->cardstate;		gdef.cardtype = card->cardtype;		if ((rc = copy_to_user(data, (void *) &gdef,					 sizeof(avmb1_getdef))))			return rc;		return 0;	case AVMB1_REMOVECARD:		if ((rc = copy_from_user((void *) &rdef, data,					 sizeof(avmb1_resetdef))))			return rc;		if (!VALID_CARD(rdef.contr))			return -ESRCH;		card = CARD(rdef.contr);		if (card->cardstate != CARD_DETECTED)			return -EBUSY;		return avmb1_unregistercard(rdef.contr, 1);	}	return -EINVAL;}struct capi_interface avmb1_interface ={	capi_installed,	capi_register,	capi_release,	capi_put_message,	capi_get_message,	capi_set_signal,	capi_get_manufacturer,	capi_get_version,	capi_get_serial,	capi_get_profile,	capi_manufacturer};/* ------------------------------------------------------------- *//* -------- Exported Functions --------------------------------- *//* ------------------------------------------------------------- */struct capi_interface *attach_capi_interface(struct capi_interface_user *userp){	struct capi_interface_user *p;	for (p = capi_users; p; p = p->next) {		if (p == userp) {			printk(KERN_ERR "b1capi: double attach from %s\n",			       userp->name);			return 0;		}	}	userp->next = capi_users;	capi_users = userp;	MOD_INC_USE_COUNT;	printk(KERN_NOTICE "b1capi: %s attached\n", userp->name);	return &avmb1_interface;}int detach_capi_interface(struct capi_interface_user *userp){	struct capi_interface_user **pp;	for (pp = &capi_users; *pp; pp = &(*pp)->next) {		if (*pp == userp) {			*pp = userp->next;			userp->next = 0;			MOD_DEC_USE_COUNT;			printk(KERN_NOTICE "b1capi: %s detached\n", userp->name);			return 0;		}	}	printk(KERN_ERR "b1capi: double detach from %s\n", userp->name);	return -1;}/* ------------------------------------------------------------- *//* -------- Init & Cleanup ------------------------------------- *//* ------------------------------------------------------------- */#ifdef HAS_NEW_SYMTABEXPORT_SYMBOL(attach_capi_interface);EXPORT_SYMBOL(detach_capi_interface);EXPORT_SYMBOL(avmb1_addcard);EXPORT_SYMBOL(avmb1_probecard);EXPORT_SYMBOL(avmb1_registercard);EXPORT_SYMBOL(avmb1_unregistercard);EXPORT_SYMBOL(avmb1_resetcard);EXPORT_SYMBOL(avmb1_detectcard);#elsestatic struct symbol_table capidev_syms ={#include <linux/symtab_begin.h>	X(attach_capi_interface),	X(detach_capi_interface),	X(avmb1_addcard),	X(avmb1_probecard),	X(avmb1_registercard),	X(avmb1_unregistercard),	X(avmb1_resetcard),	X(avmb1_detectcard),#include <linux/symtab_end.h>};#endif/* * init / exit functions */#ifdef MODULE#define avmb1_init init_module#endifint avmb1_init(void){	char *p;	char rev[10];#ifndef HAS_NEW_SYMTAB	/* No symbols to export, hide all symbols */	register_symtab(&capidev_syms);#endif	skb_queue_head_init(&recv_queue);	/* init_bh(CAPI_BH, do_capi_bh); */	tq_state_notify.routine = notify_handler;	tq_state_notify.data = 0;	tq_recv_notify.routine = recv_handler;	tq_recv_notify.data = 0;	if ((p = strchr(revision, ':'))) {		strcpy(rev, p + 1);		p = strchr(rev, '$');		*p = 0;	} else		strcpy(rev, " ??? ");#ifdef MODULE        printk(KERN_NOTICE "AVM-B1-CAPI-driver Rev%s: loaded\n", rev);#else	printk(KERN_NOTICE "AVM-B1-CAPI-driver Rev%s: started\n", rev);#endif	return 0;}#ifdef MODULEvoid cleanup_module(void){	char rev[10];	char *p;	int i;	if ((p = strchr(revision, ':'))) {		strcpy(rev, p + 1);		p = strchr(rev, '$');		*p = 0;	} else {		strcpy(rev, " ??? ");	}	for (i = 0; i < CAPI_MAXCONTR; i++) {		if (cards[i].cardstate != CARD_FREE) {			/*			 * disable card			 */			B1_disable_irq(cards[i].port);			avmb1_resetcard(i+1);			/*			 * free kernel resources			 */			avmb1_unregistercard(i+1, 1);		}	}	schedule(); /* execute queued tasks .... */	printk(KERN_NOTICE "AVM-B1-CAPI-driver Rev%s: unloaded\n", rev);}#endif

⌨️ 快捷键说明

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