summaryrefslogtreecommitdiff
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorGuido Kiener <guido@kiener-muenchen.de>2018-07-18 11:45:39 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-21 09:22:15 +0300
commit12dcaeb77e67c1162a2604f6b589266baec2d1ef (patch)
tree8e705a16b689c9fa2b73a6c1df4d7bdc562bcbc9 /drivers/usb/class
parentfbd83971f9429849dd3a105b663822d15b7b992b (diff)
downloadlinux-12dcaeb77e67c1162a2604f6b589266baec2d1ef.tar.xz
usb: usbtmc: Add ioctl for termination character
add USBTMC_IOCTL_CONFIG_TERMCHAR to control TermChar handling for next read(). Controls field 'TermChar' and Bit 1 of field 'bmTransferAttributes' of REQUEST_DEV_DEP_MSG_IN BULK-OUT header. Allows enabling/disabling of terminating a read on reception of term_char individually for each read request. 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>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/usbtmc.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index c77e0ac6260b..1b7b2e402adb 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -121,6 +121,8 @@ struct usbtmc_file_data {
u8 srq_byte;
atomic_t srq_asserted;
u8 eom_val;
+ u8 term_char;
+ bool term_char_enabled;
};
/* Forward declarations */
@@ -157,7 +159,10 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
mutex_lock(&data->io_mutex);
file_data->data = data;
+ /* copy default values from device settings */
file_data->timeout = USBTMC_TIMEOUT;
+ file_data->term_char = data->TermChar;
+ file_data->term_char_enabled = data->TermCharEnabled;
file_data->eom_val = 1;
INIT_LIST_HEAD(&file_data->file_elem);
@@ -634,9 +639,9 @@ static int send_request_dev_dep_msg_in(struct usbtmc_file_data *file_data,
buffer[5] = transfer_size >> 8;
buffer[6] = transfer_size >> 16;
buffer[7] = transfer_size >> 24;
- buffer[8] = data->TermCharEnabled * 2;
+ buffer[8] = file_data->term_char_enabled * 2;
/* Use term character? */
- buffer[9] = data->TermChar;
+ buffer[9] = file_data->term_char;
buffer[10] = 0; /* Reserved */
buffer[11] = 0; /* Reserved */
@@ -1298,6 +1303,28 @@ static int usbtmc_ioctl_eom_enable(struct usbtmc_file_data *file_data,
return 0;
}
+/*
+ * Configure termination character for read()
+ */
+static int usbtmc_ioctl_config_termc(struct usbtmc_file_data *file_data,
+ void __user *arg)
+{
+ struct usbtmc_termchar termc;
+
+ if (copy_from_user(&termc, arg, sizeof(termc)))
+ return -EFAULT;
+
+ if ((termc.term_char_enabled > 1) ||
+ (termc.term_char_enabled &&
+ !(file_data->data->capabilities.device_capabilities & 1)))
+ return -EINVAL;
+
+ file_data->term_char = termc.term_char;
+ file_data->term_char_enabled = termc.term_char_enabled;
+
+ return 0;
+}
+
static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct usbtmc_file_data *file_data;
@@ -1353,6 +1380,11 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
(void __user *)arg);
break;
+ case USBTMC_IOCTL_CONFIG_TERMCHAR:
+ retval = usbtmc_ioctl_config_termc(file_data,
+ (void __user *)arg);
+ break;
+
case USBTMC488_IOCTL_GET_CAPS:
retval = copy_to_user((void __user *)arg,
&data->usb488_caps,