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

📄 mkiss.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
{	switch (s) {		case END:			/* drop keeptest bit = VSV */			if (test_bit(AXF_KEEPTEST, &ax->flags))				clear_bit(AXF_KEEPTEST, &ax->flags);			if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))				ax_bump(ax);			clear_bit(AXF_ESCAPE, &ax->flags);			ax->rcount = 0;			return;		case ESC:			set_bit(AXF_ESCAPE, &ax->flags);			return;		case ESC_ESC:			if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))				s = ESC;			break;		case ESC_END:			if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))				s = END;			break;	}	if (!test_bit(AXF_ERROR, &ax->flags)) {		if (ax->rcount < ax->buffsize) {			ax->rbuff[ax->rcount++] = s;			return;		}		ax->rx_over_errors++;		set_bit(AXF_ERROR, &ax->flags);	}}int ax_set_mac_address(struct device *dev, void *addr){	if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN))		return -EFAULT;	return 0;}static int ax_set_dev_mac_address(struct device *dev, void *addr){	struct sockaddr *sa = addr;	memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);	return 0;}/* Perform I/O control on an active ax25 channel. */static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg){	struct ax_disp *ax = (struct ax_disp *)tty->disc_data;	unsigned int tmp;	/* First make sure we're connected. */	if (ax == NULL || ax->magic != AX25_MAGIC)		return -EINVAL;	switch (cmd) {	 	case SIOCGIFNAME:			if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1))				return -EFAULT;			return 0;		case SIOCGIFENCAP:			put_user(4, (int *)arg);			return 0;		case SIOCSIFENCAP:			get_user(tmp, (int *)arg);	 		ax->mode = tmp;			ax->dev->addr_len        = AX25_ADDR_LEN;	  /* sizeof an AX.25 addr */			ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;			ax->dev->type            = ARPHRD_AX25;			return 0;		 case SIOCSIFHWADDR:			return ax_set_mac_address(ax->dev, arg);		default:			return -ENOIOCTLCMD;	}}static int ax_open_dev(struct device *dev){	struct ax_disp *ax = (struct ax_disp*)dev->priv;	if (ax->tty==NULL)		return -ENODEV;	return 0;}/* Initialize AX25 control device -- register AX25 line discipline */__initfunc(int mkiss_init_ctrl_dev(void)){	int status;	if (ax25_maxdev < 4) ax25_maxdev = 4; /* Sanity */	if ((ax25_ctrls = kmalloc(sizeof(void*) * ax25_maxdev, GFP_KERNEL)) == NULL) {		printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array !  No mkiss available\n");		return -ENOMEM;	}	/* Clear the pointer array, we allocate devices when we need them */	memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */	/* Fill in our line protocol discipline, and register it */	memset(&ax_ldisc, 0, sizeof(ax_ldisc));	ax_ldisc.magic  = TTY_LDISC_MAGIC;	ax_ldisc.name   = "mkiss";	ax_ldisc.flags  = 0;	ax_ldisc.open   = ax25_open;	ax_ldisc.close  = ax25_close;	ax_ldisc.read   = NULL;	ax_ldisc.write  = NULL;	ax_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *, unsigned int, unsigned long))ax25_disp_ioctl;	ax_ldisc.poll   = NULL;	ax_ldisc.receive_buf  = ax25_receive_buf;	ax_ldisc.receive_room = ax25_receive_room;	ax_ldisc.write_wakeup = ax25_write_wakeup;	if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)		printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status);	mkiss_init();#ifdef MODULE	return status;#else	/*	 * Return "not found", so that dev_init() will unlink	 * the placeholder device entry for us.	 */	return ENODEV;#endif}/* Initialize the driver.  Called by network startup. */static int ax25_init(struct device *dev){	struct ax_disp *ax = (struct ax_disp*)dev->priv;	static char ax25_bcast[AX25_ADDR_LEN] =		{'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};	static char ax25_test[AX25_ADDR_LEN] =		{'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};	if (ax == NULL)		/* Allocation failed ?? */		return -ENODEV;	/* Set up the "AX25 Control Block". (And clear statistics) */	memset(ax, 0, sizeof (struct ax_disp));	ax->magic  = AX25_MAGIC;	ax->dev	   = dev;	/* Finish setting up the DEVICE info. */	dev->mtu             = AX_MTU;	dev->hard_start_xmit = ax_xmit;	dev->open            = ax_open_dev;	dev->stop            = ax_close;	dev->get_stats	     = ax_get_stats;#ifdef HAVE_SET_MAC_ADDR	dev->set_mac_address = ax_set_dev_mac_address;#endif	dev->hard_header_len = 0;	dev->addr_len        = 0;	dev->type            = ARPHRD_AX25;	dev->tx_queue_len    = 10;	memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);	memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)	dev->hard_header     = ax_header;	dev->rebuild_header  = ax_rebuild_header;#endif	dev_init_buffers(dev);	/* New-style flags. */	dev->flags      = 0;	return 0;}static int mkiss_open(struct tty_struct *tty, struct file *filp){	struct mkiss_channel *mkiss;	int chan;	chan = MINOR(tty->device) - tty->driver.minor_start;	if (chan < 0 || chan >= NR_MKISS)		return -ENODEV;	mkiss = &MKISS_Info[chan];	mkiss->magic =  MKISS_DRIVER_MAGIC;	mkiss->init  = 1;	mkiss->tty   = tty;	tty->driver_data = mkiss;	tty->termios->c_iflag  = IGNBRK | IGNPAR;	tty->termios->c_cflag  = B9600 | CS8 | CLOCAL;	tty->termios->c_cflag &= ~CBAUD;	return 0;}static void mkiss_close(struct tty_struct *tty, struct file * filp){	struct mkiss_channel *mkiss = tty->driver_data;	if (mkiss == NULL || mkiss->magic != MKISS_DRIVER_MAGIC)                return;	mkiss->tty   = NULL;	mkiss->init  = 0;	tty->stopped = 0;}static int mkiss_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count){	return 0;}static int mkiss_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg){	/* Ignore serial ioctl's */	switch (cmd) {		case TCSBRK:		case TIOCMGET:		case TIOCMBIS:		case TIOCMBIC:		case TIOCMSET:		case TCSETS:		case TCSETSF:		/* should flush first, but... */		case TCSETSW:		/* should wait until flush, but... */			return 0;		default:			return -ENOIOCTLCMD;	}}static void mkiss_dummy(struct tty_struct *tty){	struct mkiss_channel *mkiss = tty->driver_data;	if (tty == NULL)		return;	if (mkiss == NULL)		return;}static void mkiss_dummy2(struct tty_struct *tty, unsigned char ch){	struct mkiss_channel *mkiss = tty->driver_data;	if (tty == NULL)		return;	if (mkiss == NULL)		return;}static int mkiss_write_room(struct tty_struct * tty){	struct mkiss_channel *mkiss = tty->driver_data;	if (tty == NULL)		return 0;	if (mkiss == NULL)		return 0;	return 65536;  /* We can handle an infinite amount of data. :-) */}static int mkiss_chars_in_buffer(struct tty_struct *tty){	struct mkiss_channel *mkiss = tty->driver_data;	if (tty == NULL)		return 0;	if (mkiss == NULL)		return 0;	return 0;}static void mkiss_set_termios(struct tty_struct *tty, struct termios *old_termios){	/* we don't do termios */}/* ******************************************************************** *//* * 			Init MKISS driver 			      * *//* ******************************************************************** */__initfunc(static int mkiss_init(void)){	memset(&mkiss_driver, 0, sizeof(struct tty_driver));	mkiss_driver.magic       = MKISS_DRIVER_MAGIC;	mkiss_driver.name        = "mkiss";	mkiss_driver.major       = MKISS_MAJOR;	mkiss_driver.minor_start = 0;	mkiss_driver.num         = NR_MKISS;	mkiss_driver.type        = TTY_DRIVER_TYPE_SERIAL;	mkiss_driver.subtype     = MKISS_SERIAL_TYPE_NORMAL;	/* not needed */	mkiss_driver.init_termios         = tty_std_termios;	mkiss_driver.init_termios.c_iflag = IGNBRK | IGNPAR;	mkiss_driver.init_termios.c_cflag = B9600 | CS8 | CLOCAL;	mkiss_driver.flags           = TTY_DRIVER_REAL_RAW;	mkiss_driver.refcount        = &mkiss_refcount;	mkiss_driver.table           = mkiss_table;	mkiss_driver.termios         = (struct termios **)mkiss_termios;	mkiss_driver.termios_locked  = (struct termios **)mkiss_termios_locked;	mkiss_driver.ioctl           = mkiss_ioctl;	mkiss_driver.open            = mkiss_open;	mkiss_driver.close           = mkiss_close;	mkiss_driver.write           = mkiss_write;	mkiss_driver.write_room      = mkiss_write_room;	mkiss_driver.chars_in_buffer = mkiss_chars_in_buffer;	mkiss_driver.set_termios     = mkiss_set_termios;	/* some unused functions */	mkiss_driver.flush_buffer = mkiss_dummy;	mkiss_driver.throttle     = mkiss_dummy;	mkiss_driver.unthrottle   = mkiss_dummy;	mkiss_driver.stop         = mkiss_dummy;	mkiss_driver.start        = mkiss_dummy;	mkiss_driver.hangup       = mkiss_dummy;	mkiss_driver.flush_chars  = mkiss_dummy;	mkiss_driver.put_char     = mkiss_dummy2;	if (tty_register_driver(&mkiss_driver)) {		printk(KERN_ERR "mkiss: couldn't register Mkiss device\n");		return -EIO;	}	printk(KERN_INFO "AX.25 Multikiss device enabled\n");	return 0;}#ifdef MODULEEXPORT_NO_SYMBOLS;MODULE_PARM(ax25_maxdev, "i");MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices");MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>");MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");int init_module(void){	return mkiss_init_ctrl_dev();}void cleanup_module(void){	int i;	if (ax25_ctrls != NULL) {		for (i = 0; i < ax25_maxdev; i++) {			if (ax25_ctrls[i]) {				/*				 * VSV = if dev->start==0, then device				 * unregistred while close proc.				 */				if (ax25_ctrls[i]->dev.start)					unregister_netdev(&(ax25_ctrls[i]->dev));				kfree(ax25_ctrls[i]);				ax25_ctrls[i] = NULL;			}		}		kfree(ax25_ctrls);		ax25_ctrls = NULL;	}	if ((i = tty_register_ldisc(N_AX25, NULL)))		printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);	if (tty_unregister_driver(&mkiss_driver))	/* remove devive */		printk(KERN_ERR "mkiss: can't unregister MKISS device\n");}#endif /* MODULE */

⌨️ 快捷键说明

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