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

📄 console.c

📁 linux-2.6.15.6
💻 C
字号:
/* * USB Serial Console driver * * Copyright (C) 2001 - 2002 Greg Kroah-Hartman (greg@kroah.com) * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License version *	2 as published by the Free Software Foundation. *  * Thanks to Randy Dunlap for the original version of this code. * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/tty.h>#include <linux/console.h>#include <linux/usb.h>static int debug;#include "usb-serial.h"struct usbcons_info {	int			magic;	int			break_flag;	struct usb_serial_port	*port;};static struct usbcons_info usbcons_info;static struct console usbcons;/* * ------------------------------------------------------------ * USB Serial console driver * * Much of the code here is copied from drivers/char/serial.c * and implements a phony serial console in the same way that * serial.c does so that in case some software queries it, * it will get the same results. * * Things that are different from the way the serial port code * does things, is that we call the lower level usb-serial * driver code to initialize the device, and we set the initial * console speeds based on the command line arguments. * ------------------------------------------------------------ *//* * The parsing of the command line works exactly like the * serial.c code, except that the specifier is "ttyUSB" instead * of "ttyS". */static int __init usb_console_setup(struct console *co, char *options){	struct usbcons_info *info = &usbcons_info;	int baud = 9600;	int bits = 8;	int parity = 'n';	int doflow = 0;	int cflag = CREAD | HUPCL | CLOCAL;	char *s;	struct usb_serial *serial;	struct usb_serial_port *port;	int retval = 0;	struct tty_struct *tty;	struct termios *termios;	dbg ("%s", __FUNCTION__);	if (options) {		baud = simple_strtoul(options, NULL, 10);		s = options;		while (*s >= '0' && *s <= '9')			s++;		if (*s)			parity = *s++;		if (*s)			bits   = *s++ - '0';		if (*s)			doflow = (*s++ == 'r');	}	/* build a cflag setting */	switch (baud) {		case 1200:			cflag |= B1200;			break;		case 2400:			cflag |= B2400;			break;		case 4800:			cflag |= B4800;			break;		case 19200:			cflag |= B19200;			break;		case 38400:			cflag |= B38400;			break;		case 57600:			cflag |= B57600;			break;		case 115200:			cflag |= B115200;			break;		case 9600:		default:			cflag |= B9600;			/*			 * Set this to a sane value to prevent a divide error			 */			baud  = 9600;			break;	}	switch (bits) {		case 7:			cflag |= CS7;			break;		default:		case 8:			cflag |= CS8;			break;	}	switch (parity) {		case 'o': case 'O':			cflag |= PARODD;			break;		case 'e': case 'E':			cflag |= PARENB;			break;	}	co->cflag = cflag;	/* grab the first serial port that happens to be connected */	serial = usb_serial_get_by_index(0);	if (serial == NULL) {		/* no device is connected yet, sorry :( */		err ("No USB device connected to ttyUSB0");		return -ENODEV;	}	port = serial->port[0];	port->tty = NULL;	info->port = port;	 	++port->open_count;	if (port->open_count == 1) {		/* only call the device specific open if this 		 * is the first time the port is opened */		if (serial->type->open)			retval = serial->type->open(port, NULL);		else			retval = usb_serial_generic_open(port, NULL);		if (retval)			port->open_count = 0;	}	if (retval) {		err ("could not open USB console port");		return retval;	}	if (serial->type->set_termios) {		/* build up a fake tty structure so that the open call has something		 * to look at to get the cflag value */		tty = kmalloc (sizeof (*tty), GFP_KERNEL);		if (!tty) {			err ("no more memory");			return -ENOMEM;		}		termios = kmalloc (sizeof (*termios), GFP_KERNEL);		if (!termios) {			err ("no more memory");			kfree (tty);			return -ENOMEM;		}		memset (tty, 0x00, sizeof(*tty));		memset (termios, 0x00, sizeof(*termios));		termios->c_cflag = cflag;		tty->termios = termios;		port->tty = tty;		/* set up the initial termios settings */		serial->type->set_termios(port, NULL);		port->tty = NULL;		kfree (termios);		kfree (tty);	}	return retval;}static void usb_console_write(struct console *co, const char *buf, unsigned count){	static struct usbcons_info *info = &usbcons_info;	struct usb_serial_port *port = info->port;	struct usb_serial *serial;	int retval = -ENODEV;	if (!port)		return;	serial = port->serial;	if (count == 0)		return;	dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);	if (!port->open_count) {		dbg ("%s - port not opened", __FUNCTION__);		goto exit;	}	/* pass on to the driver specific version of this function if it is available */	if (serial->type->write)		retval = serial->type->write(port, buf, count);	else		retval = usb_serial_generic_write(port, buf, count);exit:	dbg("%s - return value (if we had one): %d", __FUNCTION__, retval);}static struct console usbcons = {	.name =		"ttyUSB",	.write =	usb_console_write,	.setup =	usb_console_setup,	.flags =	CON_PRINTBUFFER,	.index =	-1,};void usb_serial_console_init (int serial_debug, int minor){	debug = serial_debug;	if (minor == 0) {		/* 		 * Call register_console() if this is the first device plugged		 * in.  If we call it earlier, then the callback to		 * console_setup() will fail, as there is not a device seen by		 * the USB subsystem yet.		 */		/*		 * Register console.		 * NOTES:		 * console_setup() is called (back) immediately (from register_console).		 * console_write() is called immediately from register_console iff		 * CON_PRINTBUFFER is set in flags.		 */		dbg ("registering the USB serial console.");		register_console(&usbcons);	}}void usb_serial_console_exit (void){	unregister_console(&usbcons);}

⌨️ 快捷键说明

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