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

📄 capi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		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,			    const unsigned char *buf, int count){	struct capiminor *mp = (struct capiminor *)tty->driver_data;	struct sk_buff *skb;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", 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 = NULL;		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);	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 = NULL;		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 = NULL;		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	if (mp)		mp->ttyinstop = 1;}static void capinc_tty_unthrottle(struct tty_struct * tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_unthrottle\n");#endif	if (mp) {		mp->ttyinstop = 0;		handle_minor_recv(mp);	}}static void capinc_tty_stop(struct tty_struct *tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_stop\n");#endif	if (mp) {		mp->ttyoutstop = 1;	}}static void capinc_tty_start(struct tty_struct *tty){	struct capiminor *mp = (struct capiminor *)tty->driver_data;#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_start\n");#endif	if (mp) {		mp->ttyoutstop = 0;		(void)handle_minor_send(mp);	}}static void capinc_tty_hangup(struct tty_struct *tty){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_hangup\n");#endif}static void capinc_tty_break_ctl(struct tty_struct *tty, int state){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);#endif}static void capinc_tty_flush_buffer(struct tty_struct *tty){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_flush_buffer\n");#endif}static void capinc_tty_set_ldisc(struct tty_struct *tty){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_set_ldisc\n");#endif}static void capinc_tty_send_xchar(struct tty_struct *tty, char ch){#ifdef _DEBUG_TTYFUNCS	printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);#endif}static int capinc_tty_read_proc(char *page, char **start, off_t off,				int count, int *eof, void *data){	return 0;}static struct tty_driver *capinc_tty_driver;static struct tty_operations capinc_ops = {	.open = capinc_tty_open,	.close = capinc_tty_close,	.write = capinc_tty_write,	.put_char = capinc_tty_put_char,	.flush_chars = capinc_tty_flush_chars,	.write_room = capinc_tty_write_room,	.chars_in_buffer = capinc_tty_chars_in_buffer,	.ioctl = capinc_tty_ioctl,	.set_termios = capinc_tty_set_termios,	.throttle = capinc_tty_throttle,	.unthrottle = capinc_tty_unthrottle,	.stop = capinc_tty_stop,	.start = capinc_tty_start,	.hangup = capinc_tty_hangup,	.break_ctl = capinc_tty_break_ctl,	.flush_buffer = capinc_tty_flush_buffer,	.set_ldisc = capinc_tty_set_ldisc,	.send_xchar = capinc_tty_send_xchar,	.read_proc = capinc_tty_read_proc,};static int capinc_tty_init(void){	struct tty_driver *drv;		if (capi_ttyminors > CAPINC_MAX_PORTS)		capi_ttyminors = CAPINC_MAX_PORTS;	if (capi_ttyminors <= 0)		capi_ttyminors = CAPINC_NR_PORTS;	drv = alloc_tty_driver(capi_ttyminors);	if (!drv)		return -ENOMEM;	drv->owner = THIS_MODULE;	drv->driver_name = "capi_nc";	drv->devfs_name = "capi/";	drv->name = "capi";	drv->major = capi_ttymajor;	drv->minor_start = 0;	drv->type = TTY_DRIVER_TYPE_SERIAL;	drv->subtype = SERIAL_TYPE_NORMAL;	drv->init_termios = tty_std_termios;	drv->init_termios.c_iflag = ICRNL;	drv->init_termios.c_oflag = OPOST | ONLCR;	drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;	drv->init_termios.c_lflag = 0;	drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS;	tty_set_operations(drv, &capinc_ops);	if (tty_register_driver(drv)) {		put_tty_driver(drv);		printk(KERN_ERR "Couldn't register capi_nc driver\n");		return -1;	}	capinc_tty_driver = drv;	return 0;}static void capinc_tty_exit(void){	struct tty_driver *drv = capinc_tty_driver;	int retval;	if ((retval = tty_unregister_driver(drv)))		printk(KERN_ERR "capi: failed to unregister capi_nc driver (%d)\n", retval);	put_tty_driver(drv);}#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE *//* -------- /proc functions ----------------------------------------- *//* * /proc/capi/capi20: *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt */static int proc_capidev_read_proc(char *page, char **start, off_t off,                                       int count, int *eof, void *data){        struct capidev *cdev;	struct list_head *l;	int len = 0;	read_lock(&capidev_list_lock);	list_for_each(l, &capidev_list) {		cdev = list_entry(l, struct capidev, list);		len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n",			cdev->ap.applid,			cdev->ap.nrecvctlpkt,			cdev->ap.nrecvdatapkt,			cdev->ap.nsentctlpkt,			cdev->ap.nsentdatapkt);		if (len <= off) {			off -= len;			len = 0;		} else {			if (len-off > count)				goto endloop;		}	}endloop:	read_unlock(&capidev_list_lock);	if (len < count)		*eof = 1;	if (len > count) len = count;	if (len < 0) len = 0;	return len;}/* * /proc/capi/capi20ncci: *  applid ncci */static int proc_capincci_read_proc(char *page, char **start, off_t off,                                       int count, int *eof, void *data){        struct capidev *cdev;        struct capincci *np;	struct list_head *l;	int len = 0;	read_lock(&capidev_list_lock);	list_for_each(l, &capidev_list) {		cdev = list_entry(l, struct capidev, list);		for (np=cdev->nccis; np; np = np->next) {			len += sprintf(page+len, "%d 0x%x\n",				       cdev->ap.applid,				       np->ncci);			if (len <= off) {				off -= len;				len = 0;			} else {				if (len-off > count)					goto endloop;			}		}	}endloop:	read_unlock(&capidev_list_lock);	*start = page+off;	if (len < count)		*eof = 1;	if (len>count) len = count;	if (len<0) len = 0;	return len;}static struct procfsentries {  char *name;  mode_t mode;  int (*read_proc)(char *page, char **start, off_t off,                                       int count, int *eof, void *data);  struct proc_dir_entry *procent;} procfsentries[] = {   /* { "capi",		  S_IFDIR, 0 }, */   { "capi/capi20", 	  0	 , proc_capidev_read_proc },   { "capi/capi20ncci",   0	 , proc_capincci_read_proc },};static void __init proc_init(void){    int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);    int i;    for (i=0; i < nelem; i++) {        struct procfsentries *p = procfsentries + i;	p->procent = create_proc_entry(p->name, p->mode, NULL);	if (p->procent) p->procent->read_proc = p->read_proc;    }}static void __exit proc_exit(void){    int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);    int i;    for (i=nelem-1; i >= 0; i--) {        struct procfsentries *p = procfsentries + i;	if (p->procent) {	   remove_proc_entry(p->name, NULL);	   p->procent = NULL;	}    }}/* -------- init function and module interface ---------------------- */static char rev[32];static int __init capi_init(void){	char *p;	char *compileinfo;	if ((p = strchr(revision, ':')) != 0 && p[1]) {		strlcpy(rev, p + 2, sizeof(rev));		if ((p = strchr(rev, '$')) != 0 && p > rev)		   *(p-1) = 0;	} else		strcpy(rev, "1.0");	if (register_chrdev(capi_major, "capi20", &capi_fops)) {		printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);		return -EIO;	}	capi_class = class_create(THIS_MODULE, "capi");	if (IS_ERR(capi_class)) {		unregister_chrdev(capi_major, "capi20");		return PTR_ERR(capi_class);	}	class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");	devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,			"isdn/capi20");#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE	if (capinc_tty_init() < 0) {		class_device_destroy(capi_class, MKDEV(capi_major, 0));		class_destroy(capi_class);		unregister_chrdev(capi_major, "capi20");		return -ENOMEM;	}#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */	proc_init();#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)        compileinfo = " (middleware+capifs)";#else        compileinfo = " (no capifs)";#endif#else        compileinfo = " (no middleware)";#endif	printk(KERN_NOTICE "capi20: Rev %s: started up with major %d%s\n",				rev, capi_major, compileinfo);	return 0;}static void __exit capi_exit(void){	proc_exit();	class_device_destroy(capi_class, MKDEV(capi_major, 0));	class_destroy(capi_class);	unregister_chrdev(capi_major, "capi20");	devfs_remove("isdn/capi20");#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE	capinc_tty_exit();#endif	printk(KERN_NOTICE "capi: Rev %s: unloaded\n", rev);}module_init(capi_init);module_exit(capi_exit);

⌨️ 快捷键说明

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