[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-hackers
Subject:    Implementing 'tcflush()' support for ns8250 UART driver
From:       Shrikanth Kamath <shrikanth07 () gmail ! com>
Date:       2020-08-21 0:11:42
Message-ID: CAEOAkMUD+zBesiz8y24TRJDoX+nWM0NfukNUy4-QcSSgz_njiQ () mail ! gmail ! com
[Download RAW message or body]

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

["012f4a2.diff" (application/octet-stream)]

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);
 	}


_______________________________________________
freebsd-hackers@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic