pluart(4) fixes

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

pluart(4) fixes

Mark Kettenis
Diff below fixes two issues with pluart(4):

1. Output sometimes gets stuck, i.e. when running "systat vm .1" on
   the console.  It seems that checking TXFE bit in the UARTFR
   register in pluart_start() fixes that issue.  But I restructured
   that function a bit to be closer to comstart() and removed the
   (unused) FIFO support code.  I hope to add FIFO support later, but
   for now it is just a distraction.

2. Tx interrupts aren't counted.  To fix that I restructured the
   interrupt handler a bit.  It now actually looks at the interrupt
   status bits.

More fixes and cleanups coming at a later stage.

ok?


Index: dev/ic/pluart.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/pluart.c,v
retrieving revision 1.3
diff -u -p -r1.3 pluart.c
--- dev/ic/pluart.c 19 Jul 2019 00:17:15 -0000 1.3
+++ dev/ic/pluart.c 10 Aug 2019 14:16:43 -0000
@@ -188,26 +188,26 @@ pluart_intr(void *arg)
  bus_space_tag_t iot = sc->sc_iot;
  bus_space_handle_t ioh = sc->sc_ioh;
  struct tty *tp = sc->sc_tty;
- u_int16_t fr;
+ u_int16_t is;
  u_int16_t *p;
  u_int16_t c;
 
- bus_space_write_4(iot, ioh, UART_ICR, -1);
+ is = bus_space_read_4(iot, ioh, UART_RIS);
+ bus_space_write_4(iot, ioh, UART_ICR, is);
 
  if (sc->sc_tty == NULL)
- return(0);
+ return 0;
 
- fr = bus_space_read_4(iot, ioh, UART_FR);
- if (ISSET(fr, UART_FR_TXFE) && ISSET(tp->t_state, TS_BUSY)) {
+ if (!ISSET(is, UART_IMSC_RXIM) && !ISSET(is, UART_IMSC_TXIM))
+ return 0;
+
+ if (ISSET(is, UART_IMSC_TXIM) && ISSET(tp->t_state, TS_BUSY)) {
  CLR(tp->t_state, TS_BUSY | TS_FLUSH);
  if (sc->sc_halt > 0)
  wakeup(&tp->t_outq);
  (*linesw[tp->t_line].l_start)(tp);
  }
 
- if(!ISSET(bus_space_read_4(iot, ioh, UART_FR), UART_FR_RXFF))
- return 0;
-
  p = sc->sc_ibufp;
 
  while (ISSET(bus_space_read_4(iot, ioh, UART_FR), UART_FR_RXFF)) {
@@ -326,35 +326,22 @@ pluart_start(struct tty *tp)
  struct pluart_softc *sc = pluart_cd.cd_devs[DEVUNIT(tp->t_dev)];
  bus_space_tag_t iot = sc->sc_iot;
  bus_space_handle_t ioh = sc->sc_ioh;
-
+ u_int16_t fr;
  int s;
+
  s = spltty();
  if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
  goto out;
- if (tp->t_outq.c_cc <= tp->t_lowat) {
- if (ISSET(tp->t_state, TS_ASLEEP)) {
- CLR(tp->t_state, TS_ASLEEP);
- wakeup(&tp->t_outq);
- }
- if (tp->t_outq.c_cc == 0)
- goto out;
- selwakeup(&tp->t_wsel);
- }
+ ttwakeupwr(tp);
+ if (tp->t_outq.c_cc == 0)
+ goto out;
  SET(tp->t_state, TS_BUSY);
 
- if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
- u_char buffer[64]; /* largest fifo */
- int i, n;
-
- n = q_to_b(&tp->t_outq, buffer,
-    min(sc->sc_fifolen, sizeof buffer));
- for (i = 0; i < n; i++) {
- bus_space_write_4(iot, ioh, UART_DR, buffer[i]);
- }
- bzero(buffer, n);
- } else if (tp->t_outq.c_cc != 0)
+ fr = bus_space_read_4(iot, ioh, UART_FR);
+ while (tp->t_outq.c_cc != 0 && ISSET(fr, UART_FR_TXFE)) {
  bus_space_write_4(iot, ioh, UART_DR, getc(&tp->t_outq));
-
+ fr = bus_space_read_4(iot, ioh, UART_FR);
+ }
 out:
  splx(s);
 }