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

📄 kcapi.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int i;	if (!VALID_APPLID(applid) || APPL(applid)->releasing)		return CAPI_ILLAPPNR;	APPL(applid)->releasing++;	skb_queue_purge(&APPL(applid)->recv_queue);	for (i = 0; i < CAPI_MAXCONTR; i++) {		if (cards[i].cardstate != CARD_RUNNING)			continue;		APPL(applid)->releasing++;		cards[i].driver->release_appl(&cards[i], applid);	}	APPL(applid)->releasing--;	if (APPL(applid)->releasing <= 0) {	        APPL(applid)->signal = 0;		APPL_MARK_FREE(applid);		printk(KERN_INFO "kcapi: appl %d down\n", applid);	}	return CAPI_NOERROR;}static __u16 capi_put_message(__u16 applid, struct sk_buff *skb){	struct capi_ncci *np;	__u32 contr;	int showctl = 0;	__u8 cmd, subcmd;	if (ncards == 0)		return CAPI_REGNOTINSTALLED;	if (!VALID_APPLID(applid))		return CAPI_ILLAPPNR;	if (skb->len < 12	    || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))	    || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;	contr = CAPIMSG_CONTROLLER(skb->data);	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) {		contr = 1;	        if (CARD(contr)->cardstate != CARD_RUNNING) 			return CAPI_REGNOTINSTALLED;	}	if (CARD(contr)->blocked)		return CAPI_SENDQUEUEFULL;	cmd = CAPIMSG_COMMAND(skb->data);        subcmd = CAPIMSG_SUBCOMMAND(skb->data);	if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {	    	if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0	            && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)			return CAPI_SENDQUEUEFULL;		CARD(contr)->nsentdatapkt++;		APPL(applid)->nsentdatapkt++;	        if (CARD(contr)->traceflag > 2) showctl |= 2;	} else {		CARD(contr)->nsentctlpkt++;		APPL(applid)->nsentctlpkt++;	        if (CARD(contr)->traceflag) showctl |= 2;	}	showctl |= (CARD(contr)->traceflag & 1);	if (showctl & 2) {		if (showctl & 1) {			printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n",			       (unsigned long) contr,			       CAPIMSG_APPID(skb->data),			       capi_cmd2str(cmd, subcmd),			       CAPIMSG_LEN(skb->data));		} else {			printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n",					(unsigned long) contr,					capi_message2str(skb->data));		}	}	CARD(contr)->driver->send_message(CARD(contr), skb);	return CAPI_NOERROR;}static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp){	struct sk_buff *skb;	if (!VALID_APPLID(applid))		return CAPI_ILLAPPNR;	if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0)		return CAPI_RECEIVEQUEUEEMPTY;	*msgp = skb;	return CAPI_NOERROR;}static __u16 capi_set_signal(__u16 applid,			     void (*signal) (__u16 applid, void *param),			     void *param){	if (!VALID_APPLID(applid))		return CAPI_ILLAPPNR;	APPL(applid)->signal = signal;	APPL(applid)->param = param;	return CAPI_NOERROR;}static __u16 capi_get_manufacturer(__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN]){	if (contr == 0) {		strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return CAPI_REGNOTINSTALLED;	strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN);	return CAPI_NOERROR;}static __u16 capi_get_version(__u32 contr, struct capi_version *verp){	if (contr == 0) {		*verp = driver_version;		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return CAPI_REGNOTINSTALLED;	memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version));	return CAPI_NOERROR;}static __u16 capi_get_serial(__u32 contr, __u8 serial[CAPI_SERIAL_LEN]){	if (contr == 0) {		strncpy(serial, driver_serial, CAPI_SERIAL_LEN);		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return CAPI_REGNOTINSTALLED;	strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN);	return CAPI_NOERROR;}static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp){	if (contr == 0) {		profp->ncontroller = ncards;		return CAPI_NOERROR;	}	if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) 		return CAPI_REGNOTINSTALLED;	memcpy((void *) profp, &CARD(contr)->profile,			sizeof(struct capi_profile));	return CAPI_NOERROR;}static struct capi_driver *find_driver(char *name){	struct capi_driver *dp;	spin_lock(&drivers_lock);	for (dp = drivers; dp; dp = dp->next)		if (strcmp(dp->name, name) == 0)			break;	spin_unlock(&drivers_lock);	return dp;}#ifdef CONFIG_AVMB1_COMPATstatic int old_capi_manufacturer(unsigned int cmd, void *data){	avmb1_loadandconfigdef ldef;	avmb1_extcarddef cdef;	avmb1_resetdef rdef;	avmb1_getdef gdef;	struct capi_driver *driver;	struct capi_ctr *card;	capicardparams cparams;	capiloaddata ldata;	int retval;	switch (cmd) {	case AVMB1_ADDCARD:	case AVMB1_ADDCARD_WITH_TYPE:		if (cmd == AVMB1_ADDCARD) {		   if ((retval = copy_from_user((void *) &cdef, data,					    sizeof(avmb1_carddef))))			   return retval;		   cdef.cardtype = AVM_CARDTYPE_B1;		} else {		   if ((retval = copy_from_user((void *) &cdef, data,					    sizeof(avmb1_extcarddef))))			   return retval;		}		cparams.port = cdef.port;		cparams.irq = cdef.irq;		cparams.cardnr = cdef.cardnr;                switch (cdef.cardtype) {			case AVM_CARDTYPE_B1:				driver = find_driver("b1isa");				break;			case AVM_CARDTYPE_T1:				driver = find_driver("t1isa");				break;			default:				driver = 0;				break;		}		if (!driver) {			printk(KERN_ERR "kcapi: driver not loaded.\n");			return -EIO;		}		if (!driver->add_card) {			printk(KERN_ERR "kcapi: driver has no add card function.\n");			return -EIO;		}		return driver->add_card(driver, &cparams);	case AVMB1_LOAD:	case AVMB1_LOAD_AND_CONFIG:		if (cmd == AVMB1_LOAD) {			if ((retval = copy_from_user((void *) &ldef, data,						sizeof(avmb1_loaddef))))				return retval;			ldef.t4config.len = 0;			ldef.t4config.data = 0;		} else {			if ((retval = copy_from_user((void *) &ldef, data,					    	sizeof(avmb1_loadandconfigdef))))				return retval;		}		if (!VALID_CARD(ldef.contr))			return -ESRCH;		card = CARD(ldef.contr);		if (card->cardstate == CARD_FREE)			return -ESRCH;		if (card->driver->load_firmware == 0) {			printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);			return -ESRCH;		}		if (ldef.t4file.len <= 0) {			printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);			return -EINVAL;		}		if (ldef.t4file.data == 0) {			printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");			return -EINVAL;		}		ldata.firmware.user = 1;		ldata.firmware.data = ldef.t4file.data;		ldata.firmware.len = ldef.t4file.len;		ldata.configuration.user = 1;		ldata.configuration.data = ldef.t4config.data;		ldata.configuration.len = ldef.t4config.len;		if (card->cardstate != CARD_DETECTED) {			printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);			return -EBUSY;		}		card->cardstate = CARD_LOADING;		retval = card->driver->load_firmware(card, &ldata);		if (retval) {			card->cardstate = CARD_DETECTED;			return retval;		}		while (card->cardstate != CARD_RUNNING) {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(HZ/10);	/* 0.1 sec */			if (signal_pending(current))				return -EINTR;		}		return 0;	case AVMB1_RESETCARD:		if ((retval = copy_from_user((void *) &rdef, data,					 sizeof(avmb1_resetdef))))			return retval;		if (!VALID_CARD(rdef.contr))			return -ESRCH;		card = CARD(rdef.contr);		if (card->cardstate == CARD_FREE)			return -ESRCH;		if (card->cardstate == CARD_DETECTED)			return 0;		card->driver->reset_ctr(card);		while (card->cardstate > CARD_DETECTED) {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(HZ/10);	/* 0.1 sec */			if (signal_pending(current))				return -EINTR;		}		return 0;	case AVMB1_GET_CARDINFO:		if ((retval = copy_from_user((void *) &gdef, data,					 sizeof(avmb1_getdef))))			return retval;		if (!VALID_CARD(gdef.contr))			return -ESRCH;		card = CARD(gdef.contr);		if (card->cardstate == CARD_FREE)			return -ESRCH;		gdef.cardstate = card->cardstate;		if (card->driver == find_driver("t1isa"))			gdef.cardtype = AVM_CARDTYPE_T1;		else gdef.cardtype = AVM_CARDTYPE_B1;		if ((retval = copy_to_user(data, (void *) &gdef,					 sizeof(avmb1_getdef))))			return retval;		return 0;	case AVMB1_REMOVECARD:		if ((retval = copy_from_user((void *) &rdef, data,					 sizeof(avmb1_resetdef))))			return retval;		if (!VALID_CARD(rdef.contr))			return -ESRCH;		card = CARD(rdef.contr);		if (card->cardstate == CARD_FREE)			return -ESRCH;		if (card->cardstate != CARD_DETECTED)			return -EBUSY;		card->driver->remove_ctr(card);		while (card->cardstate != CARD_FREE) {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(HZ/10);	/* 0.1 sec */			if (signal_pending(current))				return -EINTR;		}		return 0;	}	return -EINVAL;}#endifstatic int capi_manufacturer(unsigned int cmd, void *data){        struct capi_ctr *card;	int retval;	switch (cmd) {#ifdef CONFIG_AVMB1_COMPAT	case AVMB1_ADDCARD:	case AVMB1_ADDCARD_WITH_TYPE:	case AVMB1_LOAD:	case AVMB1_LOAD_AND_CONFIG:	case AVMB1_RESETCARD:	case AVMB1_GET_CARDINFO:	case AVMB1_REMOVECARD:		return old_capi_manufacturer(cmd, data);#endif	case KCAPI_CMD_TRACE:	{		kcapi_flagdef fdef;		if ((retval = copy_from_user((void *) &fdef, data,					 sizeof(kcapi_flagdef))))			return retval;		if (!VALID_CARD(fdef.contr))			return -ESRCH;		card = CARD(fdef.contr);		if (card->cardstate == CARD_FREE)			return -ESRCH;		card->traceflag = fdef.flag;		printk(KERN_INFO "kcapi: contr %d set trace=%d\n",			card->cnr, card->traceflag);		return 0;	}	case KCAPI_CMD_ADDCARD:	{		struct capi_driver *driver;		capicardparams cparams;		kcapi_carddef cdef;		if ((retval = copy_from_user((void *) &cdef, data,							sizeof(cdef))))			return retval;		cparams.port = cdef.port;		cparams.irq = cdef.irq;		cparams.membase = cdef.membase;		cparams.cardnr = cdef.cardnr;		cparams.cardtype = 0;		cdef.driver[sizeof(cdef.driver)-1] = 0;		if ((driver = find_driver(cdef.driver)) == 0) {			printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",					cdef.driver);			return -ESRCH;		}		if (!driver->add_card) {			printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);			return -EIO;		}		return driver->add_card(driver, &cparams);	}	default:		printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",					cmd);		break;	}	return -EINVAL;}struct capi_interface avmb1_interface ={	capi_isinstalled,	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;	MOD_INC_USE_COUNT;	spin_lock(&capi_users_lock);	for (p = capi_users; p; p = p->next) {		if (p == userp) {			spin_unlock(&capi_users_lock);			printk(KERN_ERR "kcapi: double attach from %s\n",			       userp->name);			MOD_DEC_USE_COUNT;			return 0;		}	}	userp->next = capi_users;	capi_users = userp;	spin_unlock(&capi_users_lock);	printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);	return &avmb1_interface;}int detach_capi_interface(struct capi_interface_user *userp){	struct capi_interface_user **pp;	spin_lock(&capi_users_lock);	for (pp = &capi_users; *pp; pp = &(*pp)->next) {		if (*pp == userp) {			*pp = userp->next;			spin_unlock(&capi_users_lock);			userp->next = 0;			printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);			MOD_DEC_USE_COUNT;			return 0;		}	}	spin_unlock(&capi_users_lock);	printk(KERN_ERR "kcapi: double detach from %s\n", userp->name);	return -1;}/* ------------------------------------------------------------- *//* -------- Init & Cleanup ------------------------------------- *//* ------------------------------------------------------------- */EXPORT_SYMBOL(attach_capi_interface);EXPORT_SYMBOL(detach_capi_interface);EXPORT_SYMBOL(attach_capi_driver);EXPORT_SYMBOL(detach_capi_driver);/* * init / exit functions */static int __init kcapi_init(void){	char *p;	char rev[32];	MOD_INC_USE_COUNT;	skb_queue_head_init(&recv_queue);	tq_state_notify.routine = notify_handler;	tq_state_notify.data = 0;	tq_recv_notify.routine = recv_handler;	tq_recv_notify.data = 0;        proc_capi_init();	if ((p = strchr(revision, ':')) != 0 && p[1]) {		strncpy(rev, p + 2, sizeof(rev));		rev[sizeof(rev)-1] = 0;		if ((p = strchr(rev, '$')) != 0 && p > rev)		   *(p-1) = 0;	} else		strcpy(rev, "1.0");#ifdef MODULE        printk(KERN_NOTICE "CAPI-driver Rev %s: loaded\n", rev);#else	printk(KERN_NOTICE "CAPI-driver Rev %s: started\n", rev);#endif	MOD_DEC_USE_COUNT;	return 0;}static void __exit kcapi_exit(void){	char rev[10];	char *p;	if ((p = strchr(revision, ':'))) {		strcpy(rev, p + 1);		p = strchr(rev, '$');		*p = 0;	} else {		strcpy(rev, "1.0");	}        proc_capi_exit();	printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);}module_init(kcapi_init);module_exit(kcapi_exit);

⌨️ 快捷键说明

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