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

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

USB: stop io performed by mos7720 upon close()



This fixes a problem where the mos7720 driver will make io to a device from
which it has been logically disconnected. It does so by introducing a flag by
which the generic usb serial code can signal the subdrivers their
disconnection and appropriate locking.

Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 828d55c5
Loading
Loading
Loading
Loading
+18 −15
Original line number Diff line number Diff line
@@ -564,14 +564,16 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp)
	}

	/* While closing port, shutdown all bulk read, write  *
	 * and interrupt read if they exists                  */
	if (serial->dev) {
	 * and interrupt read if they exists, otherwise nop   */
	dbg("Shutdown bulk write");
	usb_kill_urb(port->write_urb);
	dbg("Shutdown bulk read");
	usb_kill_urb(port->read_urb);
	}

	mutex_lock(&serial->disc_mutex);
	/* these commands must not be issued if the device has
	 * been disconnected */
	if (!serial->disconnected) {
		data = 0x00;
		send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
			     0x04, &data);
@@ -579,7 +581,8 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp)
		data = 0x00;
		send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
			     0x01, &data);

	}
	mutex_unlock(&serial->disc_mutex);
	mos7720_port->open = 0;

	dbg("Leaving %s", __FUNCTION__);
+14 −14
Original line number Diff line number Diff line
@@ -634,6 +634,7 @@ static struct usb_serial * create_serial (struct usb_device *dev,
	serial->type = driver;
	serial->interface = interface;
	kref_init(&serial->kref);
	mutex_init(&serial->disc_mutex);

	return serial;
}
@@ -1089,8 +1090,10 @@ void usb_serial_disconnect(struct usb_interface *interface)
	usb_serial_console_disconnect(serial);
	dbg ("%s", __FUNCTION__);

	mutex_lock(&serial->disc_mutex);
	usb_set_intfdata (interface, NULL);
	if (serial) {
	/* must set a flag, to signal subdrivers */
	serial->disconnected = 1;
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port) {
@@ -1101,8 +1104,8 @@ void usb_serial_disconnect(struct usb_interface *interface)
	}
	/* let the last holder of this object
	 * cause it to be cleaned up */
	mutex_unlock(&serial->disc_mutex);
	usb_serial_put(serial);
	}
	dev_info(dev, "device disconnected\n");
}

@@ -1112,9 +1115,6 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
	struct usb_serial_port *port;
	int i, r = 0;

	if (!serial) /* device has been disconnected */
		return 0;

	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port)
+2 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ struct usb_serial {
	struct usb_device *		dev;
	struct usb_serial_driver *	type;
	struct usb_interface *		interface;
	unsigned char			disconnected;
	unsigned char			minor;
	unsigned char			num_ports;
	unsigned char			num_port_pointers;
@@ -138,6 +139,7 @@ struct usb_serial {
	char				num_bulk_out;
	struct usb_serial_port *	port[MAX_NUM_PORTS];
	struct kref			kref;
	struct mutex			disc_mutex;
	void *				private;
};
#define to_usb_serial(d) container_of(d, struct usb_serial, kref)