simserial.c revision 5dcded1b0b4f1537bb6dff453fb805517756c94b
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 { 0, 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#if 0 201/* 202 * not really used in our situation so keep them commented out for now 203 */ 204static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */ 205static void do_serial_bh(void) 206{ 207 run_task_queue(&tq_serial); 208 printk(KERN_ERR "do_serial_bh: called\n"); 209} 210#endif 211 212static void do_softint(void *private_) 213{ 214 printk(KERN_ERR "simserial: do_softint called\n"); 215} 216 217static void rs_put_char(struct tty_struct *tty, unsigned char ch) 218{ 219 struct async_struct *info = (struct async_struct *)tty->driver_data; 220 unsigned long flags; 221 222 if (!tty || !info->xmit.buf) return; 223 224 local_irq_save(flags); 225 if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) { 226 local_irq_restore(flags); 227 return; 228 } 229 info->xmit.buf[info->xmit.head] = ch; 230 info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); 231 local_irq_restore(flags); 232} 233 234static void transmit_chars(struct async_struct *info, int *intr_done) 235{ 236 int count; 237 unsigned long flags; 238 239 240 local_irq_save(flags); 241 242 if (info->x_char) { 243 char c = info->x_char; 244 245 console->write(console, &c, 1); 246 247 info->state->icount.tx++; 248 info->x_char = 0; 249 250 goto out; 251 } 252 253 if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { 254#ifdef SIMSERIAL_DEBUG 255 printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", 256 info->xmit.head, info->xmit.tail, info->tty->stopped); 257#endif 258 goto out; 259 } 260 /* 261 * We removed the loop and try to do it in to chunks. We need 262 * 2 operations maximum because it's a ring buffer. 263 * 264 * First from current to tail if possible. 265 * Then from the beginning of the buffer until necessary 266 */ 267 268 count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE), 269 SERIAL_XMIT_SIZE - info->xmit.tail); 270 console->write(console, info->xmit.buf+info->xmit.tail, count); 271 272 info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1); 273 274 /* 275 * We have more at the beginning of the buffer 276 */ 277 count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 278 if (count) { 279 console->write(console, info->xmit.buf, count); 280 info->xmit.tail += count; 281 } 282out: 283 local_irq_restore(flags); 284} 285 286static void rs_flush_chars(struct tty_struct *tty) 287{ 288 struct async_struct *info = (struct async_struct *)tty->driver_data; 289 290 if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || 291 !info->xmit.buf) 292 return; 293 294 transmit_chars(info, NULL); 295} 296 297 298static int rs_write(struct tty_struct * tty, 299 const unsigned char *buf, int count) 300{ 301 int c, ret = 0; 302 struct async_struct *info = (struct async_struct *)tty->driver_data; 303 unsigned long flags; 304 305 if (!tty || !info->xmit.buf || !tmp_buf) return 0; 306 307 local_irq_save(flags); 308 while (1) { 309 c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 310 if (count < c) 311 c = count; 312 if (c <= 0) { 313 break; 314 } 315 memcpy(info->xmit.buf + info->xmit.head, buf, c); 316 info->xmit.head = ((info->xmit.head + c) & 317 (SERIAL_XMIT_SIZE-1)); 318 buf += c; 319 count -= c; 320 ret += c; 321 } 322 local_irq_restore(flags); 323 /* 324 * Hey, we transmit directly from here in our case 325 */ 326 if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) 327 && !tty->stopped && !tty->hw_stopped) { 328 transmit_chars(info, NULL); 329 } 330 return ret; 331} 332 333static int rs_write_room(struct tty_struct *tty) 334{ 335 struct async_struct *info = (struct async_struct *)tty->driver_data; 336 337 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 338} 339 340static int rs_chars_in_buffer(struct tty_struct *tty) 341{ 342 struct async_struct *info = (struct async_struct *)tty->driver_data; 343 344 return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 345} 346 347static void rs_flush_buffer(struct tty_struct *tty) 348{ 349 struct async_struct *info = (struct async_struct *)tty->driver_data; 350 unsigned long flags; 351 352 local_irq_save(flags); 353 info->xmit.head = info->xmit.tail = 0; 354 local_irq_restore(flags); 355 356 wake_up_interruptible(&tty->write_wait); 357 358 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 359 tty->ldisc.write_wakeup) 360 (tty->ldisc.write_wakeup)(tty); 361} 362 363/* 364 * This function is used to send a high-priority XON/XOFF character to 365 * the device 366 */ 367static void rs_send_xchar(struct tty_struct *tty, char ch) 368{ 369 struct async_struct *info = (struct async_struct *)tty->driver_data; 370 371 info->x_char = ch; 372 if (ch) { 373 /* 374 * I guess we could call console->write() directly but 375 * let's do that for now. 376 */ 377 transmit_chars(info, NULL); 378 } 379} 380 381/* 382 * ------------------------------------------------------------ 383 * rs_throttle() 384 * 385 * This routine is called by the upper-layer tty layer to signal that 386 * incoming characters should be throttled. 387 * ------------------------------------------------------------ 388 */ 389static void rs_throttle(struct tty_struct * tty) 390{ 391 if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); 392 393 printk(KERN_INFO "simrs_throttle called\n"); 394} 395 396static void rs_unthrottle(struct tty_struct * tty) 397{ 398 struct async_struct *info = (struct async_struct *)tty->driver_data; 399 400 if (I_IXOFF(tty)) { 401 if (info->x_char) 402 info->x_char = 0; 403 else 404 rs_send_xchar(tty, START_CHAR(tty)); 405 } 406 printk(KERN_INFO "simrs_unthrottle called\n"); 407} 408 409/* 410 * rs_break() --- routine which turns the break handling on or off 411 */ 412static void rs_break(struct tty_struct *tty, int break_state) 413{ 414} 415 416static int rs_ioctl(struct tty_struct *tty, struct file * file, 417 unsigned int cmd, unsigned long arg) 418{ 419 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 420 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && 421 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 422 if (tty->flags & (1 << TTY_IO_ERROR)) 423 return -EIO; 424 } 425 426 switch (cmd) { 427 case TIOCMGET: 428 printk(KERN_INFO "rs_ioctl: TIOCMGET called\n"); 429 return -EINVAL; 430 case TIOCMBIS: 431 case TIOCMBIC: 432 case TIOCMSET: 433 printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n"); 434 return -EINVAL; 435 case TIOCGSERIAL: 436 printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); 437 return 0; 438 case TIOCSSERIAL: 439 printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n"); 440 return 0; 441 case TIOCSERCONFIG: 442 printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n"); 443 return -EINVAL; 444 445 case TIOCSERGETLSR: /* Get line status register */ 446 printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n"); 447 return -EINVAL; 448 449 case TIOCSERGSTRUCT: 450 printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n"); 451#if 0 452 if (copy_to_user((struct async_struct *) arg, 453 info, sizeof(struct async_struct))) 454 return -EFAULT; 455#endif 456 return 0; 457 458 /* 459 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 460 * - mask passed in arg for lines of interest 461 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 462 * Caller should use TIOCGICOUNT to see which one it was 463 */ 464 case TIOCMIWAIT: 465 printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n"); 466 return 0; 467 /* 468 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 469 * Return: write counters to the user passed counter struct 470 * NB: both 1->0 and 0->1 transitions are counted except for 471 * RI where only 0->1 is counted. 472 */ 473 case TIOCGICOUNT: 474 printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n"); 475 return 0; 476 477 case TIOCSERGWILD: 478 case TIOCSERSWILD: 479 /* "setserial -W" is called in Debian boot */ 480 printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); 481 return 0; 482 483 default: 484 return -ENOIOCTLCMD; 485 } 486 return 0; 487} 488 489#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 490 491static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) 492{ 493 unsigned int cflag = tty->termios->c_cflag; 494 495 if ( (cflag == old_termios->c_cflag) 496 && ( RELEVANT_IFLAG(tty->termios->c_iflag) 497 == RELEVANT_IFLAG(old_termios->c_iflag))) 498 return; 499 500 501 /* Handle turning off CRTSCTS */ 502 if ((old_termios->c_cflag & CRTSCTS) && 503 !(tty->termios->c_cflag & CRTSCTS)) { 504 tty->hw_stopped = 0; 505 rs_start(tty); 506 } 507} 508/* 509 * This routine will shutdown a serial port; interrupts are disabled, and 510 * DTR is dropped if the hangup on close termio flag is on. 511 */ 512static void shutdown(struct async_struct * info) 513{ 514 unsigned long flags; 515 struct serial_state *state; 516 int retval; 517 518 if (!(info->flags & ASYNC_INITIALIZED)) return; 519 520 state = info->state; 521 522#ifdef SIMSERIAL_DEBUG 523 printk("Shutting down serial port %d (irq %d)....", info->line, 524 state->irq); 525#endif 526 527 local_irq_save(flags); 528 { 529 /* 530 * First unlink the serial port from the IRQ chain... 531 */ 532 if (info->next_port) 533 info->next_port->prev_port = info->prev_port; 534 if (info->prev_port) 535 info->prev_port->next_port = info->next_port; 536 else 537 IRQ_ports[state->irq] = info->next_port; 538 539 /* 540 * Free the IRQ, if necessary 541 */ 542 if (state->irq && (!IRQ_ports[state->irq] || 543 !IRQ_ports[state->irq]->next_port)) { 544 if (IRQ_ports[state->irq]) { 545 free_irq(state->irq, NULL); 546 retval = request_irq(state->irq, rs_interrupt_single, 547 IRQ_T(info), "serial", NULL); 548 549 if (retval) 550 printk(KERN_ERR "serial shutdown: request_irq: error %d" 551 " Couldn't reacquire IRQ.\n", retval); 552 } else 553 free_irq(state->irq, NULL); 554 } 555 556 if (info->xmit.buf) { 557 free_page((unsigned long) info->xmit.buf); 558 info->xmit.buf = 0; 559 } 560 561 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 562 563 info->flags &= ~ASYNC_INITIALIZED; 564 } 565 local_irq_restore(flags); 566} 567 568/* 569 * ------------------------------------------------------------ 570 * rs_close() 571 * 572 * This routine is called when the serial port gets closed. First, we 573 * wait for the last remaining data to be sent. Then, we unlink its 574 * async structure from the interrupt chain if necessary, and we free 575 * that IRQ if nothing is left in the chain. 576 * ------------------------------------------------------------ 577 */ 578static void rs_close(struct tty_struct *tty, struct file * filp) 579{ 580 struct async_struct * info = (struct async_struct *)tty->driver_data; 581 struct serial_state *state; 582 unsigned long flags; 583 584 if (!info ) return; 585 586 state = info->state; 587 588 local_irq_save(flags); 589 if (tty_hung_up_p(filp)) { 590#ifdef SIMSERIAL_DEBUG 591 printk("rs_close: hung_up\n"); 592#endif 593 local_irq_restore(flags); 594 return; 595 } 596#ifdef SIMSERIAL_DEBUG 597 printk("rs_close ttys%d, count = %d\n", info->line, state->count); 598#endif 599 if ((tty->count == 1) && (state->count != 1)) { 600 /* 601 * Uh, oh. tty->count is 1, which means that the tty 602 * structure will be freed. state->count should always 603 * be one in these conditions. If it's greater than 604 * one, we've got real problems, since it means the 605 * serial port won't be shutdown. 606 */ 607 printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " 608 "state->count is %d\n", state->count); 609 state->count = 1; 610 } 611 if (--state->count < 0) { 612 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", 613 info->line, state->count); 614 state->count = 0; 615 } 616 if (state->count) { 617 local_irq_restore(flags); 618 return; 619 } 620 info->flags |= ASYNC_CLOSING; 621 local_irq_restore(flags); 622 623 /* 624 * Now we wait for the transmit buffer to clear; and we notify 625 * the line discipline to only process XON/XOFF characters. 626 */ 627 shutdown(info); 628 if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); 629 if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); 630 info->event = 0; 631 info->tty = 0; 632 if (info->blocked_open) { 633 if (info->close_delay) 634 schedule_timeout_interruptible(info->close_delay); 635 wake_up_interruptible(&info->open_wait); 636 } 637 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 638 wake_up_interruptible(&info->close_wait); 639} 640 641/* 642 * rs_wait_until_sent() --- wait until the transmitter is empty 643 */ 644static void rs_wait_until_sent(struct tty_struct *tty, int timeout) 645{ 646} 647 648 649/* 650 * rs_hangup() --- called by tty_hangup() when a hangup is signaled. 651 */ 652static void rs_hangup(struct tty_struct *tty) 653{ 654 struct async_struct * info = (struct async_struct *)tty->driver_data; 655 struct serial_state *state = info->state; 656 657#ifdef SIMSERIAL_DEBUG 658 printk("rs_hangup: called\n"); 659#endif 660 661 state = info->state; 662 663 rs_flush_buffer(tty); 664 if (info->flags & ASYNC_CLOSING) 665 return; 666 shutdown(info); 667 668 info->event = 0; 669 state->count = 0; 670 info->flags &= ~ASYNC_NORMAL_ACTIVE; 671 info->tty = 0; 672 wake_up_interruptible(&info->open_wait); 673} 674 675 676static int get_async_struct(int line, struct async_struct **ret_info) 677{ 678 struct async_struct *info; 679 struct serial_state *sstate; 680 681 sstate = rs_table + line; 682 sstate->count++; 683 if (sstate->info) { 684 *ret_info = sstate->info; 685 return 0; 686 } 687 info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); 688 if (!info) { 689 sstate->count--; 690 return -ENOMEM; 691 } 692 memset(info, 0, sizeof(struct async_struct)); 693 init_waitqueue_head(&info->open_wait); 694 init_waitqueue_head(&info->close_wait); 695 init_waitqueue_head(&info->delta_msr_wait); 696 info->magic = SERIAL_MAGIC; 697 info->port = sstate->port; 698 info->flags = sstate->flags; 699 info->xmit_fifo_size = sstate->xmit_fifo_size; 700 info->line = line; 701 INIT_WORK(&info->work, do_softint, info); 702 info->state = sstate; 703 if (sstate->info) { 704 kfree(info); 705 *ret_info = sstate->info; 706 return 0; 707 } 708 *ret_info = sstate->info = info; 709 return 0; 710} 711 712static int 713startup(struct async_struct *info) 714{ 715 unsigned long flags; 716 int retval=0; 717 irqreturn_t (*handler)(int, void *); 718 struct serial_state *state= info->state; 719 unsigned long page; 720 721 page = get_zeroed_page(GFP_KERNEL); 722 if (!page) 723 return -ENOMEM; 724 725 local_irq_save(flags); 726 727 if (info->flags & ASYNC_INITIALIZED) { 728 free_page(page); 729 goto errout; 730 } 731 732 if (!state->port || !state->type) { 733 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 734 free_page(page); 735 goto errout; 736 } 737 if (info->xmit.buf) 738 free_page(page); 739 else 740 info->xmit.buf = (unsigned char *) page; 741 742#ifdef SIMSERIAL_DEBUG 743 printk("startup: ttys%d (irq %d)...", info->line, state->irq); 744#endif 745 746 /* 747 * Allocate the IRQ if necessary 748 */ 749 if (state->irq && (!IRQ_ports[state->irq] || 750 !IRQ_ports[state->irq]->next_port)) { 751 if (IRQ_ports[state->irq]) { 752 retval = -EBUSY; 753 goto errout; 754 } else 755 handler = rs_interrupt_single; 756 757 retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL); 758 if (retval) { 759 if (capable(CAP_SYS_ADMIN)) { 760 if (info->tty) 761 set_bit(TTY_IO_ERROR, 762 &info->tty->flags); 763 retval = 0; 764 } 765 goto errout; 766 } 767 } 768 769 /* 770 * Insert serial port into IRQ chain. 771 */ 772 info->prev_port = 0; 773 info->next_port = IRQ_ports[state->irq]; 774 if (info->next_port) 775 info->next_port->prev_port = info; 776 IRQ_ports[state->irq] = info; 777 778 if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); 779 780 info->xmit.head = info->xmit.tail = 0; 781 782#if 0 783 /* 784 * Set up serial timers... 785 */ 786 timer_table[RS_TIMER].expires = jiffies + 2*HZ/100; 787 timer_active |= 1 << RS_TIMER; 788#endif 789 790 /* 791 * Set up the tty->alt_speed kludge 792 */ 793 if (info->tty) { 794 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 795 info->tty->alt_speed = 57600; 796 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 797 info->tty->alt_speed = 115200; 798 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 799 info->tty->alt_speed = 230400; 800 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 801 info->tty->alt_speed = 460800; 802 } 803 804 info->flags |= ASYNC_INITIALIZED; 805 local_irq_restore(flags); 806 return 0; 807 808errout: 809 local_irq_restore(flags); 810 return retval; 811} 812 813 814/* 815 * This routine is called whenever a serial port is opened. It 816 * enables interrupts for a serial port, linking in its async structure into 817 * the IRQ chain. It also performs the serial-specific 818 * initialization for the tty structure. 819 */ 820static int rs_open(struct tty_struct *tty, struct file * filp) 821{ 822 struct async_struct *info; 823 int retval, line; 824 unsigned long page; 825 826 line = tty->index; 827 if ((line < 0) || (line >= NR_PORTS)) 828 return -ENODEV; 829 retval = get_async_struct(line, &info); 830 if (retval) 831 return retval; 832 tty->driver_data = info; 833 info->tty = tty; 834 835#ifdef SIMSERIAL_DEBUG 836 printk("rs_open %s, count = %d\n", tty->name, info->state->count); 837#endif 838 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 839 840 if (!tmp_buf) { 841 page = get_zeroed_page(GFP_KERNEL); 842 if (!page) 843 return -ENOMEM; 844 if (tmp_buf) 845 free_page(page); 846 else 847 tmp_buf = (unsigned char *) page; 848 } 849 850 /* 851 * If the port is the middle of closing, bail out now 852 */ 853 if (tty_hung_up_p(filp) || 854 (info->flags & ASYNC_CLOSING)) { 855 if (info->flags & ASYNC_CLOSING) 856 interruptible_sleep_on(&info->close_wait); 857#ifdef SERIAL_DO_RESTART 858 return ((info->flags & ASYNC_HUP_NOTIFY) ? 859 -EAGAIN : -ERESTARTSYS); 860#else 861 return -EAGAIN; 862#endif 863 } 864 865 /* 866 * Start up serial port 867 */ 868 retval = startup(info); 869 if (retval) { 870 return retval; 871 } 872 873 /* 874 * figure out which console to use (should be one already) 875 */ 876 console = console_drivers; 877 while (console) { 878 if ((console->flags & CON_ENABLED) && console->write) break; 879 console = console->next; 880 } 881 882#ifdef SIMSERIAL_DEBUG 883 printk("rs_open ttys%d successful\n", info->line); 884#endif 885 return 0; 886} 887 888/* 889 * /proc fs routines.... 890 */ 891 892static inline int line_info(char *buf, struct serial_state *state) 893{ 894 return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", 895 state->line, uart_config[state->type].name, 896 state->port, state->irq); 897} 898 899static int rs_read_proc(char *page, char **start, off_t off, int count, 900 int *eof, void *data) 901{ 902 int i, len = 0, l; 903 off_t begin = 0; 904 905 len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); 906 for (i = 0; i < NR_PORTS && len < 4000; i++) { 907 l = line_info(page + len, &rs_table[i]); 908 len += l; 909 if (len+begin > off+count) 910 goto done; 911 if (len+begin < off) { 912 begin += len; 913 len = 0; 914 } 915 } 916 *eof = 1; 917done: 918 if (off >= len+begin) 919 return 0; 920 *start = page + (begin-off); 921 return ((count < begin+len-off) ? count : begin+len-off); 922} 923 924/* 925 * --------------------------------------------------------------------- 926 * rs_init() and friends 927 * 928 * rs_init() is called at boot-time to initialize the serial driver. 929 * --------------------------------------------------------------------- 930 */ 931 932/* 933 * This routine prints out the appropriate serial driver version 934 * number, and identifies which options were configured into this 935 * driver. 936 */ 937static inline void show_serial_version(void) 938{ 939 printk(KERN_INFO "%s version %s with", serial_name, serial_version); 940 printk(KERN_INFO " no serial options enabled\n"); 941} 942 943static const struct tty_operations hp_ops = { 944 .open = rs_open, 945 .close = rs_close, 946 .write = rs_write, 947 .put_char = rs_put_char, 948 .flush_chars = rs_flush_chars, 949 .write_room = rs_write_room, 950 .chars_in_buffer = rs_chars_in_buffer, 951 .flush_buffer = rs_flush_buffer, 952 .ioctl = rs_ioctl, 953 .throttle = rs_throttle, 954 .unthrottle = rs_unthrottle, 955 .send_xchar = rs_send_xchar, 956 .set_termios = rs_set_termios, 957 .stop = rs_stop, 958 .start = rs_start, 959 .hangup = rs_hangup, 960 .break_ctl = rs_break, 961 .wait_until_sent = rs_wait_until_sent, 962 .read_proc = rs_read_proc, 963}; 964 965/* 966 * The serial driver boot-time initialization code! 967 */ 968static int __init 969simrs_init (void) 970{ 971 int i, rc; 972 struct serial_state *state; 973 974 if (!ia64_platform_is("hpsim")) 975 return -ENODEV; 976 977 hp_simserial_driver = alloc_tty_driver(1); 978 if (!hp_simserial_driver) 979 return -ENOMEM; 980 981 show_serial_version(); 982 983 /* Initialize the tty_driver structure */ 984 985 hp_simserial_driver->owner = THIS_MODULE; 986 hp_simserial_driver->driver_name = "simserial"; 987 hp_simserial_driver->name = "ttyS"; 988 hp_simserial_driver->major = TTY_MAJOR; 989 hp_simserial_driver->minor_start = 64; 990 hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL; 991 hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL; 992 hp_simserial_driver->init_termios = tty_std_termios; 993 hp_simserial_driver->init_termios.c_cflag = 994 B9600 | CS8 | CREAD | HUPCL | CLOCAL; 995 hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW; 996 tty_set_operations(hp_simserial_driver, &hp_ops); 997 998 /* 999 * Let's have a little bit of fun ! 1000 */ 1001 for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { 1002 1003 if (state->type == PORT_UNKNOWN) continue; 1004 1005 if (!state->irq) { 1006 if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) 1007 panic("%s: out of interrupt vectors!\n", 1008 __FUNCTION__); 1009 state->irq = rc; 1010 ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); 1011 } 1012 1013 printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", 1014 state->line, 1015 state->port, state->irq, 1016 uart_config[state->type].name); 1017 } 1018 1019 if (tty_register_driver(hp_simserial_driver)) 1020 panic("Couldn't register simserial driver\n"); 1021 1022 return 0; 1023} 1024 1025#ifndef MODULE 1026__initcall(simrs_init); 1027#endif 1028