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