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

📄 con3270.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  drivers/s390/char/con3270.c *    IBM/3270 Driver - console view. * *  Author(s): *    Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) *    Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> *	-- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation */#include <linux/config.h>#include <linux/bootmem.h>#include <linux/console.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/list.h>#include <linux/types.h>#include <asm/ccwdev.h>#include <asm/cio.h>#include <asm/cpcmd.h>#include <asm/ebcdic.h>#include "raw3270.h"#include "ctrlchar.h"#define CON3270_OUTPUT_BUFFER_SIZE 1024#define CON3270_STRING_PAGES 4static struct raw3270_fn con3270_fn;/* * Main 3270 console view data structure. */struct con3270 {	struct raw3270_view view;	spinlock_t lock;	struct list_head freemem;	/* list of free memory for strings. */	/* Output stuff. */	struct list_head lines;		/* list of lines. */	struct list_head update;	/* list of lines to update. */	int line_nr;			/* line number for next update. */	int nr_lines;			/* # lines in list. */	int nr_up;			/* # lines up in history. */	unsigned long update_flags;	/* Update indication bits. */	struct string *cline;		/* current output line. */	struct string *status;		/* last line of display. */	struct raw3270_request *write;	/* single write request. */	struct timer_list timer;	/* Input stuff. */	struct string *input;		/* input string for read request. */	struct raw3270_request *read;	/* single read request. */	struct raw3270_request *kreset;	/* single keyboard reset request. */	struct tasklet_struct readlet;	/* tasklet to issue read request. */};static struct con3270 *condev;/* con3270->update_flags. See con3270_update for details. */#define CON_UPDATE_ERASE	1	/* Use EWRITEA instead of WRITE. */#define CON_UPDATE_LIST		2	/* Update lines in tty3270->update. */#define CON_UPDATE_STATUS	4	/* Update status line. */#define CON_UPDATE_ALL		7static void con3270_update(struct con3270 *);/* * Setup timeout for a device. On timeout trigger an update. */voidcon3270_set_timer(struct con3270 *cp, int expires){	if (expires == 0) {		if (timer_pending(&cp->timer))			del_timer(&cp->timer);		return;	}	if (timer_pending(&cp->timer) &&	    mod_timer(&cp->timer, jiffies + expires))		return;	cp->timer.function = (void (*)(unsigned long)) con3270_update;	cp->timer.data = (unsigned long) cp;	cp->timer.expires = jiffies + expires;	add_timer(&cp->timer);}/* * The status line is the last line of the screen. It shows the string * "console view" in the lower left corner and "Running"/"More..."/"Holding" * in the lower right corner of the screen. */static voidcon3270_update_status(struct con3270 *cp){	char *str;	str = (cp->nr_up != 0) ? "History" : "Running";	memcpy(cp->status->string + 24, str, 7);	codepage_convert(cp->view.ascebc, cp->status->string + 24, 7);	cp->update_flags |= CON_UPDATE_STATUS;}static voidcon3270_create_status(struct con3270 *cp){	static const unsigned char blueprint[] =		{ TO_SBA, 0, 0, TO_SF,TF_LOG,TO_SA,TAT_COLOR, TAC_GREEN,		  'c','o','n','s','o','l','e',' ','v','i','e','w',		  TO_RA,0,0,0,'R','u','n','n','i','n','g',TO_SF,TF_LOG };	cp->status = alloc_string(&cp->freemem, sizeof(blueprint));	/* Copy blueprint to status line */	memcpy(cp->status->string, blueprint, sizeof(blueprint));	/* Set TO_RA addresses. */	raw3270_buffer_address(cp->view.dev, cp->status->string + 1,			       cp->view.cols * (cp->view.rows - 1));	raw3270_buffer_address(cp->view.dev, cp->status->string + 21,			       cp->view.cols * cp->view.rows - 8);	/* Convert strings to ebcdic. */	codepage_convert(cp->view.ascebc, cp->status->string + 8, 12);	codepage_convert(cp->view.ascebc, cp->status->string + 24, 7);}/* * Set output offsets to 3270 datastream fragment of a console string. */static voidcon3270_update_string(struct con3270 *cp, struct string *s, int nr){	if (s->len >= cp->view.cols - 5)		return;	raw3270_buffer_address(cp->view.dev, s->string + s->len - 3,			       cp->view.cols * (nr + 1));}/* * Rebuild update list to print all lines. */static voidcon3270_rebuild_update(struct con3270 *cp){	struct string *s, *n;	int nr;	/* 	 * Throw away update list and create a new one,	 * containing all lines that will fit on the screen.	 */	list_for_each_entry_safe(s, n, &cp->update, update)		list_del_init(&s->update);	nr = cp->view.rows - 2 + cp->nr_up;	list_for_each_entry_reverse(s, &cp->lines, list) {		if (nr < cp->view.rows - 1)			list_add(&s->update, &cp->update);		if (--nr < 0)			break;	}	cp->line_nr = 0;	cp->update_flags |= CON_UPDATE_LIST;}/* * Alloc string for size bytes. Free strings from history if necessary. */static struct string *con3270_alloc_string(struct con3270 *cp, size_t size){	struct string *s, *n;	s = alloc_string(&cp->freemem, size);	if (s)		return s;	list_for_each_entry_safe(s, n, &cp->lines, list) {		list_del(&s->list);		if (!list_empty(&s->update))			list_del(&s->update);		cp->nr_lines--;		if (free_string(&cp->freemem, s) >= size)			break;	}	s = alloc_string(&cp->freemem, size);	BUG_ON(!s);	if (cp->nr_up != 0 && cp->nr_up + cp->view.rows > cp->nr_lines) {		cp->nr_up = cp->nr_lines - cp->view.rows + 1;		con3270_rebuild_update(cp);		con3270_update_status(cp);	}	return s;}/* * Write completion callback. */static voidcon3270_write_callback(struct raw3270_request *rq, void *data){	raw3270_request_reset(rq);	xchg(&((struct con3270 *) rq->view)->write, rq);}/* * Update console display. */static voidcon3270_update(struct con3270 *cp){	struct raw3270_request *wrq;	char wcc, prolog[6];	unsigned long flags;	unsigned long updated;	struct string *s, *n;	int rc;	if (cp->view.dev)		raw3270_activate_view(&cp->view);	wrq = xchg(&cp->write, 0);	if (!wrq) {		con3270_set_timer(cp, 1);		return;	}	spin_lock_irqsave(&cp->view.lock, flags);	updated = 0;	if (cp->update_flags & CON_UPDATE_ERASE) {		/* Use erase write alternate to initialize display. */		raw3270_request_set_cmd(wrq, TC_EWRITEA);		updated |= CON_UPDATE_ERASE;	} else		raw3270_request_set_cmd(wrq, TC_WRITE);	wcc = TW_NONE;	raw3270_request_add_data(wrq, &wcc, 1);	/*	 * Update status line.	 */	if (cp->update_flags & CON_UPDATE_STATUS)		if (raw3270_request_add_data(wrq, cp->status->string,					     cp->status->len) == 0)			updated |= CON_UPDATE_STATUS;	if (cp->update_flags & CON_UPDATE_LIST) {		prolog[0] = TO_SBA;		prolog[3] = TO_SA;		prolog[4] = TAT_COLOR;		prolog[5] = TAC_TURQ;		raw3270_buffer_address(cp->view.dev, prolog + 1,				       cp->view.cols * cp->line_nr);		raw3270_request_add_data(wrq, prolog, 6);		/* Write strings in the update list to the screen. */		list_for_each_entry_safe(s, n, &cp->update, update) {			if (s != cp->cline)				con3270_update_string(cp, s, cp->line_nr);			if (raw3270_request_add_data(wrq, s->string,						     s->len) != 0)				break;			list_del_init(&s->update);			if (s != cp->cline)				cp->line_nr++;		}		if (list_empty(&cp->update))			updated |= CON_UPDATE_LIST;	}	wrq->callback = con3270_write_callback;	rc = raw3270_start(&cp->view, wrq);	if (rc == 0) {		cp->update_flags &= ~updated;		if (cp->update_flags)			con3270_set_timer(cp, 1);	} else {		raw3270_request_reset(wrq);		xchg(&cp->write, wrq);	}	spin_unlock_irqrestore(&cp->view.lock, flags);}/* * Read tasklet. */static voidcon3270_read_tasklet(struct raw3270_request *rrq){	static char kreset_data = TW_KR;	struct con3270 *cp;	unsigned long flags;	int nr_up, deactivate;	cp = (struct con3270 *) rrq->view;	spin_lock_irqsave(&cp->view.lock, flags);	nr_up = cp->nr_up;	deactivate = 0;	/* Check aid byte. */	switch (cp->input->string[0]) {	case 0x7d:	/* enter: jump to bottom. */		nr_up = 0;		break;	case 0xf3:	/* PF3: deactivate the console view. */		deactivate = 1;		break;	case 0x6d:	/* clear: start from scratch. */		con3270_rebuild_update(cp);		cp->update_flags = CON_UPDATE_ALL;		con3270_set_timer(cp, 1);		break;	case 0xf7:	/* PF7: do a page up in the console log. */		nr_up += cp->view.rows - 2;		if (nr_up + cp->view.rows - 1 > cp->nr_lines) {			nr_up = cp->nr_lines - cp->view.rows + 1;			if (nr_up < 0)				nr_up = 0;		}		break;	case 0xf8:	/* PF8: do a page down in the console log. */		nr_up -= cp->view.rows - 2;		if (nr_up < 0)			nr_up = 0;		break;

⌨️ 快捷键说明

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