diff options
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index bd7581b3a48a..3c8923f62ed1 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -340,6 +340,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
| 340 | 340 | ||
| 341 | dbg("%s - port %d", __func__, port->number); | 341 | dbg("%s - port %d", __func__, port->number); |
| 342 | 342 | ||
| 343 | /* FIXME: | ||
| 344 | This leaves a very narrow race. Really we should do the | ||
| 345 | serial_do_free() on tty->shutdown(), but tty->shutdown can | ||
| 346 | be called from IRQ context and serial_do_free can sleep. | ||
| 347 | |||
| 348 | The right fix is probably to make the tty free (which is rare) | ||
| 349 | and thus tty->shutdown() occur via a work queue and simplify all | ||
| 350 | the drivers that use it. | ||
| 351 | */ | ||
| 352 | if (tty_hung_up_p(filp)) { | ||
| 353 | /* serial_hangup already called serial_down at this point. | ||
| 354 | Another user may have already reopened the port but | ||
| 355 | serial_do_free is refcounted */ | ||
| 356 | serial_do_free(port); | ||
| 357 | return; | ||
| 358 | } | ||
| 343 | 359 | ||
| 344 | if (tty_port_close_start(&port->port, tty, filp) == 0) | 360 | if (tty_port_close_start(&port->port, tty, filp) == 0) |
| 345 | return; | 361 | return; |
| @@ -355,7 +371,8 @@ static void serial_hangup(struct tty_struct *tty) | |||
| 355 | struct usb_serial_port *port = tty->driver_data; | 371 | struct usb_serial_port *port = tty->driver_data; |
| 356 | serial_do_down(port); | 372 | serial_do_down(port); |
| 357 | tty_port_hangup(&port->port); | 373 | tty_port_hangup(&port->port); |
| 358 | serial_do_free(port); | 374 | /* We must not free port yet - the USB serial layer depends on it's |
| 375 | continued existence */ | ||
| 359 | } | 376 | } |
| 360 | 377 | ||
| 361 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, | 378 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, |
