patch-2.2.15 linux/drivers/char/generic_serial.c
Next file: linux/drivers/char/generic_serial.h
Previous file: linux/drivers/char/esp.c
Back to the patch index
Back to the overall index
- Lines: 339
- Date:
Fri Apr 21 12:46:02 2000
- Orig file:
v2.2.14/drivers/char/generic_serial.c
- Orig date:
Sat Aug 28 20:00:55 1999
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/char/generic_serial.c linux/drivers/char/generic_serial.c
@@ -19,93 +19,11 @@
#include <linux/mm.h>
#include <asm/semaphore.h>
#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/compatmac.h>
+#include <linux/generic_serial.h>
-
-#if LINUX_VERSION_CODE < 0x020100 /* Less than 2.1.0 */
-#define TWO_ZERO
-#else
-#if LINUX_VERSION_CODE < 0x020200 /* less than 2.2.x */
-#warning "Please use a 2.2.x kernel. "
-#else
-#if LINUX_VERSION_CODE < 0x020300 /* less than 2.2.x */
-#define TWO_TWO
-#else
-#define TWO_THREE
-#endif
-#endif
-#endif
-
-#ifdef TWO_ZERO
-
-/* Here is the section that makes the 2.2 compatible driver source
- work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2,
- and provide for compatibility stuff here if possible. */
-
-/* Some 200 days (on intel) */
-#define MAX_SCHEDULE_TIMEOUT ((long)(~0UL>>1))
-
-
-#ifndef MODULE
-
-#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
-
-static inline int copy_from_user(void *to,const void *from, int c)
-{
- memcpy_fromfs(to, from, c);
- return 0;
-}
-
-
-#define capable(x) suser()
-
-#define queue_task queue_task_irq_off
-#define tty_flip_buffer_push(tty) queue_task(&tty->flip.tqueue, &tq_timer)
-#define signal_pending(current) (current->signal & ~current->blocked)
-#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0)
-#define time_after(t1,t2) (((long)t1-t2) > 0)
-
-#define test_and_set_bit(nr, addr) set_bit(nr, addr)
-#define test_and_clear_bit(nr, addr) clear_bit(nr, addr)
-
-/* Not yet implemented on 2.0 */
-#define ASYNC_SPD_SHI -1
-#define ASYNC_SPD_WARP -1
-
-
-
-/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it
- to the "name" field that does exist. As long as the assignments are
- done in the right order, there is nothing to worry about. */
-#define driver_name name
-
-
-/* Should be in a header somewhere. */
-#define TTY_HW_COOK_OUT 14 /* Flag to tell ntty what we can handle */
-#define TTY_HW_COOK_IN 15 /* in hardware - output and input */
-#endif
-
-#endif
-
-#ifndef TWO_ZERO
-/* This include is new with 2.2 (and required!) */
-#include <asm/uaccess.h>
-#endif
-
-#ifndef TWO_THREE
-/* These are new in 2.3. The source now uses 2.3 syntax, and here is
- the compatibility define... */
-#define wait_queue_head_t struct wait_queue *
-#define DECLARE_MUTEX(name) struct semaphore name = MUTEX
-#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL }
-
-#endif
-
-#include "generic_serial.h"
-
-
-#ifndef MODULE
-extern void my_hd (unsigned char *ptr, int n);
-#endif
+#define DEBUG
static char * tmp_buf;
static DECLARE_MUTEX(tmp_buf_sem);
@@ -119,8 +37,8 @@
#define gs_dprintk(f, str...) /* nothing */
#endif
-#define func_enter() gs_dprintk (SX_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
-#define func_exit() gs_dprintk (SX_DEBUG_FLOW, "gs: exit " __FUNCTION__ "\n")
+#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
+#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit " __FUNCTION__ "\n")
@@ -135,6 +53,27 @@
#endif
+#ifdef DEBUG
+static void my_hd (unsigned char *addr, int len)
+{
+ int i, j, ch;
+
+ for (i=0;i<len;i+=16) {
+ printk ("%08x ", (int) addr+i);
+ for (j=0;j<16;j++) {
+ printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+ }
+ for (j=0;j<16;j++) {
+ ch = addr[j+i];
+ printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+ }
+ printk ("\n");
+ }
+}
+#else
+#define my_hd(addr,len)
+#endif
+
void gs_put_char(struct tty_struct * tty, unsigned char ch)
{
@@ -397,16 +336,19 @@
if (!tty) return 0;
port = tty->driver_data;
+ if (!port->rd) return 0;
+ if (!port->rd->chars_in_buffer) return 0;
+
func_exit ();
return port->xmit_cnt + port->rd->chars_in_buffer (port);
}
-static void gs_wait_tx_flushed (void * ptr, int timeout)
+static int gs_wait_tx_flushed (void * ptr, int timeout)
{
struct gs_port *port = ptr;
long end_jiffies;
- int jiffies_to_transmit, charsleft;
+ int jiffies_to_transmit, charsleft = 0, rv = 0;
int to, rcib;
func_enter();
@@ -420,7 +362,7 @@
if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
func_exit();
- return; /* This is an error which we don't know how to handle. */
+ return -EINVAL; /* This is an error which we don't know how to handle. */
}
gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
@@ -430,8 +372,8 @@
if(rcib <= 0) {
gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
- func_exit();
- return;
+ func_exit();
+ return rv;
}
gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
@@ -464,14 +406,18 @@
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(jiffies_to_transmit);
- if (signal_pending (current))
+ if (signal_pending (current)) {
+ gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: ");
+ rv = -EINTR;
break;
+ }
}
gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft);
current->state = TASK_RUNNING;
func_exit();
+ return rv;
}
@@ -488,6 +434,7 @@
restore_flags(flags);
wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible(&tty->poll_wait);
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
@@ -545,7 +492,7 @@
void gs_shutdown_port (struct gs_port *port)
{
long flags;
-
+ func_enter();
if (!(port->flags & ASYNC_INITIALIZED))
return;
@@ -564,6 +511,7 @@
port->flags &= ~ASYNC_INITIALIZED;
restore_flags (flags);
+ func_exit();
}
@@ -601,6 +549,7 @@
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible(&tty->poll_wait);
}
func_exit ();
}
@@ -750,8 +699,10 @@
func_exit();
return;
}
+
if (!port->tty) {
- printk (KERN_WARNING "gs: Odd: port->tty is NULL\n");
+ /* This seems to happen when this is called from vhangup. */
+ gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n");
port->tty = tty;
}
@@ -775,6 +726,7 @@
port->count = 0;
}
if (port->count) {
+ gs_dprintk(GS_DEBUG_CLOSE, "gs_close: count: %d\n", port->count);
restore_flags(flags);
func_exit ();
return;
@@ -806,6 +758,7 @@
port->rd->disable_rx_interrupts (port);
+ /* close has no way of returning "EINTR", so discard return value */
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
gs_wait_tx_flushed (port, port->closing_wait);
@@ -816,8 +769,12 @@
if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
tty->closing = 0;
+
port->event = 0;
+ port->rd->close (port);
+ port->rd->shutdown_port (port);
port->tty = 0;
+
if (port->blocked_open) {
if (port->close_delay) {
current->state = TASK_INTERRUPTIBLE;
@@ -829,8 +786,6 @@
ASYNC_CLOSING | ASYNC_INITIALIZED);
wake_up_interruptible(&port->close_wait);
- port->rd->close (port);
- port->rd->shutdown_port (port);
restore_flags(flags);
func_exit ();
}
@@ -846,7 +801,7 @@
struct termios * old_termios)
{
struct gs_port *port = tty->driver_data;
- int baudrate, tmp;
+ int baudrate, tmp, rv;
struct termios *tiosp;
func_enter();
@@ -872,7 +827,7 @@
&& (tiosp->c_line == old_termios->c_line)
&& (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) {
gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n");
- return;
+ return /* 0 */;
}
} else
gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: "
@@ -928,9 +883,11 @@
/* We should really wait for the characters to be all sent before
changing the settings. -- CAL */
- gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT);
+ rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT);
+ if (rv < 0) return /* rv */;
- port->rd->set_real_termios(port);
+ rv = port->rd->set_real_termios(port);
+ if (rv < 0) return /* rv */;
if ((!old_termios ||
(old_termios->c_cflag & CRTSCTS)) &&
@@ -948,7 +905,7 @@
#endif
func_exit();
- return;
+ return /* 0 */;
}
@@ -1072,3 +1029,15 @@
copy_to_user(sp, &sio, sizeof(struct serial_struct));
}
+
+#ifdef MODULE
+int init_module (void)
+{
+ return 0;
+}
+
+int cleanup_module (void)
+{
+ return 0;
+}
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)