aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido Kiener <guido@kiener-muenchen.de>2018-07-18 04:45:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-21 02:22:15 -0400
commit12dcaeb77e67c1162a2604f6b589266baec2d1ef (patch)
tree8e705a16b689c9fa2b73a6c1df4d7bdc562bcbc9
parentfbd83971f9429849dd3a105b663822d15b7b992b (diff)
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>
-rw-r--r--drivers/usb/class/usbtmc.c36
-rw-r--r--include/uapi/linux/usb/tmc.h6
2 files changed, 40 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 {
121 u8 srq_byte; 121 u8 srq_byte;
122 atomic_t srq_asserted; 122 atomic_t srq_asserted;
123 u8 eom_val; 123 u8 eom_val;
124 u8 term_char;
125 bool term_char_enabled;
124}; 126};
125 127
126/* Forward declarations */ 128/* Forward declarations */
@@ -157,7 +159,10 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
157 mutex_lock(&data->io_mutex); 159 mutex_lock(&data->io_mutex);
158 file_data->data = data; 160 file_data->data = data;
159 161
162 /* copy default values from device settings */
160 file_data->timeout = USBTMC_TIMEOUT; 163 file_data->timeout = USBTMC_TIMEOUT;
164 file_data->term_char = data->TermChar;
165 file_data->term_char_enabled = data->TermCharEnabled;
161 file_data->eom_val = 1; 166 file_data->eom_val = 1;
162 167
163 INIT_LIST_HEAD(&file_data->file_elem); 168 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,
634 buffer[5] = transfer_size >> 8; 639 buffer[5] = transfer_size >> 8;
635 buffer[6] = transfer_size >> 16; 640 buffer[6] = transfer_size >> 16;
636 buffer[7] = transfer_size >> 24; 641 buffer[7] = transfer_size >> 24;
637 buffer[8] = data->TermCharEnabled * 2; 642 buffer[8] = file_data->term_char_enabled * 2;
638 /* Use term character? */ 643 /* Use term character? */
639 buffer[9] = data->TermChar; 644 buffer[9] = file_data->term_char;
640 buffer[10] = 0; /* Reserved */ 645 buffer[10] = 0; /* Reserved */
641 buffer[11] = 0; /* Reserved */ 646 buffer[11] = 0; /* Reserved */
642 647
@@ -1298,6 +1303,28 @@ static int usbtmc_ioctl_eom_enable(struct usbtmc_file_data *file_data,
1298 return 0; 1303 return 0;
1299} 1304}
1300 1305
1306/*
1307 * Configure termination character for read()
1308 */
1309static int usbtmc_ioctl_config_termc(struct usbtmc_file_data *file_data,
1310 void __user *arg)
1311{
1312 struct usbtmc_termchar termc;
1313
1314 if (copy_from_user(&termc, arg, sizeof(termc)))
1315 return -EFAULT;
1316
1317 if ((termc.term_char_enabled > 1) ||
1318 (termc.term_char_enabled &&
1319 !(file_data->data->capabilities.device_capabilities & 1)))
1320 return -EINVAL;
1321
1322 file_data->term_char = termc.term_char;
1323 file_data->term_char_enabled = termc.term_char_enabled;
1324
1325 return 0;
1326}
1327
1301static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1328static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1302{ 1329{
1303 struct usbtmc_file_data *file_data; 1330 struct usbtmc_file_data *file_data;
@@ -1353,6 +1380,11 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1353 (void __user *)arg); 1380 (void __user *)arg);
1354 break; 1381 break;
1355 1382
1383 case USBTMC_IOCTL_CONFIG_TERMCHAR:
1384 retval = usbtmc_ioctl_config_termc(file_data,
1385 (void __user *)arg);
1386 break;
1387
1356 case USBTMC488_IOCTL_GET_CAPS: 1388 case USBTMC488_IOCTL_GET_CAPS:
1357 retval = copy_to_user((void __user *)arg, 1389 retval = copy_to_user((void __user *)arg,
1358 &data->usb488_caps, 1390 &data->usb488_caps,
diff --git a/include/uapi/linux/usb/tmc.h b/include/uapi/linux/usb/tmc.h
index e7317dfdd2ae..729af2f861a4 100644
--- a/include/uapi/linux/usb/tmc.h
+++ b/include/uapi/linux/usb/tmc.h
@@ -40,6 +40,11 @@
40#define USBTMC488_REQUEST_GOTO_LOCAL 161 40#define USBTMC488_REQUEST_GOTO_LOCAL 161
41#define USBTMC488_REQUEST_LOCAL_LOCKOUT 162 41#define USBTMC488_REQUEST_LOCAL_LOCKOUT 162
42 42
43struct usbtmc_termchar {
44 __u8 term_char;
45 __u8 term_char_enabled;
46} __attribute__ ((packed));
47
43/* Request values for USBTMC driver's ioctl entry point */ 48/* Request values for USBTMC driver's ioctl entry point */
44#define USBTMC_IOC_NR 91 49#define USBTMC_IOC_NR 91
45#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1) 50#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1)
@@ -51,6 +56,7 @@
51#define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32) 56#define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32)
52#define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32) 57#define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32)
53#define USBTMC_IOCTL_EOM_ENABLE _IOW(USBTMC_IOC_NR, 11, __u8) 58#define USBTMC_IOCTL_EOM_ENABLE _IOW(USBTMC_IOC_NR, 11, __u8)
59#define USBTMC_IOCTL_CONFIG_TERMCHAR _IOW(USBTMC_IOC_NR, 12, struct usbtmc_termchar)
54 60
55#define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char) 61#define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char)
56#define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char) 62#define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char)