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>
This commit is contained in:
Родитель
c9784e23c1
Коммит
d1d9defdc6
|
@ -571,6 +571,32 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int usbtmc_ioctl_get_srq_stb(struct usbtmc_file_data *file_data,
|
||||||
|
void __user *arg)
|
||||||
|
{
|
||||||
|
struct usbtmc_device_data *data = file_data->data;
|
||||||
|
struct device *dev = &data->intf->dev;
|
||||||
|
int srq_asserted = 0;
|
||||||
|
__u8 stb = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
spin_lock_irq(&data->dev_lock);
|
||||||
|
srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted);
|
||||||
|
|
||||||
|
if (srq_asserted) {
|
||||||
|
stb = file_data->srq_byte;
|
||||||
|
spin_unlock_irq(&data->dev_lock);
|
||||||
|
rv = put_user(stb, (__u8 __user *)arg);
|
||||||
|
} else {
|
||||||
|
spin_unlock_irq(&data->dev_lock);
|
||||||
|
rv = -ENOMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dev, "stb:0x%02x with srq received %d\n", (unsigned int)stb, rv);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
|
static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
|
||||||
__u32 __user *arg)
|
__u32 __user *arg)
|
||||||
{
|
{
|
||||||
|
@ -2155,6 +2181,11 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
retval = put_user(tmp_byte, (__u8 __user *)arg);
|
retval = put_user(tmp_byte, (__u8 __user *)arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case USBTMC_IOCTL_GET_SRQ_STB:
|
||||||
|
retval = usbtmc_ioctl_get_srq_stb(file_data,
|
||||||
|
(void __user *)arg);
|
||||||
|
break;
|
||||||
|
|
||||||
case USBTMC_IOCTL_CANCEL_IO:
|
case USBTMC_IOCTL_CANCEL_IO:
|
||||||
retval = usbtmc_ioctl_cancel_io(file_data);
|
retval = usbtmc_ioctl_cancel_io(file_data);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -103,6 +103,7 @@ struct usbtmc_message {
|
||||||
#define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8)
|
#define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8)
|
||||||
|
|
||||||
#define USBTMC_IOCTL_GET_STB _IOR(USBTMC_IOC_NR, 26, __u8)
|
#define USBTMC_IOCTL_GET_STB _IOR(USBTMC_IOC_NR, 26, __u8)
|
||||||
|
#define USBTMC_IOCTL_GET_SRQ_STB _IOR(USBTMC_IOC_NR, 27, __u8)
|
||||||
|
|
||||||
/* Cancel and cleanup asynchronous calls */
|
/* Cancel and cleanup asynchronous calls */
|
||||||
#define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35)
|
#define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче