Skip to content

Commit 048c6d8

Browse files
GuidoKienergregkh
authored andcommitted
usb: usbtmc: Add ioctls to set/get usb timeout
Add ioctls USBTMC_IOCTL_GET_TIMEOUT / USBTMC_IOCTL_SET_TIMEOUT to get/set I/O timeout for specific file handle. Different operations on an instrument can take different lengths of time thus it is important to be able to set the timeout slightly longer than the expected duration of each operation to optimise the responsiveness of the application. As the instrument may be shared by multiple applications the timeout should be settable on a per file descriptor basis. Tested-by: Dave Penkler <dpenkler@gmail.com> Reviewed-by: Steve Bayless <steve_bayless@keysight.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>
1 parent 19e6c57 commit 048c6d8

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

drivers/usb/class/usbtmc.c

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
*/
3131
#define USBTMC_SIZE_IOBUFFER 2048
3232

33+
/* Minimum USB timeout (in milliseconds) */
34+
#define USBTMC_MIN_TIMEOUT 100
3335
/* Default USB timeout (in milliseconds) */
3436
#define USBTMC_TIMEOUT 5000
3537

@@ -115,6 +117,7 @@ struct usbtmc_file_data {
115117
struct usbtmc_device_data *data;
116118
struct list_head file_elem;
117119

120+
u32 timeout;
118121
u8 srq_byte;
119122
atomic_t srq_asserted;
120123
};
@@ -153,6 +156,8 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
153156
mutex_lock(&data->io_mutex);
154157
file_data->data = data;
155158

159+
file_data->timeout = USBTMC_TIMEOUT;
160+
156161
INIT_LIST_HEAD(&file_data->file_elem);
157162
spin_lock_irq(&data->dev_lock);
158163
list_add_tail(&file_data->file_elem, &data->file_list);
@@ -460,7 +465,7 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
460465
rv = wait_event_interruptible_timeout(
461466
data->waitq,
462467
atomic_read(&data->iin_data_valid) != 0,
463-
USBTMC_TIMEOUT);
468+
file_data->timeout);
464469
if (rv < 0) {
465470
dev_dbg(dev, "wait interrupted %d\n", rv);
466471
goto exit;
@@ -560,8 +565,10 @@ static int usbtmc488_ioctl_simple(struct usbtmc_device_data *data,
560565
*
561566
* Also updates bTag_last_write.
562567
*/
563-
static int send_request_dev_dep_msg_in(struct usbtmc_device_data *data, size_t transfer_size)
568+
static int send_request_dev_dep_msg_in(struct usbtmc_file_data *file_data,
569+
size_t transfer_size)
564570
{
571+
struct usbtmc_device_data *data = file_data->data;
565572
int retval;
566573
u8 *buffer;
567574
int actual;
@@ -590,7 +597,8 @@ static int send_request_dev_dep_msg_in(struct usbtmc_device_data *data, size_t t
590597
retval = usb_bulk_msg(data->usb_dev,
591598
usb_sndbulkpipe(data->usb_dev,
592599
data->bulk_out),
593-
buffer, USBTMC_HEADER_SIZE, &actual, USBTMC_TIMEOUT);
600+
buffer, USBTMC_HEADER_SIZE,
601+
&actual, file_data->timeout);
594602

595603
/* Store bTag (in case we need to abort) */
596604
data->bTag_last_write = data->bTag;
@@ -640,7 +648,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
640648

641649
dev_dbg(dev, "usb_bulk_msg_in: count(%zu)\n", count);
642650

643-
retval = send_request_dev_dep_msg_in(data, count);
651+
retval = send_request_dev_dep_msg_in(file_data, count);
644652

645653
if (retval < 0) {
646654
if (data->auto_abort)
@@ -659,7 +667,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
659667
usb_rcvbulkpipe(data->usb_dev,
660668
data->bulk_in),
661669
buffer, USBTMC_SIZE_IOBUFFER, &actual,
662-
USBTMC_TIMEOUT);
670+
file_data->timeout);
663671

664672
dev_dbg(dev, "usb_bulk_msg: retval(%u), done(%zu), remaining(%zu), actual(%d)\n", retval, done, remaining, actual);
665673

@@ -832,7 +840,7 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
832840
usb_sndbulkpipe(data->usb_dev,
833841
data->bulk_out),
834842
buffer, n_bytes,
835-
&actual, USBTMC_TIMEOUT);
843+
&actual, file_data->timeout);
836844
if (retval != 0)
837845
break;
838846
n_bytes -= actual;
@@ -1189,6 +1197,41 @@ static int usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data *data)
11891197
return rv;
11901198
}
11911199

1200+
/*
1201+
* Get the usb timeout value
1202+
*/
1203+
static int usbtmc_ioctl_get_timeout(struct usbtmc_file_data *file_data,
1204+
void __user *arg)
1205+
{
1206+
u32 timeout;
1207+
1208+
timeout = file_data->timeout;
1209+
1210+
return put_user(timeout, (__u32 __user *)arg);
1211+
}
1212+
1213+
/*
1214+
* Set the usb timeout value
1215+
*/
1216+
static int usbtmc_ioctl_set_timeout(struct usbtmc_file_data *file_data,
1217+
void __user *arg)
1218+
{
1219+
u32 timeout;
1220+
1221+
if (get_user(timeout, (__u32 __user *)arg))
1222+
return -EFAULT;
1223+
1224+
/* Note that timeout = 0 means
1225+
* MAX_SCHEDULE_TIMEOUT in usb_control_msg
1226+
*/
1227+
if (timeout < USBTMC_MIN_TIMEOUT)
1228+
return -EINVAL;
1229+
1230+
file_data->timeout = timeout;
1231+
1232+
return 0;
1233+
}
1234+
11921235
static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
11931236
{
11941237
struct usbtmc_file_data *file_data;
@@ -1229,6 +1272,16 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
12291272
retval = usbtmc_ioctl_abort_bulk_in(data);
12301273
break;
12311274

1275+
case USBTMC_IOCTL_GET_TIMEOUT:
1276+
retval = usbtmc_ioctl_get_timeout(file_data,
1277+
(void __user *)arg);
1278+
break;
1279+
1280+
case USBTMC_IOCTL_SET_TIMEOUT:
1281+
retval = usbtmc_ioctl_set_timeout(file_data,
1282+
(void __user *)arg);
1283+
break;
1284+
12321285
case USBTMC488_IOCTL_GET_CAPS:
12331286
retval = copy_to_user((void __user *)arg,
12341287
&data->usb488_caps,

include/uapi/linux/usb/tmc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#ifndef __LINUX_USB_TMC_H
1717
#define __LINUX_USB_TMC_H
1818

19+
#include <linux/types.h> /* __u8 etc */
20+
1921
/* USB TMC status values */
2022
#define USBTMC_STATUS_SUCCESS 0x01
2123
#define USBTMC_STATUS_PENDING 0x02
@@ -46,6 +48,8 @@
4648
#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4)
4749
#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6)
4850
#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7)
51+
#define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32)
52+
#define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32)
4953
#define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char)
5054
#define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char)
5155
#define USBTMC488_IOCTL_REN_CONTROL _IOW(USBTMC_IOC_NR, 19, unsigned char)

0 commit comments

Comments
 (0)