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

📄 capi.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
				return 0;#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE			if ((mp = nccip->minorp) != 0) {				count += atomic_read(&mp->ttyopencount);				if (mp->file)					count++;			}#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */			return count;		}		return 0;#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE	case CAPI_NCCI_GETUNIT:		{			struct capincci *nccip;			struct capiminor *mp;			unsigned ncci;			retval = copy_from_user((void *) &ncci,						(void *) arg,						sizeof(ncci));			if (retval)				return -EFAULT;			nccip = capincci_find(cdev, (u32) ncci);			if (!nccip || (mp = nccip->minorp) == 0)				return -ESRCH;			return mp->minor;		}		return 0;#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */	}	return -EINVAL;}static intcapi_open(struct inode *inode, struct file *file){	if (file->private_data)		return -EEXIST;	if ((file->private_data = capidev_alloc(file)) == 0)		return -ENOMEM;	MOD_INC_USE_COUNT;#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capi_open %d\n", GET_USE_COUNT(THIS_MODULE));#endif	return 0;}static intcapi_release(struct inode *inode, struct file *file){	struct capidev *cdev = (struct capidev *)file->private_data;	lock_kernel();	capincci_free(cdev, 0xffffffff);	capidev_free(cdev);	file->private_data = NULL;		MOD_DEC_USE_COUNT;#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE));#endif	unlock_kernel();	return 0;}static struct file_operations capi_fops ={	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		capi_read,	write:		capi_write,	poll:		capi_poll,	ioctl:		capi_ioctl,	open:		capi_open,	release:	capi_release,};#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE/* -------- file_operations for capincci ---------------------------- */static intcapinc_raw_open(struct inode *inode, struct file *file){	struct capiminor *mp;	if (file->private_data)		return -EEXIST;	if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)		return -ENXIO;	if (mp->nccip == 0)		return -ENXIO;	if (mp->file)		return -EBUSY;#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capi_raw_open %d\n", GET_USE_COUNT(THIS_MODULE));#endif	mp->datahandle = 0;	mp->file = file;	file->private_data = (void *)mp;	handle_minor_recv(mp);	return 0;}static ssize_tcapinc_raw_read(struct file *file, char *buf, size_t count, loff_t *ppos){	struct capiminor *mp = (struct capiminor *)file->private_data;	struct sk_buff *skb;	int retval;	size_t copied = 0;        if (ppos != &file->f_pos)		return -ESPIPE;	if (!mp || !mp->nccip)		return -EINVAL;	if ((skb = skb_dequeue(&mp->recvqueue)) == 0) {		if (file->f_flags & O_NONBLOCK)			return -EAGAIN;		for (;;) {			interruptible_sleep_on(&mp->recvwait);			if (mp->nccip == 0)				return 0;			if ((skb = skb_dequeue(&mp->recvqueue)) != 0)				break;			if (signal_pending(current))				break;		}		if (skb == 0)			return -ERESTARTNOHAND;	}	do {		if (count < skb->len) {			retval = copy_to_user(buf, skb->data, count);			if (retval) {				skb_queue_head(&mp->recvqueue, skb);				return retval;			}			skb_pull(skb, count);			skb_queue_head(&mp->recvqueue, skb);			copied += count;			return copied;		} else {			retval = copy_to_user(buf, skb->data, skb->len);			if (retval) {				skb_queue_head(&mp->recvqueue, skb);				return copied;			}			copied += skb->len;			count -= skb->len;			buf += skb->len;			kfree_skb(skb);		}	} while ((skb = skb_dequeue(&mp->recvqueue)) != 0);	return copied;}static ssize_tcapinc_raw_write(struct file *file, const char *buf, size_t count, loff_t *ppos){	struct capiminor *mp = (struct capiminor *)file->private_data;	struct sk_buff *skb;	int retval;        if (ppos != &file->f_pos)		return -ESPIPE;	if (!mp || !mp->nccip)		return -EINVAL;	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_USER);	if (!skb)		return -ENOMEM;	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);	if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {		kfree_skb(skb);		return -EFAULT;	}	while (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE) {		if (file->f_flags & O_NONBLOCK)			return -EAGAIN;		interruptible_sleep_on(&mp->sendwait);		if (mp->nccip == 0) {			kfree_skb(skb);			return -EIO;		}		if (signal_pending(current))			return -ERESTARTNOHAND;	}	skb_queue_tail(&mp->outqueue, skb);	mp->outbytes += skb->len;	(void)handle_minor_send(mp);	return count;}static unsigned intcapinc_raw_poll(struct file *file, poll_table * wait){	struct capiminor *mp = (struct capiminor *)file->private_data;	unsigned int mask = 0;	if (!mp || !mp->nccip)		return POLLERR|POLLHUP;	poll_wait(file, &(mp->recvwait), wait);	if (!skb_queue_empty(&mp->recvqueue))		mask |= POLLIN | POLLRDNORM;	poll_wait(file, &(mp->sendwait), wait);	if (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE)		mask = POLLOUT | POLLWRNORM;	return mask;}static intcapinc_raw_ioctl(struct inode *inode, struct file *file,		      unsigned int cmd, unsigned long arg){	struct capiminor *mp = (struct capiminor *)file->private_data;	if (!mp || !mp->nccip)		return -EINVAL;	switch (cmd) {	}	return -EINVAL;}static intcapinc_raw_release(struct inode *inode, struct file *file){	struct capiminor *mp = (struct capiminor *)file->private_data;	if (mp) {		lock_kernel();		mp->file = 0;		if (mp->nccip == 0) {			capiminor_free(mp);			file->private_data = NULL;		}		unlock_kernel();	}#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capinc_raw_release %d\n", GET_USE_COUNT(THIS_MODULE));#endif	return 0;}static struct file_operations capinc_raw_fops ={	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		capinc_raw_read,	write:		capinc_raw_write,	poll:		capinc_raw_poll,	ioctl:		capinc_raw_ioctl,	open:		capinc_raw_open,	release:	capinc_raw_release,};/* -------- tty_operations for capincci ----------------------------- */static int capinc_tty_open(struct tty_struct * tty, struct file * file){	struct capiminor *mp;	if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)		return -ENXIO;	if (mp->nccip == 0)		return -ENXIO;	if (mp->file)		return -EBUSY;	skb_queue_head_init(&mp->recvqueue);	init_waitqueue_head(&mp->recvwait);	init_waitqueue_head(&mp->sendwait);	tty->driver_data = (void *)mp;#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capi_tty_open %d\n", GET_USE_COUNT(THIS_MODULE));#endif	if (atomic_read(&mp->ttyopencount) == 0)		mp->tty = tty;	atomic_inc(&mp->ttyopencount);#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capinc_tty_open ocount=%d\n", atomic_read(&mp->ttyopencount));#endif	handle_minor_recv(mp);	return 0;}static void capinc_tty_close(struct tty_struct * tty, struct file * file){	struct capiminor *mp;	mp = (struct capiminor *)tty->driver_data;	if (mp)	{		if (atomic_dec_and_test(&mp->ttyopencount)) {#ifdef _DEBUG_REFCOUNT			printk(KERN_DEBUG "capinc_tty_close lastclose\n");#endif			tty->driver_data = (void *)0;			mp->tty = 0;		}#ifdef _DEBUG_REFCOUNT		printk(KERN_DEBUG "capinc_tty_close ocount=%d\n", atomic_read(&mp->ttyopencount));#endif		if (mp->nccip == 0)			capiminor_free(mp);	}#ifdef _DEBUG_REFCOUNT	printk(KERN_DEBUG "capinc_tty_close\n");#endif}static int capinc_tty_write(struct tty_struct * tty, int from_user,			    const unsigned char *buf, int count){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	struct sk_buff *skb;	int retval;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_write(from_user=%d,count=%d)\n",				from_user, count);#endif	if (!mp || !mp->nccip) {#ifdef _DEBUG_TTYFUNCS		printk(KERN_DEBUG "capinc_tty_write: mp or mp->ncci NULL\n");#endif		return 0;	}	skb = mp->ttyskb;	if (skb) {		mp->ttyskb = 0;		skb_queue_tail(&mp->outqueue, skb);		mp->outbytes += skb->len;	}	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);	if (!skb) {		printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");		return -ENOMEM;	}	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);	if (from_user) {		if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {			kfree_skb(skb);#ifdef _DEBUG_TTYFUNCS			printk(KERN_DEBUG "capinc_tty_write: copy_from_user=%d\n", retval);#endif			return -EFAULT;		}	} else {		memcpy(skb_put(skb, count), buf, count);	}	skb_queue_tail(&mp->outqueue, skb);	mp->outbytes += skb->len;	(void)handle_minor_send(mp);	(void)handle_minor_recv(mp);	return count;}static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	struct sk_buff *skb;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);#endif	if (!mp || !mp->nccip) {#ifdef _DEBUG_TTYFUNCS		printk(KERN_DEBUG "capinc_tty_put_char: mp or mp->ncci NULL\n");#endif		return;	}	skb = mp->ttyskb;	if (skb) {		if (skb_tailroom(skb) > 0) {			*(skb_put(skb, 1)) = ch;			return;		}		mp->ttyskb = 0;		skb_queue_tail(&mp->outqueue, skb);		mp->outbytes += skb->len;		(void)handle_minor_send(mp);	}	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);	if (skb) {		skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);		*(skb_put(skb, 1)) = ch;		mp->ttyskb = skb;	} else {		printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);	}}static void capinc_tty_flush_chars(struct tty_struct *tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	struct sk_buff *skb;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_flush_chars\n");#endif	if (!mp || !mp->nccip) {#ifdef _DEBUG_TTYFUNCS		printk(KERN_DEBUG "capinc_tty_flush_chars: mp or mp->ncci NULL\n");#endif		return;	}	skb = mp->ttyskb;	if (skb) {		mp->ttyskb = 0;		skb_queue_tail(&mp->outqueue, skb);		mp->outbytes += skb->len;		(void)handle_minor_send(mp);	}	(void)handle_minor_recv(mp);}static int capinc_tty_write_room(struct tty_struct *tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	int room;	if (!mp || !mp->nccip) {#ifdef _DEBUG_TTYFUNCS		printk(KERN_DEBUG "capinc_tty_write_room: mp or mp->ncci NULL\n");#endif		return 0;	}	room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);	room *= CAPI_MAX_BLKSIZE;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);#endif	return room;}static int capinc_tty_chars_in_buffer(struct tty_struct *tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	if (!mp || !mp->nccip) {#ifdef _DEBUG_TTYFUNCS		printk(KERN_DEBUG "capinc_tty_chars_in_buffer: mp or mp->ncci NULL\n");#endif		return 0;	}#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",			mp->outbytes, mp->nack,			skb_queue_len(&mp->outqueue),			skb_queue_len(&mp->inqueue));#endif	return mp->outbytes;}static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,		    unsigned int cmd, unsigned long arg){	int error = 0;	switch (cmd) {	default:		error = n_tty_ioctl (tty, file, cmd, arg);		break;	}	return error;}static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_set_termios\n");#endif}static void capinc_tty_throttle(struct tty_struct * tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_throttle\n");#endif

⌨️ 快捷键说明

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