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

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>

authored by

Dave Penkler and committed by
Greg Kroah-Hartman
379d3d33 29779d89

+76
+70
drivers/usb/class/usbtmc.c
··· 474 474 return rv; 475 475 } 476 476 477 + static 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 533 * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-IN endpoint. 479 534 * @transfer_size: number of bytes to request from the device. ··· 1237 1182 1238 1183 case USBTMC488_IOCTL_READ_STB: 1239 1184 retval = usbtmc488_ioctl_read_stb(data, (void __user *)arg); 1185 + break; 1186 + 1187 + case USBTMC488_IOCTL_REN_CONTROL: 1188 + retval = usbtmc488_ioctl_simple(data, (void __user *)arg, 1189 + USBTMC488_REQUEST_REN_CONTROL); 1190 + break; 1191 + 1192 + case USBTMC488_IOCTL_GOTO_LOCAL: 1193 + retval = usbtmc488_ioctl_simple(data, (void __user *)arg, 1194 + USBTMC488_REQUEST_GOTO_LOCAL); 1195 + break; 1196 + 1197 + case USBTMC488_IOCTL_LOCAL_LOCKOUT: 1198 + retval = usbtmc488_ioctl_simple(data, (void __user *)arg, 1199 + USBTMC488_REQUEST_LOCAL_LOCKOUT); 1240 1200 break; 1241 1201 } 1242 1202
+6
include/uapi/linux/usb/tmc.h
··· 33 33 #define USBTMC_REQUEST_GET_CAPABILITIES 7 34 34 #define USBTMC_REQUEST_INDICATOR_PULSE 64 35 35 #define USBTMC488_REQUEST_READ_STATUS_BYTE 128 36 + #define USBTMC488_REQUEST_REN_CONTROL 160 37 + #define USBTMC488_REQUEST_GOTO_LOCAL 161 38 + #define USBTMC488_REQUEST_LOCAL_LOCKOUT 162 36 39 37 40 /* Request values for USBTMC driver's ioctl entry point */ 38 41 #define USBTMC_IOC_NR 91 ··· 47 44 #define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7) 48 45 #define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char) 49 46 #define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char) 47 + #define USBTMC488_IOCTL_REN_CONTROL _IOW(USBTMC_IOC_NR, 19, unsigned char) 48 + #define USBTMC488_IOCTL_GOTO_LOCAL _IO(USBTMC_IOC_NR, 20) 49 + #define USBTMC488_IOCTL_LOCAL_LOCKOUT _IO(USBTMC_IOC_NR, 21) 50 50 51 51 /* Driver encoded usb488 capabilities */ 52 52 #define USBTMC488_CAPABILITY_TRIGGER 1