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

📄 synclink_cs.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		printk("%s(%d):mgslpc_throttle(%s) entry\n",			 __FILE__,__LINE__, info->device_name );	if (mgslpc_paranoia_check(info, tty->device, "mgslpc_throttle"))		return;		if (I_IXOFF(tty))		mgslpc_send_xchar(tty, STOP_CHAR(tty));  	if (tty->termios->c_cflag & CRTSCTS) {		spin_lock_irqsave(&info->lock,flags);		info->serial_signals &= ~SerialSignal_RTS;	 	set_signals(info);		spin_unlock_irqrestore(&info->lock,flags);	}}/* Signal remote device to stop throttling send data (our receive data) */static void mgslpc_unthrottle(struct tty_struct * tty){	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	unsigned long flags;		if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgslpc_unthrottle(%s) entry\n",			 __FILE__,__LINE__, info->device_name );	if (mgslpc_paranoia_check(info, tty->device, "mgslpc_unthrottle"))		return;		if (I_IXOFF(tty)) {		if (info->x_char)			info->x_char = 0;		else			mgslpc_send_xchar(tty, START_CHAR(tty));	}	 	if (tty->termios->c_cflag & CRTSCTS) {		spin_lock_irqsave(&info->lock,flags);		info->serial_signals |= SerialSignal_RTS;	 	set_signals(info);		spin_unlock_irqrestore(&info->lock,flags);	}}/* get the current serial statistics */static int get_stats(MGSLPC_INFO * info, struct mgsl_icount *user_icount){	int err;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("get_params(%s)\n", info->device_name);	COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));	if (err)		return -EFAULT;	return 0;}/* get the current serial parameters */static int get_params(MGSLPC_INFO * info, MGSL_PARAMS *user_params){	int err;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("get_params(%s)\n", info->device_name);	COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));	if (err)		return -EFAULT;	return 0;}/* set the serial parameters * 	 * Arguments: *  * 	info		pointer to device instance data * 	new_params	user buffer containing new serial params * * Returns:	0 if success, otherwise error code */static int set_params(MGSLPC_INFO * info, MGSL_PARAMS *new_params){ 	unsigned long flags;	MGSL_PARAMS tmp_params;	int err; 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):set_params %s\n", __FILE__,__LINE__,			info->device_name );	COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS));	if (err) {		if ( debug_level >= DEBUG_LEVEL_INFO )			printk( "%s(%d):set_params(%s) user buffer copy failed\n",				__FILE__,__LINE__,info->device_name);		return -EFAULT;	}		spin_lock_irqsave(&info->lock,flags);	memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));	spin_unlock_irqrestore(&info->lock,flags);	 	mgslpc_change_params(info);		return 0;}static int get_txidle(MGSLPC_INFO * info, int*idle_mode){	int err;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("get_txidle(%s)=%d\n", info->device_name, info->idle_mode);	COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int));	if (err)		return -EFAULT;	return 0;}static int set_txidle(MGSLPC_INFO * info, int idle_mode){ 	unsigned long flags;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("set_txidle(%s,%d)\n", info->device_name, idle_mode);	spin_lock_irqsave(&info->lock,flags);	info->idle_mode = idle_mode;	tx_set_idle(info);	spin_unlock_irqrestore(&info->lock,flags);	return 0;}static int get_interface(MGSLPC_INFO * info, int*if_mode){	int err;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("get_interface(%s)=%d\n", info->device_name, info->if_mode);	COPY_TO_USER(err,if_mode, &info->if_mode, sizeof(int));	if (err)		return -EFAULT;	return 0;}static int set_interface(MGSLPC_INFO * info, int if_mode){ 	unsigned long flags;	unsigned char val;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("set_interface(%s,%d)\n", info->device_name, if_mode);	spin_lock_irqsave(&info->lock,flags);	info->if_mode = if_mode;	val = read_reg(info, PVR) & 0x0f;	switch (info->if_mode)	{	case MGSL_INTERFACE_RS232: val |= PVR_RS232; break;	case MGSL_INTERFACE_V35:   val |= PVR_V35;   break;	case MGSL_INTERFACE_RS422: val |= PVR_RS422; break;	}	write_reg(info, PVR, val);	spin_unlock_irqrestore(&info->lock,flags);	return 0;}static int set_txenable(MGSLPC_INFO * info, int enable){ 	unsigned long flags; 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("set_txenable(%s,%d)\n", info->device_name, enable);				spin_lock_irqsave(&info->lock,flags);	if (enable) {		if (!info->tx_enabled)			tx_start(info);	} else {		if (info->tx_enabled)			tx_stop(info);	}	spin_unlock_irqrestore(&info->lock,flags);	return 0;}static int tx_abort(MGSLPC_INFO * info){ 	unsigned long flags; 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("tx_abort(%s)\n", info->device_name);				spin_lock_irqsave(&info->lock,flags);	if (info->tx_active && info->tx_count &&	    info->params.mode == MGSL_MODE_HDLC) {		/* clear data count so FIFO is not filled on next IRQ.		 * This results in underrun and abort transmission.		 */		info->tx_count = info->tx_put = info->tx_get = 0;		info->tx_aborting = TRUE;	}	spin_unlock_irqrestore(&info->lock,flags);	return 0;}static int set_rxenable(MGSLPC_INFO * info, int enable){ 	unsigned long flags; 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("set_rxenable(%s,%d)\n", info->device_name, enable);				spin_lock_irqsave(&info->lock,flags);	if (enable) {		if (!info->rx_enabled)			rx_start(info);	} else {		if (info->rx_enabled)			rx_stop(info);	}	spin_unlock_irqrestore(&info->lock,flags);	return 0;}/* wait for specified event to occur * 	 * Arguments:	 	info	pointer to device instance data * 			mask	pointer to bitmask of events to wait for * Return Value:	0 	if successful and bit mask updated with *				of events triggerred, * 			otherwise error code */static int wait_events(MGSLPC_INFO * info, int * mask_ptr){ 	unsigned long flags;	int s;	int rc=0;	struct mgsl_icount cprev, cnow;	int events;	int mask;	struct	_input_signal_events oldsigs, newsigs;	DECLARE_WAITQUEUE(wait, current);	COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int));	if (rc)		return  -EFAULT;		 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("wait_events(%s,%d)\n", info->device_name, mask);	spin_lock_irqsave(&info->lock,flags);	/* return immediately if state matches requested events */	get_signals(info);	s = info->serial_signals;	events = mask &		( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + 		  ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +		  ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +		  ((s & SerialSignal_RI)  ? MgslEvent_RiActive :MgslEvent_RiInactive) );	if (events) {		spin_unlock_irqrestore(&info->lock,flags);		goto exit;	}	/* save current irq counts */	cprev = info->icount;	oldsigs = info->input_signal_events;		if ((info->params.mode == MGSL_MODE_HDLC) &&	    (mask & MgslEvent_ExitHuntMode))		irq_enable(info, CHA, IRQ_EXITHUNT);		set_current_state(TASK_INTERRUPTIBLE);	add_wait_queue(&info->event_wait_q, &wait);		spin_unlock_irqrestore(&info->lock,flags);			for(;;) {		schedule();		if (signal_pending(current)) {			rc = -ERESTARTSYS;			break;		}					/* get current irq counts */		spin_lock_irqsave(&info->lock,flags);		cnow = info->icount;		newsigs = info->input_signal_events;		set_current_state(TASK_INTERRUPTIBLE);		spin_unlock_irqrestore(&info->lock,flags);		/* if no change, wait aborted for some reason */		if (newsigs.dsr_up   == oldsigs.dsr_up   &&		    newsigs.dsr_down == oldsigs.dsr_down &&		    newsigs.dcd_up   == oldsigs.dcd_up   &&		    newsigs.dcd_down == oldsigs.dcd_down &&		    newsigs.cts_up   == oldsigs.cts_up   &&		    newsigs.cts_down == oldsigs.cts_down &&		    newsigs.ri_up    == oldsigs.ri_up    &&		    newsigs.ri_down  == oldsigs.ri_down  &&		    cnow.exithunt    == cprev.exithunt   &&		    cnow.rxidle      == cprev.rxidle) {			rc = -EIO;			break;		}		events = mask &			( (newsigs.dsr_up   != oldsigs.dsr_up   ? MgslEvent_DsrActive:0)   +			  (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +			  (newsigs.dcd_up   != oldsigs.dcd_up   ? MgslEvent_DcdActive:0)   +			  (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +			  (newsigs.cts_up   != oldsigs.cts_up   ? MgslEvent_CtsActive:0)   +			  (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +			  (newsigs.ri_up    != oldsigs.ri_up    ? MgslEvent_RiActive:0)    +			  (newsigs.ri_down  != oldsigs.ri_down  ? MgslEvent_RiInactive:0)  +			  (cnow.exithunt    != cprev.exithunt   ? MgslEvent_ExitHuntMode:0) +			  (cnow.rxidle      != cprev.rxidle     ? MgslEvent_IdleReceived:0) );		if (events)			break;				cprev = cnow;		oldsigs = newsigs;	}		remove_wait_queue(&info->event_wait_q, &wait);	set_current_state(TASK_RUNNING);	if (mask & MgslEvent_ExitHuntMode) {		spin_lock_irqsave(&info->lock,flags);		if (!waitqueue_active(&info->event_wait_q))			irq_disable(info, CHA, IRQ_EXITHUNT);		spin_unlock_irqrestore(&info->lock,flags);	}exit:	if (rc == 0)		PUT_USER(rc, events, mask_ptr);	return rc;}static int modem_input_wait(MGSLPC_INFO *info,int arg){ 	unsigned long flags;	int rc;	struct mgsl_icount cprev, cnow;	DECLARE_WAITQUEUE(wait, current);	/* save current irq counts */	spin_lock_irqsave(&info->lock,flags);	cprev = info->icount;	add_wait_queue(&info->status_event_wait_q, &wait);	set_current_state(TASK_INTERRUPTIBLE);	spin_unlock_irqrestore(&info->lock,flags);	for(;;) {		schedule();		if (signal_pending(current)) {			rc = -ERESTARTSYS;			break;		}		/* get new irq counts */		spin_lock_irqsave(&info->lock,flags);		cnow = info->icount;		set_current_state(TASK_INTERRUPTIBLE);		spin_unlock_irqrestore(&info->lock,flags);		/* if no change, wait aborted for some reason */		if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&		    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {			rc = -EIO;			break;		}		/* check for change in caller specified modem input */		if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||		    (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||		    (arg & TIOCM_CD  && cnow.dcd != cprev.dcd) ||		    (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {			rc = 0;			break;		}		cprev = cnow;	}	remove_wait_queue(&info->status_event_wait_q, &wait);	set_current_state(TASK_RUNNING);	return rc;}/* Return state of the serial control/status signals * 	 * Arguments:	 	info	pointer to device instance data * 			value	pointer to int to hold returned info * 	 * Return Value:	0 if success, otherwise error code */static int get_modem_info(MGSLPC_INFO * info, unsigned int *value){	unsigned int result; 	unsigned long flags;	int err; 	spin_lock_irqsave(&info->lock,flags); 	get_signals(info);	spin_unlock_irqrestore(&info->lock,flags);	result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) |		 ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) |		 ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) |		 ((info->serial_signals & SerialSignal_RI)  ? TIOCM_RNG:0) |		 ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) |		 ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0);	if (debug_level >= DEBUG_LEVEL_INFO)		printk("mgslpc_get_modem_info %s value=%08X\n", info->device_name, result);				PUT_USER(err,result,value);	return err ? -EFAULT : 0;}/* Set the state of the modem control signals (DTR/RTS) * 	 * Arguments: *  * 	info	pointer to device instance data * 	cmd	signal command: TIOCMBIS = set bit TIOCMBIC = clear bit *		TIOCMSET = set/clear signal values * 	value	bit mask for command * 	 * Return Value:	0 if success, otherwise error code */static int set_modem_info(MGSLPC_INFO * info, unsigned int cmd,			  unsigned int *value){ 	int error; 	unsigned int arg; 	unsigned long flags; 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("mgslpc_set_modem_info %s\n", info->device_name);			 	GET_USER(error,arg,value); 	if (error) 		return error;		 	switch (cmd) { 	case TIOCMBIS:  		if (arg & TIOCM_RTS) 			info->serial_signals |= SerialSignal_RTS; 		if (arg & TIOCM_DTR) 			info->serial_signals |= SerialSignal_DTR; 		break; 	case TIOCMBIC: 		if (arg & TIOCM_RTS) 			info->serial_signals &= ~SerialSignal_RTS; 		if (arg & TIOCM_DTR) 			info->serial_signals &= ~SerialSignal_DTR; 		break; 	case TIOCMSET: 		if (arg & TIOCM_RTS) 			info->serial_signals |= SerialSignal_RTS;		else 			info->serial_signals &= ~SerialSignal_RTS;		 		if (arg & TIOCM_DTR) 			info->serial_signals |= SerialSignal_DTR;		else 			info->serial_signals &= ~SerialSignal_DTR; 		break; 	default: 		return -EINVAL; 	}		spin_lock_irqsave(&info->lock,flags); 	set_signals(info);	spin_unlock_irqrestore(&info->lock,flags);		return 0;}/* Set or clear transmit break condition * * Arguments:		tty		pointer to tty instance data *			break_state	-1=set break condition, 0=clear */static void mgslpc_break(struct tty_struct *tty, int break_state){	MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;	unsigned long flags;		if (d

⌨️ 快捷键说明

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