[PATCH 2/5] SLIP: Handle error codes from the TTY layer

Dean Jenkins
2013-07-02T15:42:25Z

It appears that SLIP does not handle error codes from the TTY layer.
This will result in a malfunction because the remaining length of
data will be corrupted by the negative error code values from the TTY
layer.

Therefore, add error code checks in sl_encaps() and sl_encaps_wakeup()
to prevent the corruption of the sent data length.

Note that SLIP is connectionless so on TTY error indicate that all data
was sent. It seems SLIP does not return error codes to the network
layer.

Signed-off-by: Dean Jenkins <Dean_Jenkins@mentor.com>
---
drivers/net/slip/slip.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index a34d6bf..bed819f 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -374,7 +374,7 @@ static void sl_bump(struct slip *sl)
static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
{
unsigned char *p;
- int actual, count;
+ int actual, count, err;

if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */
printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
@@ -404,7 +404,16 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
* 14 Oct 1994 Dmitry Gorodchanin.
*/
set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
- actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
+ err = sl->tty->ops->write(sl->tty, sl->xbuff, count);
+
+ if (err < 0) {
+ /* error case, say all was sent as connectionless */
+ actual = count;
+ } else {
+ /* good case, err contains the number sent */
+ actual = err;
+ }
+
#ifdef SL_CHECK_TRANSMIT
sl->dev->trans_start = jiffies;
#endif
@@ -422,7 +431,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
*/
static void slip_write_wakeup(struct tty_struct *tty)
{
- int actual;
+ int actual, err;
struct slip *sl = tty->disc_data;

/* First make sure we're connected. */
@@ -438,7 +447,16 @@ static void slip_write_wakeup(struct tty_struct *tty)
return;
}

- actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+ err = tty->ops->write(tty, sl->xhead, sl->xleft);
+
+ if (err < 0) {
+ /* error case, say all was sent as connectionless */
+ actual = sl->xleft;
+ } else {
+ /* good case, err contains the number sent */
+ actual = err;
+ }
+
sl->xleft -= actual;
sl->xhead += actual;
}
--
1.8.1.5