a5f7e00b9c5d550f055e80f75608205668cba412
/* cons.c 1.3 86/11/03 */
/* Minor device 0 is the CP itself.
/* No real read/writes can be done to him.
/* Minor 1 is the console terminal.
/* Minor 2 is the remote line trminal.
* Tahoe console processor driver
#include "../tahoe/cpu.h"
#include "../tahoe/mtpr.h"
struct tty
*constty
[3] = { &CPtty
, &cons
, &RLtty
};
char cs_lastc
; /* last char sent */
#define CSF_ACTIVE 0x1 /* timeout active */
#define CSF_RETRY 0x2 /* try again at a later time */
struct cpdcb_o consout
[3] = {
/* unit, cmd,count, buf */
{ (char)(CPTAKE
| CPDONE
),0, 0 },
{ (char)(CPTAKE
| CPDONE
),0, 0 },
{ (char)(CPTAKE
| CPDONE
),0, 0 }
struct cpdcb_i consin
[3] = {
/* unit, cmd,count, buf */
{ (char)(CPTAKE
| CPDONE
),0, 0 },
{ (char)(CPTAKE
| CPDONE
),0, 0 },
{ (char)(CPTAKE
| CPDONE
),0, 0 }
register struct cpdcb_i
*cin
;
if (tp
->t_state
&TS_XCLUDE
&& u
.u_uid
!= 0)
if (lasthdr
!= (struct cphdr
*)0) {
uncache(&lasthdr
->cp_unit
);
while ((lasthdr
->cp_unit
&CPTAKE
) == 0 && --timo
)
uncache(&lasthdr
->cp_unit
);
cin
->cp_hdr
.cp_unit
= unit
;
cin
->cp_hdr
.cp_comm
= CPREAD
;
cin
->cp_hdr
.cp_count
= 1; /* Get ready for input */
lasthdr
= (struct cphdr
*)cin
;
if ((tp
->t_state
&TS_ISOPEN
) == 0) {
tp
->t_state
= TS_ISOPEN
|TS_CARR_ON
;
tp
->t_flags
= EVENP
|ECHO
|XTABS
|CRMOD
;
return ((*linesw
[tp
->t_line
].l_open
)(dev
, tp
));
register struct tty
*tp
= constty
[minor(dev
)];
(*linesw
[tp
->t_line
].l_close
)(tp
);
struct tty
*tp
= constty
[minor(dev
)];
return ((*linesw
[tp
->t_line
].l_read
)(tp
, uio
));
struct tty
*tp
= constty
[minor(dev
)];
return ((*linesw
[tp
->t_line
].l_write
)(tp
, uio
));
* Got a console receive interrupt -
* the console processor wants to give us a character.
* Catch the character, and see who it goes to.
/* make sure we dont take it from cache */
uncache(&consin
[unit
].cpi_buf
[0]);
c
= consin
[unit
].cpi_buf
[0];
/* Wait about 5 milli for last CPMDCB to be read by CP,
uncache(&lasthdr
->cp_unit
);
while ((lasthdr
->cp_unit
&CPTAKE
) == 0 && --timo
)
uncache(&lasthdr
->cp_unit
);
uncache(&lasthdr
->cp_unit
);
if (lasthdr
->cp_unit
&CPTAKE
) {
consin
[unit
].cp_hdr
.cp_unit
= unit
;
/* This resets status bits */
mtpr(CPMDCB
, &consin
[unit
]); /* Ready for new character */
lasthdr
= (struct cphdr
*)&consin
[unit
];
(*linesw
[tp
->t_line
].l_rint
)(c
, tp
);
cnioctl(dev
, cmd
, addr
, flag
)
register struct tty
*tp
= constty
[minor(dev
)];
error
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, addr
);
if ((error
= ttioctl(tp
, cmd
, addr
, flag
)) < 0)
else if (cmd
== TIOCSETP
|| cmd
== TIOCSETN
)
* Got a console transmission interrupt -
* the console processor wants another character.
if (intenable
== 0 || consintr
== 0)
scope_in(unit
== CPCONS
? 1 : 2);
consoftc
[unit
].cs_lastc
= (char)0;
(*linesw
[tp
->t_line
].l_start
)(tp
);
scope_in(minor(tp
->t_dev
) == CPCONS
? 3 : 4);
if (tp
->t_state
& (TS_TIMEOUT
|TS_BUSY
|TS_TTSTOP
))
if (tp
->t_outq
.c_cc
<= TTLOWAT(tp
)) {
if (tp
->t_state
&TS_ASLEEP
) {
tp
->t_state
&= ~TS_ASLEEP
;
wakeup((caddr_t
)&tp
->t_outq
);
selwakeup(tp
->t_wsel
, tp
->t_state
& TS_WCOLL
);
tp
->t_state
&= ~TS_WCOLL
;
if (tp
->t_outq
.c_cc
== 0)
c
= getc(&tp
->t_outq
) & 0xff;
if (tp
->t_flags
&(RAW
|LITOUT
))
cnputchar((c
| (partab
[c
]&0200))&0xff, tp
);
timeout(ttrstrt
, (caddr_t
)tp
, (c
&0177));
tp
->t_state
|= TS_TIMEOUT
;
cnputchar('\r', (struct tty
*)0);
cnputchar(c
, (struct tty
*)0);
* Print a character on console.
register struct cpdcb_o
*current
;
/* tp == 0 only in system error messages */
current
= &consout
[CPCONS
];
if (lasthdr
== 0) /* not done anythig yet */
lasthdr
= (struct cphdr
*)current
;
c
|= partab
[c
&0177]&0200;
current
= &consout
[minor(tp
->t_dev
)];
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
* make sure we dont test this bit in cache!
uncache(¤t
->cp_hdr
.cp_unit
);
while ((current
->cp_hdr
.cp_unit
&CPDONE
) == 0 && --timo
)
uncache(¤t
->cp_hdr
.cp_unit
);
current
->cp_hdr
.cp_comm
= CPWRITE
;
current
->cp_hdr
.cp_count
= 1;
current
->cp_buf
[0] = c
& 0xff;
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
uncache(&lasthdr
->cp_unit
);
while ((lasthdr
->cp_unit
&CPTAKE
) == 0 && --timo
)
uncache(&lasthdr
->cp_unit
);
current
->cp_hdr
.cp_unit
= (char)unit
;
lasthdr
= (struct cphdr
*)current
;
consoftc
[unit
].cs_lastc
= c
;
if ((consoftc
[unit
].cs_flags
&CSF_ACTIVE
) == 0 && clk_enable
) {
consoftc
[unit
].cs_flags
|= CSF_ACTIVE
;
timeout(cnrestart
, (caddr_t
)tp
, 10);
consoftc
[unit
].cs_flags
|= CSF_RETRY
; /* wait some more */
* Restart (if necessary) transfer to CP line.
* This way, lost 'transmit' interrupts don't break the chain.
register struct consoftc
*cs
;
cs
= &consoftc
[tp
== 0 ? CPCONS
: minor(tp
->t_dev
)];
if (cs
->cs_flags
&CSF_RETRY
) {
cs
->cs_flags
&= ~CSF_RETRY
;
timeout(cnrestart
, (caddr_t
)tp
, 10);
cs
->cs_flags
&= ~CSF_ACTIVE
;
if (cs
->cs_lastc
!= (char)0)
cnputchar(cs
->cs_lastc
, tp
);
register struct cpdcb_o
*current
;
register struct cpdcb_i
*cin
;
current
= &consout
[minor(tp
->t_dev
)];
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
* make sure we dont test this bit in cache!
uncache(¤t
->cp_hdr
.cp_unit
);
while ((current
->cp_hdr
.cp_unit
&CPDONE
) == 0 && --timo
)
uncache(¤t
->cp_hdr
.cp_unit
);
current
->cp_hdr
.cp_comm
= CPSTTY
;
current
->cp_hdr
.cp_count
= 4;
current
->cp_buf
[0] = tp
->t_ispeed
;
/* the rest are defaults */
current
->cp_buf
[1] = 0; /* no parity */
current
->cp_buf
[2] = 0; /* stop bits */
current
->cp_buf
[3] = 8; /* data bits */
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
uncache(&lasthdr
->cp_unit
);
while ((lasthdr
->cp_unit
&CPTAKE
) == 0 && --timo
)
uncache(&lasthdr
->cp_unit
);
current
->cp_hdr
.cp_unit
= (char)minor(tp
->t_dev
);
lasthdr
= (struct cphdr
*)current
;
uncache(&lasthdr
->cp_unit
);
while ((lasthdr
->cp_unit
&CPTAKE
) == 0 && --timo
)
uncache(&lasthdr
->cp_unit
);
cin
= &consin
[minor(tp
->t_dev
)];
cin
->cp_hdr
.cp_unit
= minor(tp
->t_dev
);
cin
->cp_hdr
.cp_comm
= CPREAD
;
cin
->cp_hdr
.cp_count
= 1; /* Get ready for input */
lasthdr
= (struct cphdr
*)cin
;