]>
git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - drivers/staging/generic_serial/generic_serial.c
4 * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl
6 * written for the SX serial driver.
7 * Contains the code that should be shared over all the serial drivers.
9 * Credit for the idea to do it this way might go to Alan Cox.
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.
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
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>
28 #include <linux/generic_serial.h>
29 #include <linux/interrupt.h>
30 #include <linux/tty_flip.h>
31 #include <linux/delay.h>
32 #include <linux/gfp.h>
33 #include <asm/uaccess.h>
40 #define gs_dprintk(f, str...) if (gs_debug & f) printk (str)
42 #define gs_dprintk(f, str...) /* nothing */
45 #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__)
46 #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__)
48 #define RS_EVENT_WRITE_WAKEUP 1
50 module_param(gs_debug
, int, 0644);
53 int gs_put_char(struct tty_struct
* tty
, unsigned char ch
)
59 port
= tty
->driver_data
;
63 if (! (port
->port
.flags
& ASYNC_INITIALIZED
)) return 0;
65 /* Take a lock on the serial tranmit buffer! */
66 mutex_lock(& port
->port_write_mutex
);
68 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) {
69 /* Sorry, buffer is full, drop character. Update statistics???? -- REW */
70 mutex_unlock(&port
->port_write_mutex
);
74 port
->xmit_buf
[port
->xmit_head
++] = ch
;
75 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
76 port
->xmit_cnt
++; /* Characters in buffer */
78 mutex_unlock(&port
->port_write_mutex
);
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".
91 int gs_write(struct tty_struct
* tty
,
92 const unsigned char *buf
, int count
)
100 port
= tty
->driver_data
;
104 if (! (port
->port
.flags
& ASYNC_INITIALIZED
))
107 /* get exclusive "write" access to this port (problem 3) */
108 /* This is not a spinlock because we can have a disk access (page
109 fault) in copy_from_user */
110 mutex_lock(& port
->port_write_mutex
);
116 /* This is safe because we "OWN" the "head". No one else can
117 change the "head": we own the port_write_mutex. */
118 /* Don't overrun the end of the buffer */
119 t
= SERIAL_XMIT_SIZE
- port
->xmit_head
;
122 /* This is safe because the xmit_cnt can only decrease. This
123 would increase "t", so we might copy too little chars. */
124 /* Don't copy past the "head" of the buffer */
125 t
= SERIAL_XMIT_SIZE
- 1 - port
->xmit_cnt
;
128 /* Can't copy more? break out! */
131 memcpy (port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
133 port
-> xmit_cnt
+= c
;
134 port
-> xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
139 mutex_unlock(& port
->port_write_mutex
);
141 gs_dprintk (GS_DEBUG_WRITE
, "write: interrupts are %s\n",
142 (port
->port
.flags
& GS_TX_INTEN
)?"enabled": "disabled");
144 if (port
->xmit_cnt
&&
147 !(port
->port
.flags
& GS_TX_INTEN
)) {
148 port
->port
.flags
|= GS_TX_INTEN
;
149 port
->rd
->enable_tx_interrupts (port
);
157 int gs_write_room(struct tty_struct
* tty
)
159 struct gs_port
*port
= tty
->driver_data
;
163 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
171 int gs_chars_in_buffer(struct tty_struct
*tty
)
173 struct gs_port
*port
= tty
->driver_data
;
177 return port
->xmit_cnt
;
181 static int gs_real_chars_in_buffer(struct tty_struct
*tty
)
183 struct gs_port
*port
;
186 port
= tty
->driver_data
;
188 if (!port
->rd
) return 0;
189 if (!port
->rd
->chars_in_buffer
) return 0;
192 return port
->xmit_cnt
+ port
->rd
->chars_in_buffer (port
);
196 static int gs_wait_tx_flushed (void * ptr
, unsigned long timeout
)
198 struct gs_port
*port
= ptr
;
199 unsigned long end_jiffies
;
200 int jiffies_to_transmit
, charsleft
= 0, rv
= 0;
205 gs_dprintk (GS_DEBUG_FLUSH
, "port=%p.\n", port
);
207 gs_dprintk (GS_DEBUG_FLUSH
, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n",
208 port
->xmit_cnt
, port
->xmit_buf
, port
->port
.tty
);
211 if (!port
|| port
->xmit_cnt
< 0 || !port
->xmit_buf
) {
212 gs_dprintk (GS_DEBUG_FLUSH
, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
214 return -EINVAL
; /* This is an error which we don't know how to handle. */
217 rcib
= gs_real_chars_in_buffer(port
->port
.tty
);
220 gs_dprintk (GS_DEBUG_FLUSH
, "nothing to wait for.\n");
224 /* stop trying: now + twice the time it would normally take + seconds */
225 if (timeout
== 0) timeout
= MAX_SCHEDULE_TIMEOUT
;
226 end_jiffies
= jiffies
;
227 if (timeout
!= MAX_SCHEDULE_TIMEOUT
)
228 end_jiffies
+= port
->baud
?(2 * rcib
* 10 * HZ
/ port
->baud
):0;
229 end_jiffies
+= timeout
;
231 gs_dprintk (GS_DEBUG_FLUSH
, "now=%lx, end=%lx (%ld).\n",
232 jiffies
, end_jiffies
, end_jiffies
-jiffies
);
234 /* the expression is actually jiffies < end_jiffies, but that won't
235 work around the wraparound. Tricky eh? */
236 while ((charsleft
= gs_real_chars_in_buffer (port
->port
.tty
)) &&
237 time_after (end_jiffies
, jiffies
)) {
239 chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
242 charsleft
+= 16; /* Allow 16 chars more to be transmitted ... */
243 jiffies_to_transmit
= port
->baud
?(1 + charsleft
* 10 * HZ
/ port
->baud
):0;
244 /* ^^^ Round up.... */
245 if (jiffies_to_transmit
<= 0) jiffies_to_transmit
= 1;
247 gs_dprintk (GS_DEBUG_FLUSH
, "Expect to finish in %d jiffies "
248 "(%d chars).\n", jiffies_to_transmit
, charsleft
);
250 msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit
));
251 if (signal_pending (current
)) {
252 gs_dprintk (GS_DEBUG_FLUSH
, "Signal pending. Bombing out: ");
258 gs_dprintk (GS_DEBUG_FLUSH
, "charsleft = %d.\n", charsleft
);
259 set_current_state (TASK_RUNNING
);
267 void gs_flush_buffer(struct tty_struct
*tty
)
269 struct gs_port
*port
;
274 port
= tty
->driver_data
;
278 /* XXX Would the write semaphore do? */
279 spin_lock_irqsave (&port
->driver_lock
, flags
);
280 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
281 spin_unlock_irqrestore (&port
->driver_lock
, flags
);
288 void gs_flush_chars(struct tty_struct
* tty
)
290 struct gs_port
*port
;
294 port
= tty
->driver_data
;
298 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
304 /* Beats me -- REW */
305 port
->port
.flags
|= GS_TX_INTEN
;
306 port
->rd
->enable_tx_interrupts (port
);
311 void gs_stop(struct tty_struct
* tty
)
313 struct gs_port
*port
;
317 port
= tty
->driver_data
;
321 if (port
->xmit_cnt
&&
323 (port
->port
.flags
& GS_TX_INTEN
) ) {
324 port
->port
.flags
&= ~GS_TX_INTEN
;
325 port
->rd
->disable_tx_interrupts (port
);
331 void gs_start(struct tty_struct
* tty
)
333 struct gs_port
*port
;
335 port
= tty
->driver_data
;
339 if (port
->xmit_cnt
&&
341 !(port
->port
.flags
& GS_TX_INTEN
) ) {
342 port
->port
.flags
|= GS_TX_INTEN
;
343 port
->rd
->enable_tx_interrupts (port
);
349 static void gs_shutdown_port (struct gs_port
*port
)
357 if (!(port
->port
.flags
& ASYNC_INITIALIZED
))
360 spin_lock_irqsave(&port
->driver_lock
, flags
);
362 if (port
->xmit_buf
) {
363 free_page((unsigned long) port
->xmit_buf
);
364 port
->xmit_buf
= NULL
;
368 set_bit(TTY_IO_ERROR
, &port
->port
.tty
->flags
);
370 port
->rd
->shutdown_port (port
);
372 port
->port
.flags
&= ~ASYNC_INITIALIZED
;
373 spin_unlock_irqrestore(&port
->driver_lock
, flags
);
379 void gs_hangup(struct tty_struct
*tty
)
381 struct gs_port
*port
;
386 port
= tty
->driver_data
;
387 tty
= port
->port
.tty
;
391 gs_shutdown_port (port
);
392 spin_lock_irqsave(&port
->port
.lock
, flags
);
393 port
->port
.flags
&= ~(ASYNC_NORMAL_ACTIVE
|GS_ACTIVE
);
394 port
->port
.tty
= NULL
;
395 port
->port
.count
= 0;
396 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
398 wake_up_interruptible(&port
->port
.open_wait
);
403 int gs_block_til_ready(void *port_
, struct file
* filp
)
405 struct gs_port
*gp
= port_
;
406 struct tty_port
*port
= &gp
->port
;
407 DECLARE_WAITQUEUE(wait
, current
);
411 struct tty_struct
*tty
;
420 gs_dprintk (GS_DEBUG_BTR
, "Entering gs_block_till_ready.\n");
422 * If the device is in the middle of being closed, then block
423 * until it's done, and then try again.
425 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
426 interruptible_sleep_on(&port
->close_wait
);
427 if (port
->flags
& ASYNC_HUP_NOTIFY
)
433 gs_dprintk (GS_DEBUG_BTR
, "after hung up\n");
436 * If non-blocking mode is set, or the port is not enabled,
437 * then make the check up front and then exit.
439 if ((filp
->f_flags
& O_NONBLOCK
) ||
440 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
441 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
445 gs_dprintk (GS_DEBUG_BTR
, "after nonblock\n");
451 * Block waiting for the carrier detect and the line to become
452 * free (i.e., not in use by the callout). While we are in
453 * this loop, port->count is dropped by one, so that
454 * rs_close() knows when to free things. We restore it upon
455 * exit, either normal or abnormal.
459 add_wait_queue(&port
->open_wait
, &wait
);
461 gs_dprintk (GS_DEBUG_BTR
, "after add waitq.\n");
462 spin_lock_irqsave(&port
->lock
, flags
);
463 if (!tty_hung_up_p(filp
)) {
466 port
->blocked_open
++;
467 spin_unlock_irqrestore(&port
->lock
, flags
);
469 CD
= tty_port_carrier_raised(port
);
470 gs_dprintk (GS_DEBUG_BTR
, "CD is now %d.\n", CD
);
471 set_current_state (TASK_INTERRUPTIBLE
);
472 if (tty_hung_up_p(filp
) ||
473 !(port
->flags
& ASYNC_INITIALIZED
)) {
474 if (port
->flags
& ASYNC_HUP_NOTIFY
)
477 retval
= -ERESTARTSYS
;
480 if (!(port
->flags
& ASYNC_CLOSING
) &&
483 gs_dprintk (GS_DEBUG_BTR
, "signal_pending is now: %d (%lx)\n",
484 (int)signal_pending (current
), *(long*)(¤t
->blocked
));
485 if (signal_pending(current
)) {
486 retval
= -ERESTARTSYS
;
491 gs_dprintk (GS_DEBUG_BTR
, "Got out of the loop. (%d)\n",
493 set_current_state (TASK_RUNNING
);
494 remove_wait_queue(&port
->open_wait
, &wait
);
496 spin_lock_irqsave(&port
->lock
, flags
);
497 if (!tty_hung_up_p(filp
)) {
500 port
->blocked_open
--;
502 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
503 spin_unlock_irqrestore(&port
->lock
, flags
);
509 void gs_close(struct tty_struct
* tty
, struct file
* filp
)
512 struct gs_port
*port
;
516 port
= tty
->driver_data
;
520 if (!port
->port
.tty
) {
521 /* This seems to happen when this is called from vhangup. */
522 gs_dprintk (GS_DEBUG_CLOSE
, "gs: Odd: port->port.tty is NULL\n");
523 port
->port
.tty
= tty
;
526 spin_lock_irqsave(&port
->port
.lock
, flags
);
528 if (tty_hung_up_p(filp
)) {
529 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
530 if (port
->rd
->hungup
)
531 port
->rd
->hungup (port
);
536 if ((tty
->count
== 1) && (port
->port
.count
!= 1)) {
537 printk(KERN_ERR
"gs: gs_close port %p: bad port count;"
538 " tty->count is 1, port count is %d\n", port
, port
->port
.count
);
539 port
->port
.count
= 1;
541 if (--port
->port
.count
< 0) {
542 printk(KERN_ERR
"gs: gs_close port %p: bad port count: %d\n", port
, port
->port
.count
);
543 port
->port
.count
= 0;
546 if (port
->port
.count
) {
547 gs_dprintk(GS_DEBUG_CLOSE
, "gs_close port %p: count: %d\n", port
, port
->port
.count
);
548 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
552 port
->port
.flags
|= ASYNC_CLOSING
;
555 * Now we wait for the transmit buffer to clear; and we notify
556 * the line discipline to only process XON/XOFF characters.
559 /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
560 tty_wait_until_sent(tty, port->closing_wait); */
563 * At this point we stop accepting input. To do this, we
564 * disable the receive line status interrupts, and tell the
565 * interrupt driver to stop checking the data ready bit in the
566 * line status register.
569 spin_lock(&port
->driver_lock
);
570 port
->rd
->disable_rx_interrupts (port
);
571 spin_unlock(&port
->driver_lock
);
572 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
574 /* close has no way of returning "EINTR", so discard return value */
575 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
576 gs_wait_tx_flushed (port
, port
->closing_wait
);
578 port
->port
.flags
&= ~GS_ACTIVE
;
580 gs_flush_buffer(tty
);
582 tty_ldisc_flush(tty
);
585 spin_lock_irqsave(&port
->driver_lock
, flags
);
587 port
->rd
->close (port
);
588 port
->rd
->shutdown_port (port
);
589 spin_unlock_irqrestore(&port
->driver_lock
, flags
);
591 spin_lock_irqsave(&port
->port
.lock
, flags
);
592 port
->port
.tty
= NULL
;
594 if (port
->port
.blocked_open
) {
595 if (port
->close_delay
) {
596 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
597 msleep_interruptible(jiffies_to_msecs(port
->close_delay
));
598 spin_lock_irqsave(&port
->port
.lock
, flags
);
600 wake_up_interruptible(&port
->port
.open_wait
);
602 port
->port
.flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
| ASYNC_INITIALIZED
);
603 spin_unlock_irqrestore(&port
->port
.lock
, flags
);
604 wake_up_interruptible(&port
->port
.close_wait
);
610 void gs_set_termios (struct tty_struct
* tty
,
611 struct ktermios
* old_termios
)
613 struct gs_port
*port
;
614 int baudrate
, tmp
, rv
;
615 struct ktermios
*tiosp
;
619 port
= tty
->driver_data
;
622 if (!port
->port
.tty
) {
623 /* This seems to happen when this is called after gs_close. */
624 gs_dprintk (GS_DEBUG_TERMIOS
, "gs: Odd: port->port.tty is NULL\n");
625 port
->port
.tty
= tty
;
629 tiosp
= tty
->termios
;
631 if (gs_debug
& GS_DEBUG_TERMIOS
) {
632 gs_dprintk (GS_DEBUG_TERMIOS
, "termios structure (%p):\n", tiosp
);
635 if(old_termios
&& (gs_debug
& GS_DEBUG_TERMIOS
)) {
636 if(tiosp
->c_iflag
!= old_termios
->c_iflag
) printk("c_iflag changed\n");
637 if(tiosp
->c_oflag
!= old_termios
->c_oflag
) printk("c_oflag changed\n");
638 if(tiosp
->c_cflag
!= old_termios
->c_cflag
) printk("c_cflag changed\n");
639 if(tiosp
->c_lflag
!= old_termios
->c_lflag
) printk("c_lflag changed\n");
640 if(tiosp
->c_line
!= old_termios
->c_line
) printk("c_line changed\n");
641 if(!memcmp(tiosp
->c_cc
, old_termios
->c_cc
, NCC
)) printk("c_cc changed\n");
644 baudrate
= tty_get_baud_rate(tty
);
646 if ((tiosp
->c_cflag
& CBAUD
) == B38400
) {
647 if ( (port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
649 else if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
651 else if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_SHI
)
653 else if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_WARP
)
655 else if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_CUST
)
656 baudrate
= (port
->baud_base
/ port
->custom_divisor
);
659 /* I recommend using THIS instead of the mess in termios (and
660 duplicating the above code). Next we should create a clean
661 interface towards this variable. If your card supports arbitrary
662 baud rates, (e.g. CD1400 or 16550 based cards) then everything
663 will be very easy..... */
664 port
->baud
= baudrate
;
666 /* Two timer ticks seems enough to wakeup something like SLIP driver */
667 /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */
668 tmp
= (baudrate
/ 10 / HZ
) * 2;
670 if (tmp
< 0) tmp
= 0;
671 if (tmp
>= SERIAL_XMIT_SIZE
) tmp
= SERIAL_XMIT_SIZE
-1;
673 port
->wakeup_chars
= tmp
;
675 /* We should really wait for the characters to be all sent before
676 changing the settings. -- CAL */
677 rv
= gs_wait_tx_flushed (port
, MAX_SCHEDULE_TIMEOUT
);
678 if (rv
< 0) return /* rv */;
680 rv
= port
->rd
->set_real_termios(port
);
681 if (rv
< 0) return /* rv */;
684 (old_termios
->c_cflag
& CRTSCTS
)) &&
685 !( tiosp
->c_cflag
& CRTSCTS
)) {
690 #ifdef tytso_patch_94Nov25_1726
691 /* This "makes sense", Why is it commented out? */
693 if (!(old_termios
->c_cflag
& CLOCAL
) &&
694 (tty
->termios
->c_cflag
& CLOCAL
))
695 wake_up_interruptible(&port
->gs
.open_wait
);
704 /* Must be called with interrupts enabled */
705 int gs_init_port(struct gs_port
*port
)
711 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
715 if (!port
->xmit_buf
) {
716 /* We may sleep in get_zeroed_page() */
719 tmp
= get_zeroed_page(GFP_KERNEL
);
720 spin_lock_irqsave (&port
->driver_lock
, flags
);
724 port
->xmit_buf
= (unsigned char *) tmp
;
725 spin_unlock_irqrestore(&port
->driver_lock
, flags
);
726 if (!port
->xmit_buf
) {
732 spin_lock_irqsave (&port
->driver_lock
, flags
);
734 clear_bit(TTY_IO_ERROR
, &port
->port
.tty
->flags
);
735 mutex_init(&port
->port_write_mutex
);
736 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
737 spin_unlock_irqrestore(&port
->driver_lock
, flags
);
738 gs_set_termios(port
->port
.tty
, NULL
);
739 spin_lock_irqsave (&port
->driver_lock
, flags
);
740 port
->port
.flags
|= ASYNC_INITIALIZED
;
741 port
->port
.flags
&= ~GS_TX_INTEN
;
743 spin_unlock_irqrestore(&port
->driver_lock
, flags
);
749 int gs_setserial(struct gs_port
*port
, struct serial_struct __user
*sp
)
751 struct serial_struct sio
;
753 if (copy_from_user(&sio
, sp
, sizeof(struct serial_struct
)))
756 if (!capable(CAP_SYS_ADMIN
)) {
757 if ((sio
.baud_base
!= port
->baud_base
) ||
758 (sio
.close_delay
!= port
->close_delay
) ||
759 ((sio
.flags
& ~ASYNC_USR_MASK
) !=
760 (port
->port
.flags
& ~ASYNC_USR_MASK
)))
764 port
->port
.flags
= (port
->port
.flags
& ~ASYNC_USR_MASK
) |
765 (sio
.flags
& ASYNC_USR_MASK
);
767 port
->baud_base
= sio
.baud_base
;
768 port
->close_delay
= sio
.close_delay
;
769 port
->closing_wait
= sio
.closing_wait
;
770 port
->custom_divisor
= sio
.custom_divisor
;
772 gs_set_termios (port
->port
.tty
, NULL
);
778 /*****************************************************************************/
781 * Generate the serial struct info.
784 int gs_getserial(struct gs_port
*port
, struct serial_struct __user
*sp
)
786 struct serial_struct sio
;
788 memset(&sio
, 0, sizeof(struct serial_struct
));
789 sio
.flags
= port
->port
.flags
;
790 sio
.baud_base
= port
->baud_base
;
791 sio
.close_delay
= port
->close_delay
;
792 sio
.closing_wait
= port
->closing_wait
;
793 sio
.custom_divisor
= port
->custom_divisor
;
796 /* If you want you can override these. */
797 sio
.type
= PORT_UNKNOWN
;
798 sio
.xmit_fifo_size
= -1;
803 if (port
->rd
->getserial
)
804 port
->rd
->getserial (port
, &sio
);
806 if (copy_to_user(sp
, &sio
, sizeof(struct serial_struct
)))
813 void gs_got_break(struct gs_port
*port
)
817 tty_insert_flip_char(port
->port
.tty
, 0, TTY_BREAK
);
818 tty_schedule_flip(port
->port
.tty
);
819 if (port
->port
.flags
& ASYNC_SAK
) {
820 do_SAK (port
->port
.tty
);
827 EXPORT_SYMBOL(gs_put_char
);
828 EXPORT_SYMBOL(gs_write
);
829 EXPORT_SYMBOL(gs_write_room
);
830 EXPORT_SYMBOL(gs_chars_in_buffer
);
831 EXPORT_SYMBOL(gs_flush_buffer
);
832 EXPORT_SYMBOL(gs_flush_chars
);
833 EXPORT_SYMBOL(gs_stop
);
834 EXPORT_SYMBOL(gs_start
);
835 EXPORT_SYMBOL(gs_hangup
);
836 EXPORT_SYMBOL(gs_block_til_ready
);
837 EXPORT_SYMBOL(gs_close
);
838 EXPORT_SYMBOL(gs_set_termios
);
839 EXPORT_SYMBOL(gs_init_port
);
840 EXPORT_SYMBOL(gs_setserial
);
841 EXPORT_SYMBOL(gs_getserial
);
842 EXPORT_SYMBOL(gs_got_break
);
844 MODULE_LICENSE("GPL");