Showing error 1093

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: drivers/char/generic_serial.c
Line in file: 593
Project: Linux Kernel
Project version: 2.6.28
Tools: Undetermined 1
Stanse (1.2)
Entered: 2012-03-04 17:07:06 UTC


Source:

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