patch-1.3.91 linux/drivers/char/serial.c
Next file: linux/drivers/char/stallion.c
Previous file: linux/drivers/char/pcxx.c
Back to the patch index
Back to the overall index
- Lines: 180
- Date:
Wed Apr 17 09:01:19 1996
- Orig file:
v1.3.90/linux/drivers/char/serial.c
- Orig date:
Mon Apr 8 19:01:43 1996
diff -u --recursive --new-file v1.3.90/linux/drivers/char/serial.c linux/drivers/char/serial.c
@@ -11,7 +11,9 @@
* set_serial_info fixed to set the flags, custom divisor, and uart
* type fields. Fix suggested by Michael K. Johnson 12/12/92.
*
- * TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
+ * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
+ *
+ * 03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
*
* This module exports the following rs232 io functions:
*
@@ -19,6 +21,7 @@
* int rs_open(struct tty_struct * tty, struct file * filp)
*/
+#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -41,6 +44,9 @@
#include <asm/segment.h>
#include <asm/bitops.h>
+static char *serial_name = "Serial driver";
+static char *serial_version = "4.12";
+
DECLARE_TASK_QUEUE(tq_serial);
struct tty_driver serial_driver, callout_driver;
@@ -80,6 +86,13 @@
#define _INLINE_ inline
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
/*
* IRQ_timeout - How long the timeout should be for each IRQ
* should be after the IRQ has been active.
@@ -1076,6 +1089,12 @@
#endif
save_flags(flags); cli(); /* Disable interrupts */
+
+ /*
+ * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+ * here so the queue might never be waken up
+ */
+ wake_up_interruptible(&info->delta_msr_wait);
/*
* First unlink the serial port from the IRQ chain...
@@ -2002,6 +2021,9 @@
cli();
cnow = info->icount; /* atomic copy */
sti();
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
@@ -2089,6 +2111,8 @@
save_flags(flags); cli();
if (tty_hung_up_p(filp)) {
+ DBG_CNT("before DEC-hung");
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
return;
}
@@ -2114,6 +2138,8 @@
info->count = 0;
}
if (info->count) {
+ DBG_CNT("before DEC-2");
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
return;
}
@@ -2165,14 +2191,6 @@
tty->closing = 0;
info->event = 0;
info->tty = 0;
- if (tty->ldisc.num != ldiscs[N_TTY].num) {
- if (tty->ldisc.close)
- (tty->ldisc.close)(tty);
- tty->ldisc = ldiscs[N_TTY];
- tty->termios->c_line = N_TTY;
- if (tty->ldisc.open)
- (tty->ldisc.open)(tty);
- }
if (info->blocked_open) {
if (info->close_delay) {
current->state = TASK_INTERRUPTIBLE;
@@ -2184,6 +2202,7 @@
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
}
@@ -2387,6 +2406,7 @@
if (retval)
return retval;
+ MOD_INC_USE_COUNT;
retval = block_til_ready(tty, filp, info);
if (retval) {
#ifdef SERIAL_DEBUG_OPEN
@@ -2428,7 +2448,7 @@
*/
static void show_serial_version(void)
{
- printk("Serial driver version 4.11a with");
+ printk("%s version %s with", serial_name, serial_version);
#ifdef CONFIG_HUB6
printk(" HUB-6");
#define SERIAL_OPT
@@ -2663,6 +2683,16 @@
restore_flags(flags);
}
+int register_serial(struct serial_struct *req);
+void unregister_serial(int line);
+
+static struct symbol_table serial_syms = {
+#include <linux/symtab_begin.h>
+ X(register_serial),
+ X(unregister_serial),
+#include <linux/symtab_end.h>
+};
+
/*
* The serial driver boot-time initialization code!
*/
@@ -2791,6 +2821,7 @@
break;
}
}
+ register_symtab(&serial_syms);
return 0;
}
@@ -2867,3 +2898,30 @@
printk("tty%02d unloaded\n", info->line);
restore_flags(flags);
}
+
+#ifdef MODULE
+int init_module(void)
+{
+ return rs_init();
+}
+
+void cleanup_module(void)
+{
+ unsigned long flags;
+ int e1, e2;
+
+ /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+ save_flags(flags);
+ cli();
+ timer_active &= ~(1 << RS_TIMER);
+ timer_table[RS_TIMER].fn = NULL;
+ timer_table[RS_TIMER].expires = 0;
+ if ((e1 = tty_unregister_driver(&serial_driver)))
+ printk("SERIAL: failed to unregister serial driver (%d)\n",
+ e1);
+ if ((e2 = tty_unregister_driver(&callout_driver)))
+ printk("SERIAL: failed to unregister callout driver (%d)\n",
+ e2);
+ restore_flags(flags);
+}
+#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this