* frees the memory that ppp_asynctty_receive is using. The best
* way to fix this is to use a rwlock in the tty struct, but for now
* we use a single global rwlock for all ttys in ppp line discipline.
+ *
+ * FIXME: this is no longer true. The _close path for the ldisc is
+ * now guaranteed to be sane.
*/
static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
}
/*
- * Called when a tty is put into PPP line discipline.
+ * Called when a tty is put into PPP line discipline. Called in process
+ * context.
*/
static int
ppp_asynctty_open(struct tty_struct *tty)
kfree(ap);
}
+/*
+ * Called on tty hangup in process context.
+ *
+ * Wait for I/O to driver to complete and unregister PPP channel.
+ * This is already done by the close routine, so just call that.
+ */
+static int ppp_asynctty_hangup(struct tty_struct *tty)
+{
+ ppp_asynctty_close(tty);
+ return 0;
+}
+
/*
* Read does nothing - no data is ever available this way.
* Pppd reads and writes packets via /dev/ppp instead.
return -EAGAIN;
}
+/*
+ * Called in process context only. May be re-entered by multiple
+ * ioctl calling threads.
+ */
+
static int
ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
.name = "ppp",
.open = ppp_asynctty_open,
.close = ppp_asynctty_close,
+ .hangup = ppp_asynctty_hangup,
.read = ppp_asynctty_read,
.write = ppp_asynctty_write,
.ioctl = ppp_asynctty_ioctl,
/*
* Flush output from our internal buffers.
- * Called for the TCFLSH ioctl.
+ * Called for the TCFLSH ioctl. Can be entered in parallel
+ * but this is covered by the xmit_lock.
*/
static void
ppp_async_flush_output(struct asyncppp *ap)
skb_trim(skb, 0);
}
-/* called when the tty driver has data for us. */
+/* Called when the tty driver has data for us. Runs parallel with the
+ other ldisc functions but will not be re-entered */
+
static void
ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
char *flags, int count)