aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>2012-12-10 05:49:59 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-15 21:24:38 -0500
commit7e5730d7c22267e406454b5cff0c40e4ebf9a0da (patch)
treeda9191e21e3db5d93fd3b1050251fff8d1940744
parent69a6b9b1b6aec645d2efa23db2c15ed287e672dd (diff)
ipack/devices/ipoctal: fix kernel bug when using pppd
Trying to setup the pppd server to use ipoctal's serial ports, it says the ports are busy the first time. If the operation is repeated, a kernel bug due to a dereference of a NULL pointer appears. Removing the one-access-only setup from the driver, removes this kernel bug. Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/ipack/devices/ipoctal.c21
1 files changed, 2 insertions, 19 deletions
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index a33a849765c6..8d0a86631908 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -38,7 +38,6 @@ struct ipoctal_channel {
38 spinlock_t lock; 38 spinlock_t lock;
39 unsigned int pointer_read; 39 unsigned int pointer_read;
40 unsigned int pointer_write; 40 unsigned int pointer_write;
41 atomic_t open;
42 struct tty_port tty_port; 41 struct tty_port tty_port;
43 union scc2698_channel __iomem *regs; 42 union scc2698_channel __iomem *regs;
44 union scc2698_block __iomem *block_regs; 43 union scc2698_block __iomem *block_regs;
@@ -70,22 +69,12 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
70 69
71static int ipoctal_open(struct tty_struct *tty, struct file *file) 70static int ipoctal_open(struct tty_struct *tty, struct file *file)
72{ 71{
73 int res;
74 struct ipoctal_channel *channel; 72 struct ipoctal_channel *channel;
75 73
76 channel = dev_get_drvdata(tty->dev); 74 channel = dev_get_drvdata(tty->dev);
77
78 if (atomic_read(&channel->open))
79 return -EBUSY;
80
81 tty->driver_data = channel; 75 tty->driver_data = channel;
82 76
83 res = tty_port_open(&channel->tty_port, tty, file); 77 return tty_port_open(&channel->tty_port, tty, file);
84 if (res)
85 return res;
86
87 atomic_inc(&channel->open);
88 return 0;
89} 78}
90 79
91static void ipoctal_reset_stats(struct ipoctal_stats *stats) 80static void ipoctal_reset_stats(struct ipoctal_stats *stats)
@@ -111,9 +100,7 @@ static void ipoctal_close(struct tty_struct *tty, struct file *filp)
111 struct ipoctal_channel *channel = tty->driver_data; 100 struct ipoctal_channel *channel = tty->driver_data;
112 101
113 tty_port_close(&channel->tty_port, tty, filp); 102 tty_port_close(&channel->tty_port, tty, filp);
114 103 ipoctal_free_channel(channel);
115 if (atomic_dec_and_test(&channel->open))
116 ipoctal_free_channel(channel);
117} 104}
118 105
119static int ipoctal_get_icount(struct tty_struct *tty, 106static int ipoctal_get_icount(struct tty_struct *tty,
@@ -205,10 +192,6 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel)
205 u8 isr, sr; 192 u8 isr, sr;
206 struct tty_struct *tty; 193 struct tty_struct *tty;
207 194
208 /* If there is no client, skip the check */
209 if (!atomic_read(&channel->open))
210 return;
211
212 tty = tty_port_tty_get(&channel->tty_port); 195 tty = tty_port_tty_get(&channel->tty_port);
213 if (!tty) 196 if (!tty)
214 return; 197 return;