|
@@ -30,6 +30,8 @@
|
|
|
*/
|
|
|
#define USBTMC_SIZE_IOBUFFER 2048
|
|
|
|
|
|
+/* Minimum USB timeout (in milliseconds) */
|
|
|
+#define USBTMC_MIN_TIMEOUT 100
|
|
|
/* Default USB timeout (in milliseconds) */
|
|
|
#define USBTMC_TIMEOUT 5000
|
|
|
|
|
@@ -115,6 +117,7 @@ struct usbtmc_file_data {
|
|
|
struct usbtmc_device_data *data;
|
|
|
struct list_head file_elem;
|
|
|
|
|
|
+ u32 timeout;
|
|
|
u8 srq_byte;
|
|
|
atomic_t srq_asserted;
|
|
|
};
|
|
@@ -153,6 +156,8 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
|
|
|
mutex_lock(&data->io_mutex);
|
|
|
file_data->data = data;
|
|
|
|
|
|
+ file_data->timeout = USBTMC_TIMEOUT;
|
|
|
+
|
|
|
INIT_LIST_HEAD(&file_data->file_elem);
|
|
|
spin_lock_irq(&data->dev_lock);
|
|
|
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,
|
|
|
rv = wait_event_interruptible_timeout(
|
|
|
data->waitq,
|
|
|
atomic_read(&data->iin_data_valid) != 0,
|
|
|
- USBTMC_TIMEOUT);
|
|
|
+ file_data->timeout);
|
|
|
if (rv < 0) {
|
|
|
dev_dbg(dev, "wait interrupted %d\n", rv);
|
|
|
goto exit;
|
|
@@ -560,8 +565,10 @@ static int usbtmc488_ioctl_simple(struct usbtmc_device_data *data,
|
|
|
*
|
|
|
* Also updates bTag_last_write.
|
|
|
*/
|
|
|
-static int send_request_dev_dep_msg_in(struct usbtmc_device_data *data, size_t transfer_size)
|
|
|
+static int send_request_dev_dep_msg_in(struct usbtmc_file_data *file_data,
|
|
|
+ size_t transfer_size)
|
|
|
{
|
|
|
+ struct usbtmc_device_data *data = file_data->data;
|
|
|
int retval;
|
|
|
u8 *buffer;
|
|
|
int actual;
|
|
@@ -590,7 +597,8 @@ static int send_request_dev_dep_msg_in(struct usbtmc_device_data *data, size_t t
|
|
|
retval = usb_bulk_msg(data->usb_dev,
|
|
|
usb_sndbulkpipe(data->usb_dev,
|
|
|
data->bulk_out),
|
|
|
- buffer, USBTMC_HEADER_SIZE, &actual, USBTMC_TIMEOUT);
|
|
|
+ buffer, USBTMC_HEADER_SIZE,
|
|
|
+ &actual, file_data->timeout);
|
|
|
|
|
|
/* Store bTag (in case we need to abort) */
|
|
|
data->bTag_last_write = data->bTag;
|
|
@@ -640,7 +648,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
|
|
|
|
|
|
dev_dbg(dev, "usb_bulk_msg_in: count(%zu)\n", count);
|
|
|
|
|
|
- retval = send_request_dev_dep_msg_in(data, count);
|
|
|
+ retval = send_request_dev_dep_msg_in(file_data, count);
|
|
|
|
|
|
if (retval < 0) {
|
|
|
if (data->auto_abort)
|
|
@@ -659,7 +667,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
|
|
|
usb_rcvbulkpipe(data->usb_dev,
|
|
|
data->bulk_in),
|
|
|
buffer, USBTMC_SIZE_IOBUFFER, &actual,
|
|
|
- USBTMC_TIMEOUT);
|
|
|
+ file_data->timeout);
|
|
|
|
|
|
dev_dbg(dev, "usb_bulk_msg: retval(%u), done(%zu), remaining(%zu), actual(%d)\n", retval, done, remaining, actual);
|
|
|
|
|
@@ -832,7 +840,7 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
|
|
|
usb_sndbulkpipe(data->usb_dev,
|
|
|
data->bulk_out),
|
|
|
buffer, n_bytes,
|
|
|
- &actual, USBTMC_TIMEOUT);
|
|
|
+ &actual, file_data->timeout);
|
|
|
if (retval != 0)
|
|
|
break;
|
|
|
n_bytes -= actual;
|
|
@@ -1189,6 +1197,41 @@ exit:
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Get the usb timeout value
|
|
|
+ */
|
|
|
+static int usbtmc_ioctl_get_timeout(struct usbtmc_file_data *file_data,
|
|
|
+ void __user *arg)
|
|
|
+{
|
|
|
+ u32 timeout;
|
|
|
+
|
|
|
+ timeout = file_data->timeout;
|
|
|
+
|
|
|
+ return put_user(timeout, (__u32 __user *)arg);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Set the usb timeout value
|
|
|
+ */
|
|
|
+static int usbtmc_ioctl_set_timeout(struct usbtmc_file_data *file_data,
|
|
|
+ void __user *arg)
|
|
|
+{
|
|
|
+ u32 timeout;
|
|
|
+
|
|
|
+ if (get_user(timeout, (__u32 __user *)arg))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ /* Note that timeout = 0 means
|
|
|
+ * MAX_SCHEDULE_TIMEOUT in usb_control_msg
|
|
|
+ */
|
|
|
+ if (timeout < USBTMC_MIN_TIMEOUT)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ file_data->timeout = timeout;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
|
struct usbtmc_file_data *file_data;
|
|
@@ -1229,6 +1272,16 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
retval = usbtmc_ioctl_abort_bulk_in(data);
|
|
|
break;
|
|
|
|
|
|
+ case USBTMC_IOCTL_GET_TIMEOUT:
|
|
|
+ retval = usbtmc_ioctl_get_timeout(file_data,
|
|
|
+ (void __user *)arg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case USBTMC_IOCTL_SET_TIMEOUT:
|
|
|
+ retval = usbtmc_ioctl_set_timeout(file_data,
|
|
|
+ (void __user *)arg);
|
|
|
+ break;
|
|
|
+
|
|
|
case USBTMC488_IOCTL_GET_CAPS:
|
|
|
retval = copy_to_user((void __user *)arg,
|
|
|
&data->usb488_caps,
|