if (serial->minor != SERIAL_TTY_NO_MINOR)
return_serial(serial);
- serial->type->release(serial);
+ if (serial->attached)
+ serial->type->release(serial);
/* Now that nothing is using the ports, they can be freed */
for (i = 0; i < serial->num_port_pointers; ++i) {
* This is the first place a new tty gets used. Hence this is where we
* acquire references to the usb_serial structure and the driver module,
* where we store a pointer to the port, and where we do an autoresume.
- * All these actions are reversed in serial_release().
+ * All these actions are reversed in serial_cleanup().
*/
static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
{
}
/**
- * serial_release - free resources post close/hangup
+ * serial_cleanup - free resources post close/hangup
* @port: port to free up
*
* Do the resource freeing and refcount dropping for the port.
* Avoid freeing the console.
*
- * Called when the last tty kref is dropped.
+ * Called asynchronously after the last tty kref is dropped,
+ * and the tty layer has already done the tty_shutdown(tty);
*/
-static void serial_release(struct tty_struct *tty)
+static void serial_cleanup(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial;
dbg("%s - port %d", __func__, port->number);
- /* Standard shutdown processing */
- tty_shutdown(tty);
-
tty->driver_data = NULL;
serial = port->serial;
module_put(type->driver.owner);
if (retval < 0)
goto probe_error;
+ serial->attached = 1;
if (retval > 0) {
/* quietly accept this device, but don't bind to a
serial port as it's about to disappear */
serial->num_ports = 0;
goto exit;
}
+ } else {
+ serial->attached = 1;
}
if (get_free_serial(serial, num_ports, &minor) == NULL) {
if (serial->type->suspend) {
r = serial->type->suspend(serial, message);
- if (r < 0)
+ if (r < 0) {
+ serial->suspending = 0;
goto err_out;
+ }
}
for (i = 0; i < serial->num_ports; ++i) {
.chars_in_buffer = serial_chars_in_buffer,
.tiocmget = serial_tiocmget,
.tiocmset = serial_tiocmset,
- .shutdown = serial_release,
+ .cleanup = serial_cleanup,
.install = serial_install,
.proc_fops = &serial_proc_fops,
};