diff options
Diffstat (limited to 'lib/iface.c')
-rw-r--r-- | lib/iface.c | 317 |
1 files changed, 149 insertions, 168 deletions
diff --git a/lib/iface.c b/lib/iface.c index 3c8cb80..85dfcd8 100644 --- a/lib/iface.c +++ b/lib/iface.c @@ -74,6 +74,155 @@ uhd_iface_free(uhd_iface *iface) } +enum libusb_error +uhd_iface_detach(uhd_iface *iface) +{ + enum libusb_error err; + + assert(uhd_iface_valid(iface)); + + err = libusb_detach_kernel_driver(iface->handle, iface->number); + if (err == LIBUSB_SUCCESS) + iface->detached = true; + else if (err != LIBUSB_ERROR_NOT_FOUND) + return err; + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_attach(uhd_iface *iface) +{ + enum libusb_error err; + + assert(uhd_iface_valid(iface)); + + if (iface->detached) + { + err = libusb_attach_kernel_driver(iface->handle, iface->number); + if (err != LIBUSB_SUCCESS) + return err; + iface->detached = false; + } + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_claim(uhd_iface *iface) +{ + enum libusb_error err; + + assert(uhd_iface_valid(iface)); + + err = libusb_claim_interface(iface->handle, iface->number); + if (err != LIBUSB_SUCCESS) + return err; + + iface->claimed = true; + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_release(uhd_iface *iface) +{ + enum libusb_error err; + + assert(uhd_iface_valid(iface)); + + err = libusb_release_interface(iface->handle, iface->number); + if (err != LIBUSB_SUCCESS) + return err; + + iface->claimed = false; + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_clear_halt(uhd_iface *iface) +{ + enum libusb_error err; + + assert(uhd_iface_valid(iface)); + + err = libusb_clear_halt(iface->handle, iface->int_in_ep_addr); + if (err != LIBUSB_SUCCESS) + return err; + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_set_idle(const uhd_iface *iface, + uint8_t duration, + unsigned int timeout) +{ + int rc; + + assert(uhd_iface_valid(iface)); + + rc = libusb_control_transfer(iface->handle, + /* host->device, class, interface */ + 0x21, + /* Set_Idle */ + 0x0A, + /* duration for all report IDs */ + duration << 8, + /* interface */ + iface->number, + NULL, 0, + timeout); + /* + * Ignoring EPIPE, which means a STALL handshake, which is OK on + * control pipes and indicates request is not supported. + * See USB 2.0 spec, 8.4.5 Handshake Packets + */ + if (rc < 0 && rc != LIBUSB_ERROR_PIPE) + return rc; + + return LIBUSB_SUCCESS; +} + + +enum libusb_error +uhd_iface_set_protocol(const uhd_iface *iface, + bool report, + unsigned int timeout) +{ + int rc; + + assert(uhd_iface_valid(iface)); + + rc = libusb_control_transfer(iface->handle, + /* host->device, class, interface */ + 0x21, + /* Set_Protocol */ + 0x0B, + /* 0 - boot, 1 - report */ + report ? 1 : 0, + /* interface */ + iface->number, + NULL, 0, + timeout); + /* + * Ignoring EPIPE, which means a STALL handshake, which is OK on + * control pipes and indicates request is not supported. + * See USB 2.0 spec, 8.4.5 Handshake Packets + */ + if (rc < 0 && rc != LIBUSB_ERROR_PIPE) + return rc; + + return LIBUSB_SUCCESS; +} + + bool uhd_iface_list_valid(const uhd_iface *list) { @@ -224,171 +373,3 @@ uhd_iface_list_fltr_by_num(uhd_iface *list, } -enum libusb_error -uhd_iface_list_detach(uhd_iface *list) -{ - enum libusb_error err; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - { - err = libusb_detach_kernel_driver(list->handle, list->number); - if (err == LIBUSB_SUCCESS) - list->detached = true; - else if (err != LIBUSB_ERROR_NOT_FOUND) - return err; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_attach(uhd_iface *list) -{ - enum libusb_error err; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - if (list->detached) - { - err = libusb_attach_kernel_driver(list->handle, list->number); - if (err != LIBUSB_SUCCESS) - return err; - list->detached = false; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_claim(uhd_iface *list) -{ - enum libusb_error err; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - { - err = libusb_claim_interface(list->handle, list->number); - if (err != LIBUSB_SUCCESS) - return err; - - list->claimed = true; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_clear_halt(uhd_iface *list) -{ - enum libusb_error err; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - { - err = libusb_clear_halt(list->handle, list->int_in_ep_addr); - if (err != LIBUSB_SUCCESS) - return err; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_set_idle(const uhd_iface *list, - uint8_t duration, - unsigned int timeout) -{ - int rc; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - { - rc = libusb_control_transfer(list->handle, - /* host->device, class, interface */ - 0x21, - /* Set_Idle */ - 0x0A, - /* duration for all report IDs */ - duration << 8, - /* interface */ - list->number, - NULL, 0, - timeout); - /* - * Ignoring EPIPE, which means a STALL handshake, which is OK on - * control pipes and indicates request is not supported. - * See USB 2.0 spec, 8.4.5 Handshake Packets - */ - if (rc < 0 && rc != LIBUSB_ERROR_PIPE) - return rc; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_set_protocol(const uhd_iface *list, - bool report, - unsigned int timeout) -{ - int rc; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - { - rc = libusb_control_transfer(list->handle, - /* host->device, class, interface */ - 0x21, - /* Set_Protocol */ - 0x0B, - /* 0 - boot, 1 - report */ - report ? 1 : 0, - /* interface */ - list->number, - NULL, 0, - timeout); - /* - * Ignoring EPIPE, which means a STALL handshake, which is OK on - * control pipes and indicates request is not supported. - * See USB 2.0 spec, 8.4.5 Handshake Packets - */ - if (rc < 0 && rc != LIBUSB_ERROR_PIPE) - return rc; - } - - return LIBUSB_SUCCESS; -} - - -enum libusb_error -uhd_iface_list_release(uhd_iface *list) -{ - enum libusb_error err; - - assert(uhd_iface_list_valid(list)); - - for (; list != NULL; list = list->next) - if (list->claimed) - { - err = libusb_release_interface(list->handle, list->number); - if (err != LIBUSB_SUCCESS) - return err; - list->claimed = false; - } - - return LIBUSB_SUCCESS; -} - - |