Commit 5c1a0f41 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: cypress_m8: fix port-data memory leak

Fix port-data memory leak by replacing attach and release with
port_probe and port_remove.

Since commit 0998d063 (device-core: Ensure drvdata = NULL when no
driver is bound) the port private data is no longer freed at release as
it is no longer accessible.

Compile-only tested.

Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 301a29da
...@@ -123,10 +123,10 @@ struct cypress_private { ...@@ -123,10 +123,10 @@ struct cypress_private {
}; };
/* function prototypes for the Cypress USB to serial device */ /* function prototypes for the Cypress USB to serial device */
static int cypress_earthmate_startup(struct usb_serial *serial); static int cypress_earthmate_port_probe(struct usb_serial_port *port);
static int cypress_hidcom_startup(struct usb_serial *serial); static int cypress_hidcom_port_probe(struct usb_serial_port *port);
static int cypress_ca42v2_startup(struct usb_serial *serial); static int cypress_ca42v2_port_probe(struct usb_serial_port *port);
static void cypress_release(struct usb_serial *serial); static int cypress_port_remove(struct usb_serial_port *port);
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
static void cypress_close(struct usb_serial_port *port); static void cypress_close(struct usb_serial_port *port);
static void cypress_dtr_rts(struct usb_serial_port *port, int on); static void cypress_dtr_rts(struct usb_serial_port *port, int on);
...@@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = { ...@@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = {
.description = "DeLorme Earthmate USB", .description = "DeLorme Earthmate USB",
.id_table = id_table_earthmate, .id_table = id_table_earthmate,
.num_ports = 1, .num_ports = 1,
.attach = cypress_earthmate_startup, .port_probe = cypress_earthmate_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = { ...@@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = {
.description = "HID->COM RS232 Adapter", .description = "HID->COM RS232 Adapter",
.id_table = id_table_cyphidcomrs232, .id_table = id_table_cyphidcomrs232,
.num_ports = 1, .num_ports = 1,
.attach = cypress_hidcom_startup, .port_probe = cypress_hidcom_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { ...@@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = {
.description = "Nokia CA-42 V2 Adapter", .description = "Nokia CA-42 V2 Adapter",
.id_table = id_table_nokiaca42v2, .id_table = id_table_nokiaca42v2,
.num_ports = 1, .num_ports = 1,
.attach = cypress_ca42v2_startup, .port_probe = cypress_ca42v2_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port) ...@@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port)
*****************************************************************************/ *****************************************************************************/
static int generic_startup(struct usb_serial *serial) static int cypress_generic_port_probe(struct usb_serial_port *port)
{ {
struct usb_serial *serial = port->serial;
struct cypress_private *priv; struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial) ...@@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial)
} }
static int cypress_earthmate_startup(struct usb_serial *serial) static int cypress_earthmate_port_probe(struct usb_serial_port *port)
{ {
struct usb_serial *serial = port->serial;
struct cypress_private *priv; struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0]; int ret;
if (generic_startup(serial)) { ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
...@@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial) ...@@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial)
} }
return 0; return 0;
} /* cypress_earthmate_startup */ }
static int cypress_hidcom_startup(struct usb_serial *serial) static int cypress_hidcom_port_probe(struct usb_serial_port *port)
{ {
struct cypress_private *priv; struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0]; int ret;
if (generic_startup(serial)) { ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CYPHIDCOM; priv->chiptype = CT_CYPHIDCOM;
return 0; return 0;
} /* cypress_hidcom_startup */ }
static int cypress_ca42v2_startup(struct usb_serial *serial) static int cypress_ca42v2_port_probe(struct usb_serial_port *port)
{ {
struct cypress_private *priv; struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0]; int ret;
if (generic_startup(serial)) { ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CA42V2; priv->chiptype = CT_CA42V2;
return 0; return 0;
} /* cypress_ca42v2_startup */ }
static void cypress_release(struct usb_serial *serial) static int cypress_port_remove(struct usb_serial_port *port)
{ {
struct cypress_private *priv; struct cypress_private *priv;
/* all open ports are closed at this point */ priv = usb_get_serial_port_data(port);
priv = usb_get_serial_port_data(serial->port[0]);
if (priv) { kfifo_free(&priv->write_fifo);
kfifo_free(&priv->write_fifo); kfree(priv);
kfree(priv);
}
}
return 0;
}
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
......
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