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

📄 console.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_leds();}/* * Turn the Scroll-Lock LED off when the console is started */static void con_start(struct tty_struct *tty){	int console_num;	if (!tty)		return;	console_num = MINOR(tty->device) - (tty->driver.minor_start);	if (!vc_cons_allocated(console_num))		return;	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);	set_leds();}static void con_flush_chars(struct tty_struct *tty){	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;	set_cursor(vt->vc_num);}/* * Allocate the console screen memory. */static int con_open(struct tty_struct *tty, struct file * filp){	unsigned int	currcons;	int i;	currcons = MINOR(tty->device) - tty->driver.minor_start;	i = vc_allocate(currcons);	if (i)		return i;	vt_cons[currcons]->vc_num = currcons;	tty->driver_data = vt_cons[currcons];	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {		tty->winsize.ws_row = video_num_lines;		tty->winsize.ws_col = video_num_columns;	}	return 0;}static void con_close(struct tty_struct *tty, struct file * filp){	if (tty->count == 1)		tty->driver_data = 0;}static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear){	int j, k ;	video_num_columns = cols;	video_num_lines = rows;	video_size_row = cols<<1;	screenbuf_size = video_num_lines * video_size_row;	set_origin(currcons);	pos = origin;	reset_vc(currcons);	for (j=k=0; j<16; j++) {		vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;		vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;		vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;	}	def_color       = 0x07;   /* white */	ulcolor		= 0x0f;   /* bold white */	halfcolor       = 0x08;   /* grey */	vt_cons[currcons]->paste_wait = 0;	reset_terminal(currcons, do_clear);}/* * This routine initializes console interrupts, and does nothing * else. If you want the screen to clear, call tty_write with * the appropriate escape-sequence. */struct tty_driver console_driver;static int console_refcount;__initfunc(unsigned long con_init(unsigned long kmem_start)){	const char *display_desc = NULL;	unsigned int currcons = 0;	if (conswitchp)		display_desc = conswitchp->con_startup();	if (!display_desc) {		fg_console = 0;		return kmem_start;	}	memset(&console_driver, 0, sizeof(struct tty_driver));	console_driver.magic = TTY_DRIVER_MAGIC;	console_driver.name = "tty";	console_driver.name_base = 1;	console_driver.major = TTY_MAJOR;	console_driver.minor_start = 1;	console_driver.num = MAX_NR_CONSOLES;	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;	console_driver.init_termios = tty_std_termios;	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;	console_driver.refcount = &console_refcount;	console_driver.table = console_table;	console_driver.termios = console_termios;	console_driver.termios_locked = console_termios_locked;	console_driver.open = con_open;	console_driver.close = con_close;	console_driver.write = con_write;	console_driver.write_room = con_write_room;	console_driver.put_char = con_put_char;	console_driver.flush_chars = con_flush_chars;	console_driver.chars_in_buffer = con_chars_in_buffer;	console_driver.ioctl = vt_ioctl;	console_driver.stop = con_stop;	console_driver.start = con_start;	console_driver.throttle = con_throttle;	console_driver.unthrottle = con_unthrottle;	if (tty_register_driver(&console_driver))		panic("Couldn't register console driver\n");	timer_table[BLANK_TIMER].fn = blank_screen;	timer_table[BLANK_TIMER].expires = 0;	if (blankinterval) {		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;		timer_active |= 1<<BLANK_TIMER;	}	/* Unfortunately, kmalloc is not running yet */	/* Due to kmalloc roundup allocating statically is more efficient -	   so provide MIN_NR_CONSOLES for people with very little memory */	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {		int j, k ;		vc_cons[currcons].d = (struct vc_data *) kmem_start;		kmem_start += sizeof(struct vc_data);		vt_cons[currcons] = (struct vt_struct *) kmem_start;		kmem_start += sizeof(struct vt_struct);		visual_init(currcons, 1);		screenbuf = (unsigned short *) kmem_start;		kmem_start += screenbuf_size;		kmalloced = 0;		vc_init(currcons, video_num_lines, video_num_columns, 			currcons || !sw->con_save_screen);		for (j=k=0; j<16; j++) {			vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;			vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;			vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;		}	}	currcons = fg_console = 0;	master_display_fg = vc_cons[currcons].d;	set_origin(currcons);	save_screen(currcons);	gotoxy(currcons,x,y);	csi_J(currcons, 0);	update_screen(fg_console);	printk("Console: %s %s %dx%d",		can_do_color ? "colour" : "mono",		display_desc, video_num_columns, video_num_lines);	printable = 1;	printk("\n");#ifdef CONFIG_VT_CONSOLE	register_console(&vt_console_driver);#endif	init_bh(CONSOLE_BH, console_bh);		return kmem_start;}#ifndef VT_SINGLE_DRIVERstatic void clear_buffer_attributes(int currcons){	unsigned short *p = (unsigned short *) origin;	int count = screenbuf_size/2;	int mask = hi_font_mask | 0xff;	for (; count > 0; count--, p++) {		scr_writew((scr_readw(p)&mask) | (video_erase_char&~mask), p);	}}/* *	If we support more console drivers, this function is used *	when a driver wants to take over some existing consoles *	and become default driver for newly opened ones. */void take_over_console(struct consw *csw, int first, int last, int deflt){	int i, j = -1;	const char *desc;	desc = csw->con_startup();	if (!desc) return;	if (deflt)		conswitchp = csw;	for (i = first; i <= last; i++) {		int old_was_color;		int currcons = i;		con_driver_map[i] = csw;		if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)			continue;		j = i;		if (IS_VISIBLE)			save_screen(i);		old_was_color = vc_cons[i].d->vc_can_do_color;		vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);		visual_init(i, 0);		update_attr(i);		/* If the console changed between mono <-> color, then		 * the attributes in the screenbuf will be wrong.  The		 * following resets all attributes to something sane.		 */		if (old_was_color != vc_cons[i].d->vc_can_do_color)			clear_buffer_attributes(i);		if (IS_VISIBLE)			update_screen(i);	}	printk("Console: switching ");	if (!deflt)		printk("consoles %d-%d ", first+1, last+1);	if (j >= 0)		printk("to %s %s %dx%d\n",		       vc_cons[j].d->vc_can_do_color ? "colour" : "mono",		       desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows);	else		printk("to %s\n", desc);}void give_up_console(struct consw *csw){	int i;	for(i = 0; i < MAX_NR_CONSOLES; i++)		if (con_driver_map[i] == csw)			con_driver_map[i] = NULL;}#endif/* *	Screen blanking */static void set_vesa_blanking(unsigned long arg){    char *argp = (char *)arg + 1;    unsigned int mode;    get_user(mode, argp);    vesa_blank_mode = (mode < 4) ? mode : 0;}static void vesa_powerdown(void){    struct vc_data *c = vc_cons[fg_console].d;    /*     *  Power down if currently suspended (1 or 2),     *  suspend if currently blanked (0),     *  else do nothing (i.e. already powered down (3)).     *  Called only if powerdown features are allowed.     */    switch (vesa_blank_mode) {	case VESA_NO_BLANKING:	    c->vc_sw->con_blank(c, VESA_VSYNC_SUSPEND+1);	    break;	case VESA_VSYNC_SUSPEND:	case VESA_HSYNC_SUSPEND:	    c->vc_sw->con_blank(c, VESA_POWERDOWN+1);	    break;    }}static void vesa_powerdown_screen(void){	timer_active &= ~(1<<BLANK_TIMER);	timer_table[BLANK_TIMER].fn = unblank_screen;	vesa_powerdown();}void do_blank_screen(int entering_gfx){	int currcons = fg_console;	int i;	if (console_blanked)		return;	/* entering graphics mode? */	if (entering_gfx) {		hide_cursor(currcons);		save_screen(currcons);		sw->con_blank(vc_cons[currcons].d, -1);		console_blanked = fg_console + 1;		set_origin(currcons);		return;	}	/* don't blank graphics */	if (vcmode != KD_TEXT) {		console_blanked = fg_console + 1;		return;	}	hide_cursor(currcons);	if (vesa_off_interval) {		timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;		timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;		timer_active |= (1<<BLANK_TIMER);	} else {		timer_active &= ~(1<<BLANK_TIMER);		timer_table[BLANK_TIMER].fn = unblank_screen;	}	save_screen(currcons);	/* In case we need to reset origin, blanking hook returns 1 */	i = sw->con_blank(vc_cons[currcons].d, 1);	console_blanked = fg_console + 1;	if (i)		set_origin(currcons);#ifdef CONFIG_APM	if (apm_display_blank())		return;#endif    	if (vesa_blank_mode)		sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1);}void unblank_screen(void){	int currcons;	if (!console_blanked)		return;	if (!vc_cons_allocated(fg_console)) {		/* impossible */		printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);		return;	}	timer_table[BLANK_TIMER].fn = blank_screen;	if (blankinterval) {		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;		timer_active |= 1<<BLANK_TIMER;	}	currcons = fg_console;	console_blanked = 0;#ifdef CONFIG_APM	apm_display_unblank();#endif	if (sw->con_blank(vc_cons[currcons].d, 0))		/* Low-level driver cannot restore -> do it ourselves */		update_screen(fg_console);	set_cursor(fg_console);}static void blank_screen(void){	do_blank_screen(0);}void poke_blanked_console(void){	timer_active &= ~(1<<BLANK_TIMER);	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)		return;	if (console_blanked) {		timer_table[BLANK_TIMER].fn = unblank_screen;		timer_table[BLANK_TIMER].expires = jiffies;	/* Now */		timer_active |= 1<<BLANK_TIMER;	} else if (blankinterval) {		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;		timer_active |= 1<<BLANK_TIMER;	}}/* *	Palettes */void set_palette(int currcons){	if (vcmode != KD_GRAPHICS)		sw->con_set_palette(vc_cons[currcons].d, color_table);}static int set_get_cmap(unsigned char *arg, int set){    int i, j, k;    for (i = 0; i < 16; i++)	if (set) {	    get_user(default_red[i], arg++);	    get_user(default_grn[i], arg++);	    get_user(default_blu[i], arg++);	} else {	    put_user(default_red[i], arg++);	    put_user(default_grn[i], arg++);	    put_user(default_blu[i], arg++);	}    if (set) {	for (i = 0; i < MAX_NR_CONSOLES; i++)	    if (vc_cons_allocated(i)) {		for (j = k = 0; j < 16; j++) {		    vc_cons[i].d->vc_palette[k++] = default_red[j];		    vc_cons[i].d->vc_palette[k++] = default_grn[j];		    vc_cons[i].d->vc_palette[k++] = default_blu[j];		}		set_palette(i);	    }    }    return 0;}/* * Load palette into the DAC registers. arg points to a colour * map, 3 bytes per colour, 16 colours, range from 0 to 255. */int con_set_cmap(unsigned char *arg){	return set_get_cmap (arg,1);}int con_get_cmap(unsigned char *arg){	return set_get_cmap (arg,0);}void reset_palette(int currcons){	int j, k;	for (j=k=0; j<16; j++) {		palette[k++] = default_red[j];		palette[k++] = default_grn[j];		palette[k++] = default_blu[j];	}	set_palette(currcons);}/* *  Font switching * *  Currently we only support fonts up to 32 pixels wide, at a maximum height *  of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,  *  depending on width) reserved for each character which is kinda wasty, but  *  this is done in order to maintain compatibility with the EGA/VGA fonts. It  *  is upto the actual low-level console-driver convert data into its favorite *  format (maybe we should add a `fontoffset' field to the `display' *  structure so we wont have to convert the fontdata all the time. *  /Jes */#define max_font_size 65536int con_font_op(int currcons, struct console_font_op *op){	int rc = -EINVAL;	int size = max_font_size, set;	u8 *temp = NULL;	struct console_font_op old_op;	if (vt_cons[currcons]->vc_mode != KD_TEXT)		goto quit;	memcpy(&old_op, op, sizeof(old_op));	if (op->op == KD_FONT_OP_SET) {		if (!op->data)			return -EINVAL;		if (op->charcount > 512)			goto quit;		if (!op->height) {		/* Need to guess font height [compat] */			int h, i;			u8 *charmap = op->data, tmp;						/* If from KDFONTOP ioctl, don't allow things which can be done in userland,			   so that we can get rid of this soon */			if (!(op->flags & KD_FONT_FLAG_OLD))				goto quit;			rc = -EFAULT;			for (h = 32; h > 0; h--)				for (i = 0; i < op->charcount; i++) {					if (get_user(tmp, &charmap[32*i+h-1]))						goto quit;					if (tmp)						goto nonzero;				}			rc = -EINVAL;			goto quit;		nonzero:			rc = -EINVAL;			op->height = h;		}		if (op->width > 32 || op->height > 32)			goto quit;		size = (op->width+7)/8 * 32 * op->charcount;		if (size > max_font_size)			return -ENOSPC;		set = 1;	} else if (op->op == KD_FONT_OP_GET)		set = 0;	else		return sw->con_font_op(vc_cons[currcons].d, op);	if (op->data) {		temp = kmalloc(size, GFP_KERNEL);		if (!temp)			return -ENOMEM;		if (set && copy_from_user(temp, op->data, size)) {			rc = -EFAULT;			goto quit;		}		op->data = temp;	}	disable_bh(CONSOLE_BH);	rc = sw->con_font_op(vc_cons[currcons].d, op);	enable_bh(CONSOLE_BH);	op->data = old_op.data;	if (!rc && !set) {		int c = (op->width+7)/8 * 32 * op->charcount;				if (op->data && op->charcount > old_op.charcount)			rc = -ENOSPC;		if (!(op->flags & KD_FONT_FLAG_OLD)) {			if (op->width > old_op.width || 			    op->height > old_op.height)				rc = -ENOSPC;		} else 

⌨️ 快捷键说明

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