patch-2.2.16 linux/drivers/char/n_hdlc.c
Next file: linux/drivers/char/n_tty.c
Previous file: linux/drivers/char/misc.c
Back to the patch index
Back to the overall index
- Lines: 194
- Date:
Wed Jun 7 14:26:42 2000
- Orig file:
v2.2.15/linux/drivers/char/n_hdlc.c
- Orig date:
Wed May 3 17:16:38 2000
diff -urN v2.2.15/linux/drivers/char/n_hdlc.c linux/drivers/char/n_hdlc.c
@@ -9,7 +9,7 @@
* Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
*
* Original release 01/11/99
- * ==FILEDATE 19990901==
+ * ==FILEDATE 20000515==
*
* This code is released under the GNU General Public License (GPL)
*
@@ -78,7 +78,7 @@
*/
#define HDLC_MAGIC 0x239e
-#define HDLC_VERSION "1.11"
+#define HDLC_VERSION "1.15"
#include <linux/version.h>
#include <linux/config.h>
@@ -105,7 +105,6 @@
#include <linux/malloc.h>
#include <linux/tty.h>
#include <linux/errno.h>
-#include <linux/sched.h> /* to get the struct task_struct */
#include <linux/string.h> /* used in new tty drivers */
#include <linux/signal.h> /* used in new tty drivers */
#include <asm/system.h>
@@ -172,6 +171,7 @@
#if LINUX_VERSION_CODE < VERSION(2,1,0)
#define __init
typedef int spinlock_t;
+#define spin_lock_init(a)
#define spin_lock_irqsave(a,b) {save_flags((b));cli();}
#define spin_unlock_irqrestore(a,b) {restore_flags((b));}
#define spin_lock(a)
@@ -465,9 +465,10 @@
register int actual;
unsigned long flags;
N_HDLC_BUF *tbuf;
-
+
if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
+ check_again:
save_flags(flags);
cli ();
@@ -477,6 +478,7 @@
return;
}
n_hdlc->tbusy = 1;
+ n_hdlc->woke_up = 0;
restore_flags(flags);
/* get current transmit buffer or get new transmit */
@@ -492,7 +494,6 @@
__FILE__,__LINE__,tbuf,tbuf->count);
/* Send the next block of data to device */
- n_hdlc->woke_up = 0;
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
actual = tty->driver.write(tty, 0, tbuf->buf, tbuf->count);
@@ -514,6 +515,7 @@
/* wait up sleeping writers */
wake_up_interruptible(&n_hdlc->write_wait);
+ wake_up_interruptible(&n_hdlc->poll_wait);
/* get next pending transmit buffer */
tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
@@ -523,11 +525,6 @@
__FILE__,__LINE__,tbuf);
/* buffer not accepted by driver */
-
- /* check if wake up code called since last write call */
- if (n_hdlc->woke_up)
- continue;
-
/* set this buffer as pending buffer */
n_hdlc->tbuf = tbuf;
break;
@@ -543,6 +540,9 @@
n_hdlc->tbusy = 0;
restore_flags(flags);
+ if (n_hdlc->woke_up)
+ goto check_again;
+
if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
@@ -570,11 +570,8 @@
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
return;
}
-
- if (!n_hdlc->tbuf)
- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
- else
- n_hdlc_send_frames (n_hdlc, tty);
+
+ n_hdlc_send_frames (n_hdlc, tty);
} /* end of n_hdlc_tty_wakeup() */
@@ -663,8 +660,11 @@
wake_up_interruptible (&n_hdlc->read_wait);
wake_up_interruptible (&n_hdlc->poll_wait);
if (n_hdlc->tty->fasync != NULL)
+#if LINUX_VERSION_CODE < VERSION(2,3,0)
kill_fasync (n_hdlc->tty->fasync, SIGIO);
-
+#else
+ kill_fasync (n_hdlc->tty->fasync, SIGIO, POLL_IN);
+#endif
} /* end of n_hdlc_tty_receive() */
/* n_hdlc_tty_read()
@@ -788,34 +788,31 @@
count = maxframe;
}
+ add_wait_queue(&n_hdlc->write_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
/* Allocate transmit buffer */
- tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
- if (!tbuf) {
- /* sleep until transmit buffer available */
- add_wait_queue(&n_hdlc->write_wait, &wait);
- while (!tbuf) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
-
- n_hdlc = tty2n_hdlc (tty);
- if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
- tty != n_hdlc->tty) {
- printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
- error = -EIO;
- break;
- }
+ /* sleep until transmit buffer available */
+ while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
+ schedule();
- if (signal_pending(current)) {
- error = -EINTR;
- break;
- }
+ n_hdlc = tty2n_hdlc (tty);
+ if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
+ tty != n_hdlc->tty) {
+ printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
+ error = -EIO;
+ break;
+ }
- tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
+ if (signal_pending(current)) {
+ error = -EINTR;
+ break;
}
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&n_hdlc->write_wait, &wait);
}
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&n_hdlc->write_wait, &wait);
+
if (!error) {
/* Retrieve the user's buffer */
COPY_FROM_USER (error, tbuf->buf, data, count);
@@ -991,7 +988,11 @@
if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
/* queue current process into any wait queue that */
/* may awaken in the future (read and write) */
+#if LINUX_VERSION_CODE < VERSION(2,1,89)
+ poll_wait(&n_hdlc->poll_wait, wait);
+#else
poll_wait(filp, &n_hdlc->poll_wait, wait);
+#endif
/* set bits for operations that wont block */
if(n_hdlc->rx_buf_list.head)
mask |= POLLIN | POLLRDNORM; /* readable */
@@ -1071,7 +1072,7 @@
void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list)
{
memset(list,0,sizeof(N_HDLC_BUF_LIST));
-
+ spin_lock_init(&list->spinlock);
} /* end of n_hdlc_buf_list_init() */
/* n_hdlc_buf_put()
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)