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

18
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 Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe

Upload: kiwamu-okabe

Post on 15-Jan-2015

146 views

Category:

Technology


0 download

DESCRIPTION

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

TRANSCRIPT

Page 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()

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

Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe

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

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.cvoidcom_attach_subr(struct com_softc *sc){// -- snip --fifodone:

tp = tty_alloc();tp->t_oproc = comstart;

// File: sys/dev/ic/com.cvoidcom_attach_subr(struct com_softc *sc){// -- snip --fifodone:

tp = tty_alloc();tp->t_oproc = comstart;

// File: sys/dev/ic/com.cvoidcom_attach_subr(struct com_softc *sc){// -- snip --fifodone:

tp = tty_alloc();tp->t_oproc = comstart;

// File: sys/dev/ic/com.cvoidcom_attach_subr(struct com_softc *sc){// -- snip --fifodone:

tp = tty_alloc();tp->t_oproc = comstart;

// File: sys/dev/ic/com.cvoidcom_attach_subr(struct com_softc *sc){// -- snip --fifodone:

tp = tty_alloc();tp->t_oproc = comstart;

Page 3: start_printf: dev/ic/com.c 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 com0com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isaattach com at isa with com_isafile dev/isa/com_isa.c com_isa

$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isaattach com at isa with com_isafile dev/isa/com_isa.c com_isa

$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isaattach com at isa with com_isafile dev/isa/com_isa.c com_isa

$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isaattach com at isa with com_isafile dev/isa/com_isa.c com_isa

$ grep 3f8 sys/arch/i386/conf/GENERIC | grep com0com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports$ grep -B 1 dev/isa/com_isa.c sys/dev/isa/files.isaattach com at isa with com_isafile dev/isa/com_isa.c com_isa

// File: sys/dev/isa/com_isa.cvoidcom_isa_attach(device_t parent, device_t self, void *aux){// -- snip --

com_attach_subr(sc);

// File: sys/dev/isa/com_isa.cvoidcom_isa_attach(device_t parent, device_t self, void *aux){// -- snip --

com_attach_subr(sc);

// File: sys/dev/isa/com_isa.cvoidcom_isa_attach(device_t parent, device_t self, void *aux){// -- snip --

com_attach_subr(sc);

// File: sys/dev/isa/com_isa.cvoidcom_isa_attach(device_t parent, device_t self, void *aux){// -- snip --

com_attach_subr(sc);

// File: sys/dev/isa/com_isa.cvoidcom_isa_attach(device_t parent, device_t self, void *aux){// -- snip --

com_attach_subr(sc);

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

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.cvoidcom_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.cvoidcom_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.cvoidcom_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.cvoidcom_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.cvoidcom_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.hstruct com_softc {

device_t sc_dev;void *sc_si;struct tty *sc_tty;

// File: sys/dev/ic/comvar.hstruct com_softc {

device_t sc_dev;void *sc_si;struct tty *sc_tty;

// File: sys/dev/ic/comvar.hstruct com_softc {

device_t sc_dev;void *sc_si;struct tty *sc_tty;

// File: sys/dev/ic/comvar.hstruct com_softc {

device_t sc_dev;void *sc_si;struct tty *sc_tty;

// File: sys/dev/ic/comvar.hstruct com_softc {

device_t sc_dev;void *sc_si;struct tty *sc_tty;

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

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

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

comwrite()comwrite()comwrite()comwrite()comwrite()#define COM_ISALIVE(sc) ((sc)->enabled != 0 && \

device_is_active((sc)->sc_dev))

intcomwrite(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))

intcomwrite(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))

intcomwrite(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))

intcomwrite(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))

intcomwrite(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));}

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

comstart() #1comstart() #1comstart() #1comstart() #1comstart() #1voidcomstart(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;

voidcomstart(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;

voidcomstart(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;

voidcomstart(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;

voidcomstart(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;

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

ttypull()ttypull()ttypull()ttypull()ttypull()/* * Try to pull more output from the producer. Return non-zero if * there is output ready to be sent. */boolttypull(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. */boolttypull(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. */boolttypull(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. */boolttypull(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. */boolttypull(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;

}

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

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;

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

ndqb()ndqb()ndqb()ndqb()ndqb()/* * Return count of contiguous characters in clist. * Stop counting if flag&character is non-null. */intndqb(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. */intndqb(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. */intndqb(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. */intndqb(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. */intndqb(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;

}

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

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 */

};

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

struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)struct clist (figure)

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

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;

}

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

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)

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

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.

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

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, inttype, tcflag_t cflag){

if (bus_space_map(regsp->cr_iot, regsp->cr_iobase, regsp->cr_nports, 0, &regsp->cr_ioh))

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

comcnattach() callercomcnattach() callercomcnattach() callercomcnattach() callercomcnattach() callervoidconsinit(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

voidconsinit(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

voidconsinit(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

voidconsinit(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

voidconsinit(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

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

bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)bus_space_map() (figure)