1/* 2 * Simulated Serial Driver (fake serial) 3 * 4 * This driver is mostly used for bringup purposes and will go away. 5 * It has a strong dependency on the system console. All outputs 6 * are rerouted to the same facility as the one used by printk which, in our 7 * case means sys_sim.c console (goes via the simulator). The code hereafter 8 * is completely leveraged from the serial.c driver. 9 * 10 * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co 11 * Stephane Eranian <eranian@hpl.hp.com> 12 * David Mosberger-Tang <davidm@hpl.hp.com> 13 * 14 * 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close(). 15 * 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c. 16 * 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking 17 */ 18 19#include <linux/init.h> 20#include <linux/errno.h> 21#include <linux/sched.h> 22#include <linux/tty.h> 23#include <linux/tty_flip.h> 24#include <linux/major.h> 25#include <linux/fcntl.h> 26#include <linux/mm.h> 27#include <linux/slab.h> 28#include <linux/capability.h> 29#include <linux/console.h> 30#include <linux/module.h> 31#include <linux/serial.h> 32#include <linux/serialP.h> 33#include <linux/sysrq.h> 34 35#include <asm/irq.h> 36#include <asm/hw_irq.h> 37#include <asm/uaccess.h> 38 39#ifdef CONFIG_KDB 40# include <linux/kdb.h> 41#endif 42 43#undef SIMSERIAL_DEBUG /* define this to get some debug information */ 44 45#define KEYBOARD_INTR 3 /* must match with simulator! */ 46 47#define NR_PORTS 1 /* only one port for now */ 48 49#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED) 50 51#define SSC_GETCHAR 21 52 53extern long ia64_ssc (long, long, long, long, int); 54extern void ia64_ssc_connect_irq (long intr, long irq); 55 56static char *serial_name = "SimSerial driver"; 57static char *serial_version = "0.6"; 58 59/* 60 * This has been extracted from asm/serial.h. We need one eventually but 61 * I don't know exactly what we're going to put in it so just fake one 62 * for now. 63 */ 64#define BASE_BAUD ( 1843200 / 16 ) 65 66#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) 67 68/* 69 * Most of the values here are meaningless to this particular driver. 70 * However some values must be preserved for the code (leveraged from serial.c 71 * to work correctly). 72 * port must not be 0 73 * type must not be UNKNOWN 74 * So I picked arbitrary (guess from where?) values instead 75 */ 76static struct serial_state rs_table[NR_PORTS]={ 77 /* UART CLK PORT IRQ FLAGS */ 78 { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 } /* ttyS0 */ 79}; 80 81/* 82 * Just for the fun of it ! 83 */ 84static struct serial_uart_config uart_config[] = { 85 { "unknown", 1, 0 }, 86 { "8250", 1, 0 }, 87 { "16450", 1, 0 }, 88 { "16550", 1, 0 }, 89 { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 90 { "cirrus", 1, 0 }, 91 { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, 92 { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | 93 UART_STARTECH }, 94 { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, 95 { NULL, 0} 96}; 97 98struct tty_driver *hp_simserial_driver; 99 100static struct async_struct *IRQ_ports[NR_IRQS]; 101 102static struct console *console; 103 104static unsigned char *tmp_buf; 105 106extern struct console *console_drivers; /* from kernel/printk.c */ 107 108/* 109 * ------------------------------------------------------------ 110 * rs_stop() and rs_start() 111 * 112 * This routines are called before setting or resetting tty->stopped. 113 * They enable or disable transmitter interrupts, as necessary. 114 * ------------------------------------------------------------ 115 */ 116static void rs_stop(struct tty_struct *tty) 117{ 118#ifdef SIMSERIAL_DEBUG 119 printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", 120 tty->stopped, tty->hw_stopped, tty->flow_stopped); 121#endif 122 123} 124 125static void rs_start(struct tty_struct *tty) 126{ 127#ifdef SIMSERIAL_DEBUG 128 printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", 129 tty->stopped, tty->hw_stopped, tty->flow_stopped); 130#endif 131} 132 133static void receive_chars(struct tty_struct *tty) 134{ 135 unsigned char ch; 136 static unsigned char seen_esc = 0; 137 138 while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { 139 if ( ch == 27 && seen_esc == 0 ) { 140 seen_esc = 1; 141 continue; 142 } else { 143 if ( seen_esc==1 && ch == 'O' ) { 144 seen_esc = 2; 145 continue; 146 } else if ( seen_esc == 2 ) { 147 if ( ch == 'P' ) /* F1 */ 148 show_state(); 149#ifdef CONFIG_MAGIC_SYSRQ 150 if ( ch == 'S' ) { /* F4 */ 151 do 152 ch = ia64_ssc(0, 0, 0, 0, 153 SSC_GETCHAR); 154 while (!ch); 155 handle_sysrq(ch, NULL); 156 } 157#endif 158 seen_esc = 0; 159 continue; 160 } 161 } 162 seen_esc = 0; 163 164 if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) 165 break; 166 } 167 tty_flip_buffer_push(tty); 168} 169 170/* 171 * This is the serial driver's interrupt routine for a single port 172 */ 173static irqreturn_t rs_interrupt_single(int irq, void *dev_id) 174{ 175 struct async_struct * info; 176 177 /* 178 * I don't know exactly why they don't use the dev_id opaque data 179 * pointer instead of this extra lookup table 180 */ 181 info = IRQ_ports[irq]; 182 if (!info || !info->tty) { 183 printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info); 184 return IRQ_NONE; 185 } 186 /* 187 * pretty simple in our case, because we only get interrupts 188 * on inbound traffic 189 */ 190 receive_chars(info->tty); 191 return IRQ_HANDLED; 192} 193 194/* 195 * ------------------------------------------------------------------- 196 * Here ends the serial interrupt routines. 197 * ------------------------------------------------------------------- 198 */ 199 200 201static void do_softint(struct work_struct *private_) 202{ 203 printk(KERN_ERR "simserial: do_softint called\n"); 204} 205 206static void rs_put_char(struct tty_struct *tty, unsigned char ch) 207{ 208 struct async_struct *info = (struct async_struct *)tty->driver_data; 209 unsigned long flags; 210 211 if (!tty || !info->xmit.buf) return; 212 213 local_irq_save(flags); 214 if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) { 215 local_irq_restore(flags); 216 return; 217 } 218 info->xmit.buf[info->xmit.head] = ch; 219 info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); 220 local_irq_restore(flags); 221} 222 223static void transmit_chars(struct async_struct *info, int *intr_done) 224{ 225 int count; 226 unsigned long flags; 227 228 229 local_irq_save(flags); 230 231 if (info->x_char) { 232 char c = info->x_char; 233 234 console->write(console, &c, 1); 235 236 info->state->icount.tx++; 237 info->x_char = 0; 238 239 goto out; 240 } 241 242 if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { 243#ifdef SIMSERIAL_DEBUG 244 printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", 245 info->xmit.head, info->xmit.tail, info->tty->stopped); 246#endif 247 goto out; 248 } 249 /* 250 * We removed the loop and try to do it in to chunks. We need 251 * 2 operations maximum because it's a ring buffer. 252 * 253 * First from current to tail if possible. 254 * Then from the beginning of the buffer until necessary 255 */ 256 257 count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE), 258 SERIAL_XMIT_SIZE - info->xmit.tail); 259 console->write(console, info->xmit.buf+info->xmit.tail, count); 260 261 info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1); 262 263 /* 264 * We have more at the beginning of the buffer 265 */ 266 count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 267 if (count) { 268 console->write(console, info->xmit.buf, count); 269 info->xmit.tail += count; 270 } 271out: 272 local_irq_restore(flags); 273} 274 275static void rs_flush_chars(struct tty_struct *tty) 276{ 277 struct async_struct *info = (struct async_struct *)tty->driver_data; 278 279 if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || 280 !info->xmit.buf) 281 return; 282 283 transmit_chars(info, NULL); 284} 285 286 287static int rs_write(struct tty_struct * tty, 288 const unsigned char *buf, int count) 289{ 290 int c, ret = 0; 291 struct async_struct *info = (struct async_struct *)tty->driver_data; 292 unsigned long flags; 293 294 if (!tty || !info->xmit.buf || !tmp_buf) return 0; 295 296 local_irq_save(flags); 297 while (1) { 298 c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 299 if (count < c) 300 c = count; 301 if (c <= 0) { 302 break; 303 } 304 memcpy(info->xmit.buf + info->xmit.head, buf, c); 305 info->xmit.head = ((info->xmit.head + c) & 306 (SERIAL_XMIT_SIZE-1)); 307 buf += c; 308 count -= c; 309 ret += c; 310 } 311 local_irq_restore(flags); 312 /* 313 * Hey, we transmit directly from here in our case 314 */ 315 if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) 316 && !tty->stopped && !tty->hw_stopped) { 317 transmit_chars(info, NULL); 318 } 319 return ret; 320} 321 322static int rs_write_room(struct tty_struct *tty) 323{ 324 struct async_struct *info = (struct async_struct *)tty->driver_data; 325 326 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 327} 328 329static int rs_chars_in_buffer(struct tty_struct *tty) 330{ 331 struct async_struct *info = (struct async_struct *)tty->driver_data; 332 333 return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 334} 335 336static void rs_flush_buffer(struct tty_struct *tty) 337{ 338 struct async_struct *info = (struct async_struct *)tty->driver_data; 339 unsigned long flags; 340 341 local_irq_save(flags); 342 info->xmit.head = info->xmit.tail = 0; 343 local_irq_restore(flags); 344 345 wake_up_interruptible(&tty->write_wait); 346 347 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 348 tty->ldisc.write_wakeup) 349 (tty->ldisc.write_wakeup)(tty); 350} 351 352/* 353 * This function is used to send a high-priority XON/XOFF character to 354 * the device 355 */ 356static void rs_send_xchar(struct tty_struct *tty, char ch) 357{ 358 struct async_struct *info = (struct async_struct *)tty->driver_data; 359 360 info->x_char = ch; 361 if (ch) { 362 /* 363 * I guess we could call console->write() directly but 364 * let's do that for now. 365 */ 366 transmit_chars(info, NULL); 367 } 368} 369 370/* 371 * ------------------------------------------------------------ 372 * rs_throttle() 373 * 374 * This routine is called by the upper-layer tty layer to signal that 375 * incoming characters should be throttled. 376 * ------------------------------------------------------------ 377 */ 378static void rs_throttle(struct tty_struct * tty) 379{ 380 if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); 381 382 printk(KERN_INFO "simrs_throttle called\n"); 383} 384 385static void rs_unthrottle(struct tty_struct * tty) 386{ 387 struct async_struct *info = (struct async_struct *)tty->driver_data; 388 389 if (I_IXOFF(tty)) { 390 if (info->x_char) 391 info->x_char = 0; 392 else 393 rs_send_xchar(tty, START_CHAR(tty)); 394 } 395 printk(KERN_INFO "simrs_unthrottle called\n"); 396} 397 398/* 399 * rs_break() --- routine which turns the break handling on or off 400 */ 401static void rs_break(struct tty_struct *tty, int break_state) 402{ 403} 404 405static int rs_ioctl(struct tty_struct *tty, struct file * file, 406 unsigned int cmd, unsigned long arg) 407{ 408 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 409 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && 410 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 411 if (tty->flags & (1 << TTY_IO_ERROR)) 412 return -EIO; 413 } 414 415 switch (cmd) { 416 case TIOCMGET: 417 printk(KERN_INFO "rs_ioctl: TIOCMGET called\n"); 418 return -EINVAL; 419 case TIOCMBIS: 420 case TIOCMBIC: 421 case TIOCMSET: 422 printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n"); 423 return -EINVAL; 424 case TIOCGSERIAL: 425 printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); 426 return 0; 427 case TIOCSSERIAL: 428 printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n"); 429 return 0; 430 case TIOCSERCONFIG: 431 printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n"); 432 return -EINVAL; 433 434 case TIOCSERGETLSR: /* Get line status register */ 435 printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n"); 436 return -EINVAL; 437 438 case TIOCSERGSTRUCT: 439 printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n"); 440 return 0; 441 442 /* 443 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 444 * - mask passed in arg for lines of interest 445 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 446 * Caller should use TIOCGICOUNT to see which one it was 447 */ 448 case TIOCMIWAIT: 449 printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n"); 450 return 0; 451 /* 452 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 453 * Return: write counters to the user passed counter struct 454 * NB: both 1->0 and 0->1 transitions are counted except for 455 * RI where only 0->1 is counted. 456 */ 457 case TIOCGICOUNT: 458 printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n"); 459 return 0; 460 461 case TIOCSERGWILD: 462 case TIOCSERSWILD: 463 /* "setserial -W" is called in Debian boot */ 464 printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); 465 return 0; 466 467 default: 468 return -ENOIOCTLCMD; 469 } 470 return 0; 471} 472 473#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 474 475static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) 476{ 477 unsigned int cflag = tty->termios->c_cflag; 478 479 if ( (cflag == old_termios->c_cflag) 480 && ( RELEVANT_IFLAG(tty->termios->c_iflag) 481 == RELEVANT_IFLAG(old_termios->c_iflag))) 482 return; 483 484 485 /* Handle turning off CRTSCTS */ 486 if ((old_termios->c_cflag & CRTSCTS) && 487 !(tty->termios->c_cflag & CRTSCTS)) { 488 tty->hw_stopped = 0; 489 rs_start(tty); 490 } 491} 492/* 493 * This routine will shutdown a serial port; interrupts are disabled, and 494 * DTR is dropped if the hangup on close termio flag is on. 495 */ 496static void shutdown(struct async_struct * info) 497{ 498 unsigned long flags; 499 struct serial_state *state; 500 int retval; 501 502 if (!(info->flags & ASYNC_INITIALIZED)) return; 503 504 state = info->state; 505 506#ifdef SIMSERIAL_DEBUG 507 printk("Shutting down serial port %d (irq %d)....", info->line, 508 state->irq); 509#endif 510 511 local_irq_save(flags); 512 { 513 /* 514 * First unlink the serial port from the IRQ chain... 515 */ 516 if (info->next_port) 517 info->next_port->prev_port = info->prev_port; 518 if (info->prev_port) 519 info->prev_port->next_port = info->next_port; 520 else 521 IRQ_ports[state->irq] = info->next_port; 522 523 /* 524 * Free the IRQ, if necessary 525 */ 526 if (state->irq && (!IRQ_ports[state->irq] || 527 !IRQ_ports[state->irq]->next_port)) { 528 if (IRQ_ports[state->irq]) { 529 free_irq(state->irq, NULL); 530 retval = request_irq(state->irq, rs_interrupt_single, 531 IRQ_T(info), "serial", NULL); 532 533 if (retval) 534 printk(KERN_ERR "serial shutdown: request_irq: error %d" 535 " Couldn't reacquire IRQ.\n", retval); 536 } else 537 free_irq(state->irq, NULL); 538 } 539 540 if (info->xmit.buf) { 541 free_page((unsigned long) info->xmit.buf); 542 info->xmit.buf = NULL; 543 } 544 545 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 546 547 info->flags &= ~ASYNC_INITIALIZED; 548 } 549 local_irq_restore(flags); 550} 551 552/* 553 * ------------------------------------------------------------ 554 * rs_close() 555 * 556 * This routine is called when the serial port gets closed. First, we 557 * wait for the last remaining data to be sent. Then, we unlink its 558 * async structure from the interrupt chain if necessary, and we free 559 * that IRQ if nothing is left in the chain. 560 * ------------------------------------------------------------ 561 */ 562static void rs_close(struct tty_struct *tty, struct file * filp) 563{ 564 struct async_struct * info = (struct async_struct *)tty->driver_data; 565 struct serial_state *state; 566 unsigned long flags; 567 568 if (!info ) return; 569 570 state = info->state; 571 572 local_irq_save(flags); 573 if (tty_hung_up_p(filp)) { 574#ifdef SIMSERIAL_DEBUG 575 printk("rs_close: hung_up\n"); 576#endif 577 local_irq_restore(flags); 578 return; 579 } 580#ifdef SIMSERIAL_DEBUG 581 printk("rs_close ttys%d, count = %d\n", info->line, state->count); 582#endif 583 if ((tty->count == 1) && (state->count != 1)) { 584 /* 585 * Uh, oh. tty->count is 1, which means that the tty 586 * structure will be freed. state->count should always 587 * be one in these conditions. If it's greater than 588 * one, we've got real problems, since it means the 589 * serial port won't be shutdown. 590 */ 591 printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " 592 "state->count is %d\n", state->count); 593 state->count = 1; 594 } 595 if (--state->count < 0) { 596 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", 597 info->line, state->count); 598 state->count = 0; 599 } 600 if (state->count) { 601 local_irq_restore(flags); 602 return; 603 } 604 info->flags |= ASYNC_CLOSING; 605 local_irq_restore(flags); 606 607 /* 608 * Now we wait for the transmit buffer to clear; and we notify 609 * the line discipline to only process XON/XOFF characters. 610 */ 611 shutdown(info); 612 if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); 613 if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); 614 info->event = 0; 615 info->tty = NULL; 616 if (info->blocked_open) { 617 if (info->close_delay) 618 schedule_timeout_interruptible(info->close_delay); 619 wake_up_interruptible(&info->open_wait); 620 } 621 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 622 wake_up_interruptible(&info->close_wait); 623} 624 625/* 626 * rs_wait_until_sent() --- wait until the transmitter is empty 627 */ 628static void rs_wait_until_sent(struct tty_struct *tty, int timeout) 629{ 630} 631 632 633/* 634 * rs_hangup() --- called by tty_hangup() when a hangup is signaled. 635 */ 636static void rs_hangup(struct tty_struct *tty) 637{ 638 struct async_struct * info = (struct async_struct *)tty->driver_data; 639 struct serial_state *state = info->state; 640 641#ifdef SIMSERIAL_DEBUG 642 printk("rs_hangup: called\n"); 643#endif 644 645 state = info->state; 646 647 rs_flush_buffer(tty); 648 if (info->flags & ASYNC_CLOSING) 649 return; 650 shutdown(info); 651 652 info->event = 0; 653 state->count = 0; 654 info->flags &= ~ASYNC_NORMAL_ACTIVE; 655 info->tty = NULL; 656 wake_up_interruptible(&info->open_wait); 657} 658 659 660static int get_async_struct(int line, struct async_struct **ret_info) 661{ 662 struct async_struct *info; 663 struct serial_state *sstate; 664 665 sstate = rs_table + line; 666 sstate->count++; 667 if (sstate->info) { 668 *ret_info = sstate->info; 669 return 0; 670 } 671 info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); 672 if (!info) { 673 sstate->count--; 674 return -ENOMEM; 675 } 676 init_waitqueue_head(&info->open_wait); 677 init_waitqueue_head(&info->close_wait); 678 init_waitqueue_head(&info->delta_msr_wait); 679 info->magic = SERIAL_MAGIC; 680 info->port = sstate->port; 681 info->flags = sstate->flags; 682 info->xmit_fifo_size = sstate->xmit_fifo_size; 683 info->line = line; 684 INIT_WORK(&info->work, do_softint); 685 info->state = sstate; 686 if (sstate->info) { 687 kfree(info); 688 *ret_info = sstate->info; 689 return 0; 690 } 691 *ret_info = sstate->info = info; 692 return 0; 693} 694 695static int 696startup(struct async_struct *info) 697{ 698 unsigned long flags; 699 int retval=0; 700 irq_handler_t handler; 701 struct serial_state *state= info->state; 702 unsigned long page; 703 704 page = get_zeroed_page(GFP_KERNEL); 705 if (!page) 706 return -ENOMEM; 707 708 local_irq_save(flags); 709 710 if (info->flags & ASYNC_INITIALIZED) { 711 free_page(page); 712 goto errout; 713 } 714 715 if (!state->port || !state->type) { 716 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 717 free_page(page); 718 goto errout; 719 } 720 if (info->xmit.buf) 721 free_page(page); 722 else 723 info->xmit.buf = (unsigned char *) page; 724 725#ifdef SIMSERIAL_DEBUG 726 printk("startup: ttys%d (irq %d)...", info->line, state->irq); 727#endif 728 729 /* 730 * Allocate the IRQ if necessary 731 */ 732 if (state->irq && (!IRQ_ports[state->irq] || 733 !IRQ_ports[state->irq]->next_port)) { 734 if (IRQ_ports[state->irq]) { 735 retval = -EBUSY; 736 goto errout; 737 } else 738 handler = rs_interrupt_single; 739 740 retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL); 741 if (retval) { 742 if (capable(CAP_SYS_ADMIN)) { 743 if (info->tty) 744 set_bit(TTY_IO_ERROR, 745 &info->tty->flags); 746 retval = 0; 747 } 748 goto errout; 749 } 750 } 751 752 /* 753 * Insert serial port into IRQ chain. 754 */ 755 info->prev_port = NULL; 756 info->next_port = IRQ_ports[state->irq]; 757 if (info->next_port) 758 info->next_port->prev_port = info; 759 IRQ_ports[state->irq] = info; 760 761 if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); 762 763 info->xmit.head = info->xmit.tail = 0; 764 765 766 /* 767 * Set up the tty->alt_speed kludge 768 */ 769 if (info->tty) { 770 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 771 info->tty->alt_speed = 57600; 772 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 773 info->tty->alt_speed = 115200; 774 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 775 info->tty->alt_speed = 230400; 776 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 777 info->tty->alt_speed = 460800; 778 } 779 780 info->flags |= ASYNC_INITIALIZED; 781 local_irq_restore(flags); 782 return 0; 783 784errout: 785 local_irq_restore(flags); 786 return retval; 787} 788 789 790/* 791 * This routine is called whenever a serial port is opened. It 792 * enables interrupts for a serial port, linking in its async structure into 793 * the IRQ chain. It also performs the serial-specific 794 * initialization for the tty structure. 795 */ 796static int rs_open(struct tty_struct *tty, struct file * filp) 797{ 798 struct async_struct *info; 799 int retval, line; 800 unsigned long page; 801 802 line = tty->index; 803 if ((line < 0) || (line >= NR_PORTS)) 804 return -ENODEV; 805 retval = get_async_struct(line, &info); 806 if (retval) 807 return retval; 808 tty->driver_data = info; 809 info->tty = tty; 810 811#ifdef SIMSERIAL_DEBUG 812 printk("rs_open %s, count = %d\n", tty->name, info->state->count); 813#endif 814 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 815 816 if (!tmp_buf) { 817 page = get_zeroed_page(GFP_KERNEL); 818 if (!page) 819 return -ENOMEM; 820 if (tmp_buf) 821 free_page(page); 822 else 823 tmp_buf = (unsigned char *) page; 824 } 825 826 /* 827 * If the port is the middle of closing, bail out now 828 */ 829 if (tty_hung_up_p(filp) || 830 (info->flags & ASYNC_CLOSING)) { 831 if (info->flags & ASYNC_CLOSING) 832 interruptible_sleep_on(&info->close_wait); 833#ifdef SERIAL_DO_RESTART 834 return ((info->flags & ASYNC_HUP_NOTIFY) ? 835 -EAGAIN : -ERESTARTSYS); 836#else 837 return -EAGAIN; 838#endif 839 } 840 841 /* 842 * Start up serial port 843 */ 844 retval = startup(info); 845 if (retval) { 846 return retval; 847 } 848 849 /* 850 * figure out which console to use (should be one already) 851 */ 852 console = console_drivers; 853 while (console) { 854 if ((console->flags & CON_ENABLED) && console->write) break; 855 console = console->next; 856 } 857 858#ifdef SIMSERIAL_DEBUG 859 printk("rs_open ttys%d successful\n", info->line); 860#endif 861 return 0; 862} 863 864/* 865 * /proc fs routines.... 866 */ 867 868static inline int line_info(char *buf, struct serial_state *state) 869{ 870 return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", 871 state->line, uart_config[state->type].name, 872 state->port, state->irq); 873} 874 875static int rs_read_proc(char *page, char **start, off_t off, int count, 876 int *eof, void *data) 877{ 878 int i, len = 0, l; 879 off_t begin = 0; 880 881 len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); 882 for (i = 0; i < NR_PORTS && len < 4000; i++) { 883 l = line_info(page + len, &rs_table[i]); 884 len += l; 885 if (len+begin > off+count) 886 goto done; 887 if (len+begin < off) { 888 begin += len; 889 len = 0; 890 } 891 } 892 *eof = 1; 893done: 894 if (off >= len+begin) 895 return 0; 896 *start = page + (begin-off); 897 return ((count < begin+len-off) ? count : begin+len-off); 898} 899 900/* 901 * --------------------------------------------------------------------- 902 * rs_init() and friends 903 * 904 * rs_init() is called at boot-time to initialize the serial driver. 905 * --------------------------------------------------------------------- 906 */ 907 908/* 909 * This routine prints out the appropriate serial driver version 910 * number, and identifies which options were configured into this 911 * driver. 912 */ 913static inline void show_serial_version(void) 914{ 915 printk(KERN_INFO "%s version %s with", serial_name, serial_version); 916 printk(KERN_INFO " no serial options enabled\n"); 917} 918 919static const struct tty_operations hp_ops = { 920 .open = rs_open, 921 .close = rs_close, 922 .write = rs_write, 923 .put_char = rs_put_char, 924 .flush_chars = rs_flush_chars, 925 .write_room = rs_write_room, 926 .chars_in_buffer = rs_chars_in_buffer, 927 .flush_buffer = rs_flush_buffer, 928 .ioctl = rs_ioctl, 929 .throttle = rs_throttle, 930 .unthrottle = rs_unthrottle, 931 .send_xchar = rs_send_xchar, 932 .set_termios = rs_set_termios, 933 .stop = rs_stop, 934 .start = rs_start, 935 .hangup = rs_hangup, 936 .break_ctl = rs_break, 937 .wait_until_sent = rs_wait_until_sent, 938 .read_proc = rs_read_proc, 939}; 940 941/* 942 * The serial driver boot-time initialization code! 943 */ 944static int __init 945simrs_init (void) 946{ 947 int i, rc; 948 struct serial_state *state; 949 950 if (!ia64_platform_is("hpsim")) 951 return -ENODEV; 952 953 hp_simserial_driver = alloc_tty_driver(1); 954 if (!hp_simserial_driver) 955 return -ENOMEM; 956 957 show_serial_version(); 958 959 /* Initialize the tty_driver structure */ 960 961 hp_simserial_driver->owner = THIS_MODULE; 962 hp_simserial_driver->driver_name = "simserial"; 963 hp_simserial_driver->name = "ttyS"; 964 hp_simserial_driver->major = TTY_MAJOR; 965 hp_simserial_driver->minor_start = 64; 966 hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL; 967 hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL; 968 hp_simserial_driver->init_termios = tty_std_termios; 969 hp_simserial_driver->init_termios.c_cflag = 970 B9600 | CS8 | CREAD | HUPCL | CLOCAL; 971 hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW; 972 tty_set_operations(hp_simserial_driver, &hp_ops); 973 974 /* 975 * Let's have a little bit of fun ! 976 */ 977 for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { 978 979 if (state->type == PORT_UNKNOWN) continue; 980 981 if (!state->irq) { 982 if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) 983 panic("%s: out of interrupt vectors!\n", 984 __FUNCTION__); 985 state->irq = rc; 986 ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); 987 } 988 989 printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", 990 state->line, 991 state->port, state->irq, 992 uart_config[state->type].name); 993 } 994 995 if (tty_register_driver(hp_simserial_driver)) 996 panic("Couldn't register simserial driver\n"); 997 998 return 0; 999} 1000 1001#ifndef MODULE 1002__initcall(simrs_init); 1003#endif 1004