+static int check_usbtmc_blacklist(struct usbtmc_blacklist *blacklist,
+ uint16_t vid, uint16_t pid)
+{
+ int i;
+
+ for (i = 0; blacklist[i].vid; i++) {
+ if (blacklist[i].vid == vid && blacklist[i].pid == pid)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int scpi_usbtmc_remote(struct scpi_usbtmc_libusb *uscpi)
+{
+ struct sr_usb_dev_inst *usb = uscpi->usb;
+ struct libusb_device *dev;
+ struct libusb_device_descriptor des;
+ int ret;
+ uint8_t status;
+
+ if (!(uscpi->usb488_dev_cap & USB488_DEV_CAP_RL1))
+ return SR_OK;
+
+ dev = libusb_get_device(usb->devhdl);
+ libusb_get_device_descriptor(dev, &des);
+ if (check_usbtmc_blacklist(blacklist_remote, des.idVendor, des.idProduct))
+ return SR_OK;
+
+ sr_dbg("Locking out local control.");
+ ret = libusb_control_transfer(usb->devhdl,
+ LIBUSB_ENDPOINT_IN |
+ LIBUSB_REQUEST_TYPE_CLASS |
+ LIBUSB_RECIPIENT_INTERFACE,
+ REN_CONTROL, 1,
+ uscpi->interface,
+ &status, 1,
+ TRANSFER_TIMEOUT);
+ if (ret < 0 || status != USBTMC_STATUS_SUCCESS) {
+ if (ret < 0)
+ sr_dbg("Failed to enter REN state: %s.", libusb_error_name(ret));
+ else
+ sr_dbg("Failed to enter REN state: USBTMC status %d.", status);
+ return SR_ERR;
+ }
+
+ ret = libusb_control_transfer(usb->devhdl,
+ LIBUSB_ENDPOINT_IN |
+ LIBUSB_REQUEST_TYPE_CLASS |
+ LIBUSB_RECIPIENT_INTERFACE,
+ LOCAL_LOCKOUT, 1,
+ uscpi->interface,
+ &status, 1,
+ TRANSFER_TIMEOUT);
+ if (ret < 0 || status != USBTMC_STATUS_SUCCESS) {
+ if (ret < 0)
+ sr_dbg("Failed to enter local lockout state: %s.",
+ libusb_error_name(ret));
+ else
+ sr_dbg("Failed to enter local lockout state: USBTMC "
+ "status %d.", status);
+ return SR_ERR;
+ }
+
+ return SR_OK;
+}
+
+static void scpi_usbtmc_local(struct scpi_usbtmc_libusb *uscpi)