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

📄 drv.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
			if ((len = capi_disc_req(*(ushort*)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)				pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len);			break;  		}		cbdata.data.setup.CalledPN = NULL;		cbdata.data.setup.CallingPN = NULL;		capi_decode_conn_ind(chan, skb, &cbdata);		cbdata.type = EV_NET_SETUP;		pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL);		if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN)) 			pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata);		else			pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);		kfree(cbdata.data.setup.CalledPN);		kfree(cbdata.data.setup.CallingPN);		break;    	case MSG_CONN_CONF:		/* 		 * We should be able to find the channel by the message		 * reference number. The current version of the firmware		 * doesn't sent the ref number correctly.		 */#ifdef DEBUG		printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum, 		       dev->b1->s_refnum, 		       dev->b2->s_refnum);#endif		/* We just try to find a channel in the right state */		if (dev->b1->fsm_state == ST_CALL_INIT)			chan = dev->b1;		else { 		   			if (dev->b2->s_refnum == ST_CALL_INIT)				chan = dev->b2;			else {							chan = NULL;				printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n");				break;			}		}		if (capi_decode_conn_conf(chan, skb, &complete)) {			printk(KERN_DEBUG "conn_conf indicates error\n");			pcbit_fsm_event(dev, chan, EV_ERROR, NULL);		}		else			if (complete)				pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL);			else				pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL);		break; 	case MSG_CONN_ACTV_IND:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}				if (capi_decode_conn_actv_ind(chan, skb)) {			printk("error in capi_decode_conn_actv_ind\n");		     /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */			break;		}		chan->r_refnum = refnum;		pcbit_fsm_event(dev, chan, EV_NET_CONN, NULL);		break;	case MSG_CONN_ACTV_CONF:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}		if (capi_decode_conn_actv_conf(chan, skb) == 0)			pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL);				else			printk(KERN_DEBUG "decode_conn_actv_conf failed\n");		break;	case  MSG_SELP_CONF:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}		if (!(err = capi_decode_sel_proto_conf(chan, skb)))			pcbit_fsm_event(dev, chan, EV_NET_SELP_RESP, NULL);		else {			/* Error */			printk("error %d - capi_decode_sel_proto_conf\n", err);		}		break;	case MSG_ACT_TRANSP_CONF:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}		if (!capi_decode_actv_trans_conf(chan, skb))			pcbit_fsm_event(dev, chan, EV_NET_ACTV_RESP, NULL);		break;	case MSG_DISC_IND:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}		if (!capi_decode_disc_ind(chan, skb))			pcbit_fsm_event(dev, chan, EV_NET_DISC, NULL);		else			printk(KERN_WARNING "capi_decode_disc_ind - error\n");		break;	case MSG_DISC_CONF:		if (!(chan = capi_channel(dev, skb))) {			printk(KERN_WARNING 			       "CAPI header: unknown channel id\n");			break;		}		if (!capi_decode_disc_ind(chan, skb))			pcbit_fsm_event(dev, chan, EV_NET_RELEASE, NULL);		else			printk(KERN_WARNING "capi_decode_disc_conf - error\n");		break;	case MSG_INFO_IND:#ifdef DEBUG		printk(KERN_DEBUG "received Info Indication - discarded\n");#endif		break;#ifdef DEBUG	case MSG_DEBUG_188:		capi_decode_debug_188(skb->data, skb->len);		break;	default:		printk(KERN_DEBUG "pcbit_l3_receive: unknown message %08lx\n",		       msg);		break;#endif	}	kfree_skb(skb);}/* *   Single statbuf *   should be a statbuf per device */static char statbuf[STATBUF_LEN];static int stat_st = 0;static int stat_end = 0;static int pcbit_stat(u_char __user *buf, int len, int driver, int channel){	int stat_count;	stat_count = stat_end - stat_st;	if (stat_count < 0)		stat_count = STATBUF_LEN - stat_st + stat_end;	/* FIXME: should we sleep and wait for more cookies ? */	if (len > stat_count)            		len = stat_count;	if (stat_st < stat_end)	{		copy_to_user(buf, statbuf + stat_st, len);		stat_st += len;	   	}	else	{		if (len > STATBUF_LEN - stat_st)		{			copy_to_user(buf, statbuf + stat_st, 				       STATBUF_LEN - stat_st);			copy_to_user(buf, statbuf, 				       len - (STATBUF_LEN - stat_st));			stat_st = len - (STATBUF_LEN - stat_st);		}		else		{			copy_to_user(buf, statbuf + stat_st, len);			stat_st += len;						if (stat_st == STATBUF_LEN)				stat_st = 0;		}	}	if (stat_st == stat_end)		stat_st = stat_end = 0;	return len;}static void pcbit_logstat(struct pcbit_dev *dev, char *str){	int i;	isdn_ctrl ictl;	for (i=stat_end; i<strlen(str); i++)	{		statbuf[i]=str[i];		stat_end = (stat_end + 1) % STATBUF_LEN;		if (stat_end == stat_st)			stat_st = (stat_st + 1) % STATBUF_LEN;	}	ictl.command=ISDN_STAT_STAVAIL;	ictl.driver=dev->id;	ictl.arg=strlen(str);	dev->dev_if->statcallb(&ictl);}	extern char * isdn_state_table[];extern char * strisdnevent(unsigned short);void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan, 			unsigned short i, unsigned short ev, unsigned short f){	char buf[256];  	sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n",		dev->id, chan->id, 		isdn_state_table[i], strisdnevent(ev), isdn_state_table[f]		);#ifdef DEBUG	printk("%s", buf);#endif	pcbit_logstat(dev, buf);}static void set_running_timeout(unsigned long ptr){	struct pcbit_dev * dev;#ifdef DEBUG	printk(KERN_DEBUG "set_running_timeout\n");#endif	dev = (struct pcbit_dev *) ptr;	wake_up_interruptible(&dev->set_running_wq);}static int set_protocol_running(struct pcbit_dev * dev){	isdn_ctrl ctl;	init_timer(&dev->set_running_timer);	dev->set_running_timer.function = &set_running_timeout;	dev->set_running_timer.data = (ulong) dev;	dev->set_running_timer.expires = jiffies + SET_RUN_TIMEOUT;	/* kick it */	dev->l2_state = L2_STARTING;	writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), 	       dev->sh_mem + BANK4);	add_timer(&dev->set_running_timer);	interruptible_sleep_on(&dev->set_running_wq);	del_timer(&dev->set_running_timer);	if (dev->l2_state == L2_RUNNING)	{		printk(KERN_DEBUG "pcbit: running\n");		dev->unack_seq = dev->send_seq;		dev->writeptr = dev->sh_mem;		dev->readptr = dev->sh_mem + BANK2;    		/* tell the good news to the upper layer */  		ctl.driver = dev->id;		ctl.command = ISDN_STAT_RUN;		dev->dev_if->statcallb(&ctl);	}	else	{		printk(KERN_DEBUG "pcbit: initialization failed\n");		printk(KERN_DEBUG "pcbit: firmware not loaded\n");		dev->l2_state = L2_DOWN;#ifdef DEBUG		printk(KERN_DEBUG "Bank3 = %02x\n", 		       readb(dev->sh_mem + BANK3));#endif		writeb(0x40, dev->sh_mem + BANK4);		/* warn the upper layer */		ctl.driver = dev->id;		ctl.command = ISDN_STAT_STOP;		dev->dev_if->statcallb(&ctl);		return -EL2HLT;	/* Level 2 halted */	}	return 0;}static int pcbit_ioctl(isdn_ctrl* ctl){	struct pcbit_dev * dev;	struct pcbit_ioctl *cmd;	dev = finddev(ctl->driver);  	if (!dev)	{		printk(KERN_DEBUG "pcbit_ioctl: unknown device\n");		return -ENODEV;	}	cmd = (struct pcbit_ioctl *) ctl->parm.num;	switch(ctl->arg) {	case PCBIT_IOCTL_GETSTAT:		cmd->info.l2_status = dev->l2_state;		break;	case PCBIT_IOCTL_STRLOAD:		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		dev->unack_seq = dev->send_seq = dev->rcv_seq = 0;		dev->writeptr = dev->sh_mem;		dev->readptr = dev->sh_mem + BANK2;    		dev->l2_state = L2_LOADING;		break;	case PCBIT_IOCTL_LWMODE:		if (dev->l2_state != L2_LOADING)			return -EINVAL;		dev->l2_state = L2_LWMODE;		break;	case PCBIT_IOCTL_FWMODE:		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		dev->loadptr = LOAD_ZONE_START;		dev->l2_state = L2_FWMODE;		break; 	case PCBIT_IOCTL_ENDLOAD:		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		dev->l2_state = L2_DOWN;		break; 	case PCBIT_IOCTL_SETBYTE: 		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		/* check addr */		if (cmd->info.rdp_byte.addr > BANK4)			return -EFAULT;				writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr);		break;	case PCBIT_IOCTL_GETBYTE:		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		/* check addr */		if (cmd->info.rdp_byte.addr > BANK4)		{			printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr);			return -EFAULT;		}				cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr); 		break;	case PCBIT_IOCTL_RUNNING: 		if (dev->l2_state == L2_RUNNING)			return -EBUSY;		return set_protocol_running(dev);		break;	case PCBIT_IOCTL_WATCH188:		if (dev->l2_state != L2_LOADING)			return -EINVAL;		pcbit_l2_write(dev, MSG_WATCH188, 0x0001, NULL, 0);		break;	case PCBIT_IOCTL_PING188:		if (dev->l2_state != L2_LOADING)			return -EINVAL;		pcbit_l2_write(dev, MSG_PING188_REQ, 0x0001, NULL, 0);		break;	case PCBIT_IOCTL_APION:		if (dev->l2_state != L2_LOADING)			return -EINVAL;		pcbit_l2_write(dev, MSG_API_ON, 0x0001, NULL, 0);		break;	case PCBIT_IOCTL_STOP:		dev->l2_state = L2_DOWN;		writeb(0x40, dev->sh_mem + BANK4);		dev->rcv_seq = 0;		dev->send_seq = 0;		dev->unack_seq = 0;		break;	default:		printk("error: unknown ioctl\n");		break;	};	return 0;}/*  *        MSN list handling * *        if null reject all calls *        if first entry has null MSN accept all calls  */static void pcbit_clear_msn(struct pcbit_dev *dev){	struct msn_entry *ptr, *back;	for (ptr=dev->msn_list; ptr; )	{		back = ptr->next;		kfree(ptr);		ptr = back;	}	dev->msn_list = NULL; }static void pcbit_set_msn(struct pcbit_dev *dev, char *list){	struct msn_entry *ptr;	struct msn_entry *back = NULL;	char *cp, *sp;	int len;	if (strlen(list) == 0) {		ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);		if (!ptr) {			printk(KERN_WARNING "kmalloc failed\n");			return;		}		ptr->msn = NULL;		ptr->next = dev->msn_list;		dev->msn_list = ptr;		return;	}	if (dev->msn_list)		for (back=dev->msn_list; back->next; back=back->next);		sp = list;	do {		cp=strchr(sp, ',');		if (cp)			len = cp - sp;		else			len = strlen(sp);		ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);		if (!ptr) {			printk(KERN_WARNING "kmalloc failed\n");			return;		}		ptr->next = NULL;				ptr->msn = kmalloc(len, GFP_ATOMIC);		if (!ptr->msn) {			printk(KERN_WARNING "kmalloc failed\n");			kfree(ptr);			return;		}		memcpy(ptr->msn, sp, len - 1);		ptr->msn[len] = 0;#ifdef DEBUG		printk(KERN_DEBUG "msn: %s\n", ptr->msn);#endif		if (dev->msn_list == NULL)			dev->msn_list = ptr;		else			back->next = ptr;		back = ptr;		sp += len;	} while(cp);}/* *  check if we do signal or reject an incoming call */static int pcbit_check_msn(struct pcbit_dev *dev, char *msn){	struct msn_entry *ptr;		for (ptr=dev->msn_list; ptr; ptr=ptr->next) {		if (ptr->msn == NULL) 			return 1;				if (strcmp(ptr->msn, msn) == 0)			return 1;	}	return 0;}

⌨️ 快捷键说明

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