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

📄 ctctty.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif	/*	 * Now, initialize the UART	 */	info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;	if (info->tty)		clear_bit(TTY_IO_ERROR, &info->tty->flags);	/*	 * and set the speed of the serial port	 */	ctc_tty_change_speed(info);	info->flags |= CTC_ASYNC_INITIALIZED;	if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))		info->netdev->open(info->netdev);	info->flags |= CTC_ASYNC_NETDEV_OPEN;	return 0;}static voidctc_tty_stopdev(unsigned long data){	ctc_tty_info *info = (ctc_tty_info *)data;	if ((!info) || (!info->netdev) ||	    (info->flags & CTC_ASYNC_INITIALIZED))		return;	info->netdev->stop(info->netdev);	info->flags &= ~CTC_ASYNC_NETDEV_OPEN;}/* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. */static voidctc_tty_shutdown(ctc_tty_info * info){	DBF_TEXT(trace, 3, __FUNCTION__);	if (!(info->flags & CTC_ASYNC_INITIALIZED))		return;#ifdef CTC_DEBUG_MODEM_OPEN	printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);#endif	info->msr &= ~UART_MSR_RI;	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))		info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);	if (info->tty)		set_bit(TTY_IO_ERROR, &info->tty->flags);	mod_timer(&info->stoptimer, jiffies + (10 * HZ));	skb_queue_purge(&info->tx_queue);	skb_queue_purge(&info->rx_queue);	info->flags &= ~CTC_ASYNC_INITIALIZED;}/* ctc_tty_write() is the main send-routine. It is called from the upper * levels within the kernel to perform sending data. Depending on the * online-flag it either directs output to the at-command-interpreter or * to the lower level. Additional tasks done here: *  - If online, check for escape-sequence (+++) *  - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes. *  - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed. *  - If dialing, abort dial. */static intctc_tty_write(struct tty_struct *tty, const u_char * buf, int count){	int c;	int total = 0;	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	DBF_TEXT(trace, 5, __FUNCTION__);	if (ctc_tty_shuttingdown)		goto ex;	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))		goto ex;	if (!tty)		goto ex;	if (!info->netdev) {		total = -ENODEV;		goto ex;	}	while (1) {		struct sk_buff *skb;		int skb_res;		c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;		if (c <= 0)			break;				skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +			+ sizeof(__u32);		skb = dev_alloc_skb(skb_res + c);		if (!skb) {			printk(KERN_WARNING			       "ctc_tty: Out of memory in %s%d write\n",			       CTC_TTY_NAME, info->line);			break;		}		skb_reserve(skb, skb_res);		memcpy(skb_put(skb, c), buf, c);		skb_queue_tail(&info->tx_queue, skb);		buf += c;		total += c;		count -= c;	}	if (!skb_queue_empty(&info->tx_queue)) {		info->lsr &= ~UART_LSR_TEMT;		tasklet_schedule(&info->tasklet);	}ex:	DBF_TEXT(trace, 6, __FUNCTION__);	return total;}static intctc_tty_write_room(struct tty_struct *tty){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))		return 0;	return CTC_TTY_XMIT_SIZE;}static intctc_tty_chars_in_buffer(struct tty_struct *tty){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))		return 0;	return 0;}static voidctc_tty_flush_buffer(struct tty_struct *tty){	ctc_tty_info *info;	unsigned long flags;	DBF_TEXT(trace, 4, __FUNCTION__);	if (!tty)		goto ex;	spin_lock_irqsave(&ctc_tty_lock, flags);	info = (ctc_tty_info *) tty->driver_data;	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {		spin_unlock_irqrestore(&ctc_tty_lock, flags);		goto ex;	}	skb_queue_purge(&info->tx_queue);	info->lsr |= UART_LSR_TEMT;	spin_unlock_irqrestore(&ctc_tty_lock, flags);	wake_up_interruptible(&tty->write_wait);	tty_wakeup(tty);ex:	DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);	return;}static voidctc_tty_flush_chars(struct tty_struct *tty){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_shuttingdown)		return;	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))		return;	if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))		return;	tasklet_schedule(&info->tasklet);}/* * ------------------------------------------------------------ * ctc_tty_throttle() * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ */static voidctc_tty_throttle(struct tty_struct *tty){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))		return;	info->mcr &= ~UART_MCR_RTS;	if (I_IXOFF(tty))		ctc_tty_inject(info, STOP_CHAR(tty));	ctc_tty_transmit_status(info);}static voidctc_tty_unthrottle(struct tty_struct *tty){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))		return;	info->mcr |= UART_MCR_RTS;	if (I_IXOFF(tty))		ctc_tty_inject(info, START_CHAR(tty));	ctc_tty_transmit_status(info);}/* * ------------------------------------------------------------ * ctc_tty_ioctl() and friends * ------------------------------------------------------------ *//* * ctc_tty_get_lsr_info - get line status register info * * Purpose: Let user call ioctl() to get info when the UART physically *          is emptied.  On bus types like RS485, the transmitter must *          release the bus after transmitting. This must be done when *          the transmit shift register is empty, not be done when the *          transmit holding register is empty.  This functionality *          allows RS485 driver to be written in user space. */static intctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value){	u_char status;	uint result;	ulong flags;	DBF_TEXT(trace, 4, __FUNCTION__);	spin_lock_irqsave(&ctc_tty_lock, flags);	status = info->lsr;	spin_unlock_irqrestore(&ctc_tty_lock, flags);	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);	put_user(result, value);	return 0;}static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	u_char control,	 status;	uint result;	ulong flags;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))		return -ENODEV;	if (tty->flags & (1 << TTY_IO_ERROR))		return -EIO;	control = info->mcr;	spin_lock_irqsave(&ctc_tty_lock, flags);	status = info->msr;	spin_unlock_irqrestore(&ctc_tty_lock, flags);	result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)	    | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)	    | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)	    | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)	    | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)	    | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);	return result;}static intctc_tty_tiocmset(struct tty_struct *tty, struct file *file,		 unsigned int set, unsigned int clear){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))		return -ENODEV;	if (tty->flags & (1 << TTY_IO_ERROR))		return -EIO;	if (set & TIOCM_RTS)		info->mcr |= UART_MCR_RTS;	if (set & TIOCM_DTR)		info->mcr |= UART_MCR_DTR;	if (clear & TIOCM_RTS)		info->mcr &= ~UART_MCR_RTS;	if (clear & TIOCM_DTR)		info->mcr &= ~UART_MCR_DTR;	if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))		ctc_tty_transmit_status(info);	return 0;}static intctc_tty_ioctl(struct tty_struct *tty, struct file *file,	       uint cmd, ulong arg){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	int error;	int retval;	DBF_TEXT(trace, 4, __FUNCTION__);	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))		return -ENODEV;	if (tty->flags & (1 << TTY_IO_ERROR))		return -EIO;	switch (cmd) {		case TCSBRK:   /* SVID version: non-zero arg --> no break */#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);#endif			retval = tty_check_change(tty);			if (retval)				return retval;			tty_wait_until_sent(tty, 0);			return 0;		case TCSBRKP:  /* support for POSIX tcsendbreak() */#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);#endif			retval = tty_check_change(tty);			if (retval)				return retval;			tty_wait_until_sent(tty, 0);			return 0;		case TIOCGSOFTCAR:#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,			       info->line);#endif			error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);			return error;		case TIOCSSOFTCAR:#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,			       info->line);#endif			error = get_user(arg, (ulong __user *) arg);			if (error)				return error;			tty->termios->c_cflag =			    ((tty->termios->c_cflag & ~CLOCAL) |			     (arg ? CLOCAL : 0));			return 0;		case TIOCSERGETLSR:	/* Get line status register */#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,			       info->line);#endif			if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint)))				return ctc_tty_get_lsr_info(info, (uint __user *) arg);			else				return -EFAULT;		default:#ifdef CTC_DEBUG_MODEM_IOCTL			printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,			       CTC_TTY_NAME, info->line);#endif			return -ENOIOCTLCMD;	}	return 0;}static voidctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios){	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;	unsigned int cflag = tty->termios->c_cflag;	DBF_TEXT(trace, 4, __FUNCTION__);	ctc_tty_change_speed(info);	/* Handle transition to B0 */	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {		info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);		ctc_tty_transmit_status(info);	}	/* Handle transition from B0 to other */	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {		info->mcr |= UART_MCR_DTR;		if (!(tty->termios->c_cflag & CRTSCTS) ||                    !test_bit(TTY_THROTTLED, &tty->flags)) {                        info->mcr |= UART_MCR_RTS;                }		ctc_tty_transmit_status(info);	}	/* Handle turning off CRTSCTS */	if ((old_termios->c_cflag & CRTSCTS) &&            !(tty->termios->c_cflag & CRTSCTS))                tty->hw_stopped = 0;}/* * ------------------------------------------------------------ * ctc_tty_open() and friends * ------------------------------------------------------------ */static intctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info){	DECLARE_WAITQUEUE(wait, NULL);	int do_clocal = 0;	unsigned long flags;	int retval;	DBF_TEXT(trace, 4, __FUNCTION__);	/*	 * If the device is in the middle of being closed, then block	 * until it's done, and then try again.	 */	if (tty_hung_up_p(filp) ||	    (info->flags & CTC_ASYNC_CLOSING)) {		if (info->flags & CTC_ASYNC_CLOSING)			wait_event(info->close_wait, 				   !(info->flags & CTC_ASYNC_CLOSING));#ifdef MODEM_DO_RESTART		if (info->flags & CTC_ASYNC_HUP_NOTIFY)			return -EAGAIN;		else

⌨️ 快捷键说明

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