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

📄 synclink_cs.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* if B0 rate (hangup) specified then negate DTR and RTS */	/* otherwise assert DTR and RTS */ 	if (cflag & CBAUD)		info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;	else		info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);		/* byte size and parity */		switch (cflag & CSIZE) {	case CS5: info->params.data_bits = 5; break;	case CS6: info->params.data_bits = 6; break;	case CS7: info->params.data_bits = 7; break;	case CS8: info->params.data_bits = 8; break;	default:  info->params.data_bits = 7; break;	}	      	if (cflag & CSTOPB)		info->params.stop_bits = 2;	else		info->params.stop_bits = 1;	info->params.parity = ASYNC_PARITY_NONE;	if (cflag & PARENB) {		if (cflag & PARODD)			info->params.parity = ASYNC_PARITY_ODD;		else			info->params.parity = ASYNC_PARITY_EVEN;#ifdef CMSPAR		if (cflag & CMSPAR)			info->params.parity = ASYNC_PARITY_SPACE;#endif	}	/* calculate number of jiffies to transmit a full	 * FIFO (32 bytes) at specified data rate	 */	bits_per_char = info->params.data_bits + 			info->params.stop_bits + 1;	/* if port data rate is set to 460800 or less then	 * allow tty settings to override, otherwise keep the	 * current data rate.	 */	if (info->params.data_rate <= 460800) {		info->params.data_rate = tty_get_baud_rate(info->tty);	}		if ( info->params.data_rate ) {		info->timeout = (32*HZ*bits_per_char) / 				info->params.data_rate;	}	info->timeout += HZ/50;		/* Add .02 seconds of slop */	if (cflag & CRTSCTS)		info->flags |= ASYNC_CTS_FLOW;	else		info->flags &= ~ASYNC_CTS_FLOW;			if (cflag & CLOCAL)		info->flags &= ~ASYNC_CHECK_CD;	else		info->flags |= ASYNC_CHECK_CD;	/* process tty input control flags */		info->read_status_mask = 0;	if (I_INPCK(info->tty))		info->read_status_mask |= BIT7 | BIT6;	if (I_IGNPAR(info->tty))		info->ignore_status_mask |= BIT7 | BIT6;	mgslpc_program_hw(info);}/* Add a character to the transmit buffer */static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch){	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	unsigned long flags;	if (debug_level >= DEBUG_LEVEL_INFO) {		printk( "%s(%d):mgslpc_put_char(%d) on %s\n",			__FILE__,__LINE__,ch,info->device_name);	}	if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char"))		return;	if (!tty || !info->tx_buf)		return;	spin_lock_irqsave(&info->lock,flags);		if (info->params.mode == MGSL_MODE_ASYNC || !info->tx_active) {		if (info->tx_count < TXBUFSIZE - 1) {			info->tx_buf[info->tx_put++] = ch;			info->tx_put &= TXBUFSIZE-1;			info->tx_count++;		}	}		spin_unlock_irqrestore(&info->lock,flags);}/* Enable transmitter so remaining characters in the * transmit buffer are sent. */static void mgslpc_flush_chars(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_flush_chars() entry on %s tx_count=%d\n",			__FILE__,__LINE__,info->device_name,info->tx_count);		if (mgslpc_paranoia_check(info, tty->name, "mgslpc_flush_chars"))		return;	if (info->tx_count <= 0 || tty->stopped ||	    tty->hw_stopped || !info->tx_buf)		return;	if (debug_level >= DEBUG_LEVEL_INFO)		printk( "%s(%d):mgslpc_flush_chars() entry on %s starting transmitter\n",			__FILE__,__LINE__,info->device_name);	spin_lock_irqsave(&info->lock,flags);	if (!info->tx_active)	 	tx_start(info);	spin_unlock_irqrestore(&info->lock,flags);}/* Send a block of data * 	 * Arguments: *  * tty        pointer to tty information structure * buf	      pointer to buffer containing send data * count      size of send data in bytes * 	 * Returns: number of characters written */static int mgslpc_write(struct tty_struct * tty,			const unsigned char *buf, int count){	int c, ret = 0;	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	unsigned long flags;		if (debug_level >= DEBUG_LEVEL_INFO)		printk( "%s(%d):mgslpc_write(%s) count=%d\n",			__FILE__,__LINE__,info->device_name,count);		if (mgslpc_paranoia_check(info, tty->name, "mgslpc_write") ||	    !tty || !info->tx_buf)		goto cleanup;	if (info->params.mode == MGSL_MODE_HDLC) {		if (count > TXBUFSIZE) {			ret = -EIO;			goto cleanup;		}		if (info->tx_active)			goto cleanup;		else if (info->tx_count)			goto start;	}	for (;;) {		c = min(count,			min(TXBUFSIZE - info->tx_count - 1,			    TXBUFSIZE - info->tx_put));		if (c <= 0)			break;					memcpy(info->tx_buf + info->tx_put, buf, c);		spin_lock_irqsave(&info->lock,flags);		info->tx_put = (info->tx_put + c) & (TXBUFSIZE-1);		info->tx_count += c;		spin_unlock_irqrestore(&info->lock,flags);		buf += c;		count -= c;		ret += c;	}start: 	if (info->tx_count && !tty->stopped && !tty->hw_stopped) {		spin_lock_irqsave(&info->lock,flags);		if (!info->tx_active)		 	tx_start(info);		spin_unlock_irqrestore(&info->lock,flags); 	}cleanup:		if (debug_level >= DEBUG_LEVEL_INFO)		printk( "%s(%d):mgslpc_write(%s) returning=%d\n",			__FILE__,__LINE__,info->device_name,ret);	return ret;}/* Return the count of free bytes in transmit buffer */static int mgslpc_write_room(struct tty_struct *tty){	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	int ret;					if (mgslpc_paranoia_check(info, tty->name, "mgslpc_write_room"))		return 0;	if (info->params.mode == MGSL_MODE_HDLC) {		/* HDLC (frame oriented) mode */		if (info->tx_active)			return 0;		else			return HDLC_MAX_FRAME_SIZE;	} else {		ret = TXBUFSIZE - info->tx_count - 1;		if (ret < 0)			ret = 0;	}		if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgslpc_write_room(%s)=%d\n",			 __FILE__,__LINE__, info->device_name, ret);	return ret;}/* Return the count of bytes in transmit buffer */static int mgslpc_chars_in_buffer(struct tty_struct *tty){	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	int rc;		 	if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgslpc_chars_in_buffer(%s)\n",			 __FILE__,__LINE__, info->device_name );			 	if (mgslpc_paranoia_check(info, tty->name, "mgslpc_chars_in_buffer"))		return 0;			if (info->params.mode == MGSL_MODE_HDLC)		rc = info->tx_active ? info->max_frame_size : 0;	else		rc = info->tx_count;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgslpc_chars_in_buffer(%s)=%d\n",			 __FILE__,__LINE__, info->device_name, rc);			 	return rc;}/* Discard all data in the send buffer */static void mgslpc_flush_buffer(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_flush_buffer(%s) entry\n",			 __FILE__,__LINE__, info->device_name );		if (mgslpc_paranoia_check(info, tty->name, "mgslpc_flush_buffer"))		return;			spin_lock_irqsave(&info->lock,flags); 	info->tx_count = info->tx_put = info->tx_get = 0;	del_timer(&info->tx_timer);		spin_unlock_irqrestore(&info->lock,flags);	wake_up_interruptible(&tty->write_wait);	tty_wakeup(tty);}/* Send a high-priority XON/XOFF character */static void mgslpc_send_xchar(struct tty_struct *tty, char ch){	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;	unsigned long flags;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgslpc_send_xchar(%s,%d)\n",			 __FILE__,__LINE__, info->device_name, ch );			 	if (mgslpc_paranoia_check(info, tty->name, "mgslpc_send_xchar"))		return;	info->x_char = ch;	if (ch) {		spin_lock_irqsave(&info->lock,flags);		if (!info->tx_enabled)		 	tx_start(info);		spin_unlock_irqrestore(&info->lock,flags);	}}/* Signal remote device to throttle send data (our receive data) */static void mgslpc_throttle(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_throttle(%s) entry\n",			 __FILE__,__LINE__, info->device_name );	if (mgslpc_paranoia_check(info, tty->name, "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->name, "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 *user_icount){	int err;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("get_params(%s)\n", info->device_name);	if (!user_icount) {		memset(&info->icount, 0, sizeof(info->icount));	} else {		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 *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 __user *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 __user *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 __user *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)

⌨️ 快捷键说明

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