diff options
| author | Guido Kiener <guido@kiener-muenchen.de> | 2018-07-18 04:45:39 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-21 02:22:15 -0400 |
| commit | 12dcaeb77e67c1162a2604f6b589266baec2d1ef (patch) | |
| tree | 8e705a16b689c9fa2b73a6c1df4d7bdc562bcbc9 | |
| parent | fbd83971f9429849dd3a105b663822d15b7b992b (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.c | 36 | ||||
| -rw-r--r-- | include/uapi/linux/usb/tmc.h | 6 |
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 | */ | ||
| 1309 | static 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 | |||
| 1301 | static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1328 | static 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 | ||
| 43 | struct 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) |
