]> sigrok.org Git - libsigrok.git/blobdiff - src/serial_hid.c
serial: add routine to manipulate handshake state (RTS, DTR)
[libsigrok.git] / src / serial_hid.c
index 1aca73e62254d1ab1d928dab0223c60f3da5c4de..eccdf0f22ef5a0c1c5274d0931db98685aec3294 100644 (file)
@@ -31,9 +31,7 @@
 #include <windows.h> /* for HANDLE */
 #endif
 
-/** @cond PRIVATE */
 #define LOG_PREFIX "serial-hid"
-/** @endcond */
 
 #ifdef HAVE_SERIAL_COMM
 
@@ -74,6 +72,8 @@ static void ser_hid_mask_databits(struct sr_serial_dev_inst *serial,
 /* }}} */
 /* {{{ open/close/list/find HIDAPI connection, exchange HID requests and data */
 
+#define IOKIT_PATH_PREFIX      "IOService:"
+
 /*
  * Convert a HIDAPI path (which depends on the target platform, and may
  * depend on one of several available API variants on that platform) to
@@ -96,22 +96,49 @@ static char *get_hidapi_path_copy(const char *path)
 
        int has_colon;
        int is_hex_colon;
-       char *name;
+       const char *parse, *remain;
+       char *copy;
 
-       has_colon = strchr(path, ':') != NULL;
-       is_hex_colon = strspn(path, accept) == strlen(path);
-       if (has_colon && !is_hex_colon) {
-               sr_err("Unsupported HIDAPI path format: %s", path);
-               return NULL;
-       }
+       parse = path;
+       has_colon = strchr(parse, ':') != NULL;
+       is_hex_colon = strspn(parse, accept) == strlen(parse);
        if (is_hex_colon) {
-               name = g_strdup_printf("%s%s", SER_HID_USB_PREFIX, path);
-               g_strcanon(name + strlen(SER_HID_USB_PREFIX), keep, '.');
-       } else {
-               name = g_strdup_printf("%s%s", SER_HID_RAW_PREFIX, path);
+               /* All hex digits and colon only. Simple substitution. */
+               copy = g_strdup_printf("%s%s", SER_HID_USB_PREFIX, parse);
+               g_strcanon(copy + strlen(SER_HID_USB_PREFIX), keep, '.');
+               return copy;
        }
-
-       return name;
+       if (!has_colon) {
+               /* "Something raw" and no colon. Add raw= prefix. */
+               copy = g_strdup_printf("%s%s", SER_HID_RAW_PREFIX, parse);
+               return copy;
+       }
+       if (g_str_has_prefix(parse, IOKIT_PATH_PREFIX)) do {
+               /*
+                * Path starts with Mac IOKit literal which contains the
+                * colon. Drop that literal from the start of the path,
+                * and check whether any colon remains which we cannot
+                * deal with. Fall though to other approaches which could
+                * be more generic, or to the error path.
+                */
+               remain = &parse[strlen(IOKIT_PATH_PREFIX)];
+               if (strchr(remain, ':'))
+                       break;
+               copy = g_strdup_printf("%s%s", SER_HID_IOKIT_PREFIX, remain);
+               return copy;
+       } while (0);
+
+       /* TODO
+        * Consider adding support for more of the currently unhandled
+        * cases. When we get here, the HIDAPI path could be arbitrarily
+        * complex, none of the above "straight" approaches took effect.
+        * Proper escaping or other transformations could get applied,
+        * though they decrease usability the more they obfuscate the
+        * resulting port name. Ideally users remain able to recognize
+        * their device or cable or port after the manipulation.
+        */
+       sr_err("Unsupported HIDAPI path format: %s", path);
+       return NULL;
 }
 
 /*
@@ -122,24 +149,32 @@ static char *get_hidapi_path_copy(const char *path)
  * Strip off the "raw" prefix, or undo colon substitution. See @ref
  * get_hidapi_path_copy() for details.
  */
-static const char *extract_hidapi_path(char *buffer)
+static char *extract_hidapi_path(const char *copy)
 {
        static const char *keep = "0123456789abcdefABCDEF:";
 
        const char *p;
+       char *path;
 
-       p = buffer;
+       p = copy;
        if (!p || !*p)
                return NULL;
 
-       if (strncmp(p, SER_HID_RAW_PREFIX, strlen(SER_HID_RAW_PREFIX)) == 0) {
+       if (g_str_has_prefix(p, SER_HID_IOKIT_PREFIX)) {
+               p += strlen(SER_HID_IOKIT_PREFIX);
+               path = g_strdup_printf("%s%s", IOKIT_PATH_PREFIX, p);
+               return path;
+       }
+       if (g_str_has_prefix(p, SER_HID_RAW_PREFIX)) {
                p += strlen(SER_HID_RAW_PREFIX);
-               return p;
+               path = g_strdup(p);
+               return path;
        }
-       if (strncmp(p, SER_HID_USB_PREFIX, strlen(SER_HID_USB_PREFIX)) == 0) {
+       if (g_str_has_prefix(p, SER_HID_USB_PREFIX)) {
                p += strlen(SER_HID_USB_PREFIX);
-               g_strcanon(buffer, keep, ':');
-               return p;
+               path = g_strdup(p);
+               g_strcanon(path, keep, ':');
+               return path;
        }
 
        return NULL;
@@ -167,8 +202,6 @@ static GSList *ser_hid_hidapi_list(GSList *list, sr_ser_list_append_t append)
                 */
                vid = curdev->vendor_id;
                pid = curdev->product_id;
-               sr_dbg("DIAG: hidapi enum, vid:pid %04x:%04x, path %s\n",
-                       curdev->vendor_id, curdev->product_id, curdev->path);
                chipname = ser_hid_chip_find_name_vid_pid(vid, pid);
                if (!chipname)
                        chipname = "<chip>";
@@ -199,14 +232,14 @@ static GSList *ser_hid_hidapi_list(GSList *list, sr_ser_list_append_t append)
                pid = curdev->product_id;
                desc = g_string_sized_new(128);
                g_string_append_printf(desc, "HID");
-               if (manuf)
+               if (manuf && wcslen(manuf) != 0)
                        g_string_append_printf(desc, " %ls", manuf);
-               if (prod)
+               if (prod && wcslen(prod) != 0)
                        g_string_append_printf(desc, " %ls", prod);
-               if (serno)
+               if (serno && wcslen(serno) != 0)
                        g_string_append_printf(desc, " %ls", serno);
                if (vid && pid)
-                       g_string_append_printf(desc, " %04hx:%04hx", vid, pid);
+                       g_string_append_printf(desc, " [%04hx.%04hx]", vid, pid);
                list = append(list, name, desc->str);
                g_string_free(desc, TRUE);
                g_free(name);
@@ -240,18 +273,16 @@ static GSList *ser_hid_hidapi_find_usb(GSList *list, sr_ser_find_append_t append
 /* Get the serial number of a device specified by path. */
 static int ser_hid_hidapi_get_serno(const char *path, char *buf, size_t blen)
 {
-       char *usbpath;
-       const char *hidpath;
+       char *hidpath;
        hid_device *dev;
        wchar_t *serno_wch;
        int rc;
 
        if (!path || !*path)
                return SR_ERR_ARG;
-       usbpath = g_strdup(path);
-       hidpath = extract_hidapi_path(usbpath);
+       hidpath = extract_hidapi_path(path);
        dev = hidpath ? hid_open_path(hidpath) : NULL;
-       g_free(usbpath);
+       g_free(hidpath);
        if (!dev)
                return SR_ERR_IO;
 
@@ -305,17 +336,13 @@ static int ser_hid_hidapi_get_vid_pid(const char *path,
         * its meaning are said to be OS specific, which is why we may
         * not assume anything about it...
         */
-       char *usbpath;
-       const char *hidpath;
+       char *hidpath;
        struct hid_device_info *devs, *dev;
        int found;
 
-       usbpath = g_strdup(path);
-       hidpath = extract_hidapi_path(usbpath);
-       if (!hidpath) {
-               g_free(usbpath);
+       hidpath = extract_hidapi_path(path);
+       if (!hidpath)
                return SR_ERR_NA;
-       }
 
        devs = hid_enumerate(0x0000, 0x0000);
        found = 0;
@@ -330,7 +357,7 @@ static int ser_hid_hidapi_get_vid_pid(const char *path,
                break;
        }
        hid_free_enumeration(devs);
-       g_free(usbpath);
+       g_free(hidpath);
 
        return found ? SR_OK : SR_ERR_NA;
 #endif
@@ -351,9 +378,8 @@ static int ser_hid_hidapi_open_dev(struct sr_serial_dev_inst *serial)
        if (!serial->hid_path)
                serial->hid_path = extract_hidapi_path(serial->usb_path);
        hid_dev = hid_open_path(serial->hid_path);
-       sr_dbg("DBG: %s(), hid_open_path(\"%s\") => %p", __func__,
-                       serial->hid_path, hid_dev);
        if (!hid_dev) {
+               g_free((void *)serial->hid_path);
                serial->hid_path = NULL;
                return SR_ERR_IO;
        }
@@ -369,6 +395,7 @@ static void ser_hid_hidapi_close_dev(struct sr_serial_dev_inst *serial)
        if (serial->hid_dev) {
                hid_close(serial->hid_dev);
                serial->hid_dev = NULL;
+               g_free((void *)serial->hid_path);
                serial->hid_path = NULL;
        }
        g_slist_free_full(serial->hid_source_args, g_free);
@@ -395,7 +422,6 @@ static int hidapi_source_cb(int fd, int revents, void *cb_data)
        uint8_t rx_buf[SER_HID_CHUNK_SIZE];
        int rc;
 
-       sr_dbg("DBG: %s() fd %d, evt 0x%x, data %p.", __func__, fd, revents, cb_data);
        args = cb_data;
 
        /*
@@ -408,7 +434,6 @@ static int hidapi_source_cb(int fd, int revents, void *cb_data)
                rc = args->serial->hid_chip_funcs->read_bytes(args->serial,
                                rx_buf, sizeof(rx_buf), 0);
                if (rc > 0) {
-                       sr_dbg("DBG: %s() queueing %d bytes.", __func__, rc);
                        ser_hid_mask_databits(args->serial, rx_buf, rc);
                        sr_ser_queue_rx_data(args->serial, rx_buf, rc);
                }
@@ -423,7 +448,6 @@ static int hidapi_source_cb(int fd, int revents, void *cb_data)
        if (sr_ser_has_queued_data(args->serial))
                revents |= G_IO_IN;
        rc = args->cb(fd, revents, args->cb_data);
-       sr_dbg("DBG: %s() rc %d.", __func__, rc);
 
        return rc;
 }
@@ -436,7 +460,6 @@ static int ser_hid_hidapi_setup_source_add(struct sr_session *session,
        struct hidapi_source_args_t *args;
        int rc;
 
-       sr_dbg("DBG: %s() evt 0x%x, to %d.", __func__, events, timeout);
        (void)events;
 
        /* Optionally enforce a minimum poll period. */
@@ -457,7 +480,6 @@ static int ser_hid_hidapi_setup_source_add(struct sr_session *session,
         */
        rc = sr_session_source_add(session, -1, events, timeout,
                        hidapi_source_cb, args);
-       sr_dbg("DBG: %s() added, rc %d.", __func__, rc);
        if (rc != SR_OK) {
                g_free(args);
                return rc;
@@ -472,7 +494,6 @@ static int ser_hid_hidapi_setup_source_remove(struct sr_session *session,
 {
        (void)serial;
 
-       sr_dbg("DBG: %s().", __func__);
        (void)sr_session_source_remove(session, -1);
        /*
         * Release callback args here already? Can there be more than
@@ -552,6 +573,7 @@ static struct ser_hid_chip_functions **chips[SER_HID_CHIP_LAST] = {
        [SER_HID_CHIP_UNKNOWN] = NULL,
        [SER_HID_CHIP_BTC_BU86X] = &ser_hid_chip_funcs_bu86x,
        [SER_HID_CHIP_SIL_CP2110] = &ser_hid_chip_funcs_cp2110,
+       [SER_HID_CHIP_VICTOR_DMM] = &ser_hid_chip_funcs_victor,
        [SER_HID_CHIP_WCH_CH9325] = &ser_hid_chip_funcs_ch9325,
 };
 
@@ -590,9 +612,9 @@ static int ser_hid_setup_funcs(struct sr_serial_dev_inst *serial)
  * returns the chip index and advances the spec pointer upon match,
  * returns SER_HID_CHIP_UNKNOWN upon mismatch.
  */
-static enum ser_hid_chip_t ser_hid_chip_find_enum(char **spec_p)
+static enum ser_hid_chip_t ser_hid_chip_find_enum(const char **spec_p)
 {
-       gchar *spec;
+       const gchar *spec;
        enum ser_hid_chip_t idx;
        struct ser_hid_chip_functions *desc;
 
@@ -634,9 +656,8 @@ SR_PRIV const char *ser_hid_chip_find_name_vid_pid(uint16_t vid, uint16_t pid)
                if (!vid_pids)
                        continue;
                while (vid_pids->vid) {
-                       if (vid_pids->vid == vid && vid_pids->pid == pid) {
+                       if (vid_pids->vid == vid && vid_pids->pid == pid)
                                return desc->chipname;
-                       }
                        vid_pids++;
                }
        }
@@ -644,17 +665,6 @@ SR_PRIV const char *ser_hid_chip_find_name_vid_pid(uint16_t vid, uint16_t pid)
        return NULL;
 }
 
-static const char *ser_hid_chip_get_text(enum ser_hid_chip_t idx)
-{
-       struct ser_hid_chip_functions *desc;
-
-       desc = get_hid_chip_funcs(idx);
-       if (!desc)
-               return NULL;
-
-       return desc->chipdesc;
-}
-
 /**
  * See if a text string is a valid USB path for a HID device.
  * @param[in] serial The serial port that is about to get opened.
@@ -686,8 +696,6 @@ static int try_open_path(struct sr_serial_dev_inst *serial, const char *path)
  * @return 0 upon success, non-zero upon failure. Fills the *_ref output
  * values.
  *
- * @internal
- *
  * Summary of parsing rules as they are implemented:
  * - Insist on the "hid" prefix. Accept "hid" alone without any other
  *   additional field.
@@ -733,14 +741,11 @@ static int ser_hid_parse_conn_spec(
 
        if (!serial || !spec || !*spec)
                return SR_ERR_ARG;
-       sr_dbg("DBG: %s(), input spec: %s", __func__, spec);
        p = spec;
 
        /* The "hid" prefix is mandatory. */
-       if (!g_str_has_prefix(p, SER_HID_CONN_PREFIX)) {
-               sr_dbg("DBG: %s(), not a HID port", __func__);
+       if (!g_str_has_prefix(p, SER_HID_CONN_PREFIX))
                return SR_ERR_ARG;
-       }
        p += strlen(SER_HID_CONN_PREFIX);
 
        /*
@@ -756,38 +761,38 @@ static int ser_hid_parse_conn_spec(
                        break;
                if (g_str_has_prefix(p, SER_HID_USB_PREFIX)) {
                        rc = try_open_path(serial, p);
-                       sr_dbg("DBG: %s(), open usb path %s => rc %d", __func__, p, rc);
+                       if (rc != SR_OK)
+                               return rc;
+                       path = g_strdup(p);
+                       p += strlen(p);
+               } else if (g_str_has_prefix(p, SER_HID_IOKIT_PREFIX)) {
+                       rc = try_open_path(serial, p);
                        if (rc != SR_OK)
                                return rc;
                        path = g_strdup(p);
                        p += strlen(p);
                } else if (g_str_has_prefix(p, SER_HID_RAW_PREFIX)) {
                        rc = try_open_path(serial, p);
-                       sr_dbg("DBG: %s(), open raw path %s => rc %d", __func__, p, rc);
                        if (rc != SR_OK)
                                return rc;
                        path = g_strdup(p);
                        p += strlen(p);
                } else if (g_str_has_prefix(p, SER_HID_SNR_PREFIX)) {
                        p += strlen(SER_HID_SNR_PREFIX);
-                       sr_dbg("DBG: %s(), snr %s", __func__, p);
                        serno = g_strdup(p);
                        p += strlen(p);
                } else if (!chip) {
-                       char *copy, *endptr;
-                       const char *name;
+                       char *copy;
+                       const char *endptr;
                        copy = g_strdup(p);
                        endptr = copy;
                        chip = ser_hid_chip_find_enum(&endptr);
-                       sr_dbg("DBG: %s(), chip search, %s => %u", __func__, p, chip);
                        if (!chip) {
                                g_free(copy);
                                return SR_ERR_ARG;
                        }
                        p += endptr - copy;
                        g_free(copy);
-                       name = ser_hid_chip_get_text(chip);
-                       sr_dbg("DBG: %s(), chip %s", __func__, name);
                } else {
                        sr_err("unsupported conn= spec %s, error at %s", spec, p);
                        return SR_ERR_ARG;
@@ -798,7 +803,6 @@ static int ser_hid_parse_conn_spec(
                        break;
        }
 
-       sr_dbg("DBG: %s() done, chip %d, path %s, serno %s", __func__, chip, path, serno);
        if (chip_ref)
                *chip_ref = chip;
        if (path_ref && path)
@@ -812,28 +816,19 @@ static int ser_hid_parse_conn_spec(
 /* Get and compare serial number. Boolean return value. */
 static int check_serno(const char *path, const char *serno_want)
 {
-       char *usb_path;
-       const char *hid_path;
+       char *hid_path;
        char serno_got[128];
        int rc;
 
-       sr_dbg("DBG: %s(\"%s\", \"%s\")", __func__, path, serno_want);
-
-       usb_path = g_strdup(path);
-       hid_path = extract_hidapi_path(usb_path);
+       hid_path = extract_hidapi_path(path);
        rc = ser_hid_hidapi_get_serno(hid_path, serno_got, sizeof(serno_got));
-       sr_dbg("DBG: %s(), usb %s, hidapi %s => rc %d", __func__, usb_path, hid_path, rc);
-       g_free(usb_path);
+       g_free(hid_path);
        if (rc) {
                sr_dbg("DBG: %s(), could not get serial number", __func__);
                return 0;
        }
-       sr_dbg("DBG: %s(), got serno \"%s\"", __func__, serno_got);
-
-       rc = strcmp(serno_got, serno_want) == 0;
-       sr_dbg("DBG: %s(), return %d", __func__, rc);
 
-       return rc;
+       return strcmp(serno_got, serno_want) == 0;
 }
 
 static GSList *append_find(GSList *devs, const char *path)
@@ -865,8 +860,6 @@ static GSList *list_paths_for_vids_pids(const struct vid_pid_item *vid_pids)
                        vid = vid_pids[idx].vid;
                        pid = vid_pids[idx].pid;
                }
-               sr_dbg("DBG: %s(), searching VID:PID %04hx:%04hx",
-                               __func__, vid, pid);
                list = ser_hid_hidapi_find_usb(list, append_find, vid, pid);
                if (!vid_pids)
                        break;
@@ -885,8 +878,6 @@ static GSList *list_paths_for_vids_pids(const struct vid_pid_item *vid_pids)
  * @retval SR_OK upon success
  * @retval SR_ERR_* upon failure.
  *
- * @internal
- *
  * This routine fills in blanks which the conn= spec parser left open.
  * When not specified yet, the HID chip type gets determined. When a
  * serial number was specified, then search the corresponding device.
@@ -913,8 +904,6 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
        if (!path_ref)
                return SR_ERR_ARG;
        path = *path_ref;
-       sr_dbg("DBG: %s() enter, chip %d, path %s, serno %s", __func__,
-                       chip, path, serno ? serno : "<none>");
 
        /*
         * Simplify the more complex conditions somewhat by assigning
@@ -938,8 +927,6 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
        have_chip = (chip != SER_HID_CHIP_UNKNOWN) ? 1 : 0;
        have_path = (path && *path) ? 1 : 0;
        have_serno = (serno && *serno) ? 1 : 0;
-       sr_dbg("DBG: %s(), have chip %d, path %d, serno %d", __func__,
-                       have_chip, have_path, have_serno);
        if (have_path && have_serno) {
                sr_err("Unsupported combination of USB path and serno");
                return SR_ERR_ARG;
@@ -950,33 +937,26 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
        if (have_chip && !chip_funcs->vid_pid_items)
                return SR_ERR_NA;
        if (have_path && !have_chip) {
-               sr_dbg("DBG: %s(), searching chip for path %s", __func__, path);
                vid = pid = 0;
                rc = ser_hid_hidapi_get_vid_pid(path, &vid, &pid);
-               sr_dbg("DBG: %s(), rc %d, VID:PID %04x:%04x", __func__, rc, vid, pid);
                if (rc != SR_OK)
                        return rc;
                name = ser_hid_chip_find_name_vid_pid(vid, pid);
-               sr_dbg("DBG: %s(), name %s", __func__, name);
                if (!name || !*name)
                        return SR_ERR_NA;
-               chip = ser_hid_chip_find_enum((char **)&name);
-               sr_dbg("DBG: %s(), chip %d", __func__, chip);
+               chip = ser_hid_chip_find_enum(&name);
                if (chip == SER_HID_CHIP_UNKNOWN)
                        return SR_ERR_NA;
                have_chip = 1;
        }
        if (have_serno) {
-               sr_dbg("DBG: %s(), searching path for serno %s", __func__, serno);
                vid_pids = have_chip ? chip_funcs->vid_pid_items : NULL;
                list = list_paths_for_vids_pids(vid_pids);
-               sr_dbg("DBG: %s(), vid/pid list for chip type %p", __func__, list);
                if (!list)
                        return SR_ERR_NA;
                matched = NULL;
                for (tmplist = list; tmplist; tmplist = tmplist->next) {
                        path = get_hidapi_path_copy(tmplist->data);
-                       sr_dbg("DBG: %s(), checking %s", __func__, path);
                        serno_matched = check_serno(path, serno);
                        g_free(path);
                        if (!serno_matched)
@@ -987,31 +967,19 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
                if (!matched)
                        return SR_ERR_NA;
                path = g_strdup(matched->data);
-               sr_dbg("DBG: %s(), match, path %s", __func__, path);
                have_path = 1;
                g_slist_free_full(list, g_free);
        }
        if (!have_path) {
-               sr_dbg("DBG: %s(), searching path, chip %d", __func__, chip);
                vid_pids = have_chip ? chip_funcs->vid_pid_items : NULL;
                list = list_paths_for_vids_pids(vid_pids);
                if (!list)
                        return SR_ERR_NA;
-               for (tmplist = list; tmplist; tmplist = tmplist->next) {
-                       path = tmplist->data;
-                       sr_dbg("DBG: %s(), path %s", __func__, path);
-               }
                matched = matched2 = NULL;
                if (have_chip) {
                        /* List already only contains specified chip. */
                        matched = list;
-                       path = matched->data;
-                       sr_dbg("DBG: %s(), match 1 %s", __func__, path);
                        matched2 = list->next;
-                       if (matched2) {
-                               path = matched2->data;
-                               sr_dbg("DBG: %s(), match 2 %s", __func__, path);
-                       }
                }
                /* Works for lists with one or multiple chips. Saves indentation. */
                for (tmplist = list; tmplist; tmplist = tmplist->next) {
@@ -1023,12 +991,10 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
                                continue;
                        if (!matched) {
                                matched = tmplist;
-                               sr_dbg("DBG: %s(), match 1 %s", __func__, path);
                                continue;
                        }
                        if (!matched2) {
                                matched2 = tmplist;
-                               sr_dbg("DBG: %s(), match 2 %s", __func__, path);
                                break;
                        }
                }
@@ -1043,29 +1009,23 @@ static int ser_hid_chip_search(enum ser_hid_chip_t *chip_ref,
                if (matched2)
                        sr_info("More than one cable matches, random pick.");
                path = get_hidapi_path_copy(matched->data);
-               sr_dbg("DBG: %s(), match, path %s", __func__, path);
                have_path = 1;
                g_slist_free_full(list, g_free);
        }
        if (have_path && !have_chip) {
-               sr_dbg("DBG: %s(), searching chip for path %s", __func__, path);
                vid = pid = 0;
                rc = ser_hid_hidapi_get_vid_pid(path, &vid, &pid);
-               sr_dbg("DBG: %s(), rc %d, VID:PID %04x:%04x", __func__, rc, vid, pid);
                if (rc != SR_OK)
                        return rc;
                name = ser_hid_chip_find_name_vid_pid(vid, pid);
-               sr_dbg("DBG: %s(), name %s", __func__, name);
                if (!name || !*name)
                        return SR_ERR_NA;
-               chip = ser_hid_chip_find_enum((char **)&name);
-               sr_dbg("DBG: %s(), chip %d", __func__, chip);
+               chip = ser_hid_chip_find_enum(&name);
                if (chip == SER_HID_CHIP_UNKNOWN)
                        return SR_ERR_NA;
                have_chip = 1;
        }
 
-       sr_dbg("DBG: %s() leave, chip %d, path %s", __func__, chip, path);
        if (chip_ref)
                *chip_ref = chip;
        if (path_ref)
@@ -1123,7 +1083,6 @@ static int ser_hid_open(struct sr_serial_dev_inst *serial, int flags)
         * device's USB path.
         */
        if (!chip || !usbpath || serno) {
-               sr_dbg("DBG: %s(), searching ...", __func__);
                rc = ser_hid_chip_search(&chip, &usbpath, serno);
                if (rc != 0)
                        return SR_ERR_NA;
@@ -1153,7 +1112,6 @@ static int ser_hid_open(struct sr_serial_dev_inst *serial, int flags)
                serial->usb_serno = NULL;
                return SR_ERR_IO;
        }
-       sr_dbg("DBG: %s() done, OK", __func__);
 
        if (!serial->rcv_buffer)
                serial->rcv_buffer = g_string_sized_new(SER_HID_CHUNK_SIZE);
@@ -1163,7 +1121,6 @@ static int ser_hid_open(struct sr_serial_dev_inst *serial, int flags)
 
 static int ser_hid_close(struct sr_serial_dev_inst *serial)
 {
-       sr_dbg("DBG: %s()", __func__);
        ser_hid_hidapi_close_dev(serial);
 
        return SR_OK;
@@ -1173,21 +1130,14 @@ static int ser_hid_set_params(struct sr_serial_dev_inst *serial,
        int baudrate, int bits, int parity, int stopbits,
        int flowcontrol, int rts, int dtr)
 {
-       int rc;
-
-       sr_dbg("DBG: %s() enter", __func__);
        if (ser_hid_setup_funcs(serial) != 0)
                return SR_ERR_NA;
-       sr_dbg("DBG: %s() chip funcs set", __func__);
        if (!serial->hid_chip_funcs || !serial->hid_chip_funcs->set_params)
                return SR_ERR_NA;
-       sr_dbg("DBG: %s() set params avail", __func__);
-       rc = serial->hid_chip_funcs->set_params(serial,
+
+       return serial->hid_chip_funcs->set_params(serial,
                baudrate, bits, parity, stopbits,
                flowcontrol, rts, dtr);
-       sr_dbg("DBG: %s() set params rc %d", __func__, rc);
-
-       return rc;
 }
 
 static int ser_hid_setup_source_add(struct sr_session *session,
@@ -1243,7 +1193,6 @@ static int ser_hid_write(struct sr_serial_dev_inst *serial,
        if (!serial->hid_chip_funcs->max_bytes_per_request)
                return SR_ERR_NA;
 
-       sr_dbg("DBG: %s() shall send %zu bytes TX data.", __func__, count);
        total = 0;
        max_chunk = serial->hid_chip_funcs->max_bytes_per_request;
        while (count > 0) {
@@ -1285,9 +1234,6 @@ static int ser_hid_read(struct sr_serial_dev_inst *serial,
        int rc;
        unsigned int got;
 
-       sr_dbg("DBG: %s() count %zd, block %d, to %u", __func__,
-                       count, !nonblocking, timeout_ms);
-
        if (!serial->hid_chip_funcs || !serial->hid_chip_funcs->read_bytes)
                return SR_ERR_NA;
        if (!serial->hid_chip_funcs->max_bytes_per_request)
@@ -1297,10 +1243,8 @@ static int ser_hid_read(struct sr_serial_dev_inst *serial,
         * Immediately satisfy the caller's request from the RX buffer
         * if the requested amount of data is available already.
         */
-       if (sr_ser_has_queued_data(serial) >= count) {
-               rc = sr_ser_unqueue_rx_data(serial, buf, count);
-               return rc;
-       }
+       if (sr_ser_has_queued_data(serial) >= count)
+               return sr_ser_unqueue_rx_data(serial, buf, count);
 
        /*
         * When a timeout was specified, then determine the deadline
@@ -1352,7 +1296,6 @@ static int ser_hid_read(struct sr_serial_dev_inst *serial,
                        return SR_ERR;
                }
                if (rc) {
-                       sr_dbg("DBG: %s() queueing %d bytes.", __func__, rc);
                        ser_hid_mask_databits(serial, buffer, rc);
                        sr_ser_queue_rx_data(serial, buffer, rc);
                }
@@ -1385,10 +1328,8 @@ static int ser_hid_read(struct sr_serial_dev_inst *serial,
         */
        if (got > count)
                got = count;
-       sr_dbg("DBG: %s() passing %d bytes.", __func__, got);
-       rc = sr_ser_unqueue_rx_data(serial, buf, count);
 
-       return rc;
+       return sr_ser_unqueue_rx_data(serial, buf, count);
 }
 
 static struct ser_lib_functions serlib_hid = {
@@ -1399,6 +1340,7 @@ static struct ser_lib_functions serlib_hid = {
        .write = ser_hid_write,
        .read = ser_hid_read,
        .set_params = ser_hid_set_params,
+       .set_handshake = std_dummy_set_handshake,
        .setup_source_add = ser_hid_setup_source_add,
        .setup_source_remove = ser_hid_setup_source_remove,
        .list = ser_hid_list,