]> sigrok.org Git - libsigrok.git/commitdiff
Add a timeout parameter to blocking serial calls.
authorMartin Ling <redacted>
Sun, 28 Sep 2014 12:05:33 +0000 (13:05 +0100)
committerBert Vermeulen <redacted>
Thu, 2 Oct 2014 20:06:16 +0000 (22:06 +0200)
Set this new parameter to 0 (no timeout) at every call site. This is
consistent with previous behaviour, so cannot cause any regressions.

Waiting forever for a serial operation is clearly always wrong. Without
specific knowledge of each device and driver however, I can't choose
appropriate timeouts for each call. The maintainers of these drivers
will need to do so, and also add appropriate handling of timeouts.

When this commit is merged, a bug should be entered for each driver
that is touched by it.

21 files changed:
src/hardware/agilent-dmm/api.c
src/hardware/agilent-dmm/sched.c
src/hardware/atten-pps3xxx/api.c
src/hardware/atten-pps3xxx/protocol.c
src/hardware/brymen-dmm/parser.c
src/hardware/center-3xx/protocol.c
src/hardware/colead-slm/protocol.c
src/hardware/conrad-digi-35-cpu/protocol.c
src/hardware/fluke-dmm/api.c
src/hardware/fluke-dmm/fluke.c
src/hardware/gmc-mh-1x-2x/protocol.c
src/hardware/manson-hcs-3xxx/protocol.c
src/hardware/mic-985xx/protocol.c
src/hardware/motech-lps-30x/api.c
src/hardware/norma-dmm/api.c
src/hardware/norma-dmm/protocol.c
src/hardware/openbench-logic-sniffer/api.c
src/hardware/openbench-logic-sniffer/protocol.c
src/hardware/tondaj-sl-814/protocol.c
src/libsigrok-internal.h
src/serial.c

index b7ae7fb280d95ebace2ca9643d34b88107555dbc..96b10d41dcccfb5e530ffa079d1039797a129b88 100644 (file)
@@ -116,7 +116,7 @@ static GSList *scan(GSList *options)
                return NULL;
 
        serial_flush(serial);
-       if (serial_write_blocking(serial, "*IDN?\r\n", 7) < 7) {
+       if (serial_write_blocking(serial, "*IDN?\r\n", 7, 0) < 7) {
                sr_err("Unable to send identification string.");
                return NULL;
        }
index 5e8a968b823dfd482be2dcc5266c55c4250e4b8a..cb50c88add1444b2827f0f5e036df78441fa923f 100644 (file)
@@ -140,7 +140,7 @@ static int agdmm_send(const struct sr_dev_inst *sdi, const char *cmd)
                strcat(buf, "\r\n");
        else
                strcat(buf, "\n\r\n");
-       if (serial_write_blocking(serial, buf, strlen(buf)) < (int)strlen(buf)) {
+       if (serial_write_blocking(serial, buf, strlen(buf), 0) < (int)strlen(buf)) {
                sr_err("Failed to send.");
                return SR_ERR;
        }
index a0f84152405f6725c2af1dc2a7ed48fc818c9e61..24b392ee75a4de74770a2cc12a6dbde711fe9908 100644 (file)
@@ -130,7 +130,7 @@ static GSList *scan(GSList *options, int modelid)
        memset(packet, 0, PACKET_SIZE);
        packet[0] = 0xaa;
        packet[1] = 0xaa;
-       if (serial_write_blocking(serial, packet, PACKET_SIZE) < PACKET_SIZE) {
+       if (serial_write_blocking(serial, packet, PACKET_SIZE, 0) < PACKET_SIZE) {
                sr_err("Unable to write while probing for hardware.");
                return NULL;
        }
index 95137d2e9a8164e86041d5184129ab749173c75f..0db7e232ad5fe8b880af69dfa44ce64e6079b707 100644 (file)
@@ -86,7 +86,7 @@ SR_PRIV void send_packet(const struct sr_dev_inst *sdi, uint8_t *packet)
        struct sr_serial_dev_inst *serial;
 
        serial = sdi->conn;
-       if (serial_write_blocking(serial, packet, PACKET_SIZE) < PACKET_SIZE)
+       if (serial_write_blocking(serial, packet, PACKET_SIZE, 0) < PACKET_SIZE)
                sr_dbg("Failed to send packet.");
        dump_packet("sent", packet);
 }
index cfde37bfde5dde84906e4070b3d891c7f7e3dbea..c6de81f7c82909857c78af83f52adbf939413575 100644 (file)
@@ -78,7 +78,7 @@ static int bm_send_command(uint8_t command, uint8_t arg1, uint8_t arg2,
        /* TODO: How to compute the checksum? Hardware seems to ignore it. */
 
        /* Request reading. */
-       written = serial_write_blocking(serial, &cmdout, sizeof(cmdout));
+       written = serial_write_blocking(serial, &cmdout, sizeof(cmdout), 0);
        if (written != sizeof(cmdout))
                return SR_ERR;
 
index 82fa19094f1093ff66ae91706c8889583ad4951b..e7af103905c7cc23143d8d15ae23a5b45e18b01c 100644 (file)
@@ -31,7 +31,7 @@ static int center_send(struct sr_serial_dev_inst *serial, const char *cmd)
 {
        int ret;
 
-       if ((ret = serial_write_blocking(serial, cmd, strlen(cmd))) < 0) {
+       if ((ret = serial_write_blocking(serial, cmd, strlen(cmd), 0)) < 0) {
                sr_err("Error sending '%s' command: %d.", cmd, ret);
                return SR_ERR;
        }
index 6864cb68ee8615f369f478051ff2807e03ace329..64ac12cbf5b241c804ff2870a24126375c1d3035 100644 (file)
@@ -207,7 +207,7 @@ SR_PRIV int colead_slm_receive_data(int fd, int revents, void *cb_data)
                         * we don't want it. */
                        return TRUE;
                /* Got 0x10, "measurement ready". */
-               if (serial_write_blocking(serial, "\x20", 1) < 1)
+               if (serial_write_blocking(serial, "\x20", 1, 0) < 1)
                        sr_err("unable to send command");
                else {
                        devc->state = COMMAND_SENT;
index 8068574aa83b780212e83546db35fa7985e31650..caf1e85db17962d376a1777f9e012cbd6157eb81 100644 (file)
@@ -48,7 +48,7 @@ SR_PRIV int send_msg1(const struct sr_dev_inst *sdi, char cmd, int param)
 
        sr_spew("send_msg1(): %c%c%c%c\\r", buf[0], buf[1], buf[2], buf[3]);
 
-       if (serial_write_blocking(serial, buf, sizeof(buf)) < (int)sizeof(buf)) {
+       if (serial_write_blocking(serial, buf, sizeof(buf), 0) < (int)sizeof(buf)) {
                sr_err("Write error for cmd=%c", cmd);
                return SR_ERR;
        }
index edd737e2a09315252d9e99a271fcde4a680ebd59..f7c39c85f2f3c541d23ac089530ab7d38ffe38d9 100644 (file)
@@ -90,7 +90,7 @@ static GSList *fluke_scan(const char *conn, const char *serialcomm)
        while (!devices && retry < 3) {
                retry++;
                serial_flush(serial);
-               if (serial_write_blocking(serial, "ID\r", 3) < 0) {
+               if (serial_write_blocking(serial, "ID\r", 3, 0) < 0) {
                        sr_err("Unable to send ID string");
                        continue;
                }
@@ -286,7 +286,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
        serial_source_add(sdi->session, serial, G_IO_IN, 50,
                        fluke_receive_data, (void *)sdi);
 
-       if (serial_write_blocking(serial, "QM\r", 3) < 0) {
+       if (serial_write_blocking(serial, "QM\r", 3, 0) < 0) {
                sr_err("Unable to send QM.");
                return SR_ERR;
        }
index 1110981b7c154be743120c3606ef2c6c39cc475e..4a1d5c8277256adec20576c90894a6ec553cf010 100644 (file)
@@ -456,7 +456,7 @@ static void handle_line(const struct sr_dev_inst *sdi)
                                        /* Slip the request in now, before the main
                                         * timer loop asks for metadata again. */
                                        n = sprintf(cmd, "QM %d\r", devc->meas_type);
-                                       if (serial_write_blocking(serial, cmd, n) < 0)
+                                       if (serial_write_blocking(serial, cmd, n, 0) < 0)
                                                sr_err("Unable to send QM (measurement).");
                                }
                        } else {
@@ -525,7 +525,7 @@ SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data)
         * out-of-sync or temporary disconnect issues. */
        if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period)
                        || elapsed > devc->profile->timeout) {
-               if (serial_write_blocking(serial, "QM\r", 3) < 0)
+               if (serial_write_blocking(serial, "QM\r", 3, 0) < 0)
                        sr_err("Unable to send QM.");
                devc->cmd_sent_at = now;
                devc->expect_response = TRUE;
index 53ff9b3be390d497e4b7e98b4329d312a003c979..11ca021e6786acbfa2fbbebaee1281559cf2dc9d 100644 (file)
@@ -1307,7 +1307,7 @@ int req_meas14(const struct sr_dev_inst *sdi)
        devc->cmd_idx = 0;
        create_cmd_14(devc->addr, 8, params, msg);
        devc->req_sent_at = g_get_monotonic_time();
-       if (serial_write_blocking(serial, msg, sizeof(msg)) < (int)sizeof(msg)) {
+       if (serial_write_blocking(serial, msg, sizeof(msg), 0) < (int)sizeof(msg)) {
                return SR_ERR;
        }
 
@@ -1336,13 +1336,13 @@ int req_stat14(const struct sr_dev_inst *sdi, gboolean power_on)
 
        if (power_on) {
                sr_info("Write some data and wait 3s to turn on powered off device...");
-               if (serial_write_blocking(serial, msg, sizeof(msg)) < 0)
+               if (serial_write_blocking(serial, msg, sizeof(msg), 0) < 0)
                        return SR_ERR;
                g_usleep(1*1000*1000);
-               if (serial_write_blocking(serial, msg, sizeof(msg)) < 0)
+               if (serial_write_blocking(serial, msg, sizeof(msg), 0) < 0)
                        return SR_ERR;
                g_usleep(1*1000*1000);
-               if (serial_write_blocking(serial, msg, sizeof(msg)) < 0)
+               if (serial_write_blocking(serial, msg, sizeof(msg), 0) < 0)
                        return SR_ERR;
                g_usleep(1*1000*1000);
                serial_flush(serial);
@@ -1350,7 +1350,7 @@ int req_stat14(const struct sr_dev_inst *sdi, gboolean power_on)
 
        /* Write message and wait for reply */
        devc->req_sent_at = g_get_monotonic_time();
-       if (serial_write_blocking(serial, msg, sizeof(msg)) < (int)sizeof(msg)) {
+       if (serial_write_blocking(serial, msg, sizeof(msg), 0) < (int)sizeof(msg)) {
                return SR_ERR;
        }
 
@@ -1529,7 +1529,7 @@ SR_PRIV int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *s
                params[0] = 5;
                params[1] = 5;
                create_cmd_14(devc->addr, 6, params, msg);
-               if (serial_write_blocking(sdi->conn, msg, sizeof(msg)) < 0)
+               if (serial_write_blocking(sdi->conn, msg, sizeof(msg), 0) < 0)
                        return SR_ERR;
                else
                        g_usleep(2000000); /* Wait to ensure transfer before interface switched off. */
index a57c92d988149c7f04e729327d2c40431f72f387..cb333149c87444ad1d73d7fe40341af3d354b504 100644 (file)
@@ -43,7 +43,7 @@ SR_PRIV int hcs_send_cmd(struct sr_serial_dev_inst *serial, const char *cmd, ...
        sr_dbg("Sending '%s'.", cmd_esc);
        g_free(cmd_esc);
 
-       if ((ret = serial_write_blocking(serial, cmdbuf, strlen(cmdbuf))) < 0) {
+       if ((ret = serial_write_blocking(serial, cmdbuf, strlen(cmdbuf), 0)) < 0) {
                sr_err("Error sending command: %d.", ret);
                return ret;
        }
@@ -72,7 +72,7 @@ SR_PRIV int hcs_read_reply(struct sr_serial_dev_inst *serial, int lines, char* b
                return SR_ERR_ARG;
 
        while ((l_recv < lines) && (bufpos < (buflen + 1))) {
-               retc = serial_read_blocking(serial, &buf[bufpos], 1);
+               retc = serial_read_blocking(serial, &buf[bufpos], 1, 0);
                if (retc != 1)
                        return SR_ERR;
                if (buf[bufpos] == '\r')
@@ -177,7 +177,7 @@ static int handle_new_data(struct sr_dev_inst *sdi)
        devc = sdi->priv;
        serial = sdi->conn;
 
-       len = serial_read_blocking(serial, devc->buf + devc->buflen, 1);
+       len = serial_read_blocking(serial, devc->buf + devc->buflen, 1, 0);
        if (len < 1)
                return SR_ERR;
 
index 9d0e603b1daffad54af5ecd1e42133ab47b5d4fe..6243db15ba5e5a4fe73e1af22d63809a835d347c 100644 (file)
@@ -24,7 +24,7 @@ static int mic_send(struct sr_serial_dev_inst *serial, const char *cmd)
 {
        int ret;
 
-       if ((ret = serial_write_blocking(serial, cmd, strlen(cmd))) < 0) {
+       if ((ret = serial_write_blocking(serial, cmd, strlen(cmd), 0)) < 0) {
                sr_err("Error sending '%s' command: %d.", cmd, ret);
                return SR_ERR;
        }
index 79a32aa4336ada0c9efb9080ad936b151ae756b4..81ae3ef66aadfeaa224ea263949f804eb7003ecb 100644 (file)
@@ -146,7 +146,7 @@ SR_PRIV int lps_send_va(struct sr_serial_dev_inst *serial, const char* fmt, va_l
 
        sr_spew("lps_send_va: \"%s\"", buf);
 
-       retc = serial_write_blocking(serial, buf, strlen(buf));
+       retc = serial_write_blocking(serial, buf, strlen(buf), 0);
 
        if (retc < 0)
                return SR_ERR;
index 93c9a79d853bcf75ac16cab4bd9b75832529c20e..f95e7398701c3e9e6923f804f1753f55a48a2fe6 100644 (file)
@@ -129,7 +129,7 @@ static GSList *do_scan(struct sr_dev_driver* drv, GSList *options)
                 nmadmm_requests[NMADMM_REQ_IDN].req_str);
        g_usleep(150 * 1000); /* Wait a little to allow serial port to settle. */
        for (cnt = 0; cnt < 7; cnt++) {
-               if (serial_write_blocking(serial, req, strlen(req)) < 0) {
+               if (serial_write_blocking(serial, req, strlen(req), 0) < 0) {
                        sr_err("Unable to send identification request.");
                        return NULL;
                }
index 035e991e8f1d40db9544acc531fc99bef4b8623a..d6733b2f961e76ff3a53d43341bc84255194e61f 100644 (file)
@@ -48,7 +48,7 @@ static int nma_send_req(const struct sr_dev_inst *sdi, int req, char *params)
        devc->last_req = req;
        devc->last_req_pending = TRUE;
 
-       if (serial_write_blocking(serial, buf, len) < 0) {
+       if (serial_write_blocking(serial, buf, len, 0) < 0) {
                sr_err("Unable to send request.");
                devc->last_req_pending = FALSE;
                return SR_ERR;
index 8ed13d0013f056caed9a8df674444bd7fe15f52d..9753d0b619e96179d96065d98ecf22d75d48c4f5 100644 (file)
@@ -161,7 +161,7 @@ static GSList *scan(GSList *options)
 
        if (probefd.revents != G_IO_IN)
                return NULL;
-       if (serial_read_blocking(serial, buf, 4) != 4)
+       if (serial_read_blocking(serial, buf, 4, 0) != 4)
                return NULL;
        if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
                return NULL;
index a20d674b2bea7755a41725a68727ca6860e7199c..3d5ee6e2691da40d50f7ec448d920c53b2ad895c 100644 (file)
@@ -30,7 +30,7 @@ SR_PRIV int send_shortcommand(struct sr_serial_dev_inst *serial,
 
        sr_dbg("Sending cmd 0x%.2x.", command);
        buf[0] = command;
-       if (serial_write_blocking(serial, buf, 1) != 1)
+       if (serial_write_blocking(serial, buf, 1, 0) != 1)
                return SR_ERR;
 
        return SR_OK;
@@ -48,7 +48,7 @@ SR_PRIV int send_longcommand(struct sr_serial_dev_inst *serial,
        buf[2] = data[1];
        buf[3] = data[2];
        buf[4] = data[3];
-       if (serial_write_blocking(serial, buf, 5) != 5)
+       if (serial_write_blocking(serial, buf, 5, 0) != 5)
                return SR_ERR;
 
        return SR_OK;
@@ -155,7 +155,7 @@ SR_PRIV struct sr_dev_inst *get_metadata(struct sr_serial_dev_inst *serial)
 
        key = 0xff;
        while (key) {
-               if (serial_read_blocking(serial, &key, 1) != 1)
+               if (serial_read_blocking(serial, &key, 1, 0) != 1)
                        break;
                if (key == 0x00) {
                        sr_dbg("Got metadata key 0x00, metadata ends.");
@@ -167,7 +167,7 @@ SR_PRIV struct sr_dev_inst *get_metadata(struct sr_serial_dev_inst *serial)
                case 0:
                        /* NULL-terminated string */
                        tmp_str = g_string_new("");
-                       while (serial_read_blocking(serial, &tmp_c, 1) == 1 && tmp_c != '\0')
+                       while (serial_read_blocking(serial, &tmp_c, 1, 0) == 1 && tmp_c != '\0')
                                g_string_append_c(tmp_str, tmp_c);
                        sr_dbg("Got metadata key 0x%.2x value '%s'.",
                               key, tmp_str->str);
@@ -199,7 +199,7 @@ SR_PRIV struct sr_dev_inst *get_metadata(struct sr_serial_dev_inst *serial)
                        break;
                case 1:
                        /* 32-bit unsigned integer */
-                       if (serial_read_blocking(serial, &tmp_int, 4) != 4)
+                       if (serial_read_blocking(serial, &tmp_int, 4, 0) != 4)
                                break;
                        tmp_int = RB32(&tmp_int);
                        sr_dbg("Got metadata key 0x%.2x value 0x%.8x.",
@@ -238,7 +238,7 @@ SR_PRIV struct sr_dev_inst *get_metadata(struct sr_serial_dev_inst *serial)
                        break;
                case 2:
                        /* 8-bit unsigned integer */
-                       if (serial_read_blocking(serial, &tmp_c, 1) != 1)
+                       if (serial_read_blocking(serial, &tmp_c, 1, 0) != 1)
                                break;
                        sr_dbg("Got metadata key 0x%.2x value 0x%.2x.",
                               key, tmp_c);
index d4f89b7f2d7490c9558d6bc6423102b1c7177991..b27388d1839801fdd1303ec333635e121813ddeb 100644 (file)
@@ -133,14 +133,14 @@ int tondaj_sl_814_receive_data(int fd, int revents, void *cb_data)
                buf[2] = 0x0d;
                sr_spew("Sending init command: %02x %02x %02x.",
                        buf[0], buf[1], buf[2]);
-               if ((ret = serial_write_blocking(serial, buf, 3)) < 0) {
+               if ((ret = serial_write_blocking(serial, buf, 3, 0)) < 0) {
                        sr_err("Error sending init command: %d.", ret);
                        return FALSE;
                }
                devc->state = GET_INIT_REPLY;
        } else if (devc->state == GET_INIT_REPLY) {
                /* If we just sent the "init" command, get its reply. */
-               if ((ret = serial_read_blocking(serial, buf, 2)) < 0) {
+               if ((ret = serial_read_blocking(serial, buf, 2, 0)) < 0) {
                        sr_err("Error reading init reply: %d.", ret);
                        return FALSE;
                }
@@ -159,7 +159,7 @@ int tondaj_sl_814_receive_data(int fd, int revents, void *cb_data)
                buf[2] = 0x0d;
                sr_spew("Sending data request command: %02x %02x %02x.",
                        buf[0], buf[1], buf[2]);
-               if ((ret = serial_write_blocking(serial, buf, 3)) < 0) {
+               if ((ret = serial_write_blocking(serial, buf, 3, 0)) < 0) {
                        sr_err("Error sending request command: %d.", ret);
                        return FALSE;
                }
index 655fdeb6bec0fb264c1525a88bf283f2201fb0a6..d5b6504aea40478d2102d75ade4ca68a0bb0c209 100644 (file)
@@ -630,11 +630,11 @@ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags);
 SR_PRIV int serial_close(struct sr_serial_dev_inst *serial);
 SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial);
 SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial,
-               const void *buf, size_t count);
+               const void *buf, size_t count, unsigned int timeout_ms);
 SR_PRIV int serial_write_nonblocking(struct sr_serial_dev_inst *serial,
                const void *buf, size_t count);
 SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf,
-               size_t count);
+               size_t count, unsigned int timeout_ms);
 SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf,
                size_t count);
 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
index 4fe9b88fc0805e43b7716a4cdd1ace37501620a4..63ffbe2211f332c645289f36a8a7a81af80a0273 100644 (file)
@@ -170,7 +170,7 @@ SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
 }
 
 static int _serial_write(struct sr_serial_dev_inst *serial,
-               const void *buf, size_t count, int nonblocking)
+               const void *buf, size_t count, int nonblocking, unsigned int timeout_ms)
 {
        ssize_t ret;
        char *error;
@@ -188,7 +188,7 @@ static int _serial_write(struct sr_serial_dev_inst *serial,
        if (nonblocking)
                ret = sp_nonblocking_write(serial->data, buf, count);
        else
-               ret = sp_blocking_write(serial->data, buf, count, 0);
+               ret = sp_blocking_write(serial->data, buf, count, timeout_ms);
 
        switch (ret) {
        case SP_ERR_ARG:
@@ -212,15 +212,17 @@ static int _serial_write(struct sr_serial_dev_inst *serial,
  * @param serial Previously initialized serial port structure.
  * @param[in] buf Buffer containing the bytes to write.
  * @param[in] count Number of bytes to write.
+ * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
  *
  * @retval SR_ERR_ARG Invalid argument.
  * @retval SR_ERR Other error.
- * @retval other The number of bytes written.
+ * @retval other The number of bytes written. If this is less than the number
+ * specified in the call, the timeout was reached.
  */
 SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial,
-               const void *buf, size_t count)
+               const void *buf, size_t count, unsigned int timeout_ms)
 {
-       return _serial_write(serial, buf, count, 0);
+       return _serial_write(serial, buf, count, 0, timeout_ms);
 }
 
 /**
@@ -237,11 +239,11 @@ SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial,
 SR_PRIV int serial_write_nonblocking(struct sr_serial_dev_inst *serial,
                const void *buf, size_t count)
 {
-       return _serial_write(serial, buf, count, 1);
+       return _serial_write(serial, buf, count, 1, 0);
 }
 
 static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
-               size_t count, int nonblocking)
+               size_t count, int nonblocking, unsigned int timeout_ms)
 {
        ssize_t ret;
        char *error;
@@ -259,7 +261,7 @@ static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
        if (nonblocking)
                ret = sp_nonblocking_read(serial->data, buf, count);
        else
-               ret = sp_blocking_read(serial->data, buf, count, 0);
+               ret = sp_blocking_read(serial->data, buf, count, timeout_ms);
 
        switch (ret) {
        case SP_ERR_ARG:
@@ -284,15 +286,17 @@ static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
  * @param serial Previously initialized serial port structure.
  * @param buf Buffer where to store the bytes that are read.
  * @param[in] count The number of bytes to read.
+ * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
  *
  * @retval SR_ERR_ARG Invalid argument.
  * @retval SR_ERR     Other error.
- * @retval other      The number of bytes read.
+ * @retval other      The number of bytes read. If this is less than the number
+ * requested, the timeout was reached.
  */
 SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf,
-               size_t count)
+               size_t count, unsigned int timeout_ms)
 {
-       return _serial_read(serial, buf, count, 0);
+       return _serial_read(serial, buf, count, 0, timeout_ms);
 }
 
 /**
@@ -310,7 +314,7 @@ SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf,
 SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf,
                size_t count)
 {
-       return _serial_read(serial, buf, count, 1);
+       return _serial_read(serial, buf, count, 1, 0);
 }
 
 /**