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

📄 hycapi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
				memcpy(msghead, skb->data, 22);				memcpy(skb->data + _len2, msghead, 22);				skb_pull(skb, _len2);				CAPIMSG_SETLEN(skb->data, 22);				retval = capilib_data_b3_req(&cinfo->ncci_head,							     CAPIMSG_APPID(skb->data),							     CAPIMSG_NCCI(skb->data),							     CAPIMSG_MSGID(skb->data));			}			break;		case CAPI_LISTEN_REQ:			if(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1])			{				kfree_skb(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1]);				hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = NULL;			}			if (!(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = skb_copy(skb, GFP_ATOMIC))) 			{				printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n");			} 			break;		default:			break;	} out:	if (retval == CAPI_NOERROR)		hycapi_sendmsg_internal(ctrl, skb);	else 		dev_kfree_skb_any(skb);	return retval;}/*********************************************************************hycapi_read_procInformations provided in the /proc/capi-entries.*********************************************************************/static int hycapi_read_proc(char *page, char **start, off_t off,			    int count, int *eof, struct capi_ctr *ctrl){	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);	hysdn_card *card = cinfo->card;	int len = 0;	char *s;#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_read_proc\n");    #endif	len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname);	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->iobase);	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);    	switch (card->brdtype) {		case BD_PCCARD:  s = "HYSDN Hycard"; break;		case BD_ERGO: s = "HYSDN Ergo2"; break;		case BD_METRO: s = "HYSDN Metro4"; break;		case BD_CHAMP2: s = "HYSDN Champ2";	break;		case BD_PLEXUS: s = "HYSDN Plexus30"; break;		default: s = "???"; break;	}	len += sprintf(page+len, "%-16s %s\n", "type", s);	if ((s = cinfo->version[VER_DRIVER]) != 0)		len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);	if ((s = cinfo->version[VER_CARDTYPE]) != 0)		len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);	if ((s = cinfo->version[VER_SERIAL]) != 0)		len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);    	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);    	if (off+count >= len)		*eof = 1;	if (len < off)		return 0;	*start = page + off;	return ((count < len-off) ? count : len-off);}/**************************************************************hycapi_load_firmwareThis does NOT load any firmware, but the callback somehow is neededon capi-interface registration.**************************************************************/static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data){#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_load_firmware\n");    #endif	return 0;}static char *hycapi_procinfo(struct capi_ctr *ctrl){	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_proc_info\n");    #endif	if (!cinfo)		return "";	sprintf(cinfo->infobuf, "%s %s 0x%x %d %s",		cinfo->cardname[0] ? cinfo->cardname : "-",		cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",		cinfo->card ? cinfo->card->iobase : 0x0,		cinfo->card ? cinfo->card->irq : 0,		hycapi_revision		);	return cinfo->infobuf;}/******************************************************************hycapi_rx_capipktReceive a capi-message.All B3_DATA_IND are converted to 64K-extension compatible format.New nccis are created if necessary.*******************************************************************/voidhycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len){	struct sk_buff *skb;	hycapictrl_info *cinfo = card->hyctrlinfo;	struct capi_ctr *ctrl;	__u16 ApplId;	__u16 MsgLen, info;	__u16 len2, CapiCmd;	__u32 CP64[2] = {0,0};#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_rx_capipkt\n");    #endif	if(!cinfo) {		return;	}	ctrl = &cinfo->capi_ctrl;	if(len < CAPI_MSG_BASELEN) {		printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, lenght %d!\n",		       card->myid, len);		return;	}		MsgLen = CAPIMSG_LEN(buf);	ApplId = CAPIMSG_APPID(buf);	CapiCmd = CAPIMSG_CMD(buf);		if((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {		len2 = len + (30 - MsgLen);		if (!(skb = alloc_skb(len2, GFP_ATOMIC))) {			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",			       card->myid);			return;		}		memcpy(skb_put(skb, MsgLen), buf, MsgLen);		memcpy(skb_put(skb, 2*sizeof(__u32)), CP64, 2* sizeof(__u32));		memcpy(skb_put(skb, len - MsgLen), buf + MsgLen,		       len - MsgLen);		CAPIMSG_SETLEN(skb->data, 30);	} else {		if (!(skb = alloc_skb(len, GFP_ATOMIC))) {			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",			       card->myid);			return;		}		memcpy(skb_put(skb, len), buf, len);	}	switch(CAPIMSG_CMD(skb->data)) 	{		case CAPI_CONNECT_B3_CONF:/* Check info-field for error-indication: */			info = CAPIMSG_U16(skb->data, 12);			switch(info)			{				case 0:					capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), 							 hycapi_applications[ApplId-1].rp.datablkcnt); 										break;				case 0x0001:					printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "					       "protocol. NCPI ignored.\n", card->myid);					break;				case 0x2001:					printk(KERN_ERR "HYSDN Card%d: Message not supported in"					       " current state\n", card->myid);					break;				case 0x2002:					printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid);					break;						case 0x2004:					printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);					break;								case 0x3008:					printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n", 					       card->myid);					break;					default:					printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n", 					       card->myid, info);					break;						}			break;		case CAPI_CONNECT_B3_IND:			capilib_new_ncci(&cinfo->ncci_head, ApplId, 					 CAPIMSG_NCCI(skb->data), 					 hycapi_applications[ApplId-1].rp.datablkcnt);			break;	        case CAPI_DATA_B3_CONF:			capilib_data_b3_conf(&cinfo->ncci_head, ApplId,					     CAPIMSG_NCCI(skb->data),					     CAPIMSG_MSGID(skb->data));			break;		default:			break;	}	capi_ctr_handle_message(ctrl, ApplId, skb);}/******************************************************************hycapi_tx_capiackInternally acknowledge a msg sent. This will remove the msg from theinternal queue.*******************************************************************/void hycapi_tx_capiack(hysdn_card * card){	hycapictrl_info *cinfo = card->hyctrlinfo;#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_tx_capiack\n");    #endif	if(!cinfo) {		return;	}	spin_lock_irq(&cinfo->lock);	kfree_skb(cinfo->skbs[cinfo->out_idx]);		/* free skb */	cinfo->skbs[cinfo->out_idx++] = NULL;	if (cinfo->out_idx >= HYSDN_MAX_CAPI_SKB)		cinfo->out_idx = 0;	/* wrap around */	if (cinfo->sk_count-- == HYSDN_MAX_CAPI_SKB)	/* dec usage count */		capi_ctr_resume_output(&cinfo->capi_ctrl);	spin_unlock_irq(&cinfo->lock);}/***************************************************************hycapi_tx_capiget(hysdn_card *card)This is called when polling for messages to SEND.****************************************************************/struct sk_buff *hycapi_tx_capiget(hysdn_card *card){	hycapictrl_info *cinfo = card->hyctrlinfo;	if(!cinfo) {		return (struct sk_buff *)NULL;	}	if (!cinfo->sk_count)		return (struct sk_buff *)NULL;	/* nothing available */	return (cinfo->skbs[cinfo->out_idx]);		/* next packet to send */}/**********************************************************int hycapi_init()attach the capi-driver to the kernel-capi.***********************************************************/int hycapi_init(void){	int i;	for(i=0;i<CAPI_MAXAPPL;i++) {		memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));	}	return(0);}/**************************************************************hycapi_cleanup(void)detach the capi-driver to the kernel-capi. Actually this shouldfree some more ressources. Do that later.**************************************************************/void hycapi_cleanup(void){}/********************************************************************hycapi_capi_create(hysdn_card *card)Attach the card with its capi-ctrl.*********************************************************************/static void hycapi_fill_profile(hysdn_card *card){	hycapictrl_info *cinfo = NULL;	struct capi_ctr *ctrl = NULL;	cinfo = card->hyctrlinfo;	if(!cinfo) return;	ctrl = &cinfo->capi_ctrl;	strcpy(ctrl->manu, "Hypercope");		ctrl->version.majorversion = 2;	ctrl->version.minorversion = 0;	ctrl->version.majormanuversion = 3;	ctrl->version.minormanuversion = 2;	ctrl->profile.ncontroller = card->myid;	ctrl->profile.nbchannel = card->bchans;	ctrl->profile.goptions = GLOBAL_OPTION_INTERNAL_CONTROLLER |		GLOBAL_OPTION_B_CHANNEL_OPERATION;	ctrl->profile.support1 =  B1_PROT_64KBIT_HDLC |		(card->faxchans ? B1_PROT_T30 : 0) |		B1_PROT_64KBIT_TRANSPARENT;	ctrl->profile.support2 = B2_PROT_ISO7776 |		(card->faxchans ? B2_PROT_T30 : 0) |		B2_PROT_TRANSPARENT;	ctrl->profile.support3 = B3_PROT_TRANSPARENT |		B3_PROT_T90NL |		(card->faxchans ? B3_PROT_T30 : 0) |		(card->faxchans ? B3_PROT_T30EXT : 0) |		B3_PROT_ISO8208;}	int hycapi_capi_create(hysdn_card *card){	hycapictrl_info *cinfo = NULL;	struct capi_ctr *ctrl = NULL;	int retval;#ifdef HYCAPI_PRINTFNAMES	printk(KERN_NOTICE "hycapi_capi_create\n");        #endif	if((hycapi_enable & (1 << card->myid)) == 0) {		return 1;	}	if (!card->hyctrlinfo) {		cinfo = (hycapictrl_info *) kmalloc(sizeof(hycapictrl_info), GFP_ATOMIC);		if (!cinfo) {			printk(KERN_WARNING "HYSDN: no memory for capi-ctrl.\n");			return -ENOMEM;		}		memset(cinfo, 0, sizeof(hycapictrl_info));		card->hyctrlinfo = cinfo;		cinfo->card = card;		spin_lock_init(&cinfo->lock);		INIT_LIST_HEAD(&cinfo->ncci_head);		switch (card->brdtype) {			case BD_PCCARD:  strcpy(cinfo->cardname,"HYSDN Hycard"); break;			case BD_ERGO: strcpy(cinfo->cardname,"HYSDN Ergo2"); break;			case BD_METRO: strcpy(cinfo->cardname,"HYSDN Metro4"); break;			case BD_CHAMP2: strcpy(cinfo->cardname,"HYSDN Champ2"); break;			case BD_PLEXUS: strcpy(cinfo->cardname,"HYSDN Plexus30"); break;			default: strcpy(cinfo->cardname,"HYSDN ???"); break;		}		ctrl = &cinfo->capi_ctrl;		ctrl->driver_name   = "hycapi";		ctrl->driverdata    = cinfo;		ctrl->register_appl = hycapi_register_appl;		ctrl->release_appl  = hycapi_release_appl;		ctrl->send_message  = hycapi_send_message;		ctrl->load_firmware = hycapi_load_firmware;		ctrl->reset_ctr     = hycapi_reset_ctr;		ctrl->procinfo      = hycapi_procinfo;		ctrl->ctr_read_proc = hycapi_read_proc;		strcpy(ctrl->name, cinfo->cardname);		ctrl->owner = THIS_MODULE;		retval = attach_capi_ctr(ctrl);		if (retval) {			printk(KERN_ERR "hycapi: attach controller failed.\n");			return -EBUSY;		}		/* fill in the blanks: */		hycapi_fill_profile(card);		capi_ctr_ready(ctrl);	} else {		/* resume output on stopped ctrl */		ctrl = &card->hyctrlinfo->capi_ctrl;		hycapi_fill_profile(card);		capi_ctr_ready(ctrl);		hycapi_restart_internal(ctrl); /*		ctrl->resume_output(ctrl); */	}	return 0;}

⌨️ 快捷键说明

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