summaryrefslogtreecommitdiff
path: root/components/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'components/drivers/tty')
-rw-r--r--components/drivers/tty/console.c17
-rw-r--r--components/drivers/tty/include/tty.h1
-rw-r--r--components/drivers/tty/n_tty.c42
-rw-r--r--components/drivers/tty/pty.c7
-rw-r--r--components/drivers/tty/tty.c17
-rw-r--r--components/drivers/tty/tty_ioctl.c10
-rw-r--r--components/drivers/tty/tty_ldisc.c23
7 files changed, 56 insertions, 61 deletions
diff --git a/components/drivers/tty/console.c b/components/drivers/tty/console.c
index ffc9ab71ec..a9c9b88731 100644
--- a/components/drivers/tty/console.c
+++ b/components/drivers/tty/console.c
@@ -149,14 +149,7 @@ static rt_err_t iodev_open(struct tty_struct *console)
struct rt_device *console_get_iodev(void)
{
- rt_base_t level = 0;
- struct rt_device *iodev = RT_NULL;
-
- level = rt_hw_interrupt_disable();
- iodev = console_dev.io_dev;
- rt_hw_interrupt_enable(level);
-
- return iodev;
+ return console_dev.io_dev;
}
struct rt_device *console_set_iodev(struct rt_device *iodev)
@@ -169,7 +162,7 @@ struct rt_device *console_set_iodev(struct rt_device *iodev)
console = &console_dev;
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&console->spinlock);
RT_ASSERT(console->init_flag >= TTY_INIT_FLAG_REGED);
@@ -195,7 +188,7 @@ struct rt_device *console_set_iodev(struct rt_device *iodev)
}
exit:
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&console->spinlock, level);
return io_before;
}
@@ -213,7 +206,7 @@ static rt_err_t rt_console_init(struct rt_device *dev)
console = (struct tty_struct *)dev;
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&console->spinlock);
RT_ASSERT(console->init_flag == TTY_INIT_FLAG_REGED);
@@ -225,7 +218,7 @@ static rt_err_t rt_console_init(struct rt_device *dev)
console->init_flag = TTY_INIT_FLAG_INITED;
exit:
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&console->spinlock, level);
return result;
}
diff --git a/components/drivers/tty/include/tty.h b/components/drivers/tty/include/tty.h
index 1c0fa09ca3..79e30b6f51 100644
--- a/components/drivers/tty/include/tty.h
+++ b/components/drivers/tty/include/tty.h
@@ -166,6 +166,7 @@ struct tty_struct
#define RT_TTY_BUF 1024
rt_list_t tty_drivers;
+ struct rt_spinlock spinlock;
};
enum
diff --git a/components/drivers/tty/n_tty.c b/components/drivers/tty/n_tty.c
index 067d587746..bf1156ba38 100644
--- a/components/drivers/tty/n_tty.c
+++ b/components/drivers/tty/n_tty.c
@@ -50,6 +50,8 @@
#define ECHO_BLOCK 256
#define ECHO_DISCARD_WATERMARK RT_TTY_BUF - (ECHO_BLOCK + 32)
+static struct rt_spinlock _spinlock = RT_SPINLOCK_INIT;
+
struct n_tty_data
{
/* producer-published */
@@ -87,27 +89,29 @@ struct n_tty_data
rt_inline int set_bit(int nr,int *addr)
{
- int mask, retval, level;
+ int mask, retval;
+ rt_base_t level;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&_spinlock);
retval = (mask & *addr) != 0;
*addr |= mask;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
return retval;
}
rt_inline int clear_bit(int nr, int *addr)
{
- int mask, retval, level;
+ int mask, retval;
+ rt_base_t level;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&_spinlock);
retval = (mask & *addr) != 0;
*addr &= ~mask;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
return retval;
}
@@ -122,15 +126,16 @@ rt_inline int test_bit(int nr, int *addr)
rt_inline int test_and_clear_bit(int nr, volatile void *addr)
{
- int mask, retval, level;
+ int mask, retval;
+ rt_base_t level;
volatile unsigned int *a = addr;
a += nr >> 5;
mask = 1 << (nr & 0x1f);
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&_spinlock);
retval = (mask & *a) != 0;
*a &= ~mask;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
return retval;
}
@@ -1358,7 +1363,7 @@ static int copy_from_read_buf(struct tty_struct *tty,char *b,size_t nr)
if (n)
{
const char *from = read_buf_addr(ldata, tail);
- rt_memcpy(b, from, n);
+ memcpy(b, from, n);
is_eof = n == 1 && *from == EOF_CHAR(tty);
ldata->read_tail += n;
/* Turn single EOF into zero-length read */
@@ -1445,12 +1450,12 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, char *b, size_t nr)
size_t temp_n = n;
if (n > buf_size)
{
- rt_memcpy(b, from, buf_size);
+ memcpy(b, from, buf_size);
b += buf_size;
temp_n -= buf_size;
from = ldata->read_buf;
}
- rt_memcpy(b, from, temp_n);
+ memcpy(b, from, temp_n);
if (found)
{
@@ -2021,7 +2026,7 @@ static struct rt_wqueue *_wait_queue_current_get(struct tty_struct *tty)
static int n_tty_read(struct dfs_file *fd, void *buf, size_t count)
{
- int level = 0;
+ rt_base_t level = 0;
char *b = (char *)buf;
struct tty_struct *tty = RT_NULL;
struct rt_wqueue *wq = RT_NULL;
@@ -2029,13 +2034,11 @@ static int n_tty_read(struct dfs_file *fd, void *buf, size_t count)
int retval = 0;
int c = 0;
- level = rt_hw_interrupt_disable();
tty = (struct tty_struct *)fd->vnode->data;
RT_ASSERT(tty != RT_NULL);
c = job_control(tty);
if (c < 0)
{
- rt_hw_interrupt_enable(level);
return c;
}
@@ -2054,12 +2057,14 @@ static int n_tty_read(struct dfs_file *fd, void *buf, size_t count)
}
wait_ret = rt_wqueue_wait_interruptible(wq, 0, RT_WAITING_FOREVER);
+
if (wait_ret != 0)
{
break;
}
}
+ level = rt_spin_lock_irqsave(&tty->spinlock);
if (ldata->icanon && !L_EXTPROC(tty))
{
retval = canon_copy_from_read_buf(tty, b, count);
@@ -2068,13 +2073,14 @@ static int n_tty_read(struct dfs_file *fd, void *buf, size_t count)
{
retval = copy_from_read_buf(tty, b, count);
}
+ rt_spin_unlock_irqrestore(&tty->spinlock, level);
if (retval >= 1)
{
break;
}
}
- rt_hw_interrupt_enable(level);
+
return retval;
}
@@ -2189,12 +2195,12 @@ static int n_tty_poll(struct dfs_file *fd, struct rt_pollreq *req)
wq = _wait_queue_current_get(tty);
rt_poll_add(wq, req);
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&tty->spinlock);
if (input_available_p(tty, 1))
{
mask |= POLLIN;
}
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&tty->spinlock, level);
return mask;
}
diff --git a/components/drivers/tty/pty.c b/components/drivers/tty/pty.c
index 89a83096d6..b6cbda5574 100644
--- a/components/drivers/tty/pty.c
+++ b/components/drivers/tty/pty.c
@@ -73,17 +73,14 @@ static int pty_get_index(struct tty_struct *tty, int *arg)
*/
static rt_err_t pty_device_init(struct rt_device *dev)
{
- rt_ubase_t level = 0;
rt_err_t result = RT_EOK;
struct tty_struct *tty = RT_NULL;
RT_ASSERT(dev != RT_NULL);
tty = (struct tty_struct *)dev;
- level = rt_hw_interrupt_disable();
RT_ASSERT(tty->init_flag == TTY_INIT_FLAG_REGED);
tty->init_flag = TTY_INIT_FLAG_INITED;
- rt_hw_interrupt_enable(level);
return result;
}
@@ -150,12 +147,12 @@ static rt_ssize_t pty_device_write(struct rt_device *dev,
RT_ASSERT(tty->init_flag == TTY_INIT_FLAG_INITED);
to = tty->other_struct;
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&tty->spinlock);
if (to->ldisc->ops->receive_buf)
{
len = to->ldisc->ops->receive_buf(to, (char *)buffer, size);
}
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&tty->spinlock, level);
return len;
}
diff --git a/components/drivers/tty/tty.c b/components/drivers/tty/tty.c
index 6e05f95033..075b177d5c 100644
--- a/components/drivers/tty/tty.c
+++ b/components/drivers/tty/tty.c
@@ -142,29 +142,27 @@ int __tty_check_change(struct tty_struct *tty, int sig)
{
pid_t pgrp = 0, tty_pgrp = 0;
int ret = 0;
- int level = 0;
+ struct rt_lwp *lwp;
- level = rt_hw_interrupt_disable();
- if (current == RT_NULL)
+ lwp = lwp_self();
+
+ if (lwp == RT_NULL)
{
- rt_hw_interrupt_enable(level);
return 0;
}
- if (current->tty != tty)
+ if (lwp->tty != tty)
{
- rt_hw_interrupt_enable(level);
return 0;
}
- pgrp = current->__pgrp;
+ pgrp = lwp->__pgrp;
tty_pgrp = tty->pgrp;
if (tty_pgrp && (pgrp != tty->pgrp))
{
- lwp_signal_kill(current, sig, SI_USER, 0);
+ lwp_signal_kill(lwp, sig, SI_USER, 0);
}
- rt_hw_interrupt_enable(level);
if (!tty_pgrp)
{
@@ -494,6 +492,7 @@ int tty_init(struct tty_struct *tty, int type, int subtype, struct rt_device *io
rt_mutex_init(&tty->lock, "ttyLock", RT_IPC_FLAG_PRIO);
rt_wqueue_init(&tty->wait_queue);
+ rt_spin_lock_init(&tty->spinlock);
tty_ldisc_init(tty);
tty->init_termios = tty_std_termios;
diff --git a/components/drivers/tty/tty_ioctl.c b/components/drivers/tty/tty_ioctl.c
index 4a537f2e53..92206266c3 100644
--- a/components/drivers/tty/tty_ioctl.c
+++ b/components/drivers/tty/tty_ioctl.c
@@ -39,7 +39,7 @@ static int set_termios(struct tty_struct *tty, void *arg, int opt)
struct termios old_termios;
struct tty_ldisc *ld = RT_NULL;
struct termios *new_termios = (struct termios *)arg;
- int level = 0;
+ rt_base_t level = 0;
int retval = tty_check_change(tty);
if (retval)
@@ -47,10 +47,10 @@ static int set_termios(struct tty_struct *tty, void *arg, int opt)
return retval;
}
- rt_memcpy(&old_termios, &(tty->init_termios), sizeof(struct termios));
- level = rt_hw_interrupt_disable();
+ memcpy(&old_termios, &(tty->init_termios), sizeof(struct termios));
+ level = rt_spin_lock_irqsave(&tty->spinlock);
tty->init_termios = *new_termios;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&tty->spinlock, level);
ld = tty->ldisc;
if (ld != NULL)
{
@@ -88,7 +88,7 @@ int n_tty_ioctl_extend(struct tty_struct *tty, int cmd, void *args)
return -RT_EINVAL;
}
- rt_memcpy(tio, &real_tty->init_termios, sizeof(real_tty->init_termios));
+ memcpy(tio, &real_tty->init_termios, sizeof(real_tty->init_termios));
return ret;
}
case TCSETSF:
diff --git a/components/drivers/tty/tty_ldisc.c b/components/drivers/tty/tty_ldisc.c
index 5fb05a923c..f2aef64bcc 100644
--- a/components/drivers/tty/tty_ldisc.c
+++ b/components/drivers/tty/tty_ldisc.c
@@ -14,27 +14,29 @@ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS] = {
&n_tty_ops, /* N_TTY = 0 */
};
+static struct rt_spinlock _spinlock = RT_SPINLOCK_INIT;
+
static struct tty_ldisc_ops *get_ldops(int disc)
{
struct tty_ldisc_ops *ldops = RT_NULL;
- int level = 0;
- level = rt_hw_interrupt_disable();
+ rt_base_t level = 0;
+ level = rt_spin_lock_irqsave(&_spinlock);
ldops = tty_ldiscs[disc];
if (ldops)
{
ldops->refcount++;
}
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
return ldops;
}
static void put_ldops(struct tty_ldisc_ops *ldops)
{
- int level = 0;
+ rt_base_t level = 0;
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&_spinlock);
ldops->refcount--;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
}
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
@@ -120,18 +122,18 @@ void tty_ldisc_kill(struct tty_struct *tty)
int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
{
int ret = 0;
- int level = 0;
+ rt_base_t level = 0;
if (disc < N_TTY || disc >= NR_LDISCS)
{
return -EINVAL;
}
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&_spinlock);
tty_ldiscs[disc] = new_ldisc;
new_ldisc->num = disc;
new_ldisc->refcount = 0;
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&_spinlock, level);
return ret;
}
@@ -146,20 +148,17 @@ int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
void tty_ldisc_release(struct tty_struct *tty)
{
- int level = 0;
struct tty_struct *o_tty = tty->other_struct;
/*
* Shutdown this line discipline. As this is the final close,
* it does not race with the set_ldisc code path.
*/
- level = rt_hw_interrupt_disable();
tty_ldisc_kill(tty);
if (o_tty)
{
tty_ldisc_kill(o_tty);
}
- rt_hw_interrupt_enable(level);
}
/**