📄 con3270.c
字号:
} if (nr_up != cp->nr_up) { cp->nr_up = nr_up; con3270_rebuild_update(cp); con3270_update_status(cp); con3270_set_timer(cp, 1); } spin_unlock_irqrestore(&cp->view.lock, flags); /* Start keyboard reset command. */ raw3270_request_reset(cp->kreset); raw3270_request_set_cmd(cp->kreset, TC_WRITE); raw3270_request_add_data(cp->kreset, &kreset_data, 1); raw3270_start(&cp->view, cp->kreset); if (deactivate) raw3270_deactivate_view(&cp->view); raw3270_request_reset(rrq); xchg(&cp->read, rrq); raw3270_put_view(&cp->view);}/* * Read request completion callback. */static voidcon3270_read_callback(struct raw3270_request *rq, void *data){ raw3270_get_view(rq->view); /* Schedule tasklet to pass input to tty. */ tasklet_schedule(&((struct con3270 *) rq->view)->readlet);}/* * Issue a read request. Called only from interrupt function. */static voidcon3270_issue_read(struct con3270 *cp){ struct raw3270_request *rrq; int rc; rrq = xchg(&cp->read, 0); if (!rrq) /* Read already scheduled. */ return; rrq->callback = con3270_read_callback; rrq->callback_data = cp; raw3270_request_set_cmd(rrq, TC_READMOD); raw3270_request_set_data(rrq, cp->input->string, cp->input->len); /* Issue the read modified request. */ rc = raw3270_start_irq(&cp->view, rrq); if (rc) raw3270_request_reset(rrq);}/* * Switch to the console view. */static intcon3270_activate(struct raw3270_view *view){ unsigned long flags; struct con3270 *cp; cp = (struct con3270 *) view; spin_lock_irqsave(&cp->view.lock, flags); cp->nr_up = 0; con3270_rebuild_update(cp); con3270_update_status(cp); cp->update_flags = CON_UPDATE_ALL; con3270_set_timer(cp, 1); spin_unlock_irqrestore(&cp->view.lock, flags); return 0;}static voidcon3270_deactivate(struct raw3270_view *view){ unsigned long flags; struct con3270 *cp; cp = (struct con3270 *) view; spin_lock_irqsave(&cp->view.lock, flags); del_timer(&cp->timer); spin_unlock_irqrestore(&cp->view.lock, flags);}static intcon3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb){ /* Handle ATTN. Schedule tasklet to read aid. */ if (irb->scsw.dstat & DEV_STAT_ATTENTION) con3270_issue_read(cp); if (rq) { if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) rq->rc = -EIO; else /* Normal end. Copy residual count. */ rq->rescnt = irb->scsw.count; } return RAW3270_IO_DONE;}/* Console view to a 3270 device. */static struct raw3270_fn con3270_fn = { .activate = con3270_activate, .deactivate = con3270_deactivate, .intv = (void *) con3270_irq};static inline voidcon3270_cline_add(struct con3270 *cp){ if (!list_empty(&cp->cline->list)) /* Already added. */ return; list_add_tail(&cp->cline->list, &cp->lines); cp->nr_lines++; con3270_rebuild_update(cp);}static inline voidcon3270_cline_insert(struct con3270 *cp, unsigned char c){ cp->cline->string[cp->cline->len++] = cp->view.ascebc[(c < ' ') ? ' ' : c]; if (list_empty(&cp->cline->update)) { list_add_tail(&cp->cline->update, &cp->update); cp->update_flags |= CON_UPDATE_LIST; }}static inline voidcon3270_cline_end(struct con3270 *cp){ struct string *s; unsigned int size; /* Copy cline. */ size = (cp->cline->len < cp->view.cols - 5) ? cp->cline->len + 4 : cp->view.cols; s = con3270_alloc_string(cp, size); memcpy(s->string, cp->cline->string, cp->cline->len); if (s->len < cp->view.cols - 5) { s->string[s->len - 4] = TO_RA; s->string[s->len - 1] = 0; } else { while (--size > cp->cline->len) s->string[size] = cp->view.ascebc[' ']; } /* Replace cline with allocated line s and reset cline. */ list_add(&s->list, &cp->cline->list); list_del_init(&cp->cline->list); if (!list_empty(&cp->cline->update)) { list_add(&s->update, &cp->cline->update); list_del_init(&cp->cline->update); } cp->cline->len = 0;}/* * Write a string to the 3270 console */static voidcon3270_write(struct console *co, const char *str, unsigned int count){ struct con3270 *cp; unsigned long flags; unsigned char c; cp = condev; spin_lock_irqsave(&cp->view.lock, flags); while (count-- > 0) { c = *str++; if (cp->cline->len == 0) con3270_cline_add(cp); if (c != '\n') con3270_cline_insert(cp, c); if (c == '\n' || cp->cline->len >= cp->view.cols) con3270_cline_end(cp); } /* Setup timer to output current console buffer after 1/10 second */ if (cp->view.dev && !timer_pending(&cp->timer)) con3270_set_timer(cp, HZ/10); spin_unlock_irqrestore(&cp->view.lock,flags);}extern struct tty_driver *tty3270_driver;static struct tty_driver *con3270_device(struct console *c, int *index){ *index = c->index; return tty3270_driver;}/* * Wait for end of write request. */static voidcon3270_wait_write(struct con3270 *cp){ while (!cp->write) { raw3270_wait_cons_dev(cp->view.dev); barrier(); }}/* * panic() calls console_unblank before the system enters a * disabled, endless loop. */static voidcon3270_unblank(void){ struct con3270 *cp; unsigned long flags; cp = condev; if (!cp->view.dev) return; spin_lock_irqsave(&cp->view.lock, flags); con3270_wait_write(cp); cp->nr_up = 0; con3270_rebuild_update(cp); con3270_update_status(cp); while (cp->update_flags != 0) { spin_unlock_irqrestore(&cp->view.lock, flags); con3270_update(cp); spin_lock_irqsave(&cp->view.lock, flags); con3270_wait_write(cp); } spin_unlock_irqrestore(&cp->view.lock, flags);}static int __init con3270_consetup(struct console *co, char *options){ return 0;}/* * The console structure for the 3270 console */static struct console con3270 = { .name = "tty3270", .write = con3270_write, .device = con3270_device, .unblank = con3270_unblank, .setup = con3270_consetup, .flags = CON_PRINTBUFFER,};/* * 3270 console initialization code called from console_init(). * NOTE: This is called before kmalloc is available. */static int __initcon3270_init(void){ struct ccw_device *cdev; struct raw3270 *rp; void *cbuf; int i; /* Check if 3270 is to be the console */ if (!CONSOLE_IS_3270) return -ENODEV; /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3270", NULL, 0, NULL); cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } cdev = ccw_device_probe_console(); if (!cdev) return -ENODEV; rp = raw3270_setup_console(cdev); if (IS_ERR(rp)) return PTR_ERR(rp); condev = (struct con3270 *) alloc_bootmem_low(sizeof(struct con3270)); memset(condev, 0, sizeof(struct con3270)); condev->view.dev = rp; condev->read = raw3270_request_alloc_bootmem(0); condev->read->callback = con3270_read_callback; condev->read->callback_data = condev; condev->write = raw3270_request_alloc_bootmem(CON3270_OUTPUT_BUFFER_SIZE); condev->kreset = raw3270_request_alloc_bootmem(1); INIT_LIST_HEAD(&condev->lines); INIT_LIST_HEAD(&condev->update); init_timer(&condev->timer); tasklet_init(&condev->readlet, (void (*)(unsigned long)) con3270_read_tasklet, (unsigned long) condev->read); raw3270_add_view(&condev->view, &con3270_fn, 1); INIT_LIST_HEAD(&condev->freemem); for (i = 0; i < CON3270_STRING_PAGES; i++) { cbuf = (void *) alloc_bootmem_low_pages(PAGE_SIZE); add_string_memory(&condev->freemem, cbuf, PAGE_SIZE); } condev->cline = alloc_string(&condev->freemem, condev->view.cols); condev->cline->len = 0; con3270_create_status(condev); condev->input = alloc_string(&condev->freemem, 80); register_console(&con3270); return 0;}console_initcall(con3270_init);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -