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

USB: usbtmc: Add separate USBTMC_IOCTL_GET_SRQ_STB

This new ioctl only returns the status byte (STB) that was originally
sent by the device due to a service request (SRQ) condition.

This ioctl checks the srq_asserted bit of the associated file
descriptor. If set, the srq_asserted bit is reset and the cached
STB with original SRQ information is returned. Otherwise the ioctl
returns the error code ENOMSG.

This ioctl is useful to support non USBTMC-488 compliant devices.
Time sensitive applications can read the cached STB without incurring
the cost of an urb transaction over the bus.

Tested-by: Jian-Wei Wu <jian-wei_wu@keysight.com>
Reviewed-by: Guido Kiener <guido.kiener@rohde-schwarz.com>
Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20201215155621.9592-4-dpenkler@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Dave Penkler and committed by
Greg Kroah-Hartman
d1d9defd c9784e23

+32
+31
drivers/usb/class/usbtmc.c
··· 571 571 572 572 } 573 573 574 + static int usbtmc_ioctl_get_srq_stb(struct usbtmc_file_data *file_data, 575 + void __user *arg) 576 + { 577 + struct usbtmc_device_data *data = file_data->data; 578 + struct device *dev = &data->intf->dev; 579 + int srq_asserted = 0; 580 + __u8 stb = 0; 581 + int rv; 582 + 583 + spin_lock_irq(&data->dev_lock); 584 + srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); 585 + 586 + if (srq_asserted) { 587 + stb = file_data->srq_byte; 588 + spin_unlock_irq(&data->dev_lock); 589 + rv = put_user(stb, (__u8 __user *)arg); 590 + } else { 591 + spin_unlock_irq(&data->dev_lock); 592 + rv = -ENOMSG; 593 + } 594 + 595 + dev_dbg(dev, "stb:0x%02x with srq received %d\n", (unsigned int)stb, rv); 596 + 597 + return rv; 598 + } 599 + 574 600 static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data, 575 601 __u32 __user *arg) 576 602 { ··· 2179 2153 retval = usbtmc_get_stb(file_data, &tmp_byte); 2180 2154 if (retval > 0) 2181 2155 retval = put_user(tmp_byte, (__u8 __user *)arg); 2156 + break; 2157 + 2158 + case USBTMC_IOCTL_GET_SRQ_STB: 2159 + retval = usbtmc_ioctl_get_srq_stb(file_data, 2160 + (void __user *)arg); 2182 2161 break; 2183 2162 2184 2163 case USBTMC_IOCTL_CANCEL_IO:
+1
include/uapi/linux/usb/tmc.h
··· 103 103 #define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8) 104 104 105 105 #define USBTMC_IOCTL_GET_STB _IOR(USBTMC_IOC_NR, 26, __u8) 106 + #define USBTMC_IOCTL_GET_SRQ_STB _IOR(USBTMC_IOC_NR, 27, __u8) 106 107 107 108 /* Cancel and cleanup asynchronous calls */ 108 109 #define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35)