Implementing 'tcflush()' support for ns8250 UART driver

Shrikanth Kamath shrikanth07 at gmail.com
Fri Aug 21 00:11:58 UTC 2020


A user has a need to flush UART FIFO buffers to get out of a framing error
reported by the register REG_LSR and attempted to do a tcflush assuming it
would ioctl 'TIOCFLUSH' command to the UART but ns8250 does not seem to
have the support or is there another alternative? Below was the submitted
change from the user, wanted to clarify with the experts on this (image
based on stable/11 and hardware is a Juniper MX x86/64 custom routing
engine control board)

diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h
index a4bcf3d..5697c66 100644
--- a/sys/dev/uart/uart_bus.h
+++ b/sys/dev/uart/uart_bus.h
@@ -57,6 +57,7 @@
 #define        UART_IOCTL_IFLOW        2
 #define        UART_IOCTL_OFLOW        3
 #define        UART_IOCTL_BAUD         4
+#define        UART_IOCTL_FLUSH        5

 /*
  * UART class & instance (=softc)
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 7dd331e..492f902 100755
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -36,6 +36,7 @@
 #include <sys/conf.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
+#include <sys/fcntl.h>
 #include <machine/bus.h>

 #ifdef FDT
@@ -608,6 +609,7 @@
        struct uart_bas *bas;
        int baudrate, divisor, error;
        uint8_t efr, lcr;
+       int which = 0;

        bas = &sc->sc_bas;
        error = 0;
@@ -667,6 +669,14 @@
                else
                        error = ENXIO;
                break;

+        case UART_IOCTL_FLUSH:
+               if (data & FREAD)
+                       which |= UART_FLUSH_RECEIVER;
+               if (data & FWRITE)
+                       which |= UART_FLUSH_TRANSMITTER;
+
+               ns8250_flush(bas, which);
+               break;
        default:
                error = EINVAL;
                break;
diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c
index e9b2baf..452a34c 100644
--- a/sys/dev/uart/uart_tty.c
+++ b/sys/dev/uart/uart_tty.c
@@ -312,6 +312,8 @@
                *(uint32_t*)data = sc->sc_clk_mode;
                mtx_unlock(&sc->sc_clk_mutex);
                return 0;
+       case TIOCFLUSH:
+               return UART_IOCTL(sc, UART_IOCTL_FLUSH, *(int *)data);
        default:
                return pps_ioctl(cmd, data, &sc->sc_pps);
        }

--
Shrikanth R K
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 012f4a2.diff
Type: application/octet-stream
Size: 1489 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20200820/62332907/attachment.obj>


More information about the freebsd-hackers mailing list