mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 05:58:57 +00:00
MFC: Supported i8251 (internal COM1) FIFO mode.
Approved by: Jordan K. Hubbard
This commit is contained in:
parent
5fb6b10971
commit
080b5dd65d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/3/; revision=54183
@ -31,6 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ns16550.h 7.1 (Berkeley) 5/9/91
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -38,6 +39,10 @@
|
||||
* Kyoto University Microcomputer Club (KMC)
|
||||
*/
|
||||
|
||||
/*
|
||||
* modified for 8251(FIFO) by Seigo TANIMURA <tanimura@FreeBSD.org>
|
||||
*/
|
||||
|
||||
/* define command and status code */
|
||||
#define CMD8251_TxEN 0x01 /* transmit enable */
|
||||
#define CMD8251_DTR 0x02 /* assert DTR */
|
||||
@ -57,6 +62,26 @@
|
||||
#define STS8251_BD_SD 0x40 /* break detect (async) / sync detect (sync) */
|
||||
#define STS8251_DSR 0x80 /* DSR is asserted */
|
||||
|
||||
#define STS8251F_TxEMP 0x01 /* transmit buffer EMPTY */
|
||||
#define STS8251F_TxRDY 0x02 /* transmit READY */
|
||||
#define STS8251F_RxRDY 0x04 /* data exists in receive buffer */
|
||||
#define STS8251F_OE 0x10 /* overrun error */
|
||||
#define STS8251F_PE 0x20 /* perity error */
|
||||
#define STS8251F_BD_SD 0x80 /* break detect (async) / sync detect (sync) */
|
||||
|
||||
#define INTR8251F_DTCT 0x60 /* FIFO detection mask */
|
||||
#define INTR8251F_INTRV 0x0e /* interrupt event */
|
||||
#define INTR8251F_TO 0x0c /* receive timeout */
|
||||
#define INTR8251F_LSTS 0x06 /* line status */
|
||||
#define INTR8251F_RxRDY 0x04 /* receive READY */
|
||||
#define INTR8251F_TxRDY 0x02 /* transmit READY */
|
||||
#define INTR8251F_ISEV 0x01 /* event occured */
|
||||
#define INTR8251F_MSTS 0x00 /* modem status */
|
||||
|
||||
#define CTRL8251F_ENABLE 0x01 /* enable FIFO */
|
||||
#define CTRL8251F_RCV_RST 0x02 /* reset receive FIFO */
|
||||
#define CTRL8251F_XMT_RST 0x04 /* reset transmit FIFO */
|
||||
|
||||
#define MOD8251_5BITS 0x00
|
||||
#define MOD8251_6BITS 0x04
|
||||
#define MOD8251_7BITS 0x08
|
||||
@ -69,9 +94,14 @@
|
||||
#define MOD8251_CLKX16 0x02 /* x16 */
|
||||
#define MOD8251_CLKX1 0x01 /* x1 */
|
||||
|
||||
#define CICSCD_CI 0x80 /* CI */
|
||||
#define CICSCD_CS 0x40 /* CS */
|
||||
#define CICSCD_CD 0x20 /* CD */
|
||||
#define CICSCD_CS 0x40 /* CS */
|
||||
#define CICSCD_CI 0x80 /* CI */
|
||||
|
||||
#define CICSCDF_CS 0x10 /* CS */
|
||||
#define CICSCDF_DR 0x20 /* DR */
|
||||
#define CICSCDF_CI 0x40 /* CI */
|
||||
#define CICSCDF_CD 0x80 /* CD */
|
||||
|
||||
/* interrupt mask control */
|
||||
#define IEN_Rx 0x01
|
||||
|
@ -110,6 +110,9 @@
|
||||
/*
|
||||
* Modified by Y.Takahashi of Kogakuin University.
|
||||
*/
|
||||
/*
|
||||
* modified for 8251(FIFO) by Seigo TANIMURA <tanimura@FreeBSD.org>
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#define COM_IF_INTERNAL 0x00
|
||||
@ -363,6 +366,9 @@ struct com_s {
|
||||
int pc98_prev_siomod;
|
||||
int modem_checking;
|
||||
int pc98_if_type;
|
||||
|
||||
bool_t pc98_8251fifo;
|
||||
bool_t pc98_8251fifo_enable;
|
||||
#endif /* PC98 */
|
||||
Port_t data_port; /* i/o ports */
|
||||
#ifdef COM_ESP
|
||||
@ -542,8 +548,10 @@ static void pc98_i8251_or_cmd __P((struct com_s *com, int x));
|
||||
static void pc98_i8251_clear_cmd __P((struct com_s *com, int x));
|
||||
static void pc98_i8251_clear_or_cmd __P((struct com_s *com, int clr, int x));
|
||||
static int pc98_check_if_type __P((struct isa_device *dev, struct siodev *iod));
|
||||
static int pc98_check_8251vfast __P((void));
|
||||
static int pc98_check_8251fifo __P((void));
|
||||
static void pc98_check_sysclock __P((void));
|
||||
static int pc98_set_ioport __P((struct com_s *com, int id_flags));
|
||||
static int pc98_set_ioport __P((struct com_s *com));
|
||||
|
||||
#define com_int_Tx_disable(com) \
|
||||
pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP)
|
||||
@ -747,6 +755,14 @@ struct {
|
||||
#define PC98SIO_baud_rate_port(type) (if_8251_type[type].port_table[5])
|
||||
#define PC98SIO_func_port(type) (if_8251_type[type].port_table[6])
|
||||
|
||||
#define I8251F_data 0x130
|
||||
#define I8251F_lsr 0x132
|
||||
#define I8251F_msr 0x134
|
||||
#define I8251F_iir 0x136
|
||||
#define I8251F_fcr 0x138
|
||||
#define I8251F_div 0x13a
|
||||
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
short irr_read;
|
||||
@ -1571,9 +1587,11 @@ sioattach(isdp)
|
||||
|
||||
com->iobase = iobase;
|
||||
#ifdef PC98
|
||||
if (pc98_set_ioport(com, isdp->id_flags) == -1) {
|
||||
com->pc98_if_type = (isdp->id_flags >> 24) & 0xff;
|
||||
com->pc98_if_type = (isdp->id_flags >> 24) & 0xff;
|
||||
|
||||
if (pc98_set_ioport(com) == -1) {
|
||||
port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
|
||||
|
||||
com->data_port = iobase + (com_data << port_shift);
|
||||
com->int_id_port = iobase + (com_iir << port_shift);
|
||||
com->modem_ctl_port = iobase + (com_mcr << port_shift);
|
||||
@ -1582,6 +1600,10 @@ sioattach(isdp)
|
||||
com->modem_status_port = iobase + (com_msr << port_shift);
|
||||
com->intr_ctl_port = iobase + (com_ier << port_shift);
|
||||
}
|
||||
if (com->pc98_if_type == COM_IF_INTERNAL && pc98_check_8251fifo()) {
|
||||
com->pc98_8251fifo = 1;
|
||||
com->pc98_8251fifo_enable = 0;
|
||||
}
|
||||
#else /* not PC98 */
|
||||
com->data_port = iobase + com_data;
|
||||
com->int_id_port = iobase + com_iir;
|
||||
@ -1649,11 +1671,21 @@ sioattach(isdp)
|
||||
#endif /* !PC98 */
|
||||
#ifdef PC98
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
if (com->pc98_8251fifo && !COM_NOFIFO(isdp))
|
||||
com->tx_fifo_size = 16;
|
||||
com_int_TxRx_disable( com );
|
||||
com_cflag_and_speed_set( com, com->it_in.c_cflag, comdefaultrate );
|
||||
com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
|
||||
com_send_break_off( com );
|
||||
printf(" 8251%s", if_8251_type[com->pc98_if_type & 0x0f].name);
|
||||
|
||||
if (com->pc98_if_type == COM_IF_INTERNAL) {
|
||||
printf(" (internal%s%s)",
|
||||
com->pc98_8251fifo ? " fifo" : "",
|
||||
PC98SIO_baud_rate_port(com->pc98_if_type) != -1 ?
|
||||
" v-fast" : "");
|
||||
} else {
|
||||
printf(" 8251%s", if_8251_type[com->pc98_if_type & 0x0f].name);
|
||||
}
|
||||
} else {
|
||||
outb(iobase + (com_fifo << port_shift), FIFO_ENABLE | FIFO_RX_HIGH);
|
||||
#else
|
||||
@ -1958,6 +1990,11 @@ open_top:
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS);
|
||||
pc98_msrint_start(dev);
|
||||
if (com->pc98_8251fifo) {
|
||||
com->pc98_8251fifo_enable = 1;
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE |
|
||||
CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
@ -2222,6 +2259,13 @@ comhardclose(com)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef PC98
|
||||
if (com->pc98_8251fifo) {
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
|
||||
com->pc98_8251fifo_enable = 0;
|
||||
}
|
||||
#endif
|
||||
if (com->hasfifo) {
|
||||
/*
|
||||
* Disable fifos so that they are off after controlled
|
||||
@ -2310,11 +2354,15 @@ siobusycheck(chan)
|
||||
if (com->state & CS_BUSY)
|
||||
com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */
|
||||
#ifdef PC98
|
||||
else if (IS_8251(com->pc98_if_type) &&
|
||||
(inb(com->sts_port) & (STS8251_TxRDY | STS8251_TxEMP))
|
||||
== (STS8251_TxRDY | STS8251_TxEMP) ||
|
||||
(inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
|
||||
== (LSR_TSRE | LSR_TXRDY)) {
|
||||
else if ((IS_8251(com->pc98_if_type) &&
|
||||
((com->pc98_8251fifo_enable &&
|
||||
(inb(I8251F_lsr) & (STS8251F_TxRDY | STS8251F_TxEMP))
|
||||
== (STS8251F_TxRDY | STS8251F_TxEMP)) ||
|
||||
(!com->pc98_8251fifo_enable &&
|
||||
(inb(com->sts_port) & (STS8251_TxRDY | STS8251_TxEMP))
|
||||
== (STS8251_TxRDY | STS8251_TxEMP)))) ||
|
||||
((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
|
||||
== (LSR_TSRE | LSR_TXRDY))) {
|
||||
#else
|
||||
else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
|
||||
== (LSR_TSRE | LSR_TXRDY)) {
|
||||
@ -2431,16 +2479,28 @@ siointr1(com)
|
||||
#ifdef PC98
|
||||
status_read:;
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
tmp = inb(com->sts_port);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
tmp = inb(I8251F_lsr);
|
||||
else
|
||||
tmp = inb(com->sts_port);
|
||||
more_intr:
|
||||
line_status = 0;
|
||||
if (tmp & STS8251_TxRDY) line_status |= LSR_TXRDY;
|
||||
if (tmp & STS8251_RxRDY) line_status |= LSR_RXRDY;
|
||||
if (tmp & STS8251_TxEMP) line_status |= LSR_TSRE;
|
||||
if (tmp & STS8251_PE) line_status |= LSR_PE;
|
||||
if (tmp & STS8251_OE) line_status |= LSR_OE;
|
||||
if (tmp & STS8251_FE) line_status |= LSR_FE;
|
||||
if (tmp & STS8251_BD_SD) line_status |= LSR_BI;
|
||||
if (com->pc98_8251fifo_enable) {
|
||||
if (tmp & STS8251F_TxRDY) line_status |= LSR_TXRDY;
|
||||
if (tmp & STS8251F_RxRDY) line_status |= LSR_RXRDY;
|
||||
if (tmp & STS8251F_TxEMP) line_status |= LSR_TSRE;
|
||||
if (tmp & STS8251F_PE) line_status |= LSR_PE;
|
||||
if (tmp & STS8251F_OE) line_status |= LSR_OE;
|
||||
if (tmp & STS8251F_BD_SD) line_status |= LSR_BI;
|
||||
} else {
|
||||
if (tmp & STS8251_TxRDY) line_status |= LSR_TXRDY;
|
||||
if (tmp & STS8251_RxRDY) line_status |= LSR_RXRDY;
|
||||
if (tmp & STS8251_TxEMP) line_status |= LSR_TSRE;
|
||||
if (tmp & STS8251_PE) line_status |= LSR_PE;
|
||||
if (tmp & STS8251_OE) line_status |= LSR_OE;
|
||||
if (tmp & STS8251_FE) line_status |= LSR_FE;
|
||||
if (tmp & STS8251_BD_SD) line_status |= LSR_BI;
|
||||
}
|
||||
} else {
|
||||
#endif /* PC98 */
|
||||
if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
|
||||
@ -2471,10 +2531,20 @@ more_intr:
|
||||
/* break/unnattached error bits or real input? */
|
||||
#ifdef PC98
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
recv_data = inb(com->data_port);
|
||||
if (tmp & 0x78) {
|
||||
pc98_i8251_or_cmd(com,CMD8251_ER);
|
||||
if (com->pc98_8251fifo_enable) {
|
||||
recv_data = inb(I8251F_data);
|
||||
if (tmp & (STS8251F_PE | STS8251F_OE |
|
||||
STS8251F_BD_SD)) {
|
||||
pc98_i8251_or_cmd(com, CMD8251_ER);
|
||||
recv_data = 0;
|
||||
}
|
||||
} else {
|
||||
recv_data = inb(com->data_port);
|
||||
if (tmp & (STS8251_PE | STS8251_OE |
|
||||
STS8251_FE | STS8251_BD_SD)) {
|
||||
pc98_i8251_or_cmd(com, CMD8251_ER);
|
||||
recv_data = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#endif /* PC98 */
|
||||
@ -2624,6 +2694,16 @@ cont:
|
||||
: (line_status & LSR_TXRDY))
|
||||
&& com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
||||
#endif
|
||||
#ifdef PC98
|
||||
Port_t tmp_data_port;
|
||||
|
||||
if (IS_8251(com->pc98_if_type) &&
|
||||
com->pc98_8251fifo_enable)
|
||||
tmp_data_port = I8251F_data;
|
||||
else
|
||||
tmp_data_port = com->data_port;
|
||||
#endif
|
||||
|
||||
ioptr = com->obufq.l_head;
|
||||
if (com->tx_fifo_size > 1) {
|
||||
u_int ocount;
|
||||
@ -2634,19 +2714,27 @@ cont:
|
||||
rsa_buf_status = inb(com->rsabase + rsa_srr);
|
||||
rsa_tx_fifo_size = 1024;
|
||||
if (!(rsa_buf_status & 0x01))
|
||||
rsa_tx_fifo_size = 2048;
|
||||
rsa_tx_fifo_size = 2048;
|
||||
if (ocount > rsa_tx_fifo_size)
|
||||
ocount = rsa_tx_fifo_size;
|
||||
ocount = rsa_tx_fifo_size;
|
||||
} else
|
||||
#endif
|
||||
if (ocount > com->tx_fifo_size)
|
||||
ocount = com->tx_fifo_size;
|
||||
com->bytes_out += ocount;
|
||||
do
|
||||
#ifdef PC98
|
||||
outb(tmp_data_port, *ioptr++);
|
||||
#else
|
||||
outb(com->data_port, *ioptr++);
|
||||
#endif
|
||||
while (--ocount != 0);
|
||||
} else {
|
||||
#ifdef PC98
|
||||
outb(tmp_data_port, *ioptr++);
|
||||
#else
|
||||
outb(com->data_port, *ioptr++);
|
||||
#endif
|
||||
++com->bytes_out;
|
||||
}
|
||||
#ifdef PC98
|
||||
@ -2701,9 +2789,15 @@ cont:
|
||||
if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
|
||||
com_int_Tx_disable(com);
|
||||
}
|
||||
if (IS_8251(com->pc98_if_type))
|
||||
if ((tmp = inb(com->sts_port)) & STS8251_RxRDY)
|
||||
goto more_intr;
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
if (com->pc98_8251fifo_enable) {
|
||||
if ((tmp = inb(I8251F_lsr)) & STS8251F_RxRDY)
|
||||
goto more_intr;
|
||||
} else {
|
||||
if ((tmp = inb(com->sts_port)) & STS8251_RxRDY)
|
||||
goto more_intr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* finished? */
|
||||
@ -3147,8 +3241,6 @@ comparam(tp, t)
|
||||
int s;
|
||||
int unit;
|
||||
#ifdef PC98
|
||||
Port_t tmp_port;
|
||||
int tmp_flg;
|
||||
int port_shift = 0;
|
||||
u_char param = 0;
|
||||
#endif
|
||||
@ -4276,22 +4368,38 @@ com_tiocm_get_delta(struct com_s *com)
|
||||
static int
|
||||
pc98_get_modem_status(struct com_s *com)
|
||||
{
|
||||
int stat, stat2;
|
||||
register int msr;
|
||||
|
||||
stat = inb(com->sts_port);
|
||||
stat2 = inb(com->in_modem_port);
|
||||
msr = com->pc98_prev_modem_status
|
||||
& ~(TIOCM_CAR|TIOCM_RI|TIOCM_DSR|TIOCM_CTS);
|
||||
if ( !(stat2 & CICSCD_CD) ) msr |= TIOCM_CAR;
|
||||
if ( !(stat2 & CICSCD_CI) ) msr |= TIOCM_RI;
|
||||
if ( stat & STS8251_DSR ) msr |= TIOCM_DSR;
|
||||
if ( !(stat2 & CICSCD_CS) ) msr |= TIOCM_CTS;
|
||||
if (com->pc98_8251fifo_enable) {
|
||||
int stat2;
|
||||
|
||||
stat2 = inb(I8251F_msr);
|
||||
if ( stat2 & CICSCDF_CD ) msr |= TIOCM_CAR;
|
||||
if ( stat2 & CICSCDF_CI ) msr |= TIOCM_RI;
|
||||
if ( stat2 & CICSCDF_DR ) msr |= TIOCM_DSR;
|
||||
if ( stat2 & CICSCDF_CS ) msr |= TIOCM_CTS;
|
||||
#if COM_CARRIER_DETECT_EMULATE
|
||||
if ( msr & (TIOCM_DSR|TIOCM_CTS) ) {
|
||||
msr |= TIOCM_CAR;
|
||||
}
|
||||
if ( msr & (TIOCM_DSR|TIOCM_CTS) ) {
|
||||
msr |= TIOCM_CAR;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
int stat, stat2;
|
||||
|
||||
stat = inb(com->sts_port);
|
||||
stat2 = inb(com->in_modem_port);
|
||||
if ( !(stat2 & CICSCD_CD) ) msr |= TIOCM_CAR;
|
||||
if ( !(stat2 & CICSCD_CI) ) msr |= TIOCM_RI;
|
||||
if ( stat & STS8251_DSR ) msr |= TIOCM_DSR;
|
||||
if ( !(stat2 & CICSCD_CS) ) msr |= TIOCM_CTS;
|
||||
#if COM_CARRIER_DETECT_EMULATE
|
||||
if ( msr & (TIOCM_DSR|TIOCM_CTS) ) {
|
||||
msr |= TIOCM_CAR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return(msr);
|
||||
}
|
||||
|
||||
@ -4402,8 +4510,12 @@ pc98_i8251_clear_cmd(struct com_s *com, int x)
|
||||
|
||||
COM_INT_DISABLE
|
||||
tmp = com->pc98_prev_siocmd & ~(x);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, 0);
|
||||
outb(com->cmd_port, tmp);
|
||||
com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE);
|
||||
COM_INT_ENABLE
|
||||
}
|
||||
|
||||
@ -4413,9 +4525,13 @@ pc98_i8251_or_cmd(struct com_s *com, int x)
|
||||
int tmp;
|
||||
|
||||
COM_INT_DISABLE
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, 0);
|
||||
tmp = com->pc98_prev_siocmd | (x);
|
||||
outb(com->cmd_port, tmp);
|
||||
com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE);
|
||||
COM_INT_ENABLE
|
||||
}
|
||||
|
||||
@ -4425,9 +4541,13 @@ pc98_i8251_set_cmd(struct com_s *com, int x)
|
||||
int tmp;
|
||||
|
||||
COM_INT_DISABLE
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, 0);
|
||||
tmp = (x);
|
||||
outb(com->cmd_port, tmp);
|
||||
com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE);
|
||||
COM_INT_ENABLE
|
||||
}
|
||||
|
||||
@ -4436,10 +4556,14 @@ pc98_i8251_clear_or_cmd(struct com_s *com, int clr, int x)
|
||||
{
|
||||
int tmp;
|
||||
COM_INT_DISABLE
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, 0);
|
||||
tmp = com->pc98_prev_siocmd & ~(clr);
|
||||
tmp |= (x);
|
||||
outb(com->cmd_port, tmp);
|
||||
com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE);
|
||||
COM_INT_ENABLE
|
||||
}
|
||||
|
||||
@ -4458,6 +4582,8 @@ pc98_i8251_get_mod(struct com_s *com)
|
||||
static void
|
||||
pc98_i8251_reset(struct com_s *com, int mode, int command)
|
||||
{
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, 0);
|
||||
outb(com->cmd_port, 0); /* dummy */
|
||||
DELAY(2);
|
||||
outb(com->cmd_port, 0); /* dummy */
|
||||
@ -4470,6 +4596,10 @@ pc98_i8251_reset(struct com_s *com, int mode, int command)
|
||||
com->pc98_prev_siomod = mode;
|
||||
DELAY(2);
|
||||
pc98_i8251_set_cmd( com, (command|CMD8251_ER) );
|
||||
DELAY(10);
|
||||
if (com->pc98_8251fifo_enable)
|
||||
outb(I8251F_fcr, CTRL8251F_ENABLE |
|
||||
CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4695,17 +4825,9 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
|
||||
if (iod->if_type == COM_IF_INTERNAL) {
|
||||
iod->irq = 4;
|
||||
|
||||
/* XXX check new internal port. */
|
||||
outb(0x13a, 0);
|
||||
DELAY(10);
|
||||
for (tmp = 0; tmp < 100; tmp++) {
|
||||
if ((inb(0x13a) & 0x80) == 0) {
|
||||
PC98SIO_baud_rate_port(if_type) = 0x13a;
|
||||
if_8251_type[if_type].name = " (internal fast)";
|
||||
if (pc98_check_8251vfast()) {
|
||||
PC98SIO_baud_rate_port(if_type) = I8251F_div;
|
||||
if_8251_type[if_type].speedtab = pc98fast_speedtab;
|
||||
break;
|
||||
}
|
||||
DELAY(1);
|
||||
}
|
||||
} else {
|
||||
tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask;
|
||||
@ -4732,24 +4854,59 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
pc98_set_ioport( struct com_s *com, int id_flags )
|
||||
pc98_set_ioport(struct com_s *com)
|
||||
{
|
||||
int io, if_type;
|
||||
int if_type = com->pc98_if_type & 0x0f;
|
||||
int io = com->iobase & 0xff00;
|
||||
|
||||
if_type = (id_flags >> 24) & 0xff;
|
||||
if (IS_8251(if_type)) {
|
||||
if (IS_8251(com->pc98_if_type)) {
|
||||
pc98_check_sysclock();
|
||||
io = com->iobase & 0xff00;
|
||||
com->pc98_if_type = if_type;
|
||||
if_type &= 0x0f;
|
||||
com->data_port = io | PC98SIO_data_port(if_type);
|
||||
com->cmd_port = io | PC98SIO_cmd_port(if_type);
|
||||
com->sts_port = io | PC98SIO_sts_port(if_type);
|
||||
com->in_modem_port = io | PC98SIO_in_modem_port(if_type);
|
||||
com->intr_ctrl_port = io | PC98SIO_intr_ctrl_port(if_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
static int
|
||||
pc98_check_8251vfast(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
outb(I8251F_div, 0x8c);
|
||||
DELAY(10);
|
||||
for (i = 0; i < 100; i++) {
|
||||
if ((inb(I8251F_div) & 0x80) != 0) {
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
DELAY(1);
|
||||
}
|
||||
outb(I8251F_div, 0);
|
||||
DELAY(10);
|
||||
for (; i < 100; i++) {
|
||||
if ((inb(I8251F_div) & 0x80) == 0)
|
||||
return 1;
|
||||
DELAY(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
pc98_check_8251fifo(void)
|
||||
{
|
||||
u_char tmp1, tmp2;
|
||||
|
||||
tmp1 = inb(I8251F_iir);
|
||||
DELAY(10);
|
||||
tmp2 = inb(I8251F_iir);
|
||||
if (((tmp1 ^ tmp2) & 0x40) != 0 && ((tmp1 | tmp2) & 0x20) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* PC98 defined */
|
||||
|
Loading…
Reference in New Issue
Block a user