]> sigrok.org Git - libserialport.git/blobdiff - serialport.c
Minor Doxygen updates/fixes.
[libserialport.git] / serialport.c
index 45f9773bd56020dfbc9fba2453fbb0f3b3b0b73e..43dc4d3513e1230e2a34a3306de3ccb90bf5cf08 100644 (file)
@@ -173,7 +173,11 @@ void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler;
 #define RETURN_OK() RETURN_CODE(SP_OK);
 #define RETURN_ERROR(err, msg) do { DEBUG_ERROR(err, msg); return err; } while (0)
 #define RETURN_FAIL(msg) do { DEBUG_FAIL(msg); return SP_ERR_FAIL; } while (0)
-#define RETURN_VALUE(fmt, x) do { DEBUG("%s returning " fmt, __func__, x); return x; } while (0)
+#define RETURN_VALUE(fmt, x) do { \
+       typeof(x) _x = x; \
+       DEBUG("%s returning " fmt, __func__, _x); \
+       return _x; \
+} while (0)
 #define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0)
 #define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0)
 #define TRACE(fmt, ...) DEBUG("%s(" fmt ") called", __func__, ##__VA_ARGS__)
@@ -537,7 +541,7 @@ out:
                *list_ptr = list;
                RETURN_OK();
        case SP_ERR_SUPP:
-               DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform.");
+               DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform");
        default:
                if (list)
                        sp_free_port_list(list);
@@ -604,8 +608,9 @@ enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
        DEBUG("Opening port %s", port->name);
 
 #ifdef _WIN32
-       DWORD desired_access = 0, flags_and_attributes = 0;
+       DWORD desired_access = 0, flags_and_attributes = 0, errors;
        char *escaped_port_name;
+       COMSTAT status;
 
        /* Prefix port name with '\\.\' to work with ports above COM9. */
        if (!(escaped_port_name = malloc(strlen(port->name + 5))))
@@ -723,6 +728,11 @@ enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
        data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
 #endif
 
+#ifdef _WIN32
+       if (ClearCommError(port->hdl, &errors, &status) == 0)
+               RETURN_FAIL("ClearCommError() failed");
+#endif
+
        ret = set_config(port, &data, &config);
 
        if (ret < 0) {
@@ -996,20 +1006,27 @@ enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_
                /* Start asynchronous write. */
                if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
                        if (GetLastError() == ERROR_IO_PENDING) {
-                               DEBUG("Asynchronous write started");
-                               port->writing = 1;
-                               RETURN_VALUE("%d", ++written);
+                               if (HasOverlappedIoCompleted(&port->write_ovl)) {
+                                       DEBUG("Asynchronous write completed immediately");
+                                       port->writing = 0;
+                                       written++;
+                                       continue;
+                               } else {
+                                       DEBUG("Asynchronous write running");
+                                       port->writing = 1;
+                                       RETURN_VALUE("%d", ++written);
+                               }
                        } else {
                                /* Actual failure of some kind. */
                                RETURN_FAIL("WriteFile() failed");
                        }
                } else {
-                       DEBUG("Single byte written immediately.");
+                       DEBUG("Single byte written immediately");
                        written++;
                }
        }
 
-       DEBUG("All bytes written immediately.");
+       DEBUG("All bytes written immediately");
 
        RETURN_VALUE("%d", written);
 #else
@@ -1151,7 +1168,8 @@ enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count
                RETURN_FAIL("ReadFile() failed");
 
        /* Get number of bytes read. */
-       GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
+       if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
+               RETURN_FAIL("GetOverlappedResult() failed");
 
        RETURN_VALUE("%d", bytes_read);
 #else
@@ -1183,7 +1201,7 @@ enum sp_return sp_input_waiting(struct sp_port *port)
        COMSTAT comstat;
 
        if (ClearCommError(port->hdl, &errors, &comstat) == 0)
-               RETURN_FAIL("ClearComError() failed");
+               RETURN_FAIL("ClearCommError() failed");
        RETURN_VALUE("%d", comstat.cbInQue);
 #else
        int bytes_waiting;
@@ -1206,7 +1224,7 @@ enum sp_return sp_output_waiting(struct sp_port *port)
        COMSTAT comstat;
 
        if (ClearCommError(port->hdl, &errors, &comstat) == 0)
-               RETURN_FAIL("ClearComError() failed");
+               RETURN_FAIL("ClearCommError() failed");
        RETURN_VALUE("%d", comstat.cbOutQue);
 #else
        int bytes_waiting;
@@ -1570,7 +1588,6 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
 
        if (config->parity >= 0) {
                switch (config->parity) {
-               /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
                case SP_PARITY_NONE:
                        data->dcb.Parity = NOPARITY;
                        break;