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

📄 af_wanpipe.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
		if ((err=put_user(1, &dbg_data->debug[cnt].free)))			return err;		if ((err=put_user(sk->state, &dbg_data->debug[cnt].sk_state)))			return err;		if ((err=put_user(sk->rcvbuf, &dbg_data->debug[cnt].rcvbuf)))			return err;		if ((err=put_user(atomic_read(&sk->rmem_alloc), &dbg_data->debug[cnt].rmem)))			return err;		if ((err=put_user(atomic_read(&sk->wmem_alloc), &dbg_data->debug[cnt].wmem)))			return err;		if ((err=put_user(sk->sndbuf, &dbg_data->debug[cnt].sndbuf)))			return err;		if ((err=put_user(sk_count, &dbg_data->debug[cnt].sk_count)))			return err;		if ((err=put_user(sk->protinfo.af_wanpipe->poll_cnt, 						&dbg_data->debug[cnt].poll_cnt)))			return err;		if ((err=put_user(sk->bound_dev_if, &dbg_data->debug[cnt].bound)))			return err;		if (sk->bound_dev_if){			dev = dev_get_by_index(sk->bound_dev_if);			if (!dev)					continue;			chan=dev->priv;			dev_put(dev);				if ((err=put_user(chan->state, &dbg_data->debug[cnt].d_state)))				return err;			if ((err=put_user(chan->svc, &dbg_data->debug[cnt].svc)))				return err;			if ((err=put_user(atomic_read(&chan->command), 						&dbg_data->debug[cnt].command)))				return err;			if (sk->protinfo.af_wanpipe){				sdla_t *card = (sdla_t*)sk->protinfo.af_wanpipe->card;								if (card){					if ((err=put_user(atomic_read(&card->u.x.command_busy), 								&dbg_data->debug[cnt].cmd_busy)))						return err;				}				if ((err=put_user(sk->protinfo.af_wanpipe->lcn, 								&dbg_data->debug[cnt].lcn)))					return err;								if (sk->protinfo.af_wanpipe->mbox){					if ((err=put_user(1, &dbg_data->debug[cnt].mbox)))						return err;				}			}			if ((err=put_user(atomic_read(&chan->receive_block), 								&dbg_data->debug[cnt].rblock)))				return err;			if (copy_to_user(dbg_data->debug[cnt].name, dev->name, strlen(dev->name)))				return -EFAULT;		}			if (++cnt == MAX_NUM_DEBUG)			break;	}	return 0;}/*============================================================ *  get_ioctl_cmd *	 *	Pass up the contents of socket MBOX to the user. *===========================================================*/static int get_ioctl_cmd (struct sock *sk, void *arg){	x25api_t *usr_data = (x25api_t *)arg;	mbox_cmd_t *mbox_ptr;	int err;	if (usr_data == NULL)		return -EINVAL;	if (!sk->protinfo.af_wanpipe->mbox){		return -EINVAL;	}	mbox_ptr = (mbox_cmd_t *)sk->protinfo.af_wanpipe->mbox;	if ((err=put_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm)))		return err;	if ((err=put_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause)))		return err;	if ((err=put_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn)))		return err;	if ((err=put_user(mbox_ptr->cmd.length, &usr_data->hdr.length)))		return err;	if ((err=put_user(mbox_ptr->cmd.result, &usr_data->hdr.result)))		return err;	if ((err=put_user(mbox_ptr->cmd.lcn, &usr_data->hdr.lcn)))		return err;		if (mbox_ptr->cmd.length > 0){		if (mbox_ptr->cmd.length > X25_MAX_DATA)			return -EINVAL;		if (copy_to_user(usr_data->data, mbox_ptr->data, mbox_ptr->cmd.length)){			printk(KERN_INFO "wansock: Copy failed !!!\n");			return -EFAULT;		}	}	return 0;} /*============================================================ *  set_ioctl_cmd *	 *	Before command can be execute, socket MBOX must *      be created, and initialized with user data.	 *===========================================================*/static int set_ioctl_cmd (struct sock *sk, void *arg){	x25api_t *usr_data = (x25api_t *)arg;	mbox_cmd_t *mbox_ptr;	int err;	if (!sk->protinfo.af_wanpipe->mbox){		void *mbox_ptr;		netdevice_t *dev = dev_get_by_index(sk->bound_dev_if);		if (!dev)			return -ENODEV;		dev_put(dev);				if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)			return -ENOMEM;		memset(mbox_ptr, 0, sizeof(mbox_cmd_t));		sk->protinfo.af_wanpipe->mbox = mbox_ptr;		wanpipe_link_driver(dev,sk);	}	mbox_ptr = (mbox_cmd_t*)sk->protinfo.af_wanpipe->mbox;	memset(mbox_ptr, 0, sizeof(mbox_cmd_t));	if (usr_data == NULL){		return 0;	}	if ((err=get_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm)))		return err;	if ((err=get_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause)))		return err;	if ((err=get_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn)))		return err;	if ((err=get_user(mbox_ptr->cmd.length, &usr_data->hdr.length)))		return err;	if ((err=get_user(mbox_ptr->cmd.result, &usr_data->hdr.result)))		return err;	if (mbox_ptr->cmd.length > 0){		if (mbox_ptr->cmd.length > X25_MAX_DATA)			return -EINVAL;		if (copy_from_user(mbox_ptr->data, usr_data->data, mbox_ptr->cmd.length)){			printk(KERN_INFO "Copy failed\n");			return -EFAULT;		}	}	return 0;}/*====================================================================== * wanpipe_poll * *	Datagram poll: Again totally generic. This also handles *	sequenced packet sockets providing the socket receive queue *	is only ever holding data ready to receive. * *	Note: when you _don't_ use this routine for this protocol, *	and you use a different write policy from sock_writeable() *	then please supply your own write_space callback. *=====================================================================*/unsigned int wanpipe_poll(struct file * file, struct socket *sock, poll_table *wait){	struct sock *sk = sock->sk;	unsigned int mask;	++sk->protinfo.af_wanpipe->poll_cnt;	poll_wait(file, sk->sleep, wait);	mask = 0;	/* exceptional events? */	if (sk->err || !skb_queue_empty(&sk->error_queue)){		mask |= POLLPRI;		return mask;	}	if (sk->shutdown & RCV_SHUTDOWN)		mask |= POLLHUP;	/* readable? */	if (!skb_queue_empty(&sk->receive_queue)){		mask |= POLLIN | POLLRDNORM;	}	/* connection hasn't started yet */	if (sk->state == WANSOCK_CONNECTING){		return mask;	}	if (sk->state == WANSOCK_DISCONNECTED){		mask = POLLPRI;		return mask;	}	/* This check blocks the user process if there is   	 * a packet already queued in the socket write queue.         * This option is only for X25API protocol, for other         * protocol like chdlc enable streaming mode,          * where multiple packets can be pending in the socket          * transmit queue */	if (sk->num == htons(X25_PROT)){		if (atomic_read(&sk->protinfo.af_wanpipe->packet_sent))			return mask;	}	/* writable? */	if (sock_writeable(sk)){		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;	}else{	      #ifdef LINUX_2_4		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);	      #else 		sk->socket->flags |= SO_NOSPACE;	      #endif	}			return mask;}/*====================================================================== * wanpipe_listen * *	X25API Specific function. Set a socket into LISTENING  MODE. *=====================================================================*/static int wanpipe_listen(struct socket *sock, int backlog){	struct sock *sk = sock->sk; 	/* This is x25 specific area if protocol doesn't         * match, return error */	if (sk->num != htons(X25_PROT))		return -EINVAL;	if (sk->state == WANSOCK_BIND_LISTEN) {		sk->max_ack_backlog = backlog;		sk->state           = WANSOCK_LISTEN;		return 0;	}else{		printk(KERN_INFO "wansock: Listening sock was not binded\n");	}	return -EINVAL;}/*====================================================================== * wanpipe_link_card * *	Connects the listening socket to the driver *=====================================================================*/static int wanpipe_link_card (struct sock *sk){	sdla_t *card;	card = (sdla_t*)sk->protinfo.af_wanpipe->card;	if (!card)		return -ENOMEM;	if ((card->sk != NULL) || (card->func != NULL)){		printk(KERN_INFO "wansock: Listening queue is already established\n");		return -EINVAL;	}	card->sk=sk;	card->func=wanpipe_listen_rcv;	sk->zapped=1; 	return 0;}/*====================================================================== * wanpipe_listen * *	X25API Specific function. Disconnect listening socket from *      the driver. *=====================================================================*/static void wanpipe_unlink_card (struct sock *sk){	sdla_t *card; 	card = (sdla_t*)sk->protinfo.af_wanpipe->card; 	if (card){		card->sk=NULL;		card->func=NULL;	}}/*====================================================================== * wanpipe_exec_cmd * *	Ioctl function calls this function to execute user command. *      Connect() sytem call also calls this function to execute *      place call.  This function blocks until command is executed. *=====================================================================*/static int wanpipe_exec_cmd(struct sock *sk, int cmd, unsigned int flags){	int err = -EINVAL;	mbox_cmd_t *mbox_ptr = (mbox_cmd_t*)sk->protinfo.af_wanpipe->mbox;	if (!mbox_ptr){		printk(KERN_INFO "NO MBOX PTR !!!!!\n");		return -EINVAL;	}		/* This is x25 specific area if protocol doesn't         * match, return error */	if (sk->num != htons(X25_PROT))		return -EINVAL;	switch (cmd){		case SIOC_WANPIPE_ACCEPT_CALL:			if (sk->state != WANSOCK_CONNECTING){				err = -EHOSTDOWN;				break;			}						err = execute_command(sk,X25_ACCEPT_CALL,0);			if (err < 0)				break;			/* Update. Mar6 2000.                          * Do not set the sock lcn number here, since                         * it is done in wanpipe_listen_rcv().                          */ 		 	if (sk->state == WANSOCK_CONNECTED){				sk->protinfo.af_wanpipe->lcn =				((mbox_cmd_t*)sk->protinfo.af_wanpipe->mbox)->cmd.lcn;					DBG_PRINTK(KERN_INFO "\nwansock: Accept OK %i\n",					sk->protinfo.af_wanpipe->lcn );				err = 0;			}else{				DBG_PRINTK (KERN_INFO "\nwansock: Accept Failed %i\n",					sk->protinfo.af_wanpipe->lcn);				sk->protinfo.af_wanpipe->lcn = 0;				err = -ECONNREFUSED;			}			break;		case SIOC_WANPIPE_CLEAR_CALL:			if (sk->state == WANSOCK_DISCONNECTED){				err = -EINVAL;				break;			}			/* Check if data buffers are pending for transmission,                         * if so, check wheter user wants to wait untill data                         * is transmitted, or clear a call and drop packets */                          			if (atomic_read(&sk->wmem_alloc) || check_driver_busy(sk)){			  	mbox_cmd_t *mbox = sk->protinfo.af_wanpipe->mbox;				if (mbox->cmd.qdm & 0x80){					mbox->cmd.result = 0x35;					err = -EAGAIN;						break;				}			}			sk->state = WANSOCK_DISCONNECTING;			err = execute_command(sk,X25_CLEAR_CALL,0);			if (err < 0)				break;			err = -ECONNREFUSED;			if (sk->state == WANSOCK_DISCONNECTED){				DBG_PRINTK(KERN_INFO "\nwansock: CLEAR OK %i\n",					sk->protinfo.af_wanpipe->lcn);				sk->protinfo.af_wanpipe->lcn=0;				err = 0;			}			break;		case SIOC_WANPIPE_RESET_CALL:			if (sk->state != WANSOCK_CONNECTED){				err = -EINVAL;				break;			}			/* Check if data buffers are pending for transmission,                         * if so, check wheter user wants to wait untill data                         * is transmitted, or reset a call and drop packets */                          			if (atomic_read(&sk->wmem_alloc) || check_driver_busy(sk)){			  	mbox_cmd_t *mbox = sk->protinfo.af_wanpipe->mbox;				if (mbox->cmd.qdm & 0x80){					mbox->cmd.result = 0x35;					err = -EAGAIN;						break;				}			}			err = execute_command(sk, X25_RESET,0);			if (err < 0)				break;			err = mbox_ptr->cmd.result;			break;		case X25_PLACE_CALL:			err=execute_command(sk,X25_PLACE_CALL,flags);			if (err < 0)				break;			if (sk->state == WANSOCK_CONNECTED){				sk->protinfo.af_wanpipe->lcn =				((mbox_cmd_t*)sk->protinfo.af_wanpipe->mbox)->cmd.lcn;					DBG_PRINTK(KERN_INFO "\nwansock: PLACE CALL OK %i\n",					sk->protinfo.af_wanpipe->lcn);				err = 0;			}else if (sk->state == WANSOCK_CONNECTING && (flags & O_NONBLOCK)){				sk->protinfo.af_wanpipe->lcn = 				((mbox_cmd_t*)sk->protinfo.af_wanpipe->mbox)->cmd.lcn;				DBG_PRINTK(KERN_INFO "\nwansock: Place Call OK: Waiting %i\n",					sk->protinfo.af_wanpipe->lcn);				err = 0;			}else{				DBG_PRINTK(KERN_INFO "\nwansock: Place call Failed\n");				err = -ECONNREFUSED;			}			break;		default: 			return -EINVAL;	}	return err;}static int check_driver_busy (struct sock *sk){	netdevice_t *dev = dev_get_by_index(sk->bound_dev_if);	wanpipe_common_t *chan;	if (!dev)		return 0;	dev_put(dev);	if ((chan=dev->priv) == NULL)		return 0;	return atomic_read(&chan->driver_busy);}/*====================================================================== * wanpipe_accept * *	ACCEPT() System call.

⌨️ 快捷键说明

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