Skip to content

Commit d1d9def

Browse files
dpenklergregkh
authored andcommitted
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 <[email protected]> Reviewed-by: Guido Kiener <[email protected]> Signed-off-by: Dave Penkler <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c9784e2 commit d1d9def

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

drivers/usb/class/usbtmc.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,32 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
571571

572572
}
573573

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+
574600
static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
575601
__u32 __user *arg)
576602
{
@@ -2155,6 +2181,11 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
21552181
retval = put_user(tmp_byte, (__u8 __user *)arg);
21562182
break;
21572183

2184+
case USBTMC_IOCTL_GET_SRQ_STB:
2185+
retval = usbtmc_ioctl_get_srq_stb(file_data,
2186+
(void __user *)arg);
2187+
break;
2188+
21582189
case USBTMC_IOCTL_CANCEL_IO:
21592190
retval = usbtmc_ioctl_cancel_io(file_data);
21602191
break;

include/uapi/linux/usb/tmc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ struct usbtmc_message {
103103
#define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8)
104104

105105
#define USBTMC_IOCTL_GET_STB _IOR(USBTMC_IOC_NR, 26, __u8)
106+
#define USBTMC_IOCTL_GET_SRQ_STB _IOR(USBTMC_IOC_NR, 27, __u8)
106107

107108
/* Cancel and cleanup asynchronous calls */
108109
#define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35)

0 commit comments

Comments
 (0)