X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fcommon%2Fscpi_usbtmc_libusb.c;h=653a0d8c9f4f79f99f76490d7d9ae5ce0131222f;hb=144f6660d004d60264a57db7150ed90e5f68ea77;hp=f66c97285aac56403e8d5d65d7caecf4b64dfbf6;hpb=20ed3ceee71d97ca594931a537d035503e6d6ec4;p=libsigrok.git diff --git a/hardware/common/scpi_usbtmc_libusb.c b/hardware/common/scpi_usbtmc_libusb.c index f66c9728..653a0d8c 100644 --- a/hardware/common/scpi_usbtmc_libusb.c +++ b/hardware/common/scpi_usbtmc_libusb.c @@ -43,6 +43,7 @@ struct scpi_usbtmc_libusb { int response_length; int response_bytes_read; int remaining_length; + int rigol_ds1000; }; /* Some USBTMC-specific enums, as defined in the USBTMC standard. */ @@ -102,17 +103,23 @@ static GSList *scpi_usbtmc_libusb_scan(struct drv_context *drvc) int confidx, intfidx, ret, i; char *res; - libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); + ret = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); + if (ret < 0) { + sr_err("Failed to get device list: %s.", + libusb_error_name(ret)); + return NULL; + } for (i = 0; devlist[i]; i++) { - if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { + if ((ret = libusb_get_device_descriptor(devlist[i], &des)) < 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } for (confidx = 0; confidx < des.bNumConfigurations; confidx++) { - if (libusb_get_config_descriptor(devlist[i], confidx, &confdes) != 0) { - sr_err("Failed to get configuration descriptor."); + if ((ret = libusb_get_config_descriptor(devlist[i], confidx, &confdes)) < 0) { + sr_dbg("Failed to get configuration descriptor: %s, " + "ignoring device.", libusb_error_name(ret)); break; } for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) { @@ -187,15 +194,16 @@ static int scpi_usbtmc_libusb_open(void *priv) return SR_ERR; dev = libusb_get_device(usb->devhdl); - if ((ret = libusb_get_device_descriptor(dev, &des))) { + if ((ret = libusb_get_device_descriptor(dev, &des)) < 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); return SR_ERR; } for (confidx = 0; confidx < des.bNumConfigurations; confidx++) { - if (libusb_get_config_descriptor(dev, confidx, &confdes) != 0) { - sr_err("Failed to get configuration descriptor."); + if ((ret = libusb_get_config_descriptor(dev, confidx, &confdes)) < 0) { + sr_dbg("Failed to get configuration descriptor: %s, " + "ignoring device.", libusb_error_name(ret)); continue; } for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) { @@ -227,6 +235,8 @@ static int scpi_usbtmc_libusb_open(void *priv) } } found = 1; + uscpi->rigol_ds1000 = des.idVendor == 0x1ab1 && + des.idProduct == 0x0588; } libusb_free_config_descriptor(confdes); if (found) @@ -234,35 +244,51 @@ static int scpi_usbtmc_libusb_open(void *priv) } if (!found) { - sr_err("Failed to find USBTMC interface"); + sr_err("Failed to find USBTMC interface."); return SR_ERR; } if (libusb_kernel_driver_active(usb->devhdl, uscpi->interface) == 1) { if ((ret = libusb_detach_kernel_driver(usb->devhdl, uscpi->interface)) < 0) { - sr_err("failed to detach kernel driver: %s", - libusb_error_name(ret)); + sr_err("Failed to detach kernel driver: %s.", + libusb_error_name(ret)); return SR_ERR; } uscpi->detached_kernel_driver = 1; } - if ((ret = libusb_set_configuration(usb->devhdl, config))) { - sr_err("Failed to set configuration: %s.", libusb_error_name(ret)); + if ((ret = libusb_set_configuration(usb->devhdl, config)) < 0) { + sr_err("Failed to set configuration: %s.", + libusb_error_name(ret)); return SR_ERR; } - if ((ret = libusb_claim_interface(usb->devhdl, uscpi->interface))) { - sr_err("Failed to claim interface: %s.", libusb_error_name(ret)); + if ((ret = libusb_claim_interface(usb->devhdl, uscpi->interface)) < 0) { + sr_err("Failed to claim interface: %s.", + libusb_error_name(ret)); return SR_ERR; } - libusb_clear_halt(usb->devhdl, uscpi->bulk_in_ep); - libusb_clear_halt(usb->devhdl, uscpi->bulk_out_ep); - libusb_clear_halt(usb->devhdl, uscpi->interrupt_ep); + if (!uscpi->rigol_ds1000) { + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_in_ep)) < 0) { + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->bulk_in_ep, libusb_error_name(ret)); + return SR_ERR; + } + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_out_ep)) < 0) { + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->bulk_out_ep, libusb_error_name(ret)); + return SR_ERR; + } + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->interrupt_ep)) < 0) { + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->interrupt_ep, libusb_error_name(ret)); + return SR_ERR; + } + } - /* get capabilities */ + /* Get capabilities. */ ret = libusb_control_transfer(usb->devhdl, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | @@ -276,7 +302,7 @@ static int scpi_usbtmc_libusb_open(void *priv) uscpi->usbtmc_dev_cap = capabilities[ 5]; uscpi->usb488_dev_cap = capabilities[15]; } - sr_dbg("device capabilities: %s%s%s%s%s, %s, %s", + sr_dbg("Device capabilities: %s%s%s%s%s, %s, %s", uscpi->usb488_dev_cap & USB488_DEV_CAP_SCPI ? "SCPI, " : "", uscpi->usbtmc_dev_cap & USBTMC_DEV_CAP_TERMCHAR ? "TermChar, ": "", uscpi->usbtmc_int_cap & USBTMC_INT_CAP_LISTEN_ONLY? "L3, " : @@ -291,7 +317,7 @@ static int scpi_usbtmc_libusb_open(void *priv) } static int scpi_usbtmc_libusb_source_add(void *priv, int events, int timeout, - sr_receive_data_callback_t cb, void *cb_data) + sr_receive_data_callback cb, void *cb_data) { struct scpi_usbtmc_libusb *uscpi = priv; (void)events; @@ -344,12 +370,12 @@ static int scpi_usbtmc_bulkout(struct scpi_usbtmc_libusb *uscpi, int padded_size, ret, transferred; if (data && size+USBTMC_BULK_HEADER_SIZE+3 > (int)sizeof(uscpi->buffer)) { - sr_err("USBTMC bulk out transfer too big"); + sr_err("USBTMC bulk out transfer is too big."); return SR_ERR; } uscpi->bTag++; - uscpi->bTag += !uscpi->bTag; /* bTag == 0 is invalid so avoid it */ + uscpi->bTag += !uscpi->bTag; /* bTag == 0 is invalid so avoid it. */ usbtmc_bulk_out_header_write(uscpi->buffer, msg_id, uscpi->bTag, size, transfer_attributes, 0); @@ -364,13 +390,14 @@ static int scpi_usbtmc_bulkout(struct scpi_usbtmc_libusb *uscpi, ret = libusb_bulk_transfer(usb->devhdl, uscpi->bulk_out_ep, uscpi->buffer, padded_size, &transferred, TRANSFER_TIMEOUT); - if (ret) { - sr_err("USBTMC bulk out transfer error: %d", ret); + if (ret < 0) { + sr_err("USBTMC bulk out transfer error: %s.", + libusb_error_name(ret)); return SR_ERR; } if (transferred < padded_size) { - sr_dbg("USBTMC bulkout partial transfer (%d/%d bytes)", + sr_dbg("USBTMC bulk out partial transfer (%d/%d bytes).", transferred, padded_size); return SR_ERR; } @@ -387,14 +414,15 @@ static int scpi_usbtmc_bulkin_start(struct scpi_usbtmc_libusb *uscpi, ret = libusb_bulk_transfer(usb->devhdl, uscpi->bulk_in_ep, data, size, &transferred, TRANSFER_TIMEOUT); - if (ret) { - sr_err("USBTMC bulk in transfer error: %d", ret); + if (ret < 0) { + sr_err("USBTMC bulk in transfer error: %s.", + libusb_error_name(ret)); return SR_ERR; } if (usbtmc_bulk_in_header_read(data, msg_id, uscpi->bTag, &message_size, transfer_attributes) != SR_OK) { - sr_err("USBTMC invalid bulk in header"); + sr_err("USBTMC invalid bulk in header."); return SR_ERR; } @@ -414,8 +442,9 @@ static int scpi_usbtmc_bulkin_continue(struct scpi_usbtmc_libusb *uscpi, ret = libusb_bulk_transfer(usb->devhdl, uscpi->bulk_in_ep, data, size, &transferred, TRANSFER_TIMEOUT); - if (ret) { - sr_err("USBTMC bulk in transfer error: %d", ret); + if (ret < 0) { + sr_err("USBTMC bulk in transfer error: %s.", + libusb_error_name(ret)); return SR_ERR; } @@ -493,18 +522,35 @@ static int scpi_usbtmc_libusb_read_complete(void *priv) static int scpi_usbtmc_libusb_close(void *priv) { + int ret; struct scpi_usbtmc_libusb *uscpi = priv; struct sr_usb_dev_inst *usb = uscpi->usb; if (!usb->devhdl) return SR_ERR; - libusb_clear_halt(usb->devhdl, uscpi->bulk_in_ep); - libusb_clear_halt(usb->devhdl, uscpi->bulk_out_ep); - libusb_clear_halt(usb->devhdl, uscpi->interrupt_ep); - libusb_release_interface(usb->devhdl, uscpi->interface); + if (!uscpi->rigol_ds1000) { + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_in_ep)) < 0) + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->bulk_in_ep, libusb_error_name(ret)); + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_out_ep)) < 0) + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->bulk_out_ep, libusb_error_name(ret)); + if ((ret = libusb_clear_halt(usb->devhdl, uscpi->interrupt_ep)) < 0) + sr_err("Failed to clear halt/stall condition for EP %d: %s.", + uscpi->interrupt_ep, libusb_error_name(ret)); + } + + if ((ret = libusb_release_interface(usb->devhdl, uscpi->interface)) < 0) + sr_err("Failed to release interface: %s.", + libusb_error_name(ret)); + if (uscpi->detached_kernel_driver) { - libusb_attach_kernel_driver(usb->devhdl, uscpi->interface); + if ((ret = libusb_attach_kernel_driver(usb->devhdl, + uscpi->interface)) < 0) + sr_err("Failed to re-attach kernel driver: %s.", + libusb_error_name(ret)); + uscpi->detached_kernel_driver = 0; } libusb_close(usb->devhdl); @@ -519,7 +565,6 @@ static void scpi_usbtmc_libusb_free(void *priv) sr_usb_dev_inst_free(uscpi->usb); } - SR_PRIV const struct sr_scpi_dev_inst scpi_usbtmc_libusb_dev = { .name = "USBTMC", .prefix = "usbtmc",