aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/usbtmc.c
diff options
context:
space:
mode:
authorDave Penkler <dpenkler@gmail.com>2016-01-27 13:25:24 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-02-03 16:54:06 -0500
commit379d3d33c83b667b0edad0110693567306463882 (patch)
tree9a42ed42b6c3ac7b94a285ccc933c680e08b620a /drivers/usb/class/usbtmc.c
parent29779d89fd049bfc6c07f19aaf9b8d19fe2ecc8c (diff)
Add ioctls to enable and disable local controls on an instrument
These ioctls provide support for the USBTMC-USB488 control requests for REN_CONTROL, GO_TO_LOCAL and LOCAL_LOCKOUT Signed-off-by: Dave Penkler <dpenkler@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/class/usbtmc.c')
-rw-r--r--drivers/usb/class/usbtmc.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 6edb21ca9989..419c72e10464 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -474,6 +474,61 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_device_data *data,
474 return rv; 474 return rv;
475} 475}
476 476
477static int usbtmc488_ioctl_simple(struct usbtmc_device_data *data,
478 void __user *arg, unsigned int cmd)
479{
480 struct device *dev = &data->intf->dev;
481 __u8 val;
482 u8 *buffer;
483 u16 wValue;
484 int rv;
485
486 if (!(data->usb488_caps & USBTMC488_CAPABILITY_SIMPLE))
487 return -EINVAL;
488
489 buffer = kmalloc(8, GFP_KERNEL);
490 if (!buffer)
491 return -ENOMEM;
492
493 if (cmd == USBTMC488_REQUEST_REN_CONTROL) {
494 rv = copy_from_user(&val, arg, sizeof(val));
495 if (rv) {
496 rv = -EFAULT;
497 goto exit;
498 }
499 wValue = val ? 1 : 0;
500 } else {
501 wValue = 0;
502 }
503
504 rv = usb_control_msg(data->usb_dev,
505 usb_rcvctrlpipe(data->usb_dev, 0),
506 cmd,
507 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
508 wValue,
509 data->ifnum,
510 buffer, 0x01, USBTMC_TIMEOUT);
511 if (rv < 0) {
512 dev_err(dev, "simple usb_control_msg failed %d\n", rv);
513 goto exit;
514 } else if (rv != 1) {
515 dev_warn(dev, "simple usb_control_msg returned %d\n", rv);
516 rv = -EIO;
517 goto exit;
518 }
519
520 if (buffer[0] != USBTMC_STATUS_SUCCESS) {
521 dev_err(dev, "simple control status returned %x\n", buffer[0]);
522 rv = -EIO;
523 goto exit;
524 }
525 rv = 0;
526
527 exit:
528 kfree(buffer);
529 return rv;
530}
531
477/* 532/*
478 * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-IN endpoint. 533 * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-IN endpoint.
479 * @transfer_size: number of bytes to request from the device. 534 * @transfer_size: number of bytes to request from the device.
@@ -1183,6 +1238,21 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1183 case USBTMC488_IOCTL_READ_STB: 1238 case USBTMC488_IOCTL_READ_STB:
1184 retval = usbtmc488_ioctl_read_stb(data, (void __user *)arg); 1239 retval = usbtmc488_ioctl_read_stb(data, (void __user *)arg);
1185 break; 1240 break;
1241
1242 case USBTMC488_IOCTL_REN_CONTROL:
1243 retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
1244 USBTMC488_REQUEST_REN_CONTROL);
1245 break;
1246
1247 case USBTMC488_IOCTL_GOTO_LOCAL:
1248 retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
1249 USBTMC488_REQUEST_GOTO_LOCAL);
1250 break;
1251
1252 case USBTMC488_IOCTL_LOCAL_LOCKOUT:
1253 retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
1254 USBTMC488_REQUEST_LOCAL_LOCKOUT);
1255 break;
1186 } 1256 }
1187 1257
1188skip_io_on_zombie: 1258skip_io_on_zombie: