1/* 2 * SCLP VT220 terminal driver. 3 * 4 * Copyright IBM Corp. 2003, 2009 5 * 6 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com> 7 */ 8 9#include <linux/module.h> 10#include <linux/spinlock.h> 11#include <linux/list.h> 12#include <linux/wait.h> 13#include <linux/timer.h> 14#include <linux/kernel.h> 15#include <linux/sysrq.h> 16#include <linux/tty.h> 17#include <linux/tty_driver.h> 18#include <linux/tty_flip.h> 19#include <linux/errno.h> 20#include <linux/mm.h> 21#include <linux/major.h> 22#include <linux/console.h> 23#include <linux/kdev_t.h> 24#include <linux/interrupt.h> 25#include <linux/init.h> 26#include <linux/reboot.h> 27#include <linux/slab.h> 28 29#include <asm/uaccess.h> 30#include "sclp.h" 31#include "ctrlchar.h" 32 33#define SCLP_VT220_MAJOR TTY_MAJOR 34#define SCLP_VT220_MINOR 65 35#define SCLP_VT220_DRIVER_NAME "sclp_vt220" 36#define SCLP_VT220_DEVICE_NAME "ttysclp" 37#define SCLP_VT220_CONSOLE_NAME "ttyS" 38#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */ 39 40/* Representation of a single write request */ 41struct sclp_vt220_request { 42 struct list_head list; 43 struct sclp_req sclp_req; 44 int retry_count; 45}; 46 47/* VT220 SCCB */ 48struct sclp_vt220_sccb { 49 struct sccb_header header; 50 struct evbuf_header evbuf; 51}; 52 53#define SCLP_VT220_MAX_CHARS_PER_BUFFER (PAGE_SIZE - \ 54 sizeof(struct sclp_vt220_request) - \ 55 sizeof(struct sclp_vt220_sccb)) 56 57/* Structures and data needed to register tty driver */ 58static struct tty_driver *sclp_vt220_driver; 59 60static struct tty_port sclp_vt220_port; 61 62/* Lock to protect internal data from concurrent access */ 63static spinlock_t sclp_vt220_lock; 64 65/* List of empty pages to be used as write request buffers */ 66static struct list_head sclp_vt220_empty; 67 68/* List of pending requests */ 69static struct list_head sclp_vt220_outqueue; 70 71/* Suspend mode flag */ 72static int sclp_vt220_suspended; 73 74/* Flag that output queue is currently running */ 75static int sclp_vt220_queue_running; 76 77/* Timer used for delaying write requests to merge subsequent messages into 78 * a single buffer */ 79static struct timer_list sclp_vt220_timer; 80 81/* Pointer to current request buffer which has been partially filled but not 82 * yet sent */ 83static struct sclp_vt220_request *sclp_vt220_current_request; 84 85/* Number of characters in current request buffer */ 86static int sclp_vt220_buffered_chars; 87 88/* Counter controlling core driver initialization. */ 89static int __initdata sclp_vt220_init_count; 90 91/* Flag indicating that sclp_vt220_current_request should really 92 * have been already queued but wasn't because the SCLP was processing 93 * another buffer */ 94static int sclp_vt220_flush_later; 95 96static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf); 97static void sclp_vt220_pm_event_fn(struct sclp_register *reg, 98 enum sclp_pm_event sclp_pm_event); 99static int __sclp_vt220_emit(struct sclp_vt220_request *request); 100static void sclp_vt220_emit_current(void); 101 102/* Registration structure for SCLP output event buffers */ 103static struct sclp_register sclp_vt220_register = { 104 .send_mask = EVTYP_VT220MSG_MASK, 105 .pm_event_fn = sclp_vt220_pm_event_fn, 106}; 107 108/* Registration structure for SCLP input event buffers */ 109static struct sclp_register sclp_vt220_register_input = { 110 .receive_mask = EVTYP_VT220MSG_MASK, 111 .receiver_fn = sclp_vt220_receiver_fn, 112}; 113 114 115/* 116 * Put provided request buffer back into queue and check emit pending 117 * buffers if necessary. 118 */ 119static void 120sclp_vt220_process_queue(struct sclp_vt220_request *request) 121{ 122 unsigned long flags; 123 void *page; 124 125 do { 126 /* Put buffer back to list of empty buffers */ 127 page = request->sclp_req.sccb; 128 spin_lock_irqsave(&sclp_vt220_lock, flags); 129 /* Move request from outqueue to empty queue */ 130 list_del(&request->list); 131 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 132 /* Check if there is a pending buffer on the out queue. */ 133 request = NULL; 134 if (!list_empty(&sclp_vt220_outqueue)) 135 request = list_entry(sclp_vt220_outqueue.next, 136 struct sclp_vt220_request, list); 137 if (!request || sclp_vt220_suspended) { 138 sclp_vt220_queue_running = 0; 139 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 140 break; 141 } 142 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 143 } while (__sclp_vt220_emit(request)); 144 if (request == NULL && sclp_vt220_flush_later) 145 sclp_vt220_emit_current(); 146 tty_port_tty_wakeup(&sclp_vt220_port); 147} 148 149#define SCLP_BUFFER_MAX_RETRY 1 150 151/* 152 * Callback through which the result of a write request is reported by the 153 * SCLP. 154 */ 155static void 156sclp_vt220_callback(struct sclp_req *request, void *data) 157{ 158 struct sclp_vt220_request *vt220_request; 159 struct sclp_vt220_sccb *sccb; 160 161 vt220_request = (struct sclp_vt220_request *) data; 162 if (request->status == SCLP_REQ_FAILED) { 163 sclp_vt220_process_queue(vt220_request); 164 return; 165 } 166 sccb = (struct sclp_vt220_sccb *) vt220_request->sclp_req.sccb; 167 168 /* Check SCLP response code and choose suitable action */ 169 switch (sccb->header.response_code) { 170 case 0x0020 : 171 break; 172 173 case 0x05f0: /* Target resource in improper state */ 174 break; 175 176 case 0x0340: /* Contained SCLP equipment check */ 177 if (++vt220_request->retry_count > SCLP_BUFFER_MAX_RETRY) 178 break; 179 /* Remove processed buffers and requeue rest */ 180 if (sclp_remove_processed((struct sccb_header *) sccb) > 0) { 181 /* Not all buffers were processed */ 182 sccb->header.response_code = 0x0000; 183 vt220_request->sclp_req.status = SCLP_REQ_FILLED; 184 if (sclp_add_request(request) == 0) 185 return; 186 } 187 break; 188 189 case 0x0040: /* SCLP equipment check */ 190 if (++vt220_request->retry_count > SCLP_BUFFER_MAX_RETRY) 191 break; 192 sccb->header.response_code = 0x0000; 193 vt220_request->sclp_req.status = SCLP_REQ_FILLED; 194 if (sclp_add_request(request) == 0) 195 return; 196 break; 197 198 default: 199 break; 200 } 201 sclp_vt220_process_queue(vt220_request); 202} 203 204/* 205 * Emit vt220 request buffer to SCLP. Return zero on success, non-zero 206 * otherwise. 207 */ 208static int 209__sclp_vt220_emit(struct sclp_vt220_request *request) 210{ 211 request->sclp_req.command = SCLP_CMDW_WRITE_EVENT_DATA; 212 request->sclp_req.status = SCLP_REQ_FILLED; 213 request->sclp_req.callback = sclp_vt220_callback; 214 request->sclp_req.callback_data = (void *) request; 215 216 return sclp_add_request(&request->sclp_req); 217} 218 219/* 220 * Queue and emit current request. 221 */ 222static void 223sclp_vt220_emit_current(void) 224{ 225 unsigned long flags; 226 struct sclp_vt220_request *request; 227 struct sclp_vt220_sccb *sccb; 228 229 spin_lock_irqsave(&sclp_vt220_lock, flags); 230 if (sclp_vt220_current_request) { 231 sccb = (struct sclp_vt220_sccb *) 232 sclp_vt220_current_request->sclp_req.sccb; 233 /* Only emit buffers with content */ 234 if (sccb->header.length != sizeof(struct sclp_vt220_sccb)) { 235 list_add_tail(&sclp_vt220_current_request->list, 236 &sclp_vt220_outqueue); 237 sclp_vt220_current_request = NULL; 238 if (timer_pending(&sclp_vt220_timer)) 239 del_timer(&sclp_vt220_timer); 240 } 241 sclp_vt220_flush_later = 0; 242 } 243 if (sclp_vt220_queue_running || sclp_vt220_suspended) 244 goto out_unlock; 245 if (list_empty(&sclp_vt220_outqueue)) 246 goto out_unlock; 247 request = list_first_entry(&sclp_vt220_outqueue, 248 struct sclp_vt220_request, list); 249 sclp_vt220_queue_running = 1; 250 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 251 252 if (__sclp_vt220_emit(request)) 253 sclp_vt220_process_queue(request); 254 return; 255out_unlock: 256 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 257} 258 259#define SCLP_NORMAL_WRITE 0x00 260 261/* 262 * Helper function to initialize a page with the sclp request structure. 263 */ 264static struct sclp_vt220_request * 265sclp_vt220_initialize_page(void *page) 266{ 267 struct sclp_vt220_request *request; 268 struct sclp_vt220_sccb *sccb; 269 270 /* Place request structure at end of page */ 271 request = ((struct sclp_vt220_request *) 272 ((addr_t) page + PAGE_SIZE)) - 1; 273 request->retry_count = 0; 274 request->sclp_req.sccb = page; 275 /* SCCB goes at start of page */ 276 sccb = (struct sclp_vt220_sccb *) page; 277 memset((void *) sccb, 0, sizeof(struct sclp_vt220_sccb)); 278 sccb->header.length = sizeof(struct sclp_vt220_sccb); 279 sccb->header.function_code = SCLP_NORMAL_WRITE; 280 sccb->header.response_code = 0x0000; 281 sccb->evbuf.type = EVTYP_VT220MSG; 282 sccb->evbuf.length = sizeof(struct evbuf_header); 283 284 return request; 285} 286 287static inline unsigned int 288sclp_vt220_space_left(struct sclp_vt220_request *request) 289{ 290 struct sclp_vt220_sccb *sccb; 291 sccb = (struct sclp_vt220_sccb *) request->sclp_req.sccb; 292 return PAGE_SIZE - sizeof(struct sclp_vt220_request) - 293 sccb->header.length; 294} 295 296static inline unsigned int 297sclp_vt220_chars_stored(struct sclp_vt220_request *request) 298{ 299 struct sclp_vt220_sccb *sccb; 300 sccb = (struct sclp_vt220_sccb *) request->sclp_req.sccb; 301 return sccb->evbuf.length - sizeof(struct evbuf_header); 302} 303 304/* 305 * Add msg to buffer associated with request. Return the number of characters 306 * added. 307 */ 308static int 309sclp_vt220_add_msg(struct sclp_vt220_request *request, 310 const unsigned char *msg, int count, int convertlf) 311{ 312 struct sclp_vt220_sccb *sccb; 313 void *buffer; 314 unsigned char c; 315 int from; 316 int to; 317 318 if (count > sclp_vt220_space_left(request)) 319 count = sclp_vt220_space_left(request); 320 if (count <= 0) 321 return 0; 322 323 sccb = (struct sclp_vt220_sccb *) request->sclp_req.sccb; 324 buffer = (void *) ((addr_t) sccb + sccb->header.length); 325 326 if (convertlf) { 327 /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ 328 for (from=0, to=0; 329 (from < count) && (to < sclp_vt220_space_left(request)); 330 from++) { 331 /* Retrieve character */ 332 c = msg[from]; 333 /* Perform conversion */ 334 if (c == 0x0a) { 335 if (to + 1 < sclp_vt220_space_left(request)) { 336 ((unsigned char *) buffer)[to++] = c; 337 ((unsigned char *) buffer)[to++] = 0x0d; 338 } else 339 break; 340 341 } else 342 ((unsigned char *) buffer)[to++] = c; 343 } 344 sccb->header.length += to; 345 sccb->evbuf.length += to; 346 return from; 347 } else { 348 memcpy(buffer, (const void *) msg, count); 349 sccb->header.length += count; 350 sccb->evbuf.length += count; 351 return count; 352 } 353} 354 355/* 356 * Emit buffer after having waited long enough for more data to arrive. 357 */ 358static void 359sclp_vt220_timeout(unsigned long data) 360{ 361 sclp_vt220_emit_current(); 362} 363 364#define BUFFER_MAX_DELAY HZ/20 365 366/* 367 * Drop oldest console buffer if sclp_con_drop is set 368 */ 369static int 370sclp_vt220_drop_buffer(void) 371{ 372 struct list_head *list; 373 struct sclp_vt220_request *request; 374 void *page; 375 376 if (!sclp_console_drop) 377 return 0; 378 list = sclp_vt220_outqueue.next; 379 if (sclp_vt220_queue_running) 380 /* The first element is in I/O */ 381 list = list->next; 382 if (list == &sclp_vt220_outqueue) 383 return 0; 384 list_del(list); 385 request = list_entry(list, struct sclp_vt220_request, list); 386 page = request->sclp_req.sccb; 387 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 388 return 1; 389} 390 391/* 392 * Internal implementation of the write function. Write COUNT bytes of data 393 * from memory at BUF 394 * to the SCLP interface. In case that the data does not fit into the current 395 * write buffer, emit the current one and allocate a new one. If there are no 396 * more empty buffers available, wait until one gets emptied. If DO_SCHEDULE 397 * is non-zero, the buffer will be scheduled for emitting after a timeout - 398 * otherwise the user has to explicitly call the flush function. 399 * A non-zero CONVERTLF parameter indicates that 0x0a characters in the message 400 * buffer should be converted to 0x0a 0x0d. After completion, return the number 401 * of bytes written. 402 */ 403static int 404__sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, 405 int convertlf, int may_fail) 406{ 407 unsigned long flags; 408 void *page; 409 int written; 410 int overall_written; 411 412 if (count <= 0) 413 return 0; 414 overall_written = 0; 415 spin_lock_irqsave(&sclp_vt220_lock, flags); 416 do { 417 /* Create an sclp output buffer if none exists yet */ 418 if (sclp_vt220_current_request == NULL) { 419 if (list_empty(&sclp_vt220_empty)) 420 sclp_console_full++; 421 while (list_empty(&sclp_vt220_empty)) { 422 if (may_fail || sclp_vt220_suspended) 423 goto out; 424 if (sclp_vt220_drop_buffer()) 425 break; 426 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 427 428 sclp_sync_wait(); 429 spin_lock_irqsave(&sclp_vt220_lock, flags); 430 } 431 page = (void *) sclp_vt220_empty.next; 432 list_del((struct list_head *) page); 433 sclp_vt220_current_request = 434 sclp_vt220_initialize_page(page); 435 } 436 /* Try to write the string to the current request buffer */ 437 written = sclp_vt220_add_msg(sclp_vt220_current_request, 438 buf, count, convertlf); 439 overall_written += written; 440 if (written == count) 441 break; 442 /* 443 * Not all characters could be written to the current 444 * output buffer. Emit the buffer, create a new buffer 445 * and then output the rest of the string. 446 */ 447 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 448 sclp_vt220_emit_current(); 449 spin_lock_irqsave(&sclp_vt220_lock, flags); 450 buf += written; 451 count -= written; 452 } while (count > 0); 453 /* Setup timer to output current console buffer after some time */ 454 if (sclp_vt220_current_request != NULL && 455 !timer_pending(&sclp_vt220_timer) && do_schedule) { 456 sclp_vt220_timer.function = sclp_vt220_timeout; 457 sclp_vt220_timer.data = 0UL; 458 sclp_vt220_timer.expires = jiffies + BUFFER_MAX_DELAY; 459 add_timer(&sclp_vt220_timer); 460 } 461out: 462 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 463 return overall_written; 464} 465 466/* 467 * This routine is called by the kernel to write a series of 468 * characters to the tty device. The characters may come from 469 * user space or kernel space. This routine will return the 470 * number of characters actually accepted for writing. 471 */ 472static int 473sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) 474{ 475 return __sclp_vt220_write(buf, count, 1, 0, 1); 476} 477 478#define SCLP_VT220_SESSION_ENDED 0x01 479#define SCLP_VT220_SESSION_STARTED 0x80 480#define SCLP_VT220_SESSION_DATA 0x00 481 482#ifdef CONFIG_MAGIC_SYSRQ 483 484static int sysrq_pressed; 485static struct sysrq_work sysrq; 486 487static void sclp_vt220_reset_session(void) 488{ 489 sysrq_pressed = 0; 490} 491 492static void sclp_vt220_handle_input(const char *buffer, unsigned int count) 493{ 494 int i; 495 496 for (i = 0; i < count; i++) { 497 /* Handle magic sys request */ 498 if (buffer[i] == ('O' ^ 0100)) { /* CTRL-O */ 499 /* 500 * If pressed again, reset sysrq_pressed 501 * and flip CTRL-O character 502 */ 503 sysrq_pressed = !sysrq_pressed; 504 if (sysrq_pressed) 505 continue; 506 } else if (sysrq_pressed) { 507 sysrq.key = buffer[i]; 508 schedule_sysrq_work(&sysrq); 509 sysrq_pressed = 0; 510 continue; 511 } 512 tty_insert_flip_char(&sclp_vt220_port, buffer[i], 0); 513 } 514} 515 516#else 517 518static void sclp_vt220_reset_session(void) 519{ 520} 521 522static void sclp_vt220_handle_input(const char *buffer, unsigned int count) 523{ 524 tty_insert_flip_string(&sclp_vt220_port, buffer, count); 525} 526 527#endif 528 529/* 530 * Called by the SCLP to report incoming event buffers. 531 */ 532static void 533sclp_vt220_receiver_fn(struct evbuf_header *evbuf) 534{ 535 char *buffer; 536 unsigned int count; 537 538 buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); 539 count = evbuf->length - sizeof(struct evbuf_header); 540 541 switch (*buffer) { 542 case SCLP_VT220_SESSION_ENDED: 543 case SCLP_VT220_SESSION_STARTED: 544 sclp_vt220_reset_session(); 545 break; 546 case SCLP_VT220_SESSION_DATA: 547 /* Send input to line discipline */ 548 buffer++; 549 count--; 550 sclp_vt220_handle_input(buffer, count); 551 tty_flip_buffer_push(&sclp_vt220_port); 552 break; 553 } 554} 555 556/* 557 * This routine is called when a particular tty device is opened. 558 */ 559static int 560sclp_vt220_open(struct tty_struct *tty, struct file *filp) 561{ 562 if (tty->count == 1) { 563 tty_port_tty_set(&sclp_vt220_port, tty); 564 sclp_vt220_port.low_latency = 0; 565 if (!tty->winsize.ws_row && !tty->winsize.ws_col) { 566 tty->winsize.ws_row = 24; 567 tty->winsize.ws_col = 80; 568 } 569 } 570 return 0; 571} 572 573/* 574 * This routine is called when a particular tty device is closed. 575 */ 576static void 577sclp_vt220_close(struct tty_struct *tty, struct file *filp) 578{ 579 if (tty->count == 1) 580 tty_port_tty_set(&sclp_vt220_port, NULL); 581} 582 583/* 584 * This routine is called by the kernel to write a single 585 * character to the tty device. If the kernel uses this routine, 586 * it must call the flush_chars() routine (if defined) when it is 587 * done stuffing characters into the driver. 588 */ 589static int 590sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) 591{ 592 return __sclp_vt220_write(&ch, 1, 0, 0, 1); 593} 594 595/* 596 * This routine is called by the kernel after it has written a 597 * series of characters to the tty device using put_char(). 598 */ 599static void 600sclp_vt220_flush_chars(struct tty_struct *tty) 601{ 602 if (!sclp_vt220_queue_running) 603 sclp_vt220_emit_current(); 604 else 605 sclp_vt220_flush_later = 1; 606} 607 608/* 609 * This routine returns the numbers of characters the tty driver 610 * will accept for queuing to be written. This number is subject 611 * to change as output buffers get emptied, or if the output flow 612 * control is acted. 613 */ 614static int 615sclp_vt220_write_room(struct tty_struct *tty) 616{ 617 unsigned long flags; 618 struct list_head *l; 619 int count; 620 621 spin_lock_irqsave(&sclp_vt220_lock, flags); 622 count = 0; 623 if (sclp_vt220_current_request != NULL) 624 count = sclp_vt220_space_left(sclp_vt220_current_request); 625 list_for_each(l, &sclp_vt220_empty) 626 count += SCLP_VT220_MAX_CHARS_PER_BUFFER; 627 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 628 return count; 629} 630 631/* 632 * Return number of buffered chars. 633 */ 634static int 635sclp_vt220_chars_in_buffer(struct tty_struct *tty) 636{ 637 unsigned long flags; 638 struct list_head *l; 639 struct sclp_vt220_request *r; 640 int count; 641 642 spin_lock_irqsave(&sclp_vt220_lock, flags); 643 count = 0; 644 if (sclp_vt220_current_request != NULL) 645 count = sclp_vt220_chars_stored(sclp_vt220_current_request); 646 list_for_each(l, &sclp_vt220_outqueue) { 647 r = list_entry(l, struct sclp_vt220_request, list); 648 count += sclp_vt220_chars_stored(r); 649 } 650 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 651 return count; 652} 653 654/* 655 * Pass on all buffers to the hardware. Return only when there are no more 656 * buffers pending. 657 */ 658static void 659sclp_vt220_flush_buffer(struct tty_struct *tty) 660{ 661 sclp_vt220_emit_current(); 662} 663 664/* Release allocated pages. */ 665static void __init __sclp_vt220_free_pages(void) 666{ 667 struct list_head *page, *p; 668 669 list_for_each_safe(page, p, &sclp_vt220_empty) { 670 list_del(page); 671 free_page((unsigned long) page); 672 } 673} 674 675/* Release memory and unregister from sclp core. Controlled by init counting - 676 * only the last invoker will actually perform these actions. */ 677static void __init __sclp_vt220_cleanup(void) 678{ 679 sclp_vt220_init_count--; 680 if (sclp_vt220_init_count != 0) 681 return; 682 sclp_unregister(&sclp_vt220_register); 683 __sclp_vt220_free_pages(); 684 tty_port_destroy(&sclp_vt220_port); 685} 686 687/* Allocate buffer pages and register with sclp core. Controlled by init 688 * counting - only the first invoker will actually perform these actions. */ 689static int __init __sclp_vt220_init(int num_pages) 690{ 691 void *page; 692 int i; 693 int rc; 694 695 sclp_vt220_init_count++; 696 if (sclp_vt220_init_count != 1) 697 return 0; 698 spin_lock_init(&sclp_vt220_lock); 699 INIT_LIST_HEAD(&sclp_vt220_empty); 700 INIT_LIST_HEAD(&sclp_vt220_outqueue); 701 init_timer(&sclp_vt220_timer); 702 tty_port_init(&sclp_vt220_port); 703 sclp_vt220_current_request = NULL; 704 sclp_vt220_buffered_chars = 0; 705 sclp_vt220_flush_later = 0; 706 707 /* Allocate pages for output buffering */ 708 rc = -ENOMEM; 709 for (i = 0; i < num_pages; i++) { 710 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 711 if (!page) 712 goto out; 713 list_add_tail(page, &sclp_vt220_empty); 714 } 715 rc = sclp_register(&sclp_vt220_register); 716out: 717 if (rc) { 718 __sclp_vt220_free_pages(); 719 sclp_vt220_init_count--; 720 tty_port_destroy(&sclp_vt220_port); 721 } 722 return rc; 723} 724 725static const struct tty_operations sclp_vt220_ops = { 726 .open = sclp_vt220_open, 727 .close = sclp_vt220_close, 728 .write = sclp_vt220_write, 729 .put_char = sclp_vt220_put_char, 730 .flush_chars = sclp_vt220_flush_chars, 731 .write_room = sclp_vt220_write_room, 732 .chars_in_buffer = sclp_vt220_chars_in_buffer, 733 .flush_buffer = sclp_vt220_flush_buffer, 734}; 735 736/* 737 * Register driver with SCLP and Linux and initialize internal tty structures. 738 */ 739static int __init sclp_vt220_tty_init(void) 740{ 741 struct tty_driver *driver; 742 int rc; 743 744 /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve 745 * symmetry between VM and LPAR systems regarding ttyS1. */ 746 driver = alloc_tty_driver(1); 747 if (!driver) 748 return -ENOMEM; 749 rc = __sclp_vt220_init(MAX_KMEM_PAGES); 750 if (rc) 751 goto out_driver; 752 753 driver->driver_name = SCLP_VT220_DRIVER_NAME; 754 driver->name = SCLP_VT220_DEVICE_NAME; 755 driver->major = SCLP_VT220_MAJOR; 756 driver->minor_start = SCLP_VT220_MINOR; 757 driver->type = TTY_DRIVER_TYPE_SYSTEM; 758 driver->subtype = SYSTEM_TYPE_TTY; 759 driver->init_termios = tty_std_termios; 760 driver->flags = TTY_DRIVER_REAL_RAW; 761 tty_set_operations(driver, &sclp_vt220_ops); 762 tty_port_link_device(&sclp_vt220_port, driver, 0); 763 764 rc = tty_register_driver(driver); 765 if (rc) 766 goto out_init; 767 rc = sclp_register(&sclp_vt220_register_input); 768 if (rc) 769 goto out_reg; 770 sclp_vt220_driver = driver; 771 return 0; 772 773out_reg: 774 tty_unregister_driver(driver); 775out_init: 776 __sclp_vt220_cleanup(); 777out_driver: 778 put_tty_driver(driver); 779 return rc; 780} 781__initcall(sclp_vt220_tty_init); 782 783static void __sclp_vt220_flush_buffer(void) 784{ 785 unsigned long flags; 786 787 sclp_vt220_emit_current(); 788 spin_lock_irqsave(&sclp_vt220_lock, flags); 789 if (timer_pending(&sclp_vt220_timer)) 790 del_timer(&sclp_vt220_timer); 791 while (sclp_vt220_queue_running) { 792 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 793 sclp_sync_wait(); 794 spin_lock_irqsave(&sclp_vt220_lock, flags); 795 } 796 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 797} 798 799/* 800 * Resume console: If there are cached messages, emit them. 801 */ 802static void sclp_vt220_resume(void) 803{ 804 unsigned long flags; 805 806 spin_lock_irqsave(&sclp_vt220_lock, flags); 807 sclp_vt220_suspended = 0; 808 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 809 sclp_vt220_emit_current(); 810} 811 812/* 813 * Suspend console: Set suspend flag and flush console 814 */ 815static void sclp_vt220_suspend(void) 816{ 817 unsigned long flags; 818 819 spin_lock_irqsave(&sclp_vt220_lock, flags); 820 sclp_vt220_suspended = 1; 821 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 822 __sclp_vt220_flush_buffer(); 823} 824 825static void sclp_vt220_pm_event_fn(struct sclp_register *reg, 826 enum sclp_pm_event sclp_pm_event) 827{ 828 switch (sclp_pm_event) { 829 case SCLP_PM_EVENT_FREEZE: 830 sclp_vt220_suspend(); 831 break; 832 case SCLP_PM_EVENT_RESTORE: 833 case SCLP_PM_EVENT_THAW: 834 sclp_vt220_resume(); 835 break; 836 } 837} 838 839#ifdef CONFIG_SCLP_VT220_CONSOLE 840 841static void 842sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count) 843{ 844 __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0); 845} 846 847static struct tty_driver * 848sclp_vt220_con_device(struct console *c, int *index) 849{ 850 *index = 0; 851 return sclp_vt220_driver; 852} 853 854static int 855sclp_vt220_notify(struct notifier_block *self, 856 unsigned long event, void *data) 857{ 858 __sclp_vt220_flush_buffer(); 859 return NOTIFY_OK; 860} 861 862static struct notifier_block on_panic_nb = { 863 .notifier_call = sclp_vt220_notify, 864 .priority = 1, 865}; 866 867static struct notifier_block on_reboot_nb = { 868 .notifier_call = sclp_vt220_notify, 869 .priority = 1, 870}; 871 872/* Structure needed to register with printk */ 873static struct console sclp_vt220_console = 874{ 875 .name = SCLP_VT220_CONSOLE_NAME, 876 .write = sclp_vt220_con_write, 877 .device = sclp_vt220_con_device, 878 .flags = CON_PRINTBUFFER, 879 .index = SCLP_VT220_CONSOLE_INDEX 880}; 881 882static int __init 883sclp_vt220_con_init(void) 884{ 885 int rc; 886 887 rc = __sclp_vt220_init(sclp_console_pages); 888 if (rc) 889 return rc; 890 /* Attach linux console */ 891 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); 892 register_reboot_notifier(&on_reboot_nb); 893 register_console(&sclp_vt220_console); 894 return 0; 895} 896 897console_initcall(sclp_vt220_con_init); 898#endif /* CONFIG_SCLP_VT220_CONSOLE */ 899 900