Commit e6421583 authored by Johan Hovold's avatar Johan Hovold

USB: serial: opticon: stop all I/O on close()

Make sure to stop any submitted write URBs on close().

Note that the tty layer will wait up to 30 seconds for the buffers to
drain before close() is called.
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent a00e7182
...@@ -42,6 +42,8 @@ struct opticon_private { ...@@ -42,6 +42,8 @@ struct opticon_private {
bool cts; bool cts;
int outstanding_urbs; int outstanding_urbs;
int outstanding_bytes; int outstanding_bytes;
struct usb_anchor anchor;
}; };
...@@ -150,6 +152,15 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -150,6 +152,15 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
return res; return res;
} }
static void opticon_close(struct usb_serial_port *port)
{
struct opticon_private *priv = usb_get_serial_port_data(port);
usb_kill_anchored_urbs(&priv->anchor);
usb_serial_generic_close(port);
}
static void opticon_write_control_callback(struct urb *urb) static void opticon_write_control_callback(struct urb *urb)
{ {
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
...@@ -226,10 +237,13 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, ...@@ -226,10 +237,13 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
(unsigned char *)dr, buffer, count, (unsigned char *)dr, buffer, count,
opticon_write_control_callback, port); opticon_write_control_callback, port);
usb_anchor_urb(urb, &priv->anchor);
/* send it down the pipe */ /* send it down the pipe */
ret = usb_submit_urb(urb, GFP_ATOMIC); ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) { if (ret) {
dev_err(&port->dev, "failed to submit write urb: %d\n", ret); dev_err(&port->dev, "failed to submit write urb: %d\n", ret);
usb_unanchor_urb(urb);
goto error; goto error;
} }
...@@ -364,6 +378,7 @@ static int opticon_port_probe(struct usb_serial_port *port) ...@@ -364,6 +378,7 @@ static int opticon_port_probe(struct usb_serial_port *port)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
init_usb_anchor(&priv->anchor);
usb_set_serial_port_data(port, priv); usb_set_serial_port_data(port, priv);
...@@ -391,6 +406,7 @@ static struct usb_serial_driver opticon_device = { ...@@ -391,6 +406,7 @@ static struct usb_serial_driver opticon_device = {
.port_probe = opticon_port_probe, .port_probe = opticon_port_probe,
.port_remove = opticon_port_remove, .port_remove = opticon_port_remove,
.open = opticon_open, .open = opticon_open,
.close = opticon_close,
.write = opticon_write, .write = opticon_write,
.write_room = opticon_write_room, .write_room = opticon_write_room,
.chars_in_buffer = opticon_chars_in_buffer, .chars_in_buffer = opticon_chars_in_buffer,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment