X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=linux%2Fppp.c;h=4779be667809d947aa9d755b4d6357dc646a0a1b;hb=44cd25b6c5a886f3cb615f2f0d8d78c6a52a2030;hp=45a1c6015ff8e4418c7933f521f8093bad2ecee4;hpb=ec78dccdebd40253b1f26fdab3aa5a2e418ea9cd;p=ppp.git diff --git a/linux/ppp.c b/linux/ppp.c index 45a1c60..4779be6 100644 --- a/linux/ppp.c +++ b/linux/ppp.c @@ -4,7 +4,7 @@ * Al Longyear * Extensively rewritten by Paul Mackerras * - * ==FILEVERSION 990331== + * ==FILEVERSION 990910== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the number above to the @@ -45,7 +45,7 @@ #define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */ -/* $Id: ppp.c,v 1.23 1999/03/31 05:29:08 paulus Exp $ */ +/* $Id: ppp.c,v 1.32 1999/09/11 12:09:31 paulus Exp $ */ #include #include @@ -104,7 +104,7 @@ #endif #undef PPP_VERSION -#define PPP_VERSION "2.3.6" +#define PPP_VERSION "2.3.10" #if LINUX_VERSION_CODE >= VERSION(2,1,4) @@ -174,14 +174,16 @@ typedef size_t rw_count_t; #define SUSER() capable(CAP_NET_ADMIN) #endif +#if LINUX_VERSION_CODE < VERSION(2,2,0) +#define wmb() mb() +#endif + /* * Local functions */ -#ifdef CONFIG_MODULES static int ppp_register_compressor (struct compressor *cp); static void ppp_unregister_compressor (struct compressor *cp); -#endif static void ppp_async_init(struct ppp *ppp); static void ppp_async_release(struct ppp *ppp); @@ -190,6 +192,7 @@ static int ppp_tty_push(struct ppp *ppp); static int ppp_async_encode(struct ppp *ppp); static int ppp_async_send(struct ppp *, struct sk_buff *); static int ppp_sync_send(struct ppp *, struct sk_buff *); +static void ppp_tty_flush_output(struct ppp *); static int ppp_ioctl(struct ppp *, unsigned int, unsigned long); static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp); @@ -338,6 +341,9 @@ __u16 ppp_crc16_table[256] = 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; +#if LINUX_VERSION_CODE >= VERSION(2,1,18) +EXPORT_SYMBOL(ppp_crc16_table); +#endif #ifdef CHECK_CHARACTERS static __u32 paritytab[8] = @@ -552,6 +558,7 @@ ppp_tty_close (struct tty_struct *tty) ppp->tty = ppp->backup_tty; if (ppp_tty_push(ppp)) ppp_output_wakeup(ppp); + wake_up_interruptible(&ppp->read_wait); } else { ppp->tty = 0; ppp->sc_xfer = 0; @@ -831,6 +838,21 @@ ppp_tty_ioctl (struct tty_struct *tty, struct file * file, error = n_tty_ioctl (tty, file, param2, param3); break; + case TCFLSH: + /* + * Flush our buffers, then call the generic code to + * flush the serial port's buffer. + */ + if (param3 == TCIFLUSH || param3 == TCIOFLUSH) { + struct sk_buff *skb; + while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL) + KFREE_SKB(skb); + } + if (param3 == TCIOFLUSH || param3 == TCOFLUSH) + ppp_tty_flush_output(ppp); + error = n_tty_ioctl (tty, file, param2, param3); + break; + case FIONREAD: /* * Returns how many bytes are available for a read(). @@ -1035,7 +1057,7 @@ ppp_tty_sync_push(struct ppp *ppp) save_flags(flags); cli(); if (ppp->tty_pushing) { - /* record wakeup attempt so we don't loose */ + /* record wakeup attempt so we don't lose */ /* a wakeup call while doing push processing */ ppp->woke_up=1; restore_flags(flags); @@ -1118,16 +1140,20 @@ ppp_tty_push(struct ppp *ppp) int avail, sent, done = 0; struct tty_struct *tty = ppp2tty(ppp); - if ( ppp->flags & SC_SYNC ) + if (ppp->flags & SC_SYNC) return ppp_tty_sync_push(ppp); CHECK_PPP(0); - if (ppp->tty_pushing) + if (ppp->tty_pushing) { + ppp->woke_up = 1; return 0; + } if (tty == NULL || tty->disc_data != (void *) ppp) goto flush; while (ppp->optr < ppp->olim || ppp->tpkt != 0) { ppp->tty_pushing = 1; + mb(); + ppp->woke_up = 0; avail = ppp->olim - ppp->optr; if (avail > 0) { tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); @@ -1137,18 +1163,24 @@ ppp_tty_push(struct ppp *ppp) ppp->stats.ppp_obytes += sent; ppp->optr += sent; if (sent < avail) { + wmb(); ppp->tty_pushing = 0; + mb(); + if (ppp->woke_up) + continue; return done; } } if (ppp->tpkt != 0) done = ppp_async_encode(ppp); + wmb(); ppp->tty_pushing = 0; } return done; flush: ppp->tty_pushing = 1; + mb(); ppp->stats.ppp_oerrors++; if (ppp->tpkt != 0) { KFREE_SKB(ppp->tpkt); @@ -1156,6 +1188,7 @@ flush: done = 1; } ppp->optr = ppp->olim; + wmb(); ppp->tty_pushing = 0; return done; } @@ -1269,6 +1302,32 @@ ppp_async_encode(struct ppp *ppp) return 0; } +/* + * Flush output from our internal buffers. + * Called for the TCFLSH ioctl. + */ +static void +ppp_tty_flush_output(struct ppp *ppp) +{ + struct sk_buff *skb; + int done = 0; + + while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL) + KFREE_SKB(skb); + ppp->tty_pushing = 1; + mb(); + ppp->optr = ppp->olim; + if (ppp->tpkt != NULL) { + KFREE_SKB(ppp->tpkt); + ppp->tpkt = 0; + done = 1; + } + wmb(); + ppp->tty_pushing = 0; + if (done) + ppp_output_wakeup(ppp); +} + /* * Callback function from tty driver. Return the amount of space left * in the receiver's buffer to decide if remote transmitter is to be @@ -1904,6 +1963,9 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3) break; switch (npi.protocol) { + case PPP_IPV6: + npi.protocol = NP_IPV6; + break; case PPP_IP: npi.protocol = NP_IP; break; @@ -3190,7 +3252,6 @@ static struct compressor *find_compressor (int type) return (struct compressor *) 0; } -#ifdef CONFIG_MODULES static int ppp_register_compressor (struct compressor *cp) { struct compressor_link *new; @@ -3243,7 +3304,6 @@ static void ppp_unregister_compressor (struct compressor *cp) } restore_flags(flags); } -#endif /************************************************************* * Module support routines