patch-2.2.8 linux/drivers/macintosh/macserial.c
Next file: linux/drivers/macintosh/nvram.c
Previous file: linux/drivers/macintosh/macio-adb.c
Back to the patch index
Back to the overall index
- Lines: 234
- Date:
Thu Apr 29 12:53:48 1999
- Orig file:
v2.2.7/linux/drivers/macintosh/macserial.c
- Orig date:
Tue Mar 23 14:35:47 1999
diff -u --recursive --new-file v2.2.7/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
@@ -1986,6 +1986,7 @@
info->line = i;
info->tty = 0;
info->custom_divisor = 16;
+ info->timeout = 0;
info->close_delay = 50;
info->closing_wait = 3000;
info->x_char = 0;
@@ -2058,6 +2059,32 @@
static void serial_console_write(struct console *co, const char *s,
unsigned count)
{
+ struct mac_serial *info = zs_soft + co->index;
+ int i;
+
+ /* Turn of interrupts and enable the transmitter. */
+ write_zsreg(info->zs_channel, R1, info->curregs[1] & ~TxINT_ENAB);
+ write_zsreg(info->zs_channel, R5, info->curregs[5] | TxENAB | RTS | DTR);
+
+ for (i=0; i<count; i++) {
+ /* Wait for the transmit buffer to empty. */
+ while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0) {
+ eieio();
+ }
+
+ write_zsdata(info->zs_channel, s[i]);
+ if (s[i] == 10) {
+ while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP)
+ == 0)
+ eieio();
+
+ write_zsdata(info->zs_channel, 13);
+ }
+ }
+
+ /* Restore the values in the registers. */
+ write_zsreg(info->zs_channel, R1, info->curregs[1]);
+ /* Don't disable the transmitter. */
}
/*
@@ -2065,7 +2092,23 @@
*/
static int serial_console_wait_key(struct console *co)
{
- return 0;
+ struct mac_serial *info = zs_soft + co->index;
+ int val;
+
+ /* Turn of interrupts and enable the transmitter. */
+ write_zsreg(info->zs_channel, R1, info->curregs[1] & ~INT_ALL_Rx);
+ write_zsreg(info->zs_channel, R3, info->curregs[3] | RxENABLE);
+
+ /* Wait for something in the receive buffer. */
+ while((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0)
+ eieio();
+ val = read_zsdata(info->zs_channel);
+
+ /* Restore the values in the registers. */
+ write_zsreg(info->zs_channel, R1, info->curregs[1]);
+ write_zsreg(info->zs_channel, R3, info->curregs[3]);
+
+ return val;
}
static kdev_t serial_console_device(struct console *c)
@@ -2081,14 +2124,24 @@
*/
__initfunc(static int serial_console_setup(struct console *co, char *options))
{
- struct serial_state *ser;
- unsigned cval;
- int baud = 9600;
+ struct mac_serial *info = zs_soft + co->index;
+ int baud = 38400;
int bits = 8;
int parity = 'n';
int cflag = CREAD | HUPCL | CLOCAL;
- int quot = 0;
+ int brg;
char *s;
+ long flags;
+
+ /* Find out how many Z8530 SCCs we have */
+ if (zs_chain == 0)
+ probe_sccs();
+
+ if (zs_chain == 0)
+ return -1;
+
+ /* Reset the channel */
+ write_zsreg(info->zs_channel, R9, CHRA);
if (options) {
baud = simple_strtoul(options, NULL, 10);
@@ -2114,21 +2167,21 @@
case 4800:
cflag |= B4800;
break;
+ case 9600:
+ cflag |= B9600;
+ break;
case 19200:
cflag |= B19200;
break;
- case 38400:
- cflag |= B38400;
- break;
case 57600:
cflag |= B57600;
break;
case 115200:
cflag |= B115200;
break;
- case 9600:
+ case 38400:
default:
- cflag |= B9600;
+ cflag |= B38400;
break;
}
switch(bits) {
@@ -2142,7 +2195,7 @@
}
switch(parity) {
case 'o': case 'O':
- cflag |= PARODD;
+ cflag |= PARENB | PARODD;
break;
case 'e': case 'E':
cflag |= PARENB;
@@ -2150,6 +2203,90 @@
}
co->cflag = cflag;
+ save_flags(flags); cli();
+ memset(info->curregs, 0, sizeof(info->curregs));
+
+ info->zs_baud = baud;
+ info->clk_divisor = 16;
+ switch (info->zs_baud) {
+ case ZS_CLOCK/16: /* 230400 */
+ info->curregs[4] = X16CLK;
+ info->curregs[11] = 0;
+ break;
+ case ZS_CLOCK/32: /* 115200 */
+ info->curregs[4] = X32CLK;
+ info->curregs[11] = 0;
+ break;
+ default:
+ info->curregs[4] = X16CLK;
+ info->curregs[11] = TCBR | RCBR;
+ brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
+ info->curregs[12] = (brg & 255);
+ info->curregs[13] = ((brg >> 8) & 255);
+ info->curregs[14] = BRENABL;
+ }
+
+ /* byte size and parity */
+ info->curregs[3] &= ~RxNBITS_MASK;
+ info->curregs[5] &= ~TxNBITS_MASK;
+ switch (cflag & CSIZE) {
+ case CS5:
+ info->curregs[3] |= Rx5;
+ info->curregs[5] |= Tx5;
+ break;
+ case CS6:
+ info->curregs[3] |= Rx6;
+ info->curregs[5] |= Tx6;
+ break;
+ case CS7:
+ info->curregs[3] |= Rx7;
+ info->curregs[5] |= Tx7;
+ break;
+ case CS8:
+ default: /* defaults to 8 bits */
+ info->curregs[3] |= Rx8;
+ info->curregs[5] |= Tx8;
+ break;
+ }
+ info->curregs[5] |= TxENAB | RTS | DTR;
+ info->pendregs[3] = info->curregs[3];
+ info->pendregs[5] = info->curregs[5];
+
+ info->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN);
+ if (cflag & CSTOPB) {
+ info->curregs[4] |= SB2;
+ } else {
+ info->curregs[4] |= SB1;
+ }
+ if (cflag & PARENB) {
+ info->curregs[4] |= PAR_ENA;
+ if (!(cflag & PARODD)) {
+ info->curregs[4] |= PAR_EVEN;
+ }
+ }
+ info->pendregs[4] = info->curregs[4];
+
+ if (!(cflag & CLOCAL)) {
+ if (!(info->curregs[15] & DCDIE))
+ info->read_reg_zero = read_zsreg(info->zs_channel, 0);
+ info->curregs[15] |= DCDIE;
+ } else
+ info->curregs[15] &= ~DCDIE;
+ if (cflag & CRTSCTS) {
+ info->curregs[15] |= CTSIE;
+ if ((read_zsreg(info->zs_channel, 0) & CTS) != 0)
+ info->tx_stopped = 1;
+ } else {
+ info->curregs[15] &= ~CTSIE;
+ info->tx_stopped = 0;
+ }
+ info->pendregs[15] = info->curregs[15];
+
+ /* Load up the new values */
+ load_zsregs(info->zs_channel, info->curregs);
+
+ restore_flags(flags);
+
return 0;
}
@@ -2170,9 +2307,10 @@
/*
* Register console.
*/
-__initfunc (void serial_console_init(void))
+__initfunc (long serial_console_init(long kmem_start, long kmem_end))
{
register_console(&sercons);
+ return kmem_start;
}
#endif /* ifdef CONFIG_SERIAL_CONSOLE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)