Commit fe78a7c6 authored by Guido Kiener's avatar Guido Kiener Committed by Greg Kroah-Hartman
Browse files

usb: usbtmc: Add ioctl for trigger



add USBTMC488_IOCTL_TRIGGER to send TRIGGER Bulk-OUT header
according to Subclass USB488 Specification

The usbtmc trigger command is equivalent to the IEEE 488 GET (Group
Execute Trigger) action. While the "*TRG" command can be sent as
data to perform the same operation, in some situations an instrument
will be busy and unable to process the data immediately in which
case the USBTMC488_IOCTL_TRIGGER can be used to trigger the
instrument with lower latency.

Reviewed-by: default avatarSteve Bayless <steve_bayless@keysight.com>
Tested-by: default avatarDave Penkler <dpenkler@gmail.com>
Signed-off-by: default avatarDave Penkler <dpenkler@gmail.com>
Signed-off-by: default avatarGuido Kiener <guido.kiener@rohde-schwarz.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 048c6d88
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -557,6 +557,51 @@ static int usbtmc488_ioctl_simple(struct usbtmc_device_data *data,
	return rv;
}

/*
 * Sends a TRIGGER Bulk-OUT command message
 * See the USBTMC-USB488 specification, Table 2.
 *
 * Also updates bTag_last_write.
 */
static int usbtmc488_ioctl_trigger(struct usbtmc_file_data *file_data)
{
	struct usbtmc_device_data *data = file_data->data;
	int retval;
	u8 *buffer;
	int actual;

	buffer = kzalloc(USBTMC_HEADER_SIZE, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	buffer[0] = 128;
	buffer[1] = data->bTag;
	buffer[2] = ~data->bTag;

	retval = usb_bulk_msg(data->usb_dev,
			      usb_sndbulkpipe(data->usb_dev,
					      data->bulk_out),
			      buffer, USBTMC_HEADER_SIZE,
			      &actual, file_data->timeout);

	/* Store bTag (in case we need to abort) */
	data->bTag_last_write = data->bTag;

	/* Increment bTag -- and increment again if zero */
	data->bTag++;
	if (!data->bTag)
		data->bTag++;

	kfree(buffer);
	if (retval < 0) {
		dev_err(&data->intf->dev, "%s returned %d\n",
			__func__, retval);
		return retval;
	}

	return 0;
}

/*
 * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-OUT endpoint.
 * @transfer_size: number of bytes to request from the device.
@@ -1309,6 +1354,10 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
		retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
						USBTMC488_REQUEST_LOCAL_LOCKOUT);
		break;

	case USBTMC488_IOCTL_TRIGGER:
		retval = usbtmc488_ioctl_trigger(file_data);
		break;
	}

skip_io_on_zombie:
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
#define USBTMC488_IOCTL_REN_CONTROL	_IOW(USBTMC_IOC_NR, 19, unsigned char)
#define USBTMC488_IOCTL_GOTO_LOCAL	_IO(USBTMC_IOC_NR, 20)
#define USBTMC488_IOCTL_LOCAL_LOCKOUT	_IO(USBTMC_IOC_NR, 21)
#define USBTMC488_IOCTL_TRIGGER		_IO(USBTMC_IOC_NR, 22)

/* Driver encoded usb488 capabilities */
#define USBTMC488_CAPABILITY_TRIGGER         1