Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Guido Kiener and committed by
Greg Kroah-Hartman
12dcaeb7 fbd83971

+40 -2
+34 -2
drivers/usb/class/usbtmc.c
··· 121 121 u8 srq_byte; 122 122 atomic_t srq_asserted; 123 123 u8 eom_val; 124 + u8 term_char; 125 + bool term_char_enabled; 124 126 }; 125 127 126 128 /* Forward declarations */ ··· 159 157 mutex_lock(&data->io_mutex); 160 158 file_data->data = data; 161 159 160 + /* copy default values from device settings */ 162 161 file_data->timeout = USBTMC_TIMEOUT; 162 + file_data->term_char = data->TermChar; 163 + file_data->term_char_enabled = data->TermCharEnabled; 163 164 file_data->eom_val = 1; 164 165 165 166 INIT_LIST_HEAD(&file_data->file_elem); ··· 639 634 buffer[5] = transfer_size >> 8; 640 635 buffer[6] = transfer_size >> 16; 641 636 buffer[7] = transfer_size >> 24; 642 - buffer[8] = data->TermCharEnabled * 2; 637 + buffer[8] = file_data->term_char_enabled * 2; 643 638 /* Use term character? */ 644 - buffer[9] = data->TermChar; 639 + buffer[9] = file_data->term_char; 645 640 buffer[10] = 0; /* Reserved */ 646 641 buffer[11] = 0; /* Reserved */ 647 642 ··· 1303 1298 return 0; 1304 1299 } 1305 1300 1301 + /* 1302 + * Configure termination character for read() 1303 + */ 1304 + static int usbtmc_ioctl_config_termc(struct usbtmc_file_data *file_data, 1305 + void __user *arg) 1306 + { 1307 + struct usbtmc_termchar termc; 1308 + 1309 + if (copy_from_user(&termc, arg, sizeof(termc))) 1310 + return -EFAULT; 1311 + 1312 + if ((termc.term_char_enabled > 1) || 1313 + (termc.term_char_enabled && 1314 + !(file_data->data->capabilities.device_capabilities & 1))) 1315 + return -EINVAL; 1316 + 1317 + file_data->term_char = termc.term_char; 1318 + file_data->term_char_enabled = termc.term_char_enabled; 1319 + 1320 + return 0; 1321 + } 1322 + 1306 1323 static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1307 1324 { 1308 1325 struct usbtmc_file_data *file_data; ··· 1378 1351 case USBTMC_IOCTL_EOM_ENABLE: 1379 1352 retval = usbtmc_ioctl_eom_enable(file_data, 1380 1353 (void __user *)arg); 1354 + break; 1355 + 1356 + case USBTMC_IOCTL_CONFIG_TERMCHAR: 1357 + retval = usbtmc_ioctl_config_termc(file_data, 1358 + (void __user *)arg); 1381 1359 break; 1382 1360 1383 1361 case USBTMC488_IOCTL_GET_CAPS:
+6
include/uapi/linux/usb/tmc.h
··· 40 40 #define USBTMC488_REQUEST_GOTO_LOCAL 161 41 41 #define USBTMC488_REQUEST_LOCAL_LOCKOUT 162 42 42 43 + struct usbtmc_termchar { 44 + __u8 term_char; 45 + __u8 term_char_enabled; 46 + } __attribute__ ((packed)); 47 + 43 48 /* Request values for USBTMC driver's ioctl entry point */ 44 49 #define USBTMC_IOC_NR 91 45 50 #define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1) ··· 56 51 #define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32) 57 52 #define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32) 58 53 #define USBTMC_IOCTL_EOM_ENABLE _IOW(USBTMC_IOC_NR, 11, __u8) 54 + #define USBTMC_IOCTL_CONFIG_TERMCHAR _IOW(USBTMC_IOC_NR, 12, struct usbtmc_termchar) 59 55 60 56 #define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char) 61 57 #define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char)