Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86286883 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

USB: usbtmc can do IO to device after disconnect



usbtmc will happily complete read/write requests even after disconnect
has returned. The fix is to introduce a flag.


Signed-off-by: default avatarOliver Neukum <oliver@neukum.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 75b48f09
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ struct usbtmc_device_data {
	bool TermCharEnabled;
	bool auto_abort;

	bool zombie; /* fd of disconnected device */

	struct usbtmc_dev_capabilities	capabilities;
	struct kref kref;
	struct mutex io_mutex;	/* only one i/o function running at a time */
@@ -384,6 +386,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
		return -ENOMEM;

	mutex_lock(&data->io_mutex);
	if (data->zombie) {
		retval = -ENODEV;
		goto exit;
	}

	remaining = count;
	done = 0;
@@ -496,6 +502,10 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
		return -ENOMEM;

	mutex_lock(&data->io_mutex);
	if (data->zombie) {
		retval = -ENODEV;
		goto exit;
	}

	remaining = count;
	done = 0;
@@ -925,6 +935,10 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

	data = file->private_data;
	mutex_lock(&data->io_mutex);
	if (data->zombie) {
		retval = -ENODEV;
		goto skip_io_on_zombie;
	}

	switch (cmd) {
	case USBTMC_IOCTL_CLEAR_OUT_HALT:
@@ -952,6 +966,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
		break;
	}

skip_io_on_zombie:
	mutex_unlock(&data->io_mutex);
	return retval;
}
@@ -995,6 +1010,7 @@ static int usbtmc_probe(struct usb_interface *intf,
	usb_set_intfdata(intf, data);
	kref_init(&data->kref);
	mutex_init(&data->io_mutex);
	data->zombie = 0;

	/* Initialize USBTMC bTag and other fields */
	data->bTag	= 1;
@@ -1065,6 +1081,9 @@ static void usbtmc_disconnect(struct usb_interface *intf)
	usb_deregister_dev(intf, &usbtmc_class);
	sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
	sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
	mutex_lock(&data->io_mutex);
	data->zombie = 1;
	mutex_unlock(&data->io_mutex);
	kref_put(&data->kref, usbtmc_delete);
}