Commit d1d9defd authored by Dave Penkler's avatar Dave Penkler Committed by Greg Kroah-Hartman
Browse files

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: default avatarJian-Wei Wu <jian-wei_wu@keysight.com>
Reviewed-by: default avatarGuido Kiener <guido.kiener@rohde-schwarz.com>
Signed-off-by: default avatarDave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20201215155621.9592-4-dpenkler@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c9784e23
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -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,
				    __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);
		break;

	case USBTMC_IOCTL_GET_SRQ_STB:
		retval = usbtmc_ioctl_get_srq_stb(file_data,
						  (void __user *)arg);
		break;

	case USBTMC_IOCTL_CANCEL_IO:
		retval = usbtmc_ioctl_cancel_io(file_data);
		break;
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ struct usbtmc_message {
#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_SRQ_STB        _IOR(USBTMC_IOC_NR, 27, __u8)

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