diff options
author | Roel Kluin <roel.kluin@gmail.com> | 2009-06-22 13:41:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 14:32:23 -0400 |
commit | 52e3632ea603ef92757d5d0dedcd9fc8643445e3 (patch) | |
tree | 8ab96a99d898ada201b55ccb30fe7c0e6a10170f /drivers/serial/zs.c | |
parent | 607c268ef9a4675287e77f732071e426e62c2d86 (diff) |
serial: fix off by one errors
In zs_console_putchar() occurs:
if (zs_transmit_drain(zport, irq))
write_zsdata(zport, ch);
However if in zs_transmit_drain() no empty Tx Buffer occurs, limit reaches
-1 => true, and the write still occurs.
This patch changes postfix to prefix decrements in this and similar
functions to prevent similar mistakes in the future. This decreases the
iterations with one but the chosen loop count was arbitrary anyway.
In sunhv limit reaches -1, not 0, so the test is off by one.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial/zs.c')
-rw-r--r-- | drivers/serial/zs.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c index 9e6a873f8203..d8c2809b1ab6 100644 --- a/drivers/serial/zs.c +++ b/drivers/serial/zs.c | |||
@@ -231,7 +231,7 @@ static int zs_receive_drain(struct zs_port *zport) | |||
231 | { | 231 | { |
232 | int loops = 10000; | 232 | int loops = 10000; |
233 | 233 | ||
234 | while ((read_zsreg(zport, R0) & Rx_CH_AV) && loops--) | 234 | while ((read_zsreg(zport, R0) & Rx_CH_AV) && --loops) |
235 | read_zsdata(zport); | 235 | read_zsdata(zport); |
236 | return loops; | 236 | return loops; |
237 | } | 237 | } |
@@ -241,7 +241,7 @@ static int zs_transmit_drain(struct zs_port *zport, int irq) | |||
241 | struct zs_scc *scc = zport->scc; | 241 | struct zs_scc *scc = zport->scc; |
242 | int loops = 10000; | 242 | int loops = 10000; |
243 | 243 | ||
244 | while (!(read_zsreg(zport, R0) & Tx_BUF_EMP) && loops--) { | 244 | while (!(read_zsreg(zport, R0) & Tx_BUF_EMP) && --loops) { |
245 | zs_spin_unlock_cond_irq(&scc->zlock, irq); | 245 | zs_spin_unlock_cond_irq(&scc->zlock, irq); |
246 | udelay(2); | 246 | udelay(2); |
247 | zs_spin_lock_cond_irq(&scc->zlock, irq); | 247 | zs_spin_lock_cond_irq(&scc->zlock, irq); |
@@ -254,7 +254,7 @@ static int zs_line_drain(struct zs_port *zport, int irq) | |||
254 | struct zs_scc *scc = zport->scc; | 254 | struct zs_scc *scc = zport->scc; |
255 | int loops = 10000; | 255 | int loops = 10000; |
256 | 256 | ||
257 | while (!(read_zsreg(zport, R1) & ALL_SNT) && loops--) { | 257 | while (!(read_zsreg(zport, R1) & ALL_SNT) && --loops) { |
258 | zs_spin_unlock_cond_irq(&scc->zlock, irq); | 258 | zs_spin_unlock_cond_irq(&scc->zlock, irq); |
259 | udelay(2); | 259 | udelay(2); |
260 | zs_spin_lock_cond_irq(&scc->zlock, irq); | 260 | zs_spin_lock_cond_irq(&scc->zlock, irq); |