diff options
| author | Johan Hovold <johan@kernel.org> | 2021-09-17 13:46:19 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-10-06 10:23:42 +0200 |
| commit | a794b76f7b3a00688f021936c4dfa0a1860f9585 (patch) | |
| tree | 29602381c8d5b435bbfa2c8e1d3d0144df86399d | |
| parent | b73995edb15ba27a90e7368e10ac756b3b6fef77 (diff) | |
| download | linux-a794b76f7b3a00688f021936c4dfa0a1860f9585.tar.gz linux-a794b76f7b3a00688f021936c4dfa0a1860f9585.tar.bz2 linux-a794b76f7b3a00688f021936c4dfa0a1860f9585.zip | |
ipack: ipoctal: fix tty-registration error handling
commit cd20d59291d1790dc74248476e928f57fc455189 upstream.
Registration of the ipoctal tty devices is unlikely to fail, but if it
ever does, make sure not to deregister a never registered tty device
(and dereference a NULL pointer) when the driver is later unbound.
Fixes: 2afb41d9d30d ("Staging: ipack/devices/ipoctal: Check tty_register_device return value.")
Cc: stable@vger.kernel.org # 3.7
Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20210917114622.5412-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/ipack/devices/ipoctal.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index f3bbd2b785fe..11d5d772b65b 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -38,6 +38,7 @@ struct ipoctal_channel { unsigned int pointer_read; unsigned int pointer_write; struct tty_port tty_port; + bool tty_registered; union scc2698_channel __iomem *regs; union scc2698_block __iomem *block_regs; unsigned int board_id; @@ -402,9 +403,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, i, NULL, channel, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port); continue; } + channel->tty_registered = true; } /* @@ -705,6 +708,10 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) for (i = 0; i < NR_CHANNELS; i++) { struct ipoctal_channel *channel = &ipoctal->channel[i]; + + if (!channel->tty_registered) + continue; + tty_unregister_device(ipoctal->tty_drv, i); tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port); |
