patch-2.2.17 linux/drivers/char/generic_serial.c
Next file: linux/drivers/char/i2c.c
Previous file: linux/drivers/char/epca.c
Back to the patch index
Back to the overall index
- Lines: 369
- Date:
Mon Sep 4 18:39:17 2000
- Orig file:
v2.2.16/drivers/char/generic_serial.c
- Orig date:
Mon Sep 4 18:37:32 2000
diff -u --recursive --new-file v2.2.16/drivers/char/generic_serial.c linux/drivers/char/generic_serial.c
@@ -12,12 +12,18 @@
* Version 0.1 -- December, 1998. Initial version.
* Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc.
* Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus.
- */
+ *
+ * BitWizard is actively maintaining this file. We sometimes find
+ * that someone submitted changes to this file. We really appreciate
+ * your help, but please submit changes through us. We're doing our
+ * best to be responsive. -- REW
+ * */
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/mm.h>
#include <asm/semaphore.h>
+#include <asm/uaccess.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/compatmac.h>
@@ -40,8 +46,6 @@
#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit " __FUNCTION__ "\n")
-
-
#if NEW_WRITE_LOCKING
#define DECL /* Nothing */
#define LOCKIT down (& port->port_write_sem);
@@ -52,6 +56,9 @@
#define RELEASEIT restore_flags (flags)
#endif
+#ifdef MODULE
+MODULE_PARM(gs_debug, "i");
+#endif
#ifdef DEBUG
static void my_hd (unsigned char *addr, int len)
@@ -77,10 +84,18 @@
void gs_put_char(struct tty_struct * tty, unsigned char ch)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
DECL
- /* func_enter (); */
+ func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
+ if (! (port->flags & ASYNC_INITIALIZED)) return;
/* Take a lock on the serial tranmit buffer! */
LOCKIT;
@@ -96,7 +111,7 @@
port->xmit_cnt++; /* Characters in buffer */
RELEASEIT;
- /* func_exit ();*/
+ func_exit ();
}
@@ -112,11 +127,17 @@
int gs_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
int c, total = 0;
int t;
- /* func_enter (); */
+ func_enter ();
+
+ if (!tty) return 0;
+
+ port = tty->driver;
+
+ if (!port) return 0;
if (! (port->flags & ASYNC_INITIALIZED))
return 0;
@@ -167,7 +188,7 @@
port->flags |= GS_TX_INTEN;
port->rd->enable_tx_interrupts (port);
}
- /* func_exit (); */
+ func_exit ();
return total;
}
#else
@@ -210,12 +231,9 @@
if (!port || !port->xmit_buf || !tmp_buf)
return -EIO;
- /* printk ("from_user = %d.\n", from_user); */
save_flags(flags);
if (from_user) {
- /* printk ("Going into the semaphore\n"); */
down(&tmp_buf_sem);
- /* printk ("got out of the semaphore\n"); */
while (1) {
c = count;
@@ -309,11 +327,11 @@
struct gs_port *port = tty->driver_data;
int ret;
- /* func_enter (); */
+ func_enter ();
ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
if (ret < 0)
ret = 0;
- /* func_exit (); */
+ func_exit ();
return ret;
}
@@ -330,7 +348,7 @@
int gs_real_chars_in_buffer(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
if (!tty) return 0;
@@ -361,22 +379,17 @@
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();
+ func_exit();
return -EINVAL; /* This is an error which we don't know how to handle. */
}
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
rcib = gs_real_chars_in_buffer(port->tty);
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n");
-
if(rcib <= 0) {
gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
func_exit();
return rv;
}
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
-
/* stop trying: now + twice the time it would normally take + seconds */
end_jiffies = jiffies;
if (timeout != MAX_SCHEDULE_TIMEOUT)
@@ -424,17 +437,23 @@
void gs_flush_buffer(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
unsigned long flags;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
/* XXX Would the write semaphore do? */
save_flags(flags); cli();
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
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);
@@ -444,9 +463,16 @@
void gs_flush_chars(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
!port->xmit_buf) {
func_exit ();
@@ -462,9 +488,16 @@
void gs_stop(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
if (port->xmit_cnt &&
port->xmit_buf &&
(port->flags & GS_TX_INTEN) ) {
@@ -477,7 +510,13 @@
void gs_start(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
if (port->xmit_cnt &&
port->xmit_buf &&
@@ -492,7 +531,11 @@
void gs_shutdown_port (struct gs_port *port)
{
long flags;
+
func_enter();
+
+ if (!port) return;
+
if (!(port->flags & ASYNC_INITIALIZED))
return;
@@ -517,10 +560,13 @@
void gs_hangup(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+ if (!tty) return;
+
+ port = tty->driver_data;
tty = port->tty;
if (!tty) return;
@@ -541,15 +587,19 @@
struct gs_port *port = private_;
struct tty_struct *tty;
+ func_enter ();
+
+ if (!port) return;
+
tty = port->tty;
- if(!tty) return;
+
+ if (!tty) return;
if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
wake_up_interruptible(&tty->write_wait);
- wake_up_interruptible(&tty->poll_wait);
}
func_exit ();
}
@@ -565,8 +615,13 @@
struct tty_struct *tty;
func_enter ();
+
+ if (!port) return 0;
+
tty = port->tty;
+ if (!tty) return 0;
+
gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n");
/*
* If the device is in the middle of being closed, then block
@@ -625,8 +680,6 @@
do_clocal = 1;
}
- gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n");
-
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
@@ -635,10 +688,10 @@
* exit, either normal or abnormal.
*/
retval = 0;
+
add_wait_queue(&port->open_wait, &wait);
gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
-
cli();
if (!tty_hung_up_p(filp))
port->count--;
@@ -690,15 +743,12 @@
struct gs_port *port;
func_enter ();
- port = (struct gs_port *) tty->driver_data;
- gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n",
- tty, port, port->tty);
+ if (!tty) return;
- if(! port) {
- func_exit();
- return;
- }
+ port = (struct gs_port *) tty->driver_data;
+
+ if (!port) return;
if (!port->tty) {
/* This seems to happen when this is called from vhangup. */
@@ -706,7 +756,6 @@
port->tty = tty;
}
-
save_flags(flags); cli();
if (tty_hung_up_p(filp)) {
@@ -800,14 +849,19 @@
void gs_set_termios (struct tty_struct * tty,
struct termios * old_termios)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
int baudrate, tmp, rv;
struct termios *tiosp;
func_enter();
- tiosp = tty->termios;
+ if (!tty) return;
+
+ port = tty->driver_data;
+ if (!port) return;
+
+ tiosp = tty->termios;
if (gs_debug & GS_DEBUG_TERMIOS) {
gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)