Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 1001 lines 24 kB view raw
1/* 2 * generic_serial.c 3 * 4 * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl 5 * 6 * written for the SX serial driver. 7 * Contains the code that should be shared over all the serial drivers. 8 * 9 * Credit for the idea to do it this way might go to Alan Cox. 10 * 11 * 12 * Version 0.1 -- December, 1998. Initial version. 13 * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. 14 * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. 15 * 16 * BitWizard is actively maintaining this file. We sometimes find 17 * that someone submitted changes to this file. We really appreciate 18 * your help, but please submit changes through us. We're doing our 19 * best to be responsive. -- REW 20 * */ 21 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/tty.h> 25#include <linux/serial.h> 26#include <linux/mm.h> 27#include <linux/generic_serial.h> 28#include <linux/interrupt.h> 29#include <linux/tty_flip.h> 30#include <linux/delay.h> 31#include <asm/semaphore.h> 32#include <asm/uaccess.h> 33 34#define DEBUG 35 36static char * tmp_buf; 37static DECLARE_MUTEX(tmp_buf_sem); 38 39static int gs_debug; 40 41#ifdef DEBUG 42#define gs_dprintk(f, str...) if (gs_debug & f) printk (str) 43#else 44#define gs_dprintk(f, str...) /* nothing */ 45#endif 46 47#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__) 48#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__) 49#define NEW_WRITE_LOCKING 1 50#if NEW_WRITE_LOCKING 51#define DECL /* Nothing */ 52#define LOCKIT down (& port->port_write_sem); 53#define RELEASEIT up (&port->port_write_sem); 54#else 55#define DECL unsigned long flags; 56#define LOCKIT save_flags (flags);cli () 57#define RELEASEIT restore_flags (flags) 58#endif 59 60#define RS_EVENT_WRITE_WAKEUP 1 61 62module_param(gs_debug, int, 0644); 63 64 65void gs_put_char(struct tty_struct * tty, unsigned char ch) 66{ 67 struct gs_port *port; 68 DECL 69 70 func_enter (); 71 72 if (!tty) return; 73 74 port = tty->driver_data; 75 76 if (!port) return; 77 78 if (! (port->flags & ASYNC_INITIALIZED)) return; 79 80 /* Take a lock on the serial tranmit buffer! */ 81 LOCKIT; 82 83 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { 84 /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ 85 RELEASEIT; 86 return; 87 } 88 89 port->xmit_buf[port->xmit_head++] = ch; 90 port->xmit_head &= SERIAL_XMIT_SIZE - 1; 91 port->xmit_cnt++; /* Characters in buffer */ 92 93 RELEASEIT; 94 func_exit (); 95} 96 97 98#ifdef NEW_WRITE_LOCKING 99 100/* 101> Problems to take into account are: 102> -1- Interrupts that empty part of the buffer. 103> -2- page faults on the access to userspace. 104> -3- Other processes that are also trying to do a "write". 105*/ 106 107int gs_write(struct tty_struct * tty, 108 const unsigned char *buf, int count) 109{ 110 struct gs_port *port; 111 int c, total = 0; 112 int t; 113 114 func_enter (); 115 116 if (!tty) return 0; 117 118 port = tty->driver_data; 119 120 if (!port) return 0; 121 122 if (! (port->flags & ASYNC_INITIALIZED)) 123 return 0; 124 125 /* get exclusive "write" access to this port (problem 3) */ 126 /* This is not a spinlock because we can have a disk access (page 127 fault) in copy_from_user */ 128 down (& port->port_write_sem); 129 130 while (1) { 131 132 c = count; 133 134 /* This is safe because we "OWN" the "head". Noone else can 135 change the "head": we own the port_write_sem. */ 136 /* Don't overrun the end of the buffer */ 137 t = SERIAL_XMIT_SIZE - port->xmit_head; 138 if (t < c) c = t; 139 140 /* This is safe because the xmit_cnt can only decrease. This 141 would increase "t", so we might copy too little chars. */ 142 /* Don't copy past the "head" of the buffer */ 143 t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; 144 if (t < c) c = t; 145 146 /* Can't copy more? break out! */ 147 if (c <= 0) break; 148 149 memcpy (port->xmit_buf + port->xmit_head, buf, c); 150 151 port -> xmit_cnt += c; 152 port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); 153 buf += c; 154 count -= c; 155 total += c; 156 } 157 up (& port->port_write_sem); 158 159 gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", 160 (port->flags & GS_TX_INTEN)?"enabled": "disabled"); 161 162 if (port->xmit_cnt && 163 !tty->stopped && 164 !tty->hw_stopped && 165 !(port->flags & GS_TX_INTEN)) { 166 port->flags |= GS_TX_INTEN; 167 port->rd->enable_tx_interrupts (port); 168 } 169 func_exit (); 170 return total; 171} 172#else 173/* 174> Problems to take into account are: 175> -1- Interrupts that empty part of the buffer. 176> -2- page faults on the access to userspace. 177> -3- Other processes that are also trying to do a "write". 178*/ 179 180int gs_write(struct tty_struct * tty, 181 const unsigned char *buf, int count) 182{ 183 struct gs_port *port; 184 int c, total = 0; 185 int t; 186 unsigned long flags; 187 188 func_enter (); 189 190 /* The standard serial driver returns 0 in this case. 191 That sounds to me as "No error, I just didn't get to writing any 192 bytes. Feel free to try again." 193 The "official" way to write n bytes from buf is: 194 195 for (nwritten = 0;nwritten < n;nwritten += rv) { 196 rv = write (fd, buf+nwritten, n-nwritten); 197 if (rv < 0) break; // Error: bail out. // 198 } 199 200 which will loop endlessly in this case. The manual page for write 201 agrees with me. In practise almost everybody writes 202 "write (fd, buf,n);" but some people might have had to deal with 203 incomplete writes in the past and correctly implemented it by now... 204 */ 205 206 if (!tty) return -EIO; 207 208 port = tty->driver_data; 209 if (!port || !port->xmit_buf || !tmp_buf) 210 return -EIO; 211 212 local_save_flags(flags); 213 while (1) { 214 cli(); 215 c = count; 216 217 /* This is safe because we "OWN" the "head". Noone else can 218 change the "head": we own the port_write_sem. */ 219 /* Don't overrun the end of the buffer */ 220 t = SERIAL_XMIT_SIZE - port->xmit_head; 221 if (t < c) c = t; 222 223 /* This is safe because the xmit_cnt can only decrease. This 224 would increase "t", so we might copy too little chars. */ 225 /* Don't copy past the "head" of the buffer */ 226 t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; 227 if (t < c) c = t; 228 229 /* Can't copy more? break out! */ 230 if (c <= 0) { 231 local_restore_flags(flags); 232 break; 233 } 234 memcpy(port->xmit_buf + port->xmit_head, buf, c); 235 port->xmit_head = ((port->xmit_head + c) & 236 (SERIAL_XMIT_SIZE-1)); 237 port->xmit_cnt += c; 238 local_restore_flags(flags); 239 buf += c; 240 count -= c; 241 total += c; 242 } 243 244 if (port->xmit_cnt && 245 !tty->stopped && 246 !tty->hw_stopped && 247 !(port->flags & GS_TX_INTEN)) { 248 port->flags |= GS_TX_INTEN; 249 port->rd->enable_tx_interrupts (port); 250 } 251 func_exit (); 252 return total; 253} 254 255#endif 256 257 258 259int gs_write_room(struct tty_struct * tty) 260{ 261 struct gs_port *port = tty->driver_data; 262 int ret; 263 264 func_enter (); 265 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; 266 if (ret < 0) 267 ret = 0; 268 func_exit (); 269 return ret; 270} 271 272 273int gs_chars_in_buffer(struct tty_struct *tty) 274{ 275 struct gs_port *port = tty->driver_data; 276 func_enter (); 277 278 func_exit (); 279 return port->xmit_cnt; 280} 281 282 283static int gs_real_chars_in_buffer(struct tty_struct *tty) 284{ 285 struct gs_port *port; 286 func_enter (); 287 288 if (!tty) return 0; 289 port = tty->driver_data; 290 291 if (!port->rd) return 0; 292 if (!port->rd->chars_in_buffer) return 0; 293 294 func_exit (); 295 return port->xmit_cnt + port->rd->chars_in_buffer (port); 296} 297 298 299static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) 300{ 301 struct gs_port *port = ptr; 302 unsigned long end_jiffies; 303 int jiffies_to_transmit, charsleft = 0, rv = 0; 304 int rcib; 305 306 func_enter(); 307 308 gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); 309 if (port) { 310 gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", 311 port->xmit_cnt, port->xmit_buf, port->tty); 312 } 313 314 if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { 315 gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); 316 func_exit(); 317 return -EINVAL; /* This is an error which we don't know how to handle. */ 318 } 319 320 rcib = gs_real_chars_in_buffer(port->tty); 321 322 if(rcib <= 0) { 323 gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); 324 func_exit(); 325 return rv; 326 } 327 /* stop trying: now + twice the time it would normally take + seconds */ 328 if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT; 329 end_jiffies = jiffies; 330 if (timeout != MAX_SCHEDULE_TIMEOUT) 331 end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0; 332 end_jiffies += timeout; 333 334 gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", 335 jiffies, end_jiffies, end_jiffies-jiffies); 336 337 /* the expression is actually jiffies < end_jiffies, but that won't 338 work around the wraparound. Tricky eh? */ 339 while ((charsleft = gs_real_chars_in_buffer (port->tty)) && 340 time_after (end_jiffies, jiffies)) { 341 /* Units check: 342 chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! 343 check! */ 344 345 charsleft += 16; /* Allow 16 chars more to be transmitted ... */ 346 jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0; 347 /* ^^^ Round up.... */ 348 if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1; 349 350 gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies " 351 "(%d chars).\n", jiffies_to_transmit, charsleft); 352 353 msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit)); 354 if (signal_pending (current)) { 355 gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); 356 rv = -EINTR; 357 break; 358 } 359 } 360 361 gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); 362 set_current_state (TASK_RUNNING); 363 364 func_exit(); 365 return rv; 366} 367 368 369 370void gs_flush_buffer(struct tty_struct *tty) 371{ 372 struct gs_port *port; 373 unsigned long flags; 374 375 func_enter (); 376 377 if (!tty) return; 378 379 port = tty->driver_data; 380 381 if (!port) return; 382 383 /* XXX Would the write semaphore do? */ 384 spin_lock_irqsave (&port->driver_lock, flags); 385 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 386 spin_unlock_irqrestore (&port->driver_lock, flags); 387 388 wake_up_interruptible(&tty->write_wait); 389 tty_wakeup(tty); 390 func_exit (); 391} 392 393 394void gs_flush_chars(struct tty_struct * tty) 395{ 396 struct gs_port *port; 397 398 func_enter (); 399 400 if (!tty) return; 401 402 port = tty->driver_data; 403 404 if (!port) return; 405 406 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 407 !port->xmit_buf) { 408 func_exit (); 409 return; 410 } 411 412 /* Beats me -- REW */ 413 port->flags |= GS_TX_INTEN; 414 port->rd->enable_tx_interrupts (port); 415 func_exit (); 416} 417 418 419void gs_stop(struct tty_struct * tty) 420{ 421 struct gs_port *port; 422 423 func_enter (); 424 425 if (!tty) return; 426 427 port = tty->driver_data; 428 429 if (!port) return; 430 431 if (port->xmit_cnt && 432 port->xmit_buf && 433 (port->flags & GS_TX_INTEN) ) { 434 port->flags &= ~GS_TX_INTEN; 435 port->rd->disable_tx_interrupts (port); 436 } 437 func_exit (); 438} 439 440 441void gs_start(struct tty_struct * tty) 442{ 443 struct gs_port *port; 444 445 if (!tty) return; 446 447 port = tty->driver_data; 448 449 if (!port) return; 450 451 if (port->xmit_cnt && 452 port->xmit_buf && 453 !(port->flags & GS_TX_INTEN) ) { 454 port->flags |= GS_TX_INTEN; 455 port->rd->enable_tx_interrupts (port); 456 } 457 func_exit (); 458} 459 460 461static void gs_shutdown_port (struct gs_port *port) 462{ 463 unsigned long flags; 464 465 func_enter(); 466 467 if (!port) return; 468 469 if (!(port->flags & ASYNC_INITIALIZED)) 470 return; 471 472 spin_lock_irqsave(&port->driver_lock, flags); 473 474 if (port->xmit_buf) { 475 free_page((unsigned long) port->xmit_buf); 476 port->xmit_buf = NULL; 477 } 478 479 if (port->tty) 480 set_bit(TTY_IO_ERROR, &port->tty->flags); 481 482 port->rd->shutdown_port (port); 483 484 port->flags &= ~ASYNC_INITIALIZED; 485 spin_unlock_irqrestore(&port->driver_lock, flags); 486 487 func_exit(); 488} 489 490 491void gs_hangup(struct tty_struct *tty) 492{ 493 struct gs_port *port; 494 495 func_enter (); 496 497 if (!tty) return; 498 499 port = tty->driver_data; 500 tty = port->tty; 501 if (!tty) 502 return; 503 504 gs_shutdown_port (port); 505 port->flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); 506 port->tty = NULL; 507 port->count = 0; 508 509 wake_up_interruptible(&port->open_wait); 510 func_exit (); 511} 512 513 514int gs_block_til_ready(void *port_, struct file * filp) 515{ 516 struct gs_port *port = port_; 517 DECLARE_WAITQUEUE(wait, current); 518 int retval; 519 int do_clocal = 0; 520 int CD; 521 struct tty_struct *tty; 522 unsigned long flags; 523 524 func_enter (); 525 526 if (!port) return 0; 527 528 tty = port->tty; 529 530 if (!tty) return 0; 531 532 gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); 533 /* 534 * If the device is in the middle of being closed, then block 535 * until it's done, and then try again. 536 */ 537 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 538 interruptible_sleep_on(&port->close_wait); 539 if (port->flags & ASYNC_HUP_NOTIFY) 540 return -EAGAIN; 541 else 542 return -ERESTARTSYS; 543 } 544 545 gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); 546 547 /* 548 * If non-blocking mode is set, or the port is not enabled, 549 * then make the check up front and then exit. 550 */ 551 if ((filp->f_flags & O_NONBLOCK) || 552 (tty->flags & (1 << TTY_IO_ERROR))) { 553 port->flags |= ASYNC_NORMAL_ACTIVE; 554 return 0; 555 } 556 557 gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); 558 559 if (C_CLOCAL(tty)) 560 do_clocal = 1; 561 562 /* 563 * Block waiting for the carrier detect and the line to become 564 * free (i.e., not in use by the callout). While we are in 565 * this loop, port->count is dropped by one, so that 566 * rs_close() knows when to free things. We restore it upon 567 * exit, either normal or abnormal. 568 */ 569 retval = 0; 570 571 add_wait_queue(&port->open_wait, &wait); 572 573 gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 574 spin_lock_irqsave(&port->driver_lock, flags); 575 if (!tty_hung_up_p(filp)) { 576 port->count--; 577 } 578 spin_unlock_irqrestore(&port->driver_lock, flags); 579 port->blocked_open++; 580 while (1) { 581 CD = port->rd->get_CD (port); 582 gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); 583 set_current_state (TASK_INTERRUPTIBLE); 584 if (tty_hung_up_p(filp) || 585 !(port->flags & ASYNC_INITIALIZED)) { 586 if (port->flags & ASYNC_HUP_NOTIFY) 587 retval = -EAGAIN; 588 else 589 retval = -ERESTARTSYS; 590 break; 591 } 592 if (!(port->flags & ASYNC_CLOSING) && 593 (do_clocal || CD)) 594 break; 595 gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", 596 (int)signal_pending (current), *(long*)(&current->blocked)); 597 if (signal_pending(current)) { 598 retval = -ERESTARTSYS; 599 break; 600 } 601 schedule(); 602 } 603 gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", 604 port->blocked_open); 605 set_current_state (TASK_RUNNING); 606 remove_wait_queue(&port->open_wait, &wait); 607 if (!tty_hung_up_p(filp)) { 608 port->count++; 609 } 610 port->blocked_open--; 611 if (retval) 612 return retval; 613 614 port->flags |= ASYNC_NORMAL_ACTIVE; 615 func_exit (); 616 return 0; 617} 618 619 620void gs_close(struct tty_struct * tty, struct file * filp) 621{ 622 unsigned long flags; 623 struct gs_port *port; 624 625 func_enter (); 626 627 if (!tty) return; 628 629 port = (struct gs_port *) tty->driver_data; 630 631 if (!port) return; 632 633 if (!port->tty) { 634 /* This seems to happen when this is called from vhangup. */ 635 gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n"); 636 port->tty = tty; 637 } 638 639 spin_lock_irqsave(&port->driver_lock, flags); 640 641 if (tty_hung_up_p(filp)) { 642 spin_unlock_irqrestore(&port->driver_lock, flags); 643 if (port->rd->hungup) 644 port->rd->hungup (port); 645 func_exit (); 646 return; 647 } 648 649 if ((tty->count == 1) && (port->count != 1)) { 650 printk(KERN_ERR "gs: gs_close port %p: bad port count;" 651 " tty->count is 1, port count is %d\n", port, port->count); 652 port->count = 1; 653 } 654 if (--port->count < 0) { 655 printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->count); 656 port->count = 0; 657 } 658 659 if (port->count) { 660 gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->count); 661 spin_unlock_irqrestore(&port->driver_lock, flags); 662 func_exit (); 663 return; 664 } 665 port->flags |= ASYNC_CLOSING; 666 667 /* 668 * Now we wait for the transmit buffer to clear; and we notify 669 * the line discipline to only process XON/XOFF characters. 670 */ 671 tty->closing = 1; 672 /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 673 tty_wait_until_sent(tty, port->closing_wait); */ 674 675 /* 676 * At this point we stop accepting input. To do this, we 677 * disable the receive line status interrupts, and tell the 678 * interrupt driver to stop checking the data ready bit in the 679 * line status register. 680 */ 681 682 port->rd->disable_rx_interrupts (port); 683 spin_unlock_irqrestore(&port->driver_lock, flags); 684 685 /* close has no way of returning "EINTR", so discard return value */ 686 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 687 gs_wait_tx_flushed (port, port->closing_wait); 688 689 port->flags &= ~GS_ACTIVE; 690 691 if (tty->driver->flush_buffer) 692 tty->driver->flush_buffer(tty); 693 694 tty_ldisc_flush(tty); 695 tty->closing = 0; 696 697 port->event = 0; 698 port->rd->close (port); 699 port->rd->shutdown_port (port); 700 port->tty = NULL; 701 702 if (port->blocked_open) { 703 if (port->close_delay) { 704 spin_unlock_irqrestore(&port->driver_lock, flags); 705 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 706 spin_lock_irqsave(&port->driver_lock, flags); 707 } 708 wake_up_interruptible(&port->open_wait); 709 } 710 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); 711 wake_up_interruptible(&port->close_wait); 712 713 func_exit (); 714} 715 716 717static unsigned int gs_baudrates[] = { 718 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 719 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 720}; 721 722 723void gs_set_termios (struct tty_struct * tty, 724 struct termios * old_termios) 725{ 726 struct gs_port *port; 727 int baudrate, tmp, rv; 728 struct termios *tiosp; 729 730 func_enter(); 731 732 if (!tty) return; 733 734 port = tty->driver_data; 735 736 if (!port) return; 737 if (!port->tty) { 738 /* This seems to happen when this is called after gs_close. */ 739 gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->tty is NULL\n"); 740 port->tty = tty; 741 } 742 743 744 tiosp = tty->termios; 745 746 if (gs_debug & GS_DEBUG_TERMIOS) { 747 gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); 748 } 749 750#if 0 751 /* This is an optimization that is only allowed for dumb cards */ 752 /* Smart cards require knowledge of iflags and oflags too: that 753 might change hardware cooking mode.... */ 754#endif 755 if (old_termios) { 756 if( (tiosp->c_iflag == old_termios->c_iflag) 757 && (tiosp->c_oflag == old_termios->c_oflag) 758 && (tiosp->c_cflag == old_termios->c_cflag) 759 && (tiosp->c_lflag == old_termios->c_lflag) 760 && (tiosp->c_line == old_termios->c_line) 761 && (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) { 762 gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n"); 763 return /* 0 */; 764 } 765 } else 766 gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: " 767 "no optimization\n"); 768 769 if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { 770 if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); 771 if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); 772 if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n"); 773 if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n"); 774 if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n"); 775 if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); 776 } 777 778 baudrate = tiosp->c_cflag & CBAUD; 779 if (baudrate & CBAUDEX) { 780 baudrate &= ~CBAUDEX; 781 if ((baudrate < 1) || (baudrate > 4)) 782 tiosp->c_cflag &= ~CBAUDEX; 783 else 784 baudrate += 15; 785 } 786 787 baudrate = gs_baudrates[baudrate]; 788 if ((tiosp->c_cflag & CBAUD) == B38400) { 789 if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 790 baudrate = 57600; 791 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 792 baudrate = 115200; 793 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 794 baudrate = 230400; 795 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 796 baudrate = 460800; 797 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) 798 baudrate = (port->baud_base / port->custom_divisor); 799 } 800 801 /* I recommend using THIS instead of the mess in termios (and 802 duplicating the above code). Next we should create a clean 803 interface towards this variable. If your card supports arbitrary 804 baud rates, (e.g. CD1400 or 16550 based cards) then everything 805 will be very easy..... */ 806 port->baud = baudrate; 807 808 /* Two timer ticks seems enough to wakeup something like SLIP driver */ 809 /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */ 810 tmp = (baudrate / 10 / HZ) * 2; 811 812 if (tmp < 0) tmp = 0; 813 if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1; 814 815 port->wakeup_chars = tmp; 816 817 /* We should really wait for the characters to be all sent before 818 changing the settings. -- CAL */ 819 rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT); 820 if (rv < 0) return /* rv */; 821 822 rv = port->rd->set_real_termios(port); 823 if (rv < 0) return /* rv */; 824 825 if ((!old_termios || 826 (old_termios->c_cflag & CRTSCTS)) && 827 !( tiosp->c_cflag & CRTSCTS)) { 828 tty->stopped = 0; 829 gs_start(tty); 830 } 831 832#ifdef tytso_patch_94Nov25_1726 833 /* This "makes sense", Why is it commented out? */ 834 835 if (!(old_termios->c_cflag & CLOCAL) && 836 (tty->termios->c_cflag & CLOCAL)) 837 wake_up_interruptible(&port->gs.open_wait); 838#endif 839 840 func_exit(); 841 return /* 0 */; 842} 843 844 845 846/* Must be called with interrupts enabled */ 847int gs_init_port(struct gs_port *port) 848{ 849 unsigned long flags; 850 unsigned long page; 851 852 func_enter (); 853 854 if (!tmp_buf) { 855 page = get_zeroed_page(GFP_KERNEL); 856 spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */ 857 if (tmp_buf) 858 free_page(page); 859 else 860 tmp_buf = (unsigned char *) page; 861 spin_unlock_irqrestore (&port->driver_lock, flags); 862 if (!tmp_buf) { 863 func_exit (); 864 return -ENOMEM; 865 } 866 } 867 868 if (port->flags & ASYNC_INITIALIZED) { 869 func_exit (); 870 return 0; 871 } 872 if (!port->xmit_buf) { 873 /* We may sleep in get_zeroed_page() */ 874 unsigned long tmp; 875 876 tmp = get_zeroed_page(GFP_KERNEL); 877 spin_lock_irqsave (&port->driver_lock, flags); 878 if (port->xmit_buf) 879 free_page (tmp); 880 else 881 port->xmit_buf = (unsigned char *) tmp; 882 spin_unlock_irqrestore(&port->driver_lock, flags); 883 if (!port->xmit_buf) { 884 func_exit (); 885 return -ENOMEM; 886 } 887 } 888 889 spin_lock_irqsave (&port->driver_lock, flags); 890 if (port->tty) 891 clear_bit(TTY_IO_ERROR, &port->tty->flags); 892 init_MUTEX(&port->port_write_sem); 893 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 894 spin_unlock_irqrestore(&port->driver_lock, flags); 895 gs_set_termios(port->tty, NULL); 896 spin_lock_irqsave (&port->driver_lock, flags); 897 port->flags |= ASYNC_INITIALIZED; 898 port->flags &= ~GS_TX_INTEN; 899 900 spin_unlock_irqrestore(&port->driver_lock, flags); 901 func_exit (); 902 return 0; 903} 904 905 906int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) 907{ 908 struct serial_struct sio; 909 910 if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) 911 return(-EFAULT); 912 913 if (!capable(CAP_SYS_ADMIN)) { 914 if ((sio.baud_base != port->baud_base) || 915 (sio.close_delay != port->close_delay) || 916 ((sio.flags & ~ASYNC_USR_MASK) != 917 (port->flags & ~ASYNC_USR_MASK))) 918 return(-EPERM); 919 } 920 921 port->flags = (port->flags & ~ASYNC_USR_MASK) | 922 (sio.flags & ASYNC_USR_MASK); 923 924 port->baud_base = sio.baud_base; 925 port->close_delay = sio.close_delay; 926 port->closing_wait = sio.closing_wait; 927 port->custom_divisor = sio.custom_divisor; 928 929 gs_set_termios (port->tty, NULL); 930 931 return 0; 932} 933 934 935/*****************************************************************************/ 936 937/* 938 * Generate the serial struct info. 939 */ 940 941int gs_getserial(struct gs_port *port, struct serial_struct __user *sp) 942{ 943 struct serial_struct sio; 944 945 memset(&sio, 0, sizeof(struct serial_struct)); 946 sio.flags = port->flags; 947 sio.baud_base = port->baud_base; 948 sio.close_delay = port->close_delay; 949 sio.closing_wait = port->closing_wait; 950 sio.custom_divisor = port->custom_divisor; 951 sio.hub6 = 0; 952 953 /* If you want you can override these. */ 954 sio.type = PORT_UNKNOWN; 955 sio.xmit_fifo_size = -1; 956 sio.line = -1; 957 sio.port = -1; 958 sio.irq = -1; 959 960 if (port->rd->getserial) 961 port->rd->getserial (port, &sio); 962 963 if (copy_to_user(sp, &sio, sizeof(struct serial_struct))) 964 return -EFAULT; 965 return 0; 966 967} 968 969 970void gs_got_break(struct gs_port *port) 971{ 972 func_enter (); 973 974 tty_insert_flip_char(port->tty, 0, TTY_BREAK); 975 tty_schedule_flip(port->tty); 976 if (port->flags & ASYNC_SAK) { 977 do_SAK (port->tty); 978 } 979 980 func_exit (); 981} 982 983 984EXPORT_SYMBOL(gs_put_char); 985EXPORT_SYMBOL(gs_write); 986EXPORT_SYMBOL(gs_write_room); 987EXPORT_SYMBOL(gs_chars_in_buffer); 988EXPORT_SYMBOL(gs_flush_buffer); 989EXPORT_SYMBOL(gs_flush_chars); 990EXPORT_SYMBOL(gs_stop); 991EXPORT_SYMBOL(gs_start); 992EXPORT_SYMBOL(gs_hangup); 993EXPORT_SYMBOL(gs_block_til_ready); 994EXPORT_SYMBOL(gs_close); 995EXPORT_SYMBOL(gs_set_termios); 996EXPORT_SYMBOL(gs_init_port); 997EXPORT_SYMBOL(gs_setserial); 998EXPORT_SYMBOL(gs_getserial); 999EXPORT_SYMBOL(gs_got_break); 1000 1001MODULE_LICENSE("GPL");