laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15692


Change subject: cuart_driver_tty: Work around linux kernel bug ignoring CREAD
......................................................................

cuart_driver_tty: Work around linux kernel bug ignoring CREAD

Almost all linux USB serial drivers are ignoring CREAD and hence
cannot disable the receiver hardware, see 
https://bugzilla.kernel.org/show_bug.cgi?id=205033

We therefore have to receive every byte we transmit before notifying the
user of transmit completion.

Change-Id: Id3cca29f78ee5469a1142aaa1ff754cc0427ec93
---
M ccid/cuart.c
M ccid/cuart.h
M ccid/cuart_driver_tty.c
M ccid/cuart_test.c
4 files changed, 24 insertions(+), 4 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware 
refs/changes/92/15692/1

diff --git a/ccid/cuart.c b/ccid/cuart.c
index 2c0428e..393bf55 100644
--- a/ccid/cuart.c
+++ b/ccid/cuart.c
@@ -113,7 +113,6 @@
        case CUART_E_TX_COMPLETE:
                cuart->tx_busy = false;
                /* re-enable receiver if we're done with transmit */
-               sleep(1);
                card_uart_ctrl(cuart, CUART_CTL_RX, true);
                break;
        default:
diff --git a/ccid/cuart.h b/ccid/cuart.h
index 7e217db..c28209f 100644
--- a/ccid/cuart.h
+++ b/ccid/cuart.h
@@ -77,6 +77,8 @@
                        size_t tx_buf_len;
                        /* index: offset of next to be transmitted byte in 
tx_buf */
                        size_t tx_index;
+                       /* number of bytes we have received echoed back during 
transmit */
+                       uint32_t rx_count_during_tx;

                        struct osmo_fd ofd;
                        unsigned int baudrate;
@@ -104,4 +106,3 @@
 void card_uart_notification(struct card_uart *cuart, enum card_uart_event evt, 
void *data);

 int card_uart_driver_register(struct card_uart_driver *drv);
-
diff --git a/ccid/cuart_driver_tty.c b/ccid/cuart_driver_tty.c
index 6bd2b52..7fc8d3a 100644
--- a/ccid/cuart_driver_tty.c
+++ b/ccid/cuart_driver_tty.c
@@ -125,7 +125,21 @@
                rc = read(ofd->fd, buf, sizeof(buf));
                OSMO_ASSERT(rc > 0);
                for (i = 0; i < rc; i++) {
+#ifndef CREAD_ACTUALLY_WORKS
                        /* work-around for 
https://bugzilla.kernel.org/show_bug.cgi?id=205033 */
+                       if (cuart->tx_busy) {
+                               if (cuart->u.tty.rx_count_during_tx < 
cuart->u.tty.tx_buf_len) {
+                                       /* FIXME: compare! */
+                                       cuart->u.tty.rx_count_during_tx += 1;
+                                       if (cuart->u.tty.rx_count_during_tx == 
cuart->u.tty.tx_buf_len) {
+                                               cuart->tx_busy = false;
+                                               card_uart_notification(cuart, 
CUART_E_TX_COMPLETE,
+                                                                       (void 
*)cuart->u.tty.tx_buf);
+                                       }
+                                       continue;
+                               }
+                       }
+#endif
                        if (!cuart->rx_enabled)
                                continue;

@@ -152,12 +166,15 @@
                /* if no more bytes to transmit, disable OSMO_FD_WRITE */
                if (cuart->u.tty.tx_index >= cuart->u.tty.tx_buf_len) {
                        ofd->when &= ~BSC_FD_WRITE;
+#ifndef CREAD_ACTUALLY_WORKS
+                       /* don't immediately notify user; first wait for 
characters to be received */
+#else
                        /* ensure everything is written (tx queue/fifo drained) 
*/
                        tcdrain(cuart->u.tty.ofd.fd);
-                       osmo_select_main(true);
                        cuart->tx_busy = false;
                        /* notify */
                        card_uart_notification(cuart, CUART_E_TX_COMPLETE, 
(void *)cuart->u.tty.tx_buf);
+#endif
                }
        }
        return 0;
@@ -209,7 +226,8 @@

        cuart->u.tty.tx_buf = data;
        cuart->u.tty.tx_buf_len = len;
-       cuart->u.tty.tx_buf_len = len;
+       cuart->u.tty.tx_index = 0;
+       cuart->u.tty.rx_count_during_tx = 0;
        cuart->tx_busy = true;
        cuart->u.tty.ofd.when |= OSMO_FD_WRITE;

diff --git a/ccid/cuart_test.c b/ccid/cuart_test.c
index aff9de7..0ed6614 100644
--- a/ccid/cuart_test.c
+++ b/ccid/cuart_test.c
@@ -47,6 +47,8 @@
        card_uart_tx(&g_cuart, select_mf, 5, true);

        osmo_select_main(true);
+       sleep(1);
+       osmo_select_main(true);
        /* we should get an RX_SINGLE event here */
 }


--
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15692
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: Id3cca29f78ee5469a1142aaa1ff754cc0427ec93
Gerrit-Change-Number: 15692
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <lafo...@osmocom.org>
Gerrit-MessageType: newchange

Reply via email to