Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / ppp_async.c
index 33b9d79..23659fd 100644 (file)
@@ -30,7 +30,9 @@
 #include <linux/ppp_channel.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 #include <asm/uaccess.h>
+#include <asm/string.h>
 
 #define PPP_VERSION    "2.4.2"
 
@@ -188,7 +190,7 @@ ppp_asynctty_open(struct tty_struct *tty)
                goto out_free;
 
        tty->disc_data = ap;
-
+       tty->receive_room = 65536;
        return 0;
 
  out_free:
@@ -342,12 +344,6 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
        return 0;
 }
 
-static int
-ppp_asynctty_room(struct tty_struct *tty)
-{
-       return 65535;
-}
-
 /*
  * This can now be called from hard interrupt level as well
  * as soft interrupt level or mainline.
@@ -364,7 +360,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
        spin_lock_irqsave(&ap->recv_lock, flags);
        ppp_async_input(ap, buf, cflags, count);
        spin_unlock_irqrestore(&ap->recv_lock, flags);
-       if (skb_queue_len(&ap->rqueue))
+       if (!skb_queue_empty(&ap->rqueue))
                tasklet_schedule(&ap->tsk);
        ap_put(ap);
        if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
@@ -397,7 +393,6 @@ static struct tty_ldisc ppp_ldisc = {
        .write  = ppp_asynctty_write,
        .ioctl  = ppp_asynctty_ioctl,
        .poll   = ppp_asynctty_poll,
-       .receive_room = ppp_asynctty_room,
        .receive_buf = ppp_asynctty_receive,
        .write_wakeup = ppp_asynctty_wakeup,
 };
@@ -576,7 +571,7 @@ ppp_async_encode(struct asyncppp *ap)
                 * character if necessary.
                 */
                if (islcp || flag_time == 0
-                   || jiffies - ap->last_xmit >= flag_time)
+                   || time_after_eq(jiffies, ap->last_xmit + flag_time))
                        *buf++ = PPP_FLAG;
                ap->last_xmit = jiffies;
                fcs = PPP_INITFCS;
@@ -835,8 +830,11 @@ process_input_packet(struct asyncppp *ap)
  err:
        /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
        ap->state = SC_PREV_ERROR;
-       if (skb)
+       if (skb) {
+               /* make skb appear as freshly allocated */
                skb_trim(skb, 0);
+               skb_reserve(skb, - skb_headroom(skb));
+       }
 }
 
 /* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +887,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                                skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
                                if (skb == 0)
                                        goto nomem;
-                               /* Try to get the payload 4-byte aligned */
+                               ap->rpkt = skb;
+                       }
+                       if (skb->len == 0) {
+                               /* Try to get the payload 4-byte aligned.
+                                * This should match the
+                                * PPP_ALLSTATIONS/PPP_UI/compressed tests in
+                                * process_input_packet, but we do not have
+                                * enough chars here to test buf[1] and buf[2].
+                                */
                                if (buf[0] != PPP_ALLSTATIONS)
                                        skb_reserve(skb, 2 + (buf[0] & 1));
-                               ap->rpkt = skb;
                        }
                        if (n > skb_tailroom(skb)) {
                                /* packet overflowed MRU */
@@ -1025,7 +1030,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
 
 static void __exit ppp_async_cleanup(void)
 {
-       if (tty_register_ldisc(N_PPP, NULL) != 0)
+       if (tty_unregister_ldisc(N_PPP) != 0)
                printk(KERN_ERR "failed to unregister PPP line discipline\n");
 }