@@ -99,6 +99,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch,
9999static inline ssize_t uart_irqwrite (FAR uart_dev_t * dev ,
100100 FAR const char * buffer ,
101101 size_t buflen );
102+ static inline ssize_t uart_irqwritev (FAR uart_dev_t * dev ,
103+ FAR struct uio * uio );
102104static int uart_tcdrain (FAR uart_dev_t * dev ,
103105 bool cancelable , clock_t timeout );
104106
@@ -110,11 +112,8 @@ static int uart_tcsendbreak(FAR uart_dev_t *dev,
110112
111113static int uart_open (FAR struct file * filep );
112114static int uart_close (FAR struct file * filep );
113- static ssize_t uart_read (FAR struct file * filep ,
114- FAR char * buffer , size_t buflen );
115- static ssize_t uart_write (FAR struct file * filep ,
116- FAR const char * buffer ,
117- size_t buflen );
115+ static ssize_t uart_readv (FAR struct file * filep , FAR struct uio * uio );
116+ static ssize_t uart_writev (FAR struct file * filep , FAR struct uio * uio );
118117static int uart_ioctl (FAR struct file * filep ,
119118 int cmd , unsigned long arg );
120119static int uart_poll (FAR struct file * filep ,
@@ -141,15 +140,15 @@ static const struct file_operations g_serialops =
141140{
142141 uart_open , /* open */
143142 uart_close , /* close */
144- uart_read , /* read */
145- uart_write , /* write */
143+ NULL , /* read */
144+ NULL , /* write */
146145 NULL , /* seek */
147146 uart_ioctl , /* ioctl */
148147 NULL , /* mmap */
149148 NULL , /* truncate */
150149 uart_poll , /* poll */
151- NULL , /* readv */
152- NULL /* writev */
150+ uart_readv , /* readv */
151+ uart_writev /* writev */
153152#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
154153 , uart_unlink /* unlink */
155154#endif
@@ -441,6 +440,50 @@ static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev,
441440 return buflen ;
442441}
443442
443+ /****************************************************************************
444+ * Name: uart_irqwritev
445+ ****************************************************************************/
446+
447+ static inline ssize_t uart_irqwritev (FAR uart_dev_t * dev ,
448+ FAR struct uio * uio )
449+ {
450+ ssize_t error = 0 ;
451+ ssize_t total = 0 ;
452+ int iovcnt = uio -> uio_iovcnt ;
453+ int i ;
454+
455+ for (i = 0 ; i < iovcnt ; i ++ )
456+ {
457+ const struct iovec * iov = & uio -> uio_iov [i ];
458+ if (iov -> iov_len == 0 )
459+ {
460+ continue ;
461+ }
462+
463+ ssize_t written = uart_irqwrite (dev , iov -> iov_base , iov -> iov_len );
464+ if (written < 0 )
465+ {
466+ error = written ;
467+ break ;
468+ }
469+
470+ if (SSIZE_MAX - total < written )
471+ {
472+ error = - EOVERFLOW ;
473+ break ;
474+ }
475+
476+ total += written ;
477+ }
478+
479+ if (error != 0 && total == 0 )
480+ {
481+ return error ;
482+ }
483+
484+ return total ;
485+ }
486+
444487/****************************************************************************
445488 * Name: uart_tcdrain
446489 *
@@ -847,11 +890,10 @@ static int uart_close(FAR struct file *filep)
847890}
848891
849892/****************************************************************************
850- * Name: uart_read
893+ * Name: uart_readv
851894 ****************************************************************************/
852895
853- static ssize_t uart_read (FAR struct file * filep ,
854- FAR char * buffer , size_t buflen )
896+ static ssize_t uart_readv (FAR struct file * filep , FAR struct uio * uio )
855897{
856898 FAR struct inode * inode = filep -> f_inode ;
857899 FAR uart_dev_t * dev = inode -> i_private ;
@@ -862,6 +904,7 @@ static ssize_t uart_read(FAR struct file *filep,
862904#endif
863905 irqstate_t flags ;
864906 ssize_t recvd = 0 ;
907+ ssize_t buflen ;
865908 bool echoed = false;
866909 int16_t tail ;
867910 char ch ;
@@ -885,7 +928,8 @@ static ssize_t uart_read(FAR struct file *filep,
885928 * data from the end of the buffer.
886929 */
887930
888- while ((size_t )recvd < buflen )
931+ buflen = uio -> uio_resid ;
932+ while (recvd < buflen )
889933 {
890934#ifdef CONFIG_SERIAL_REMOVABLE
891935 /* If the removable device is no longer connected, refuse to read any
@@ -961,7 +1005,8 @@ static ssize_t uart_read(FAR struct file *filep,
9611005 {
9621006 if (recvd > 0 )
9631007 {
964- * buffer -- = '\0' ;
1008+ static const char zero = '\0' ;
1009+ uio_copyfrom (uio , recvd , & zero , 1 );
9651010 recvd -- ;
9661011 if (dev -> tc_lflag & ECHO )
9671012 {
@@ -990,7 +1035,7 @@ static ssize_t uart_read(FAR struct file *filep,
9901035
9911036 /* Store the received character */
9921037
993- * buffer ++ = ch ;
1038+ uio_copyfrom ( uio , recvd , & ch , 1 ) ;
9941039 recvd ++ ;
9951040
9961041 if (dev -> tc_lflag & ECHO )
@@ -1325,19 +1370,24 @@ static ssize_t uart_read(FAR struct file *filep,
13251370#endif
13261371
13271372 nxmutex_unlock (& dev -> recv .lock );
1373+ if (recvd >= 0 )
1374+ {
1375+ uio_advance (uio , recvd );
1376+ }
1377+
13281378 return recvd ;
13291379}
13301380
13311381/****************************************************************************
1332- * Name: uart_write
1382+ * Name: uart_writev
13331383 ****************************************************************************/
13341384
1335- static ssize_t uart_write (FAR struct file * filep , FAR const char * buffer ,
1336- size_t buflen )
1385+ static ssize_t uart_writev (FAR struct file * filep , FAR struct uio * uio )
13371386{
13381387 FAR struct inode * inode = filep -> f_inode ;
13391388 FAR uart_dev_t * dev = inode -> i_private ;
1340- ssize_t nwritten = buflen ;
1389+ ssize_t nwritten ;
1390+ ssize_t buflen ;
13411391 bool oktoblock ;
13421392 int ret ;
13431393 char ch ;
@@ -1363,12 +1413,14 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
13631413#endif
13641414
13651415 flags = enter_critical_section ();
1366- ret = uart_irqwrite (dev , buffer , buflen );
1416+ ret = uart_irqwritev (dev , uio );
13671417 leave_critical_section (flags );
13681418
13691419 return ret ;
13701420 }
13711421
1422+ buflen = nwritten = uio -> uio_resid ;
1423+
13721424 /* Only one user can access dev->xmit.head at a time */
13731425
13741426 ret = nxmutex_lock (& dev -> xmit .lock );
@@ -1408,9 +1460,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
14081460 */
14091461
14101462 uart_disabletxint (dev );
1411- for (; buflen ; buflen -- )
1463+ for (; buflen ; uio_advance ( uio , 1 ), buflen -- )
14121464 {
1413- ch = * buffer ++ ;
1465+ uio_copyto ( uio , 0 , & ch , 1 ) ;
14141466 ret = OK ;
14151467
14161468 /* Do output post-processing */
0 commit comments