patch-2.4.0-test8 linux/drivers/sbus/char/sab82532.c
Next file: linux/drivers/sbus/char/su.c
Previous file: linux/drivers/sbus/char/rtc.c
Back to the patch index
Back to the overall index
- Lines: 448
- Date:
Thu Sep 7 08:32:01 2000
- Orig file:
v2.4.0-test7/linux/drivers/sbus/char/sab82532.c
- Orig date:
Wed Aug 23 18:36:38 2000
diff -u --recursive --new-file v2.4.0-test7/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.47 2000/08/16 21:12:14 ecd Exp $
+/* $Id: sab82532.c,v 1.51 2000/09/04 19:41:26 ecd Exp $
* sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -55,9 +55,11 @@
/* Set of debugging defines */
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_MODEM
#undef SERIAL_DEBUG_WAIT_UNTIL_SENT
#undef SERIAL_DEBUG_SEND_BREAK
#undef SERIAL_DEBUG_INTR
+#define SERIAL_DEBUG_OVERFLOW 1
/* Trace things on serial device, useful for console debugging: */
#undef SERIAL_LOG_DEVICE
@@ -79,10 +81,15 @@
static struct termios *sab82532_termios[NR_PORTS];
static struct termios *sab82532_termios_locked[NR_PORTS];
+#ifdef MODULE
+#undef CONFIG_SERIAL_CONSOLE
+#endif
+
#ifdef CONFIG_SERIAL_CONSOLE
extern int serial_console;
static struct console sab82532_console;
static int sab82532_console_init(void);
+static void batten_down_hatches(struct sab82532 *info);
#endif
#ifndef MIN
@@ -208,7 +215,10 @@
if (!(readb(&info->regs->r.star) & SAB82532_STAR_XFW))
goto out;
+ info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+ writeb(info->interrupt_mask1, &info->regs->w.imr1);
info->all_sent = 0;
+
for (i = 0; i < info->xmit_fifo_size; i++) {
u8 val = info->xmit_buf[info->xmit_tail++];
writeb(val, &info->regs->w.xfifo[i]);
@@ -264,47 +274,6 @@
restore_flags(flags);
}
-static void batten_down_hatches(struct sab82532 *info)
-{
- unsigned char saved_rfc, tmp;
-
- if (!stop_a_enabled)
- return;
-
- /* If we are doing kadb, we call the debugger
- * else we just drop into the boot monitor.
- * Note that we must flush the user windows
- * first before giving up control.
- */
- printk("\n");
- flush_user_windows();
-
- /*
- * Set FIFO to single character mode.
- */
- saved_rfc = readb(&info->regs->r.rfc);
- tmp = readb(&info->regs->rw.rfc);
- tmp &= ~(SAB82532_RFC_RFDF);
- writeb(tmp, &info->regs->rw.rfc);
- sab82532_cec_wait(info);
- writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
-
-#ifndef __sparc_v9__
- if ((((unsigned long)linux_dbvec) >= DEBUG_FIRSTVADDR) &&
- (((unsigned long)linux_dbvec) <= DEBUG_LASTVADDR))
- sp_enter_debugger();
- else
-#endif
- prom_cmdline();
-
- /*
- * Reset FIFO to character + status mode.
- */
- writeb(saved_rfc, &info->regs->w.rfc);
- sab82532_cec_wait(info);
- writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
-}
-
/*
* ----------------------------------------------------------------------
*
@@ -361,12 +330,11 @@
if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
sab82532_cec_wait(info);
writeb(SAB82532_CMDR_RFRD, &info->regs->w.cmdr);
- /* Wait for command execution, to catch the TCD below. */
- sab82532_cec_wait(info);
+ return;
}
if (stat->sreg.isr0 & SAB82532_ISR0_RFO) {
-#if 1
+#ifdef SERIAL_DEBUG_OVERFLOW
printk("sab82532: receive_chars: RFO");
#endif
free_fifo++;
@@ -382,14 +350,16 @@
writeb(SAB82532_CMDR_RMC, &info->regs->w.cmdr);
}
+#ifdef CONFIG_SERIAL_CONSOLE
if (info->is_console)
wake_up(&keypress_wait);
+#endif
if (!tty)
return;
for (i = 0; i < count; ) {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-#if 1
+#ifdef SERIAL_DEBUG_OVERFLOW
printk("sab82532: receive_chars: tty overrun\n");
#endif
info->icount.buf_overrun++;
@@ -424,9 +394,13 @@
{
int i;
- if (stat->sreg.isr1 & SAB82532_ISR1_ALLS)
+ if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
+ info->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+ writeb(info->interrupt_mask1, &info->regs->w.imr1);
info->all_sent = 1;
- if (!(readb(&info->regs->r.star) & SAB82532_STAR_XFW))
+ }
+
+ if (!(stat->sreg.isr1 & SAB82532_ISR1_XPR))
return;
if (!info->tty) {
@@ -442,8 +416,11 @@
return;
}
- /* Stuff 32 bytes into Transmit FIFO. */
+ info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+ writeb(info->interrupt_mask1, &info->regs->w.imr1);
info->all_sent = 0;
+
+ /* Stuff 32 bytes into Transmit FIFO. */
for (i = 0; i < info->xmit_fifo_size; i++) {
u8 val = info->xmit_buf[info->xmit_tail++];
writeb(val, &info->regs->w.xfifo[i]);
@@ -476,10 +453,12 @@
int modem_change = 0;
if (stat->sreg.isr1 & SAB82532_ISR1_BRK) {
+#ifdef CONFIG_SERIAL_CONSOLE
if (info->is_console) {
batten_down_hatches(info);
return;
}
+#endif
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
info->icount.buf_overrun++;
goto check_modem;
@@ -509,7 +488,7 @@
info->dcd = (readb(&info->regs->r.vstr) & SAB82532_VSTR_CD) ? 0 : 1;
info->icount.dcd++;
modem_change++;
-#if 0
+#ifdef SERIAL_DEBUG_MODEM
printk("DCD change: %d\n", info->icount.dcd);
#endif
}
@@ -517,7 +496,7 @@
info->cts = readb(&info->regs->r.star) & SAB82532_STAR_CTS;
info->icount.cts++;
modem_change++;
-#if 0
+#ifdef SERIAL_DEBUG_MODEM
printk("CTS change: %d, CTS %s\n", info->icount.cts, info->cts ? "on" : "off");
#endif
}
@@ -525,7 +504,7 @@
info->dsr = (readb(&info->regs->r.pvr) & info->pvr_dsr_bit) ? 0 : 1;
info->icount.dsr++;
modem_change++;
-#if 0
+#ifdef SERIAL_DEBUG_MODEM
printk("DSR change: %d\n", info->icount.dsr);
#endif
}
@@ -828,10 +807,12 @@
info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
SAB82532_IMR0_PLLA;
writeb(info->interrupt_mask0, &info->regs->w.imr0);
- info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_XOFF |
- SAB82532_IMR1_TIN | SAB82532_IMR1_CSC |
- SAB82532_IMR1_XON | SAB82532_IMR1_XPR;
+ info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+ SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+ SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+ SAB82532_IMR1_XPR;
writeb(info->interrupt_mask1, &info->regs->w.imr1);
+ info->all_sent = 1;
if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -880,6 +861,7 @@
info->xmit_buf = 0;
}
+#ifdef CONFIG_SERIAL_CONSOLE
if (info->is_console) {
info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
@@ -895,6 +877,7 @@
restore_flags(flags);
return;
}
+#endif
/* Disable Interrupts */
info->interrupt_mask0 = 0xff;
@@ -1238,10 +1221,6 @@
if (I_IXOFF(tty))
sab82532_send_xchar(tty, STOP_CHAR(tty));
-#if 0
- if (tty->termios->c_cflag & CRTSCTS)
- writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-#endif
}
static void sab82532_unthrottle(struct tty_struct * tty)
@@ -1263,11 +1242,6 @@
else
sab82532_send_xchar(tty, START_CHAR(tty));
}
-
-#if 0
- if (tty->termios->c_cflag & CRTSCTS)
- writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RTS), &info->regs->rw.mode);
-#endif
}
/*
@@ -1562,18 +1536,6 @@
tty->hw_stopped = 0;
sab82532_start(tty);
}
-
-#if 0
- /*
- * No need to wake up processes in open wait, since they
- * sample the CLOCAL flag once, and don't recheck it.
- * XXX It's not clear whether the current behavior is correct
- * or not. Hence, this may change.....
- */
- if (!(old_termios->c_cflag & CLOCAL) &&
- (tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&info->open_wait);
-#endif
}
/*
@@ -1651,9 +1613,6 @@
*/
info->interrupt_mask0 |= SAB82532_IMR0_TCD;
writeb(info->interrupt_mask0, &info->regs->w.imr0);
-#if 0
- writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RAC), &info->regs->rw.mode);
-#endif
if (info->flags & ASYNC_INITIALIZED) {
/*
* Before we drop DTR, make sure the UART transmitter
@@ -1722,7 +1681,6 @@
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
- current->state = TASK_RUNNING;
#ifdef SERIAL_DEBUG_WAIT_UNTIL_SENT
printk("xmit_cnt = %d, alls = %d (jiff=%lu)...done\n", info->xmit_cnt, info->all_sent, jiffies);
#endif
@@ -1738,8 +1696,10 @@
if (serial_paranoia_check(info, tty->device, "sab82532_hangup"))
return;
+#ifdef CONFIG_SERIAL_CONSOLE
if (info->is_console)
return;
+#endif
sab82532_flush_buffer(tty);
shutdown(info);
@@ -1873,7 +1833,6 @@
#endif
schedule();
}
- current->state = TASK_RUNNING;
remove_wait_queue(&info->open_wait, &wait);
if (!tty_hung_up_p(filp))
info->count++;
@@ -2010,7 +1969,7 @@
char stat_buf[30];
int ret;
- ret = sprintf(buf, "%d: uart:SAB82532 ", info->line);
+ ret = sprintf(buf, "%u: uart:SAB82532 ", info->line);
switch (info->type) {
case 0:
ret += sprintf(buf+ret, "V1.0 ");
@@ -2056,19 +2015,22 @@
restore_flags(flags);
if (info->baud)
- ret += sprintf(buf+ret, " baud:%d", info->baud);
+ ret += sprintf(buf+ret, " baud:%u", info->baud);
+
+ ret += sprintf(buf+ret, " tx:%u rx:%u",
+ info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ ret += sprintf(buf+ret, " fe:%u", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ ret += sprintf(buf+ret, " pe:%u", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ ret += sprintf(buf+ret, " brk:%u", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ ret += sprintf(buf+ret, " oe:%u", info->icount.overrun);
/*
* Last thing is the RS-232 status lines.
@@ -2161,15 +2123,17 @@
return 0;
}
+#ifndef MODULE
static void __init sab82532_kgdb_hook(int line)
{
prom_printf("sab82532: kgdb support is not implemented, yet\n");
prom_halt();
}
+#endif
static inline void __init show_serial_version(void)
{
- char *revision = "$Revision: 1.47 $";
+ char *revision = "$Revision: 1.51 $";
char *version, *p;
version = strchr(revision, ' ');
@@ -2246,7 +2210,11 @@
* major number and the subtype code.
*/
callout_driver = serial_driver;
+#ifdef CONFIG_DEVFS_FS
callout_driver.name = "cua/%d";
+#else
+ callout_driver.name = "cua";
+#endif
callout_driver.major = TTYAUX_MAJOR;
callout_driver.subtype = SERIAL_TYPE_CALLOUT;
callout_driver.read_proc = 0;
@@ -2364,8 +2332,10 @@
#ifdef CONFIG_SERIAL_CONSOLE
sunserial_setinitfunc(sab82532_console_init);
#endif
+#ifndef MODULE
sunserial_setinitfunc(sab82532_init);
rs_ops.rs_kgdb_hook = sab82532_kgdb_hook;
+#endif
return 0;
}
@@ -2400,12 +2370,56 @@
free_page((unsigned long) tmp_buf);
tmp_buf = NULL;
}
- for (sab = sab82532_chain; sab; sab = sab->next)
+ for (sab = sab82532_chain; sab; sab = sab->next) {
+ if (!(sab->line & 0x01))
+ free_irq(sab->irq, sab);
iounmap(sab->regs);
+ }
}
#endif /* MODULE */
#ifdef CONFIG_SERIAL_CONSOLE
+static void
+batten_down_hatches(struct sab82532 *info)
+{
+ unsigned char saved_rfc, tmp;
+
+ if (!stop_a_enabled)
+ return;
+
+ /* If we are doing kadb, we call the debugger
+ * else we just drop into the boot monitor.
+ * Note that we must flush the user windows
+ * first before giving up control.
+ */
+ printk("\n");
+ flush_user_windows();
+
+ /*
+ * Set FIFO to single character mode.
+ */
+ saved_rfc = readb(&info->regs->r.rfc);
+ tmp = readb(&info->regs->rw.rfc);
+ tmp &= ~(SAB82532_RFC_RFDF);
+ writeb(tmp, &info->regs->rw.rfc);
+ sab82532_cec_wait(info);
+ writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
+
+#ifndef __sparc_v9__
+ if ((((unsigned long)linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+ (((unsigned long)linux_dbvec) <= DEBUG_LASTVADDR))
+ sp_enter_debugger();
+ else
+#endif
+ prom_cmdline();
+
+ /*
+ * Reset FIFO to character + status mode.
+ */
+ writeb(saved_rfc, &info->regs->w.rfc);
+ sab82532_cec_wait(info);
+ writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
+}
static __inline__ void
sab82532_console_putchar(struct sab82532 *info, char c)
@@ -2645,4 +2659,3 @@
}
#endif /* SERIAL_LOG_DEVICE */
#endif /* CONFIG_SERIAL_CONSOLE */
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)