+/**
+ * Close the specified serial port.
+ *
+ * @param serial Previously initialized serial port structure.
+ *
+ * @return SR_OK on success, SR_ERR on failure.
+ */
+SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
+{
+ int ret;
+ char *error;
+
+ if (!serial) {
+ sr_dbg("Invalid serial port.");
+ return SR_ERR;
+ }
+
+ if (serial->fd == -1) {
+ sr_dbg("Cannot close unopened serial port %s (fd %d).",
+ serial->port, serial->fd);
+ return SR_ERR;
+ }
+
+ sr_spew("Closing serial port %s (fd %d).", serial->port, serial->fd);
+
+ ret = sp_close(serial->data);
+ sp_free_port(serial->data);
+
+ switch (ret) {
+ case SP_ERR_ARG:
+ sr_err("Attempt to close an invalid serial port.");
+ return SR_ERR_ARG;
+ case SP_ERR_FAIL:
+ error = sp_last_error_message();
+ sr_err("Error closing port: %s.", error);
+ sp_free_error_message(error);
+ return SR_ERR;
+ }
+
+ serial->fd = -1;
+
+ return SR_OK;
+}
+
+/**
+ * Flush serial port buffers.
+ *
+ * @param serial Previously initialized serial port structure.
+ *
+ * @return SR_OK on success, SR_ERR on failure.
+ */
+SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
+{
+ int ret;
+ char *error;
+
+ if (!serial) {
+ sr_dbg("Invalid serial port.");
+ return SR_ERR;
+ }
+
+ if (serial->fd == -1) {
+ sr_dbg("Cannot flush unopened serial port %s (fd %d).",
+ serial->port, serial->fd);
+ return SR_ERR;
+ }
+
+ sr_spew("Flushing serial port %s (fd %d).", serial->port, serial->fd);
+
+ ret = sp_flush(serial->data);
+
+ switch (ret) {
+ case SP_ERR_ARG:
+ sr_err("Attempt to flush an invalid serial port.");
+ return SR_ERR_ARG;
+ case SP_ERR_FAIL:
+ error = sp_last_error_message();
+ sr_err("Error flushing port: %s.", error);
+ sp_free_error_message(error);
+ return SR_ERR;
+ }
+
+ return SR_OK;
+}
+
+/**
+ * Write a number of bytes to the specified serial port.
+ *
+ * @param serial Previously initialized serial port structure.
+ * @param buf Buffer containing the bytes to write.
+ * @param count Number of bytes to write.
+ *
+ * @return The number of bytes written, or a negative error code upon failure.
+ */
+SR_PRIV int serial_write(struct sr_serial_dev_inst *serial,
+ const void *buf, size_t count)
+{
+ ssize_t ret;
+ char *error;
+
+ if (!serial) {
+ sr_dbg("Invalid serial port.");
+ return SR_ERR;
+ }
+
+ if (serial->fd == -1) {
+ sr_dbg("Cannot use unopened serial port %s (fd %d).",
+ serial->port, serial->fd);
+ return SR_ERR;
+ }
+
+ ret = sp_write(serial->data, buf, count);
+
+ switch (ret) {
+ case SP_ERR_ARG:
+ sr_err("Attempted serial port write with invalid arguments.");
+ return SR_ERR_ARG;
+ case SP_ERR_FAIL:
+ error = sp_last_error_message();
+ sr_err("Write error: %s.", error);
+ sp_free_error_message(error);
+ return SR_ERR;
+ }
+
+ sr_spew("Wrote %d/%d bytes (fd %d).", ret, count, serial->fd);
+
+ return ret;
+}
+
+/**
+ * Read a number of bytes from the specified serial port.
+ *
+ * @param serial Previously initialized serial port structure.
+ * @param buf Buffer where to store the bytes that are read.
+ * @param count The number of bytes to read.
+ *
+ * @return The number of bytes read, or a negative error code upon failure.
+ */
+SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf,
+ size_t count)