/* Encapsulate one IP datagram and stuff into a TTY queue. */ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len) { unsigned char *p; int actual, count, mtu = sl->dev->mtu; if (len > mtu) { /* Sigh, shouldn't occur BUT ... */ len = mtu; printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n", sl->dev->name); sl->dev->stats.tx_dropped++; x25_asy_unlock(sl); return; } p = icp; count = x25_asy_esc(p, sl->xbuff, len); /* Order of next two lines is *very* important. * When we are sending a little amount of data, * the transfer may be completed inside driver.write() * routine, because it's running with interrupts enabled. * In this case we *never* got WRITE_WAKEUP event, * if we did not request it before write operation. * 14 Oct 1994 Dmitry Gorodchanin. */ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); actual = sl->tty->ops->write(sl->tty, sl->xbuff, count); sl->xleft = count - actual; sl->xhead = sl->xbuff + actual; /* VSV */ clear_bit(SLF_OUTWAIT, &sl->flags); /* reset outfill flag */ }
static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len) { unsigned char *p; int actual, count, mtu = sl->dev->mtu; if (len > mtu) { /* */ len = mtu; printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n", sl->dev->name); sl->dev->stats.tx_dropped++; x25_asy_unlock(sl); return; } p = icp; count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len); /* */ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); actual = sl->tty->ops->write(sl->tty, sl->xbuff, count); sl->xleft = count - actual; sl->xhead = sl->xbuff + actual; /* */ clear_bit(SLF_OUTWAIT, &sl->flags); /* */ }
static void x25_asy_timeout(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); /* May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin. */ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); x25_asy_unlock(sl); }
static void x25_asy_timeout(struct net_device *dev) { struct x25_asy *sl = netdev_priv(dev); spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { /* May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin. */ netdev_warn(dev, "transmit timed out, %s?\n", (tty_chars_in_buffer(sl->tty) || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); x25_asy_unlock(sl); } spin_unlock(&sl->lock); }
/* * Called by the driver when there's room for more data. If we have * more packets to send, we send them here. */ static void x25_asy_write_wakeup(struct tty_struct *tty) { int actual; struct x25_asy *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) return; if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); x25_asy_unlock(sl); return; } actual = tty->ops->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; }
static void x25_asy_write_wakeup(struct tty_struct *tty) { int actual; struct x25_asy *sl = tty->disc_data; /* */ if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) return; if (sl->xleft <= 0) { /* */ sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); x25_asy_unlock(sl); return; } actual = tty->ops->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; }