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