Skip to contentSkip to conversation

UART driver problem

DISCUSSION Ralf HECKHAUSEN 2 participants 2 messages Jan 21, 2000 – Jan 25, 2000

lore
Share & tools
lore
#0 lore raw

I have a strange problem with the uart driver. The 8xx_write in uart.c always fails because copy_from_user returns 0 instead of the requested number of bytes. When I ignore the comparison with the requested number of bytes everything works ok, the correct bytes are transmitted and 8xx_write returns something >0. The next strange thing: a write to a tty file descriptor sometimes returns a negative number, although the output succeded. perror in this case outputs an unknown error.
Does anyone know this problems?

Ralf

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#1 lore raw
Quoted 5 lines · Ralf HECKHAUSEN

I have a strange problem with the uart driver. The 8xx_write in uart.c always fails because copy_from_user returns 0 instead of the requested number of bytes. When I ignore the comparison with the requested number of bytes everything works ok, the correct bytes are transmitted and 8xx_write returns something >0.

I noted that as well the other day, together with another problem, when starting to use sysvinit instead of a simple bash script.

The above problem is solved by this patch:

01/24 18:02:19 1.5 renamed from 01/17 17:20:57 1.4 +1 -2
diff -u -u -r1.4 -r1.5
@@ -976,8 +976,7 @@
                }
 
                if (from_user) {
-                       if (c !=
-                           copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+                       if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
                                if (!ret)
                                        ret = -EFAULT;
                                break;

Strangely enough drivers/char/serial.c is broken as well in standard kernels. The only difference is that there the copy_from_user() will appear to always succeed instead of always failing...

The other problem got triggered by init doing open(); write(); close(); cycles on the serial console. Without this patch the write() output gets aborted before finishing:

01/24 18:02:19 1.5 renamed from 01/17 17:20:57 1.4 +7 -1
diff -u -u -r1.4 -r1.5
@@ -1692,6 +1691,13 @@
         * be at least two characters waiting to be sent after the buffers
         * are empty.
         */
+       bdp = info->tx_cur;
+       /* We want to wait for the last buffer, not the first. */
+       if (bdp == info->tx_bd_base) {
+               bdp += (TX_NUM_FIFO-1);
+       } else {
+               bdp--;
+       }
        do {
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
                printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
@@ -1703,7 +1709,6 @@
                        break;
                if (timeout && ((orig_jiffies + timeout) < jiffies))
                        break;
-               bdp = info->tx_cur;
        } while (bdp->cbd_sc & BD_SC_READY);
        current->state = TASK_RUNNING;
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT

//Marcus
--
Signature under construction, please come back later.

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/