]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
usb: usbtmc: Add ioctl for trigger
authorGuido Kiener <guido@kiener-muenchen.de>
Wed, 18 Jul 2018 08:45:37 +0000 (10:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Jul 2018 06:22:15 +0000 (08:22 +0200)
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: Steve Bayless <steve_bayless@keysight.com>
Tested-by: Dave Penkler <dpenkler@gmail.com>
Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Signed-off-by: Guido Kiener <guido.kiener@rohde-schwarz.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/class/usbtmc.c
include/uapi/linux/usb/tmc.h

index 36d740c4c6fb0db875103d45486a863cf3d69491..38fc7abdc00cf0c0e431984387fc557bc68ed214 100644 (file)
@@ -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:
index a89ffc33532e3ceae75ce2f0c89328ff859fe590..c61bad7150dddb687b09dcc778aa6143ac78be2d 100644 (file)
@@ -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