import RT-Thread@9217865c without bsp, libcpu and components/net
This commit is contained in:
commit
e2376a3709
1414 changed files with 390370 additions and 0 deletions
179
components/drivers/tty/tty_ldisc.c
Normal file
179
components/drivers/tty/tty_ldisc.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
#include <tty.h>
|
||||
#include <tty_ldisc.h>
|
||||
|
||||
#define DBG_TAG "TTY_LDISC"
|
||||
#ifdef RT_TTY_DEBUG
|
||||
#define DBG_LVL DBG_LOG
|
||||
#else
|
||||
#define DBG_LVL DBG_INFO
|
||||
#endif /* RT_TTY_DEBUG */
|
||||
#include <rtdbg.h>
|
||||
|
||||
extern struct tty_ldisc_ops n_tty_ops;
|
||||
static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS] = {
|
||||
&n_tty_ops, /* N_TTY = 0 */
|
||||
};
|
||||
|
||||
static struct tty_ldisc_ops *get_ldops(int disc)
|
||||
{
|
||||
struct tty_ldisc_ops *ldops = RT_NULL;
|
||||
int level = 0;
|
||||
level = rt_hw_interrupt_disable();
|
||||
ldops = tty_ldiscs[disc];
|
||||
if (ldops)
|
||||
{
|
||||
ldops->refcount++;
|
||||
}
|
||||
rt_hw_interrupt_enable(level);
|
||||
return ldops;
|
||||
}
|
||||
|
||||
static void put_ldops(struct tty_ldisc_ops *ldops)
|
||||
{
|
||||
int level = 0;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
ldops->refcount--;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
|
||||
{
|
||||
struct tty_ldisc *ld = RT_NULL;
|
||||
struct tty_ldisc_ops *ldops = RT_NULL;
|
||||
|
||||
if (disc < N_TTY || disc >= NR_LDISCS)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
ldops = get_ldops(disc);
|
||||
if (ldops == RT_NULL)
|
||||
{
|
||||
LOG_E("tty ldisc get error\n");
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
ld = rt_malloc(sizeof(struct tty_ldisc));
|
||||
if (ld == RT_NULL)
|
||||
{
|
||||
ldops->refcount--;
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
ld->ops = ldops;
|
||||
ld->tty = tty;
|
||||
|
||||
return ld;
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_put - release the ldisc
|
||||
*
|
||||
* Complement of tty_ldisc_get().
|
||||
*/
|
||||
static void tty_ldisc_put(struct tty_ldisc *ld)
|
||||
{
|
||||
if (ld)
|
||||
{
|
||||
put_ldops(ld->ops);
|
||||
rt_free(ld);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_close - close a line discipline
|
||||
* @tty: tty we are opening the ldisc on
|
||||
* @ld: discipline to close
|
||||
*
|
||||
* A helper close method. Also a convenient debugging and check
|
||||
* point.
|
||||
*/
|
||||
static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
|
||||
{
|
||||
if (ld && ld->ops->close)
|
||||
{
|
||||
ld->ops->close(tty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_kill - teardown ldisc
|
||||
* @tty: tty being released
|
||||
*
|
||||
* Perform final close of the ldisc and reset tty->ldisc
|
||||
*/
|
||||
void tty_ldisc_kill(struct tty_struct *tty)
|
||||
{
|
||||
if (tty && tty->ldisc)
|
||||
{
|
||||
/*
|
||||
* Now kill off the ldisc
|
||||
*/
|
||||
tty_ldisc_close(tty, tty->ldisc);
|
||||
tty_ldisc_put(tty->ldisc);
|
||||
/* Force an oops if we mess this up */
|
||||
tty->ldisc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
|
||||
{
|
||||
int ret = 0;
|
||||
int level = 0;
|
||||
|
||||
if (disc < N_TTY || disc >= NR_LDISCS)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
tty_ldiscs[disc] = new_ldisc;
|
||||
new_ldisc->num = disc;
|
||||
new_ldisc->refcount = 0;
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_release - release line discipline
|
||||
* @tty: tty being shut down (or one end of pty pair)
|
||||
*
|
||||
* Called during the final close of a tty or a pty pair in order to shut
|
||||
* down the line discpline layer. On exit, each tty's ldisc is NULL.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_init - ldisc setup for new tty
|
||||
* @tty: tty being allocated
|
||||
*
|
||||
* Set up the line discipline objects for a newly allocated tty. Note that
|
||||
* the tty structure is not completely set up when this call is made.
|
||||
*/
|
||||
|
||||
void tty_ldisc_init(struct tty_struct *tty)
|
||||
{
|
||||
if (tty)
|
||||
{
|
||||
tty->ldisc = tty_ldisc_get(tty, N_TTY);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue