SlideShare una empresa de Scribd logo
1 de 18
Descargar para leer sin conexión
start_printf: dev/ic/com.c
comstart()
start_printf: dev/ic/com.c
comstart()
start_printf: dev/ic/com.c
comstart()
start_printf: dev/ic/com.c
comstart()
start_printf: dev/ic/com.c
comstart()
Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe
Where comstart called?Where comstart called?Where comstart called?Where comstart called?Where comstart called?
Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
fifodone:
tp = tty_alloc();
tp->t_oproc = comstart;
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
fifodone:
tp = tty_alloc();
tp->t_oproc = comstart;
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
fifodone:
tp = tty_alloc();
tp->t_oproc = comstart;
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
fifodone:
tp = tty_alloc();
tp->t_oproc = comstart;
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
fifodone:
tp = tty_alloc();
tp->t_oproc = comstart;
com0 attached at isa0com0 attached at isa0com0 attached at isa0com0 attached at isa0com0 attached at isa0
$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa
attach com at isa with com_isa
file dev/isa/com_isa.c com_isa
$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa
attach com at isa with com_isa
file dev/isa/com_isa.c com_isa
$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa
attach com at isa with com_isa
file dev/isa/com_isa.c com_isa
$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa
attach com at isa with com_isa
file dev/isa/com_isa.c com_isa
$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa
attach com at isa with com_isa
file dev/isa/com_isa.c com_isa
// File: sys/dev/isa/com_isa.c
void
com_isa_attach(device_t parent, device_t self, void *aux)
{
// -- snip --
com_attach_subr(sc);
// File: sys/dev/isa/com_isa.c
void
com_isa_attach(device_t parent, device_t self, void *aux)
{
// -- snip --
com_attach_subr(sc);
// File: sys/dev/isa/com_isa.c
void
com_isa_attach(device_t parent, device_t self, void *aux)
{
// -- snip --
com_attach_subr(sc);
// File: sys/dev/isa/com_isa.c
void
com_isa_attach(device_t parent, device_t self, void *aux)
{
// -- snip --
com_attach_subr(sc);
// File: sys/dev/isa/com_isa.c
void
com_isa_attach(device_t parent, device_t self, void *aux)
{
// -- snip --
com_attach_subr(sc);
com softc has struct tty membercom softc has struct tty membercom softc has struct tty membercom softc has struct tty membercom softc has struct tty member
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
tp = tty_alloc();
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_hwiflow = comhwiflow;
sc->sc_tty = tp;
// -- snip --
tty_attach(tp);
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
tp = tty_alloc();
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_hwiflow = comhwiflow;
sc->sc_tty = tp;
// -- snip --
tty_attach(tp);
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
tp = tty_alloc();
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_hwiflow = comhwiflow;
sc->sc_tty = tp;
// -- snip --
tty_attach(tp);
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
tp = tty_alloc();
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_hwiflow = comhwiflow;
sc->sc_tty = tp;
// -- snip --
tty_attach(tp);
// File: sys/dev/ic/com.c
void
com_attach_subr(struct com_softc *sc)
{
// -- snip --
tp = tty_alloc();
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_hwiflow = comhwiflow;
sc->sc_tty = tp;
// -- snip --
tty_attach(tp);
// File: sys/dev/ic/comvar.h
struct com_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
// File: sys/dev/ic/comvar.h
struct com_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
// File: sys/dev/ic/comvar.h
struct com_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
// File: sys/dev/ic/comvar.h
struct com_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
// File: sys/dev/ic/comvar.h
struct com_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
Maybe call tree is...Maybe call tree is...Maybe call tree is...Maybe call tree is...Maybe call tree is...
cdev_write
=> comwrite
=> ttwrite
=> ttstart
=> comstart
cdev_write
=> comwrite
=> ttwrite
=> ttstart
=> comstart
cdev_write
=> comwrite
=> ttwrite
=> ttstart
=> comstart
cdev_write
=> comwrite
=> ttwrite
=> ttstart
=> comstart
cdev_write
=> comwrite
=> ttwrite
=> ttstart
=> comstart
comwrite()comwrite()comwrite()comwrite()comwrite()
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && 
device_is_active((sc)->sc_dev))
int
comwrite(dev_t dev, struct uio *uio, int flag)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(dev));
struct tty *tp = sc->sc_tty;
if (COM_ISALIVE(sc) == 0)
return (EIO);
return ((*tp->t_linesw->l_write)(tp, uio, flag));
}
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && 
device_is_active((sc)->sc_dev))
int
comwrite(dev_t dev, struct uio *uio, int flag)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(dev));
struct tty *tp = sc->sc_tty;
if (COM_ISALIVE(sc) == 0)
return (EIO);
return ((*tp->t_linesw->l_write)(tp, uio, flag));
}
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && 
device_is_active((sc)->sc_dev))
int
comwrite(dev_t dev, struct uio *uio, int flag)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(dev));
struct tty *tp = sc->sc_tty;
if (COM_ISALIVE(sc) == 0)
return (EIO);
return ((*tp->t_linesw->l_write)(tp, uio, flag));
}
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && 
device_is_active((sc)->sc_dev))
int
comwrite(dev_t dev, struct uio *uio, int flag)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(dev));
struct tty *tp = sc->sc_tty;
if (COM_ISALIVE(sc) == 0)
return (EIO);
return ((*tp->t_linesw->l_write)(tp, uio, flag));
}
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && 
device_is_active((sc)->sc_dev))
int
comwrite(dev_t dev, struct uio *uio, int flag)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(dev));
struct tty *tp = sc->sc_tty;
if (COM_ISALIVE(sc) == 0)
return (EIO);
return ((*tp->t_linesw->l_write)(tp, uio, flag));
}
comstart() #1comstart() #1comstart() #1comstart() #1comstart() #1
void
comstart(struct tty *tp)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(tp->t_dev));
struct com_regs *regsp = &sc->sc_regs;
int s;
if (COM_ISALIVE(sc) == 0)
return;
s = spltty();
if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
goto out;
if (sc->sc_tx_stopped)
goto out;
if (!ttypull(tp))
goto out;
void
comstart(struct tty *tp)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(tp->t_dev));
struct com_regs *regsp = &sc->sc_regs;
int s;
if (COM_ISALIVE(sc) == 0)
return;
s = spltty();
if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
goto out;
if (sc->sc_tx_stopped)
goto out;
if (!ttypull(tp))
goto out;
void
comstart(struct tty *tp)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(tp->t_dev));
struct com_regs *regsp = &sc->sc_regs;
int s;
if (COM_ISALIVE(sc) == 0)
return;
s = spltty();
if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
goto out;
if (sc->sc_tx_stopped)
goto out;
if (!ttypull(tp))
goto out;
void
comstart(struct tty *tp)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(tp->t_dev));
struct com_regs *regsp = &sc->sc_regs;
int s;
if (COM_ISALIVE(sc) == 0)
return;
s = spltty();
if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
goto out;
if (sc->sc_tx_stopped)
goto out;
if (!ttypull(tp))
goto out;
void
comstart(struct tty *tp)
{
struct com_softc *sc =
device_lookup_private(&com_cd, COMUNIT(tp->t_dev));
struct com_regs *regsp = &sc->sc_regs;
int s;
if (COM_ISALIVE(sc) == 0)
return;
s = spltty();
if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
goto out;
if (sc->sc_tx_stopped)
goto out;
if (!ttypull(tp))
goto out;
ttypull()ttypull()ttypull()ttypull()ttypull()
/*
* Try to pull more output from the producer. Return non-zero if
* there is output ready to be sent.
*/
bool
ttypull(struct tty *tp)
{
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
}
/*
* Try to pull more output from the producer. Return non-zero if
* there is output ready to be sent.
*/
bool
ttypull(struct tty *tp)
{
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
}
/*
* Try to pull more output from the producer. Return non-zero if
* there is output ready to be sent.
*/
bool
ttypull(struct tty *tp)
{
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
}
/*
* Try to pull more output from the producer. Return non-zero if
* there is output ready to be sent.
*/
bool
ttypull(struct tty *tp)
{
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
}
/*
* Try to pull more output from the producer. Return non-zero if
* there is output ready to be sent.
*/
bool
ttypull(struct tty *tp)
{
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
}
comstart() #2comstart() #2comstart() #2comstart() #2comstart() #2
/* Grab the first contiguous region of buffer space. */
{
u_char *tba;
int tbc;
tba = tp->t_outq.c_cf;
tbc = ndqb(&tp->t_outq, 0);
mutex_spin_enter(&sc->sc_lock);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
}
SET(tp->t_state, TS_BUSY);
sc->sc_tx_busy = 1;
/* Grab the first contiguous region of buffer space. */
{
u_char *tba;
int tbc;
tba = tp->t_outq.c_cf;
tbc = ndqb(&tp->t_outq, 0);
mutex_spin_enter(&sc->sc_lock);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
}
SET(tp->t_state, TS_BUSY);
sc->sc_tx_busy = 1;
/* Grab the first contiguous region of buffer space. */
{
u_char *tba;
int tbc;
tba = tp->t_outq.c_cf;
tbc = ndqb(&tp->t_outq, 0);
mutex_spin_enter(&sc->sc_lock);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
}
SET(tp->t_state, TS_BUSY);
sc->sc_tx_busy = 1;
/* Grab the first contiguous region of buffer space. */
{
u_char *tba;
int tbc;
tba = tp->t_outq.c_cf;
tbc = ndqb(&tp->t_outq, 0);
mutex_spin_enter(&sc->sc_lock);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
}
SET(tp->t_state, TS_BUSY);
sc->sc_tx_busy = 1;
/* Grab the first contiguous region of buffer space. */
{
u_char *tba;
int tbc;
tba = tp->t_outq.c_cf;
tbc = ndqb(&tp->t_outq, 0);
mutex_spin_enter(&sc->sc_lock);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
}
SET(tp->t_state, TS_BUSY);
sc->sc_tx_busy = 1;
ndqb()ndqb()ndqb()ndqb()ndqb()
/*
* Return count of contiguous characters in clist.
* Stop counting if flag&character is non-null.
*/
int
ndqb(struct clist *clp, int flag)
{
int count = 0;
int i;
int cc;
int s;
s = spltty();
if ((cc = clp->c_cc) == 0)
goto out;
// --snip--
out:
splx(s);
return count;
}
/*
* Return count of contiguous characters in clist.
* Stop counting if flag&character is non-null.
*/
int
ndqb(struct clist *clp, int flag)
{
int count = 0;
int i;
int cc;
int s;
s = spltty();
if ((cc = clp->c_cc) == 0)
goto out;
// --snip--
out:
splx(s);
return count;
}
/*
* Return count of contiguous characters in clist.
* Stop counting if flag&character is non-null.
*/
int
ndqb(struct clist *clp, int flag)
{
int count = 0;
int i;
int cc;
int s;
s = spltty();
if ((cc = clp->c_cc) == 0)
goto out;
// --snip--
out:
splx(s);
return count;
}
/*
* Return count of contiguous characters in clist.
* Stop counting if flag&character is non-null.
*/
int
ndqb(struct clist *clp, int flag)
{
int count = 0;
int i;
int cc;
int s;
s = spltty();
if ((cc = clp->c_cc) == 0)
goto out;
// --snip--
out:
splx(s);
return count;
}
/*
* Return count of contiguous characters in clist.
* Stop counting if flag&character is non-null.
*/
int
ndqb(struct clist *clp, int flag)
{
int count = 0;
int i;
int cc;
int s;
s = spltty();
if ((cc = clp->c_cc) == 0)
goto out;
// --snip--
out:
splx(s);
return count;
}
struct cliststruct cliststruct cliststruct cliststruct clist
/*
* Clists are actually ring buffers. The c_cc, c_cf, c_cl fields
have
* exactly the same behaviour as in true clists.
* if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality
* (but, saves memory and CPU time)
*
* *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside
tty_subr.c!!!
*/
struct clist {
u_char *c_cf; /* points to first character */
u_char *c_cl; /* points to next open character */
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
/*
* Clists are actually ring buffers. The c_cc, c_cf, c_cl fields
have
* exactly the same behaviour as in true clists.
* if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality
* (but, saves memory and CPU time)
*
* *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside
tty_subr.c!!!
*/
struct clist {
u_char *c_cf; /* points to first character */
u_char *c_cl; /* points to next open character */
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
/*
* Clists are actually ring buffers. The c_cc, c_cf, c_cl fields
have
* exactly the same behaviour as in true clists.
* if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality
* (but, saves memory and CPU time)
*
* *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside
tty_subr.c!!!
*/
struct clist {
u_char *c_cf; /* points to first character */
u_char *c_cl; /* points to next open character */
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
/*
* Clists are actually ring buffers. The c_cc, c_cf, c_cl fields
have
* exactly the same behaviour as in true clists.
* if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality
* (but, saves memory and CPU time)
*
* *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside
tty_subr.c!!!
*/
struct clist {
u_char *c_cf; /* points to first character */
u_char *c_cl; /* points to next open character */
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
/*
* Clists are actually ring buffers. The c_cc, c_cf, c_cl fields
have
* exactly the same behaviour as in true clists.
* if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality
* (but, saves memory and CPU time)
*
* *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside
tty_subr.c!!!
*/
struct clist {
u_char *c_cf; /* points to first character */
u_char *c_cl; /* points to next open character */
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)
comstart() #3comstart() #3comstart() #3comstart() #3comstart() #3
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
u_int n;
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
mutex_spin_exit(&sc->sc_lock);
out:
splx(s);
return;
}
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
u_int n;
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
mutex_spin_exit(&sc->sc_lock);
out:
splx(s);
return;
}
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
u_int n;
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
mutex_spin_exit(&sc->sc_lock);
out:
splx(s);
return;
}
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
u_int n;
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
mutex_spin_exit(&sc->sc_lock);
out:
splx(s);
return;
}
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
u_int n;
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
mutex_spin_exit(&sc->sc_lock);
out:
splx(s);
return;
}
clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)
CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*()
// arch/i386/compile/GENERIC/opt_com.h:
// /* option `COM_REGMAP' not defined */
#define CSR_WRITE_1(r, o, v) 
bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
#define CSR_WRITE_MULTI(r, o, p, n) 
bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n)
#define COM_REG_IER com_ier
#define COM_REG_TXDATA com_data
// arch/i386/compile/GENERIC/opt_com.h:
// /* option `COM_REGMAP' not defined */
#define CSR_WRITE_1(r, o, v) 
bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
#define CSR_WRITE_MULTI(r, o, p, n) 
bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n)
#define COM_REG_IER com_ier
#define COM_REG_TXDATA com_data
// arch/i386/compile/GENERIC/opt_com.h:
// /* option `COM_REGMAP' not defined */
#define CSR_WRITE_1(r, o, v) 
bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
#define CSR_WRITE_MULTI(r, o, p, n) 
bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n)
#define COM_REG_IER com_ier
#define COM_REG_TXDATA com_data
// arch/i386/compile/GENERIC/opt_com.h:
// /* option `COM_REGMAP' not defined */
#define CSR_WRITE_1(r, o, v) 
bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
#define CSR_WRITE_MULTI(r, o, p, n) 
bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n)
#define COM_REG_IER com_ier
#define COM_REG_TXDATA com_data
// arch/i386/compile/GENERIC/opt_com.h:
// /* option `COM_REGMAP' not defined */
#define CSR_WRITE_1(r, o, v) 
bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
#define CSR_WRITE_MULTI(r, o, p, n) 
bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n)
#define COM_REG_IER com_ier
#define COM_REG_TXDATA com_data
// com.c
// = include => dev/ic/comreg.h
// = include => dev/ic/ns16550reg.h
#define com_data 0 /* data register (R/W) */
#define com_ier 1 /* interrupt enable (W) */
// com.c
// = include => dev/ic/comreg.h
// = include => dev/ic/ns16550reg.h
#define com_data 0 /* data register (R/W) */
#define com_ier 1 /* interrupt enable (W) */
// com.c
// = include => dev/ic/comreg.h
// = include => dev/ic/ns16550reg.h
#define com_data 0 /* data register (R/W) */
#define com_ier 1 /* interrupt enable (W) */
// com.c
// = include => dev/ic/comreg.h
// = include => dev/ic/ns16550reg.h
#define com_data 0 /* data register (R/W) */
#define com_ier 1 /* interrupt enable (W) */
// com.c
// = include => dev/ic/comreg.h
// = include => dev/ic/ns16550reg.h
#define com_data 0 /* data register (R/W) */
#define com_ier 1 /* interrupt enable (W) */
The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.
bus_space_map()bus_space_map()bus_space_map()bus_space_map()bus_space_map()
int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
int frequency, int type, tcflag_t cflag)
{
// --snip--
regs.cr_iot = iot;
regs.cr_iobase = iobase;
regs.cr_nports = COM_NPORTS;
return comcnattach1(&regs, rate, frequency, type, cflag);
// --snip--
int comcnattach1(struct com_regs *regsp, int rate, int frequency,
int type, tcflag_t cflag)
{
// --snip--
comcons_info.regs = *regsp;
res = cominit(&comcons_info.regs, rate, frequency, type,
cflag);
// --snip--
int cominit(struct com_regs *regsp, int rate, int frequency, int
type, tcflag_t cflag)
{
if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp-
>cr_nports, 0, &regsp->cr_ioh))
int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
int frequency, int type, tcflag_t cflag)
{
// --snip--
regs.cr_iot = iot;
regs.cr_iobase = iobase;
regs.cr_nports = COM_NPORTS;
return comcnattach1(&regs, rate, frequency, type, cflag);
// --snip--
int comcnattach1(struct com_regs *regsp, int rate, int frequency,
int type, tcflag_t cflag)
{
// --snip--
comcons_info.regs = *regsp;
res = cominit(&comcons_info.regs, rate, frequency, type,
cflag);
// --snip--
int cominit(struct com_regs *regsp, int rate, int frequency, int
type, tcflag_t cflag)
{
if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp-
>cr_nports, 0, &regsp->cr_ioh))
int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
int frequency, int type, tcflag_t cflag)
{
// --snip--
regs.cr_iot = iot;
regs.cr_iobase = iobase;
regs.cr_nports = COM_NPORTS;
return comcnattach1(&regs, rate, frequency, type, cflag);
// --snip--
int comcnattach1(struct com_regs *regsp, int rate, int frequency,
int type, tcflag_t cflag)
{
// --snip--
comcons_info.regs = *regsp;
res = cominit(&comcons_info.regs, rate, frequency, type,
cflag);
// --snip--
int cominit(struct com_regs *regsp, int rate, int frequency, int
type, tcflag_t cflag)
{
if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp-
>cr_nports, 0, &regsp->cr_ioh))
int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
int frequency, int type, tcflag_t cflag)
{
// --snip--
regs.cr_iot = iot;
regs.cr_iobase = iobase;
regs.cr_nports = COM_NPORTS;
return comcnattach1(&regs, rate, frequency, type, cflag);
// --snip--
int comcnattach1(struct com_regs *regsp, int rate, int frequency,
int type, tcflag_t cflag)
{
// --snip--
comcons_info.regs = *regsp;
res = cominit(&comcons_info.regs, rate, frequency, type,
cflag);
// --snip--
int cominit(struct com_regs *regsp, int rate, int frequency, int
type, tcflag_t cflag)
{
if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp-
>cr_nports, 0, &regsp->cr_ioh))
int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
int frequency, int type, tcflag_t cflag)
{
// --snip--
regs.cr_iot = iot;
regs.cr_iobase = iobase;
regs.cr_nports = COM_NPORTS;
return comcnattach1(&regs, rate, frequency, type, cflag);
// --snip--
int comcnattach1(struct com_regs *regsp, int rate, int frequency,
int type, tcflag_t cflag)
{
// --snip--
comcons_info.regs = *regsp;
res = cominit(&comcons_info.regs, rate, frequency, type,
cflag);
// --snip--
int cominit(struct com_regs *regsp, int rate, int frequency, int
type, tcflag_t cflag)
{
if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp-
>cr_nports, 0, &regsp->cr_ioh))
comcnattach() callercomcnattach() callercomcnattach() callercomcnattach() callercomcnattach() caller
void
consinit(void)
{
// --snip--
#if (NCOM > 0)
if (!strcmp(consinfo->devname, "com")) {
int addr = consinfo->addr;
int speed = consinfo->speed;
if (addr == 0)
addr = CONADDR; // <= 0x3f8
if (speed == 0)
speed = CONSPEED;
if (comcnattach(x86_bus_space_io, addr, speed,
COM_FREQ, COM_TYPE_NORMAL,
comcnmode))
panic("can't init serial console @%x",
consinfo->addr);
return;
}
#endif
void
consinit(void)
{
// --snip--
#if (NCOM > 0)
if (!strcmp(consinfo->devname, "com")) {
int addr = consinfo->addr;
int speed = consinfo->speed;
if (addr == 0)
addr = CONADDR; // <= 0x3f8
if (speed == 0)
speed = CONSPEED;
if (comcnattach(x86_bus_space_io, addr, speed,
COM_FREQ, COM_TYPE_NORMAL,
comcnmode))
panic("can't init serial console @%x",
consinfo->addr);
return;
}
#endif
void
consinit(void)
{
// --snip--
#if (NCOM > 0)
if (!strcmp(consinfo->devname, "com")) {
int addr = consinfo->addr;
int speed = consinfo->speed;
if (addr == 0)
addr = CONADDR; // <= 0x3f8
if (speed == 0)
speed = CONSPEED;
if (comcnattach(x86_bus_space_io, addr, speed,
COM_FREQ, COM_TYPE_NORMAL,
comcnmode))
panic("can't init serial console @%x",
consinfo->addr);
return;
}
#endif
void
consinit(void)
{
// --snip--
#if (NCOM > 0)
if (!strcmp(consinfo->devname, "com")) {
int addr = consinfo->addr;
int speed = consinfo->speed;
if (addr == 0)
addr = CONADDR; // <= 0x3f8
if (speed == 0)
speed = CONSPEED;
if (comcnattach(x86_bus_space_io, addr, speed,
COM_FREQ, COM_TYPE_NORMAL,
comcnmode))
panic("can't init serial console @%x",
consinfo->addr);
return;
}
#endif
void
consinit(void)
{
// --snip--
#if (NCOM > 0)
if (!strcmp(consinfo->devname, "com")) {
int addr = consinfo->addr;
int speed = consinfo->speed;
if (addr == 0)
addr = CONADDR; // <= 0x3f8
if (speed == 0)
speed = CONSPEED;
if (comcnattach(x86_bus_space_io, addr, speed,
COM_FREQ, COM_TYPE_NORMAL,
comcnmode))
panic("can't init serial console @%x",
consinfo->addr);
return;
}
#endif
bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)

Más contenido relacionado

La actualidad más candente

DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionFelipe Prado
 
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!..."A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...akaptur
 
Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2Kazuho Oku
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overviewhesher
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegeninovex GmbH
 
Network security mannual (2)
Network security mannual (2)Network security mannual (2)
Network security mannual (2)Vivek Kumar Sinha
 
ch8-pv1-the-virtual-filesystem
ch8-pv1-the-virtual-filesystemch8-pv1-the-virtual-filesystem
ch8-pv1-the-virtual-filesystemyushiang fu
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is hereSebastiano Armeli
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual Vivek Kumar Sinha
 
Exploring slides
Exploring slidesExploring slides
Exploring slidesakaptur
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationAttila Balazs
 
Php radomize
Php radomizePhp radomize
Php radomizedo_aki
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutinesNAVER Engineering
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays
 

La actualidad más candente (20)

DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
 
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!..."A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
 
Unix 5 en
Unix 5 enUnix 5 en
Unix 5 en
 
Sbaw091006
Sbaw091006Sbaw091006
Sbaw091006
 
Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
 
Javascript: The Important Bits
Javascript: The Important BitsJavascript: The Important Bits
Javascript: The Important Bits
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
 
Network security mannual (2)
Network security mannual (2)Network security mannual (2)
Network security mannual (2)
 
ch8-pv1-the-virtual-filesystem
ch8-pv1-the-virtual-filesystemch8-pv1-the-virtual-filesystem
ch8-pv1-the-virtual-filesystem
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual
 
dotCloud and go
dotCloud and godotCloud and go
dotCloud and go
 
Exploring slides
Exploring slidesExploring slides
Exploring slides
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
Php radomize
Php radomizePhp radomize
Php radomize
 
IT6712 lab manual
IT6712 lab manualIT6712 lab manual
IT6712 lab manual
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
 

Destacado

Functional MCU programming #0: Development environment
Functional MCU programming #0: Development environmentFunctional MCU programming #0: Development environment
Functional MCU programming #0: Development environmentKiwamu Okabe
 
Build OS X Apps on Travis CI
Build OS X Apps on Travis CIBuild OS X Apps on Travis CI
Build OS X Apps on Travis CIKiwamu Okabe
 
Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Kiwamu Okabe
 
Functional MCU programming
Functional MCU programmingFunctional MCU programming
Functional MCU programmingKiwamu Okabe
 
Safer IoT using functional language
Safer IoT using functional languageSafer IoT using functional language
Safer IoT using functional languageKiwamu Okabe
 
Real-time OS system state captured by ATS language
Real-time OS system state captured by ATS languageReal-time OS system state captured by ATS language
Real-time OS system state captured by ATS languageKiwamu Okabe
 

Destacado (6)

Functional MCU programming #0: Development environment
Functional MCU programming #0: Development environmentFunctional MCU programming #0: Development environment
Functional MCU programming #0: Development environment
 
Build OS X Apps on Travis CI
Build OS X Apps on Travis CIBuild OS X Apps on Travis CI
Build OS X Apps on Travis CI
 
Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死
 
Functional MCU programming
Functional MCU programmingFunctional MCU programming
Functional MCU programming
 
Safer IoT using functional language
Safer IoT using functional languageSafer IoT using functional language
Safer IoT using functional language
 
Real-time OS system state captured by ATS language
Real-time OS system state captured by ATS languageReal-time OS system state captured by ATS language
Real-time OS system state captured by ATS language
 

Similar a start_printf: dev/ic/com.c comstart()

Create an auto-extractible shell script linux
Create an auto-extractible shell script linuxCreate an auto-extractible shell script linux
Create an auto-extractible shell script linuxThierry Gayet
 
Im trying to run make qemu-nox In a putty terminal but it.pdf
Im trying to run  make qemu-nox  In a putty terminal but it.pdfIm trying to run  make qemu-nox  In a putty terminal but it.pdf
Im trying to run make qemu-nox In a putty terminal but it.pdfmaheshkumar12354
 
Linux seccomp(2) vs OpenBSD pledge(2)
Linux seccomp(2) vs OpenBSD pledge(2)Linux seccomp(2) vs OpenBSD pledge(2)
Linux seccomp(2) vs OpenBSD pledge(2)Giovanni Bechis
 
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Vincenzo Iozzo
 
Basicsof c make and git for a hello qt application
Basicsof c make and git for a hello qt applicationBasicsof c make and git for a hello qt application
Basicsof c make and git for a hello qt applicationDinesh Manajipet
 
(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart Pointers(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart PointersCarlo Pescio
 
为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?勇浩 赖
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak PROIDEA
 
A CTF Hackers Toolbox
A CTF Hackers ToolboxA CTF Hackers Toolbox
A CTF Hackers ToolboxStefan
 
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)CODE BLUE
 
Introduction to Kernel Programming
Introduction to Kernel ProgrammingIntroduction to Kernel Programming
Introduction to Kernel ProgrammingAhmed Mekkawy
 
04 - I love my OS, he protects me (sometimes, in specific circumstances)
04 - I love my OS, he protects me (sometimes, in specific circumstances)04 - I love my OS, he protects me (sometimes, in specific circumstances)
04 - I love my OS, he protects me (sometimes, in specific circumstances)Alexandre Moneger
 
Linux kernel debugging
Linux kernel debuggingLinux kernel debugging
Linux kernel debuggingJungMinSEO5
 
망고100 보드로 놀아보자 7
망고100 보드로 놀아보자 7망고100 보드로 놀아보자 7
망고100 보드로 놀아보자 7종인 전
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Yandex
 

Similar a start_printf: dev/ic/com.c comstart() (20)

Create an auto-extractible shell script linux
Create an auto-extractible shell script linuxCreate an auto-extractible shell script linux
Create an auto-extractible shell script linux
 
Embedding perl
Embedding perlEmbedding perl
Embedding perl
 
005 skyeye
005 skyeye005 skyeye
005 skyeye
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
Im trying to run make qemu-nox In a putty terminal but it.pdf
Im trying to run  make qemu-nox  In a putty terminal but it.pdfIm trying to run  make qemu-nox  In a putty terminal but it.pdf
Im trying to run make qemu-nox In a putty terminal but it.pdf
 
Linux seccomp(2) vs OpenBSD pledge(2)
Linux seccomp(2) vs OpenBSD pledge(2)Linux seccomp(2) vs OpenBSD pledge(2)
Linux seccomp(2) vs OpenBSD pledge(2)
 
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
 
Sysprog17
Sysprog17Sysprog17
Sysprog17
 
Basicsof c make and git for a hello qt application
Basicsof c make and git for a hello qt applicationBasicsof c make and git for a hello qt application
Basicsof c make and git for a hello qt application
 
(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart Pointers(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart Pointers
 
Gps c
Gps cGps c
Gps c
 
为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
A CTF Hackers Toolbox
A CTF Hackers ToolboxA CTF Hackers Toolbox
A CTF Hackers Toolbox
 
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
 
Introduction to Kernel Programming
Introduction to Kernel ProgrammingIntroduction to Kernel Programming
Introduction to Kernel Programming
 
04 - I love my OS, he protects me (sometimes, in specific circumstances)
04 - I love my OS, he protects me (sometimes, in specific circumstances)04 - I love my OS, he protects me (sometimes, in specific circumstances)
04 - I love my OS, he protects me (sometimes, in specific circumstances)
 
Linux kernel debugging
Linux kernel debuggingLinux kernel debugging
Linux kernel debugging
 
망고100 보드로 놀아보자 7
망고100 보드로 놀아보자 7망고100 보드로 놀아보자 7
망고100 보드로 놀아보자 7
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 

Último

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 

Último (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 

start_printf: dev/ic/com.c comstart()

  • 1. start_printf: dev/ic/com.c comstart() start_printf: dev/ic/com.c comstart() start_printf: dev/ic/com.c comstart() start_printf: dev/ic/com.c comstart() start_printf: dev/ic/com.c comstart() Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe
  • 2. Where comstart called?Where comstart called?Where comstart called?Where comstart called?Where comstart called? Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"?Who kick "tp->t_oproc"? // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- fifodone: tp = tty_alloc(); tp->t_oproc = comstart; // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- fifodone: tp = tty_alloc(); tp->t_oproc = comstart; // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- fifodone: tp = tty_alloc(); tp->t_oproc = comstart; // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- fifodone: tp = tty_alloc(); tp->t_oproc = comstart; // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- fifodone: tp = tty_alloc(); tp->t_oproc = comstart;
  • 3. com0 attached at isa0com0 attached at isa0com0 attached at isa0com0 attached at isa0com0 attached at isa0 $ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0 com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports $ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa attach com at isa with com_isa file dev/isa/com_isa.c com_isa $ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0 com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports $ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa attach com at isa with com_isa file dev/isa/com_isa.c com_isa $ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0 com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports $ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa attach com at isa with com_isa file dev/isa/com_isa.c com_isa $ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0 com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports $ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa attach com at isa with com_isa file dev/isa/com_isa.c com_isa $ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0 com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports $ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isa attach com at isa with com_isa file dev/isa/com_isa.c com_isa // File: sys/dev/isa/com_isa.c void com_isa_attach(device_t parent, device_t self, void *aux) { // -- snip -- com_attach_subr(sc); // File: sys/dev/isa/com_isa.c void com_isa_attach(device_t parent, device_t self, void *aux) { // -- snip -- com_attach_subr(sc); // File: sys/dev/isa/com_isa.c void com_isa_attach(device_t parent, device_t self, void *aux) { // -- snip -- com_attach_subr(sc); // File: sys/dev/isa/com_isa.c void com_isa_attach(device_t parent, device_t self, void *aux) { // -- snip -- com_attach_subr(sc); // File: sys/dev/isa/com_isa.c void com_isa_attach(device_t parent, device_t self, void *aux) { // -- snip -- com_attach_subr(sc);
  • 4. com softc has struct tty membercom softc has struct tty membercom softc has struct tty membercom softc has struct tty membercom softc has struct tty member // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- tp = tty_alloc(); tp->t_oproc = comstart; tp->t_param = comparam; tp->t_hwiflow = comhwiflow; sc->sc_tty = tp; // -- snip -- tty_attach(tp); // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- tp = tty_alloc(); tp->t_oproc = comstart; tp->t_param = comparam; tp->t_hwiflow = comhwiflow; sc->sc_tty = tp; // -- snip -- tty_attach(tp); // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- tp = tty_alloc(); tp->t_oproc = comstart; tp->t_param = comparam; tp->t_hwiflow = comhwiflow; sc->sc_tty = tp; // -- snip -- tty_attach(tp); // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- tp = tty_alloc(); tp->t_oproc = comstart; tp->t_param = comparam; tp->t_hwiflow = comhwiflow; sc->sc_tty = tp; // -- snip -- tty_attach(tp); // File: sys/dev/ic/com.c void com_attach_subr(struct com_softc *sc) { // -- snip -- tp = tty_alloc(); tp->t_oproc = comstart; tp->t_param = comparam; tp->t_hwiflow = comhwiflow; sc->sc_tty = tp; // -- snip -- tty_attach(tp); // File: sys/dev/ic/comvar.h struct com_softc { device_t sc_dev; void *sc_si; struct tty *sc_tty; // File: sys/dev/ic/comvar.h struct com_softc { device_t sc_dev; void *sc_si; struct tty *sc_tty; // File: sys/dev/ic/comvar.h struct com_softc { device_t sc_dev; void *sc_si; struct tty *sc_tty; // File: sys/dev/ic/comvar.h struct com_softc { device_t sc_dev; void *sc_si; struct tty *sc_tty; // File: sys/dev/ic/comvar.h struct com_softc { device_t sc_dev; void *sc_si; struct tty *sc_tty;
  • 5. Maybe call tree is...Maybe call tree is...Maybe call tree is...Maybe call tree is...Maybe call tree is... cdev_write => comwrite => ttwrite => ttstart => comstart cdev_write => comwrite => ttwrite => ttstart => comstart cdev_write => comwrite => ttwrite => ttstart => comstart cdev_write => comwrite => ttwrite => ttstart => comstart cdev_write => comwrite => ttwrite => ttstart => comstart
  • 6. comwrite()comwrite()comwrite()comwrite()comwrite() #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) int comwrite(dev_t dev, struct uio *uio, int flag) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; if (COM_ISALIVE(sc) == 0) return (EIO); return ((*tp->t_linesw->l_write)(tp, uio, flag)); } #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) int comwrite(dev_t dev, struct uio *uio, int flag) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; if (COM_ISALIVE(sc) == 0) return (EIO); return ((*tp->t_linesw->l_write)(tp, uio, flag)); } #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) int comwrite(dev_t dev, struct uio *uio, int flag) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; if (COM_ISALIVE(sc) == 0) return (EIO); return ((*tp->t_linesw->l_write)(tp, uio, flag)); } #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) int comwrite(dev_t dev, struct uio *uio, int flag) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; if (COM_ISALIVE(sc) == 0) return (EIO); return ((*tp->t_linesw->l_write)(tp, uio, flag)); } #define COM_ISALIVE(sc) ((sc)->enabled != 0 && device_is_active((sc)->sc_dev)) int comwrite(dev_t dev, struct uio *uio, int flag) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; if (COM_ISALIVE(sc) == 0) return (EIO); return ((*tp->t_linesw->l_write)(tp, uio, flag)); }
  • 7. comstart() #1comstart() #1comstart() #1comstart() #1comstart() #1 void comstart(struct tty *tp) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(tp->t_dev)); struct com_regs *regsp = &sc->sc_regs; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; void comstart(struct tty *tp) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(tp->t_dev)); struct com_regs *regsp = &sc->sc_regs; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; void comstart(struct tty *tp) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(tp->t_dev)); struct com_regs *regsp = &sc->sc_regs; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; void comstart(struct tty *tp) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(tp->t_dev)); struct com_regs *regsp = &sc->sc_regs; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; void comstart(struct tty *tp) { struct com_softc *sc = device_lookup_private(&com_cd, COMUNIT(tp->t_dev)); struct com_regs *regsp = &sc->sc_regs; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out;
  • 8. ttypull()ttypull()ttypull()ttypull()ttypull() /* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */ bool ttypull(struct tty *tp) { /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ if (tp->t_outq.c_cc <= tp->t_lowat) { cv_broadcast(&tp->t_outcv); selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); } return tp->t_outq.c_cc != 0; } /* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */ bool ttypull(struct tty *tp) { /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ if (tp->t_outq.c_cc <= tp->t_lowat) { cv_broadcast(&tp->t_outcv); selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); } return tp->t_outq.c_cc != 0; } /* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */ bool ttypull(struct tty *tp) { /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ if (tp->t_outq.c_cc <= tp->t_lowat) { cv_broadcast(&tp->t_outcv); selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); } return tp->t_outq.c_cc != 0; } /* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */ bool ttypull(struct tty *tp) { /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ if (tp->t_outq.c_cc <= tp->t_lowat) { cv_broadcast(&tp->t_outcv); selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); } return tp->t_outq.c_cc != 0; } /* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */ bool ttypull(struct tty *tp) { /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ if (tp->t_outq.c_cc <= tp->t_lowat) { cv_broadcast(&tp->t_outcv); selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); } return tp->t_outq.c_cc != 0; }
  • 9. comstart() #2comstart() #2comstart() #2comstart() #2comstart() #2 /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1;
  • 10. ndqb()ndqb()ndqb()ndqb()ndqb() /* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */ int ndqb(struct clist *clp, int flag) { int count = 0; int i; int cc; int s; s = spltty(); if ((cc = clp->c_cc) == 0) goto out; // --snip-- out: splx(s); return count; } /* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */ int ndqb(struct clist *clp, int flag) { int count = 0; int i; int cc; int s; s = spltty(); if ((cc = clp->c_cc) == 0) goto out; // --snip-- out: splx(s); return count; } /* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */ int ndqb(struct clist *clp, int flag) { int count = 0; int i; int cc; int s; s = spltty(); if ((cc = clp->c_cc) == 0) goto out; // --snip-- out: splx(s); return count; } /* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */ int ndqb(struct clist *clp, int flag) { int count = 0; int i; int cc; int s; s = spltty(); if ((cc = clp->c_cc) == 0) goto out; // --snip-- out: splx(s); return count; } /* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */ int ndqb(struct clist *clp, int flag) { int count = 0; int i; int cc; int s; s = spltty(); if ((cc = clp->c_cc) == 0) goto out; // --snip-- out: splx(s); return count; }
  • 11. struct cliststruct cliststruct cliststruct cliststruct clist /* * Clists are actually ring buffers. The c_cc, c_cf, c_cl fields have * exactly the same behaviour as in true clists. * if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality * (but, saves memory and CPU time) * * *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside tty_subr.c!!! */ struct clist { u_char *c_cf; /* points to first character */ u_char *c_cl; /* points to next open character */ u_char *c_cs; /* start of ring buffer */ u_char *c_ce; /* c_ce + c_len */ u_char *c_cq; /* N bits/bytes long, see tty_subr.c */ int c_cc; /* count of characters in queue */ int c_cn; /* total ring buffer length */ }; /* * Clists are actually ring buffers. The c_cc, c_cf, c_cl fields have * exactly the same behaviour as in true clists. * if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality * (but, saves memory and CPU time) * * *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside tty_subr.c!!! */ struct clist { u_char *c_cf; /* points to first character */ u_char *c_cl; /* points to next open character */ u_char *c_cs; /* start of ring buffer */ u_char *c_ce; /* c_ce + c_len */ u_char *c_cq; /* N bits/bytes long, see tty_subr.c */ int c_cc; /* count of characters in queue */ int c_cn; /* total ring buffer length */ }; /* * Clists are actually ring buffers. The c_cc, c_cf, c_cl fields have * exactly the same behaviour as in true clists. * if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality * (but, saves memory and CPU time) * * *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside tty_subr.c!!! */ struct clist { u_char *c_cf; /* points to first character */ u_char *c_cl; /* points to next open character */ u_char *c_cs; /* start of ring buffer */ u_char *c_ce; /* c_ce + c_len */ u_char *c_cq; /* N bits/bytes long, see tty_subr.c */ int c_cc; /* count of characters in queue */ int c_cn; /* total ring buffer length */ }; /* * Clists are actually ring buffers. The c_cc, c_cf, c_cl fields have * exactly the same behaviour as in true clists. * if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality * (but, saves memory and CPU time) * * *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside tty_subr.c!!! */ struct clist { u_char *c_cf; /* points to first character */ u_char *c_cl; /* points to next open character */ u_char *c_cs; /* start of ring buffer */ u_char *c_ce; /* c_ce + c_len */ u_char *c_cq; /* N bits/bytes long, see tty_subr.c */ int c_cc; /* count of characters in queue */ int c_cn; /* total ring buffer length */ }; /* * Clists are actually ring buffers. The c_cc, c_cf, c_cl fields have * exactly the same behaviour as in true clists. * if c_cq is NULL, the ring buffer has no TTY_QUOTE functionality * (but, saves memory and CPU time) * * *DON'T* play with c_cs, c_ce, c_cq, or c_cl outside tty_subr.c!!! */ struct clist { u_char *c_cf; /* points to first character */ u_char *c_cl; /* points to next open character */ u_char *c_cs; /* start of ring buffer */ u_char *c_ce; /* c_ce + c_len */ u_char *c_cq; /* N bits/bytes long, see tty_subr.c */ int c_cc; /* count of characters in queue */ int c_cn; /* total ring buffer length */ };
  • 12. struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)
  • 13. comstart() #3comstart() #3comstart() #3comstart() #3comstart() #3 /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) { u_int n; n = sc->sc_tbc; if (n > sc->sc_fifolen) n = sc->sc_fifolen; CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n); sc->sc_tbc -= n; sc->sc_tba += n; } mutex_spin_exit(&sc->sc_lock); out: splx(s); return; } /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) { u_int n; n = sc->sc_tbc; if (n > sc->sc_fifolen) n = sc->sc_fifolen; CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n); sc->sc_tbc -= n; sc->sc_tba += n; } mutex_spin_exit(&sc->sc_lock); out: splx(s); return; } /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) { u_int n; n = sc->sc_tbc; if (n > sc->sc_fifolen) n = sc->sc_fifolen; CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n); sc->sc_tbc -= n; sc->sc_tba += n; } mutex_spin_exit(&sc->sc_lock); out: splx(s); return; } /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) { u_int n; n = sc->sc_tbc; if (n > sc->sc_fifolen) n = sc->sc_fifolen; CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n); sc->sc_tbc -= n; sc->sc_tba += n; } mutex_spin_exit(&sc->sc_lock); out: splx(s); return; } /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) { u_int n; n = sc->sc_tbc; if (n > sc->sc_fifolen) n = sc->sc_fifolen; CSR_WRITE_MULTI(regsp,COM_REG_TXDATA,sc->sc_tba,n); sc->sc_tbc -= n; sc->sc_tba += n; } mutex_spin_exit(&sc->sc_lock); out: splx(s); return; }
  • 14. clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)clist to serial port (figure)
  • 15. CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*()CSR_WRITE_*() // arch/i386/compile/GENERIC/opt_com.h: // /* option `COM_REGMAP' not defined */ #define CSR_WRITE_1(r, o, v) bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v) #define CSR_WRITE_MULTI(r, o, p, n) bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n) #define COM_REG_IER com_ier #define COM_REG_TXDATA com_data // arch/i386/compile/GENERIC/opt_com.h: // /* option `COM_REGMAP' not defined */ #define CSR_WRITE_1(r, o, v) bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v) #define CSR_WRITE_MULTI(r, o, p, n) bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n) #define COM_REG_IER com_ier #define COM_REG_TXDATA com_data // arch/i386/compile/GENERIC/opt_com.h: // /* option `COM_REGMAP' not defined */ #define CSR_WRITE_1(r, o, v) bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v) #define CSR_WRITE_MULTI(r, o, p, n) bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n) #define COM_REG_IER com_ier #define COM_REG_TXDATA com_data // arch/i386/compile/GENERIC/opt_com.h: // /* option `COM_REGMAP' not defined */ #define CSR_WRITE_1(r, o, v) bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v) #define CSR_WRITE_MULTI(r, o, p, n) bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n) #define COM_REG_IER com_ier #define COM_REG_TXDATA com_data // arch/i386/compile/GENERIC/opt_com.h: // /* option `COM_REGMAP' not defined */ #define CSR_WRITE_1(r, o, v) bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v) #define CSR_WRITE_MULTI(r, o, p, n) bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, o, p, n) #define COM_REG_IER com_ier #define COM_REG_TXDATA com_data // com.c // = include => dev/ic/comreg.h // = include => dev/ic/ns16550reg.h #define com_data 0 /* data register (R/W) */ #define com_ier 1 /* interrupt enable (W) */ // com.c // = include => dev/ic/comreg.h // = include => dev/ic/ns16550reg.h #define com_data 0 /* data register (R/W) */ #define com_ier 1 /* interrupt enable (W) */ // com.c // = include => dev/ic/comreg.h // = include => dev/ic/ns16550reg.h #define com_data 0 /* data register (R/W) */ #define com_ier 1 /* interrupt enable (W) */ // com.c // = include => dev/ic/comreg.h // = include => dev/ic/ns16550reg.h #define com_data 0 /* data register (R/W) */ #define com_ier 1 /* interrupt enable (W) */ // com.c // = include => dev/ic/comreg.h // = include => dev/ic/ns16550reg.h #define com_data 0 /* data register (R/W) */ #define com_ier 1 /* interrupt enable (W) */ The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.The com_data address should be 0x3f8.
  • 16. bus_space_map()bus_space_map()bus_space_map()bus_space_map()bus_space_map() int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- regs.cr_iot = iot; regs.cr_iobase = iobase; regs.cr_nports = COM_NPORTS; return comcnattach1(&regs, rate, frequency, type, cflag); // --snip-- int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- comcons_info.regs = *regsp; res = cominit(&comcons_info.regs, rate, frequency, type, cflag); // --snip-- int cominit(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp- >cr_nports, 0, &regsp->cr_ioh)) int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- regs.cr_iot = iot; regs.cr_iobase = iobase; regs.cr_nports = COM_NPORTS; return comcnattach1(&regs, rate, frequency, type, cflag); // --snip-- int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- comcons_info.regs = *regsp; res = cominit(&comcons_info.regs, rate, frequency, type, cflag); // --snip-- int cominit(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp- >cr_nports, 0, &regsp->cr_ioh)) int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- regs.cr_iot = iot; regs.cr_iobase = iobase; regs.cr_nports = COM_NPORTS; return comcnattach1(&regs, rate, frequency, type, cflag); // --snip-- int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- comcons_info.regs = *regsp; res = cominit(&comcons_info.regs, rate, frequency, type, cflag); // --snip-- int cominit(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp- >cr_nports, 0, &regsp->cr_ioh)) int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- regs.cr_iot = iot; regs.cr_iobase = iobase; regs.cr_nports = COM_NPORTS; return comcnattach1(&regs, rate, frequency, type, cflag); // --snip-- int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- comcons_info.regs = *regsp; res = cominit(&comcons_info.regs, rate, frequency, type, cflag); // --snip-- int cominit(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp- >cr_nports, 0, &regsp->cr_ioh)) int comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- regs.cr_iot = iot; regs.cr_iobase = iobase; regs.cr_nports = COM_NPORTS; return comcnattach1(&regs, rate, frequency, type, cflag); // --snip-- int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { // --snip-- comcons_info.regs = *regsp; res = cominit(&comcons_info.regs, rate, frequency, type, cflag); // --snip-- int cominit(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp- >cr_nports, 0, &regsp->cr_ioh))
  • 17. comcnattach() callercomcnattach() callercomcnattach() callercomcnattach() callercomcnattach() caller void consinit(void) { // --snip-- #if (NCOM > 0) if (!strcmp(consinfo->devname, "com")) { int addr = consinfo->addr; int speed = consinfo->speed; if (addr == 0) addr = CONADDR; // <= 0x3f8 if (speed == 0) speed = CONSPEED; if (comcnattach(x86_bus_space_io, addr, speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode)) panic("can't init serial console @%x", consinfo->addr); return; } #endif void consinit(void) { // --snip-- #if (NCOM > 0) if (!strcmp(consinfo->devname, "com")) { int addr = consinfo->addr; int speed = consinfo->speed; if (addr == 0) addr = CONADDR; // <= 0x3f8 if (speed == 0) speed = CONSPEED; if (comcnattach(x86_bus_space_io, addr, speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode)) panic("can't init serial console @%x", consinfo->addr); return; } #endif void consinit(void) { // --snip-- #if (NCOM > 0) if (!strcmp(consinfo->devname, "com")) { int addr = consinfo->addr; int speed = consinfo->speed; if (addr == 0) addr = CONADDR; // <= 0x3f8 if (speed == 0) speed = CONSPEED; if (comcnattach(x86_bus_space_io, addr, speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode)) panic("can't init serial console @%x", consinfo->addr); return; } #endif void consinit(void) { // --snip-- #if (NCOM > 0) if (!strcmp(consinfo->devname, "com")) { int addr = consinfo->addr; int speed = consinfo->speed; if (addr == 0) addr = CONADDR; // <= 0x3f8 if (speed == 0) speed = CONSPEED; if (comcnattach(x86_bus_space_io, addr, speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode)) panic("can't init serial console @%x", consinfo->addr); return; } #endif void consinit(void) { // --snip-- #if (NCOM > 0) if (!strcmp(consinfo->devname, "com")) { int addr = consinfo->addr; int speed = consinfo->speed; if (addr == 0) addr = CONADDR; // <= 0x3f8 if (speed == 0) speed = CONSPEED; if (comcnattach(x86_bus_space_io, addr, speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode)) panic("can't init serial console @%x", consinfo->addr); return; } #endif
  • 18. bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)