Commit 0d202675 authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14z

parent f614125e
VERSION = 0.99
PATCHLEVEL = 14
ALPHA = y
ALPHA = z
all: Version zImage
......
......@@ -55,12 +55,14 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
{
unsigned long count, n;
struct tty_queue *fq, *tq;
int skip_readq;
if (from->stopped || EMPTY(&from->write_q))
return;
fq = &from->write_q;
/* Bypass the read_q if this is a pty master. */
tq = IS_A_PTY_MASTER(to->line) ? &to->secondary : &to->read_q;
skip_readq = IS_A_PTY_MASTER(to->line) && to->disc == N_TTY;
tq = skip_readq ? &to->secondary : &to->read_q;
count = MIN(CHARS(fq), LEFT(tq));
while (count) {
n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
......@@ -70,8 +72,8 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
}
if (IS_A_PTY_MASTER(to->line))
wake_up_interruptible(&tq->proc_list);
if (skip_readq)
wake_up_interruptible(&to->secondary.proc_list);
else
TTY_READ_FLUSH(to);
if (LEFT(fq) > WAKEUP_CHARS)
......
......@@ -292,7 +292,7 @@ el_start_xmit(struct sk_buff *skb, struct device *dev)
}
/* Fill in the ethernet header. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -310,7 +310,7 @@ el_start_xmit(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
el_status.tx_pkt_start = gp_start;
el_status.collisions = 0;
......@@ -463,7 +463,7 @@ el_receive(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
insb(DATAPORT, (void *)(skb+1), pkt_len);
insb(DATAPORT, skb->data, pkt_len);
#ifdef HAVE_NETIF_RX
netif_rx(skb);
......
......@@ -484,7 +484,7 @@ el16_send_packet(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header. This should really be done by a
higher level, rather than duplicated for each ethernet adaptor. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -496,7 +496,7 @@ el16_send_packet(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
/* Disable the 82586's input to the interrupt line. */
outb(0x80, ioaddr + MISC_CTRL);
......@@ -855,8 +855,8 @@ el16_rx(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
memcpy((unsigned char *) (skb + 1), data_frame + 5, pkt_len);
/* 'skb->data' points to the start of sk_buff data area. */
memcpy(skb->data, data_frame + 5, pkt_len);
#ifdef HAVE_NETIF_RX
netif_rx(skb);
......
......@@ -366,7 +366,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
}
/* Fill in the ethernet header. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -404,7 +404,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
outw(skb->len, ioaddr + TX_FIFO);
outw(0x00, ioaddr + TX_FIFO);
/* ... and the packet rounded to a doubleword. */
outsl(ioaddr + TX_FIFO, (void *)(skb+1), (skb->len + 3) >> 2);
outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
dev->trans_start = jiffies;
if (inw(ioaddr + TX_FREE) > 1536) {
......@@ -576,8 +576,8 @@ el3_rx(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
insl(ioaddr+RX_FIFO, (void *)(skb+1),
/* 'skb->data' points to the start of sk_buff data area. */
insl(ioaddr+RX_FIFO, skb->data,
(pkt_len + 3) >> 2);
#ifdef HAVE_NETIF_RX
......
......@@ -160,7 +160,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
return 0;
}
/* Fill in the ethernet header. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -219,7 +219,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
return 1;
}
dev->trans_start = jiffies;
ei_block_output(dev, length, (unsigned char *)(skb+1), output_page);
ei_block_output(dev, length, skb->data, output_page);
if (! ei_local->txing) {
NS8390_trigger_send(dev, send_length, output_page);
if (output_page == ei_local->tx_start_page)
......@@ -233,7 +233,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
tmp_tbusy = 1;
} else {
dev->trans_start = jiffies;
ei_block_output(dev, length, (unsigned char *)(skb+1),
ei_block_output(dev, length, skb->data,
ei_local->tx_start_page);
NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
tmp_tbusy = 1;
......@@ -495,8 +495,8 @@ static void ei_receive(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
ei_block_input(dev, pkt_len, (char *)(skb+1),
/* 'skb->data' points to the start of sk_buff data area. */
ei_block_input(dev, pkt_len, (char *) skb->data,
current_offset + sizeof(rx_frame));
#ifdef HAVE_NETIF_RX
netif_rx(skb);
......
......@@ -402,7 +402,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header. This should really be done by a
higher level, rather than duplicated for each ethernet adaptor. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -415,7 +415,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
if (net_debug > 4)
printk("%s: Transmitting a packet of length %d.\n", dev->name,
......@@ -551,14 +551,14 @@ net_rx(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
insw(ioaddr + DATAPORT, (void *)(skb+1), (pkt_len + 1) >> 1);
/* 'skb->data' points to the start of sk_buff data area. */
insw(ioaddr + DATAPORT, skb->data, (pkt_len + 1) >> 1);
if (net_debug > 5) {
int i;
printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
for (i = 0; i < 14; i++)
printk(" %02x", ((unsigned char*)(skb + 1))[i]);
printk(" %02x", skb->data[i]);
printk(".\n");
}
......
......@@ -477,7 +477,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header. This should really be done by a
higher level, rather than duplicated for each ethernet adaptor. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -490,7 +490,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
int flags;
/* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
......@@ -686,11 +686,11 @@ static void net_rx(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
read_block(ioaddr, pkt_len, (unsigned char *)(skb + 1), dev->if_port);
/* 'skb->data' points to the start of sk_buff data area. */
read_block(ioaddr, pkt_len, skb->data, dev->if_port);
if (net_debug > 6) {
unsigned char *data = (unsigned char *)(skb + 1);
unsigned char *data = skb->data;
printk(" data %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x..",
data[0], data[1], data[2], data[3], data[4], data[5],
data[6], data[7], data[8], data[9], data[10], data[11],
......
......@@ -386,7 +386,7 @@ d_link_start_xmit(struct sk_buff *skb, struct device *dev)
int transmit_from;
int len;
int tickssofar;
unsigned char *buffer = (unsigned char *)(skb + 1);
unsigned char *buffer = skb->data;
/*
* If some higher layer thinks we've missed a
......@@ -401,7 +401,7 @@ d_link_start_xmit(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header (hardware addresses) with an arp. */
if (!skb->arp)
if(dev->rebuild_header(skb + 1, dev)) {
if(dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -590,8 +590,8 @@ d_link_rx_intr(struct device *dev)
skb->lock = 0;
skb->mem_len = sksize;
skb->mem_addr = skb;
/* 'skb + 1' points to the start of sk_buff data area. */
buffer = (unsigned char *)(skb + 1);
/* 'skb->data' points to the start of sk_buff data area. */
buffer = skb->data;
/* copy the packet into the buffer */
d_link_setup_address(read_from, RW_ADDR);
......
......@@ -511,7 +511,7 @@ eexp_send_packet(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header. This should really be done by a
higher level, rather than duplicated for each ethernet adaptor. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -523,7 +523,7 @@ eexp_send_packet(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
/* Disable the 82586's input to the interrupt line. */
outb(irqrmap[dev->irq], ioaddr + SET_IRQ);
......@@ -960,7 +960,7 @@ eexp_rx(struct device *dev)
outw(data_buffer_addr + 10, ioaddr + READ_PTR);
insw(ioaddr, (void *)(skb+1), (pkt_len + 1) >> 1);
insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
#ifdef HAVE_NETIF_RX
netif_rx(skb);
......
......@@ -512,7 +512,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
}
/* Fill in the ethernet header. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -553,11 +553,11 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
/* If any part of this buffer is >16M we must copy it to a low-memory
buffer. */
if ((int)(skb+1) + skb->len > 0x01000000) {
if ((int)(skb->data) + skb->len > 0x01000000) {
if (lance_debug > 5)
printk("%s: bouncing a high-memory packet (%#x).\n",
dev->name, (int)(skb+1));
memcpy(&lp->tx_bounce_buffs[entry], skb+1, skb->len);
dev->name, (int)skb->data);
memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
lp->tx_ring[entry].base =
(int)(lp->tx_bounce_buffs + entry) | 0x83000000;
if (skb->free)
......@@ -567,7 +567,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
/* Gimme!!! */
if(skb->free==0)
skb_kept_by_device(skb);
lp->tx_ring[entry].base = (int)(skb+1) | 0x83000000;
lp->tx_ring[entry].base = (int)skb->data | 0x83000000;
}
lp->cur_tx++;
......@@ -726,7 +726,7 @@ lance_rx(struct device *dev)
skb->mem_addr = skb;
skb->len = pkt_len;
skb->dev = dev;
memcpy((unsigned char *) (skb + 1),
memcpy(skb->data,
(unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
pkt_len);
#ifdef HAVE_NETIF_RX
......
......@@ -285,7 +285,7 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev)
/* Pretend we are an ethernet and fill in the header. This could use
a simplified routine someday. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -293,7 +293,7 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev)
skb->arp=1;
dev->trans_start = jiffies;
ret_val = plip_send_packet(dev, (unsigned char *)(skb+1), skb->len);
ret_val = plip_send_packet(dev, skb->data, skb->len);
if (skb->free)
kfree_skb (skb, FREE_WRITE);
dev->tbusy = 0;
......@@ -483,8 +483,8 @@ plip_receive_packet(struct device *dev)
}
{
/* phase of receiving the data */
/* 'skb+1' points to the start of sk_buff data area. */
unsigned char *buf = (unsigned char *) (skb+1);
/* 'skb->data' points to the start of sk_buff data area. */
unsigned char *buf = skb->data;
unsigned char *eth_p = (unsigned char *)&eth;
int i;
for ( i = 0; i < sizeof(eth); i++) {
......
......@@ -316,7 +316,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
/* For ethernet, fill in the header. This should really be done by a
higher level, rather than duplicated for each ethernet adaptor. */
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
......@@ -329,7 +329,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = (void *)(skb+1);
unsigned char *buf = skb->data;
hardware_send_packet(ioaddr, buf, length);
dev->trans_start = jiffies;
......@@ -420,11 +420,11 @@ net_rx(struct device *dev)
skb->len = pkt_len;
skb->dev = dev;
/* 'skb+1' points to the start of sk_buff data area. */
memcpy((unsigned char *) (skb + 1), (void*)dev->rmem_start,
/* 'skb->data' points to the start of sk_buff data area. */
memcpy(skb->data, (void*)dev->rmem_start,
pkt_len);
/* or */
insw(ioaddr, (void *)(skb+1), (pkt_len + 1) >> 1);
insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
#ifdef HAVE_NETIF_RX
netif_rx(skb);
......
......@@ -545,7 +545,7 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
#ifdef CONFIG_AX25
if(sl->mode & SL_MODE_AX25)
{
if(!skb->arp && dev->rebuild_header(skb+1,dev))
if(!skb->arp && dev->rebuild_header(skb->data,dev))
{
skb->dev=dev;
arp_queue(skb);
......@@ -555,8 +555,8 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
}
#endif
sl_lock(sl);
/* sl_hex_dump((unsigned char *)(skb+1),skb->len);*/
sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
/* sl_hex_dump(skb->data,skb->len);*/
sl_encaps(sl, skb->data, skb->len);
if (skb->free) kfree_skb(skb, FREE_WRITE);
}
return(0);
......@@ -599,7 +599,7 @@ sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
struct slip *sl=&sl_ctrl[dev->base_addr];
if(sl->mode&SL_MODE_AX25)
arp_add(addr,((char *)(skb+1))+8,dev);
arp_add(addr,((char *) skb->data)+8,dev);
#endif
}
......@@ -686,6 +686,10 @@ sl_open(struct device *dev)
return(-ENOMEM);
}
dev->flags|=IFF_UP;
/* Needed because address '0' is special */
if(dev->pa_addr==0)
dev->pa_addr=ntohl(0xC0000001);
DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
return(0);
}
......
......@@ -642,8 +642,8 @@ static void do_timer(struct pt_regs * regs)
calc_load();
if ((VM_MASK & regs->eflags) || (3 & regs->cs)) {
current->utime++;
if(current != task[0]) {
if(current->priority != 15)
if (current != task[0]) {
if (current->priority < 15)
kstat.cpu_nice++;
else
kstat.cpu_user++;
......
......@@ -251,14 +251,19 @@ arp_send_q(void)
/* Create and send our response to an ARP request. */
static int
arp_response(struct arphdr *arp1, struct device *dev, int addrtype)
/*
* We are now a bit smarter. We know the old buffer must be big enough
* so why allocate a new one for the reply ?
*/
static int arp_response(struct sk_buff *skb,struct arphdr *arp1, struct device *dev, int addrtype)
{
struct arphdr *arp2;
struct sk_buff *skb;
unsigned long src, dst;
unsigned char *ptr1, *ptr2;
int hlen;
int len;
struct arp_table *apt = NULL;/* =NULL otherwise the compiler gives warnings */
/* Decode the source (REQUEST) message. */
......@@ -270,24 +275,28 @@ arp_response(struct arphdr *arp1, struct device *dev, int addrtype)
{
apt=arp_lookup_proxy(dst);
if(apt==NULL)
{
kfree_skb(skb,FREE_READ);
return(1);
}
}
/* Get some mem and initialize it for the return trip. */
skb = alloc_skb(sizeof(struct sk_buff) +
sizeof(struct arphdr) +
(2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
dev->hard_header_len, GFP_ATOMIC);
if (skb == NULL) {
printk("ARP: no memory available for ARP REPLY!\n");
return(1);
skb->h.raw=skb->data;
skb->len+=dev->hard_header_len; /* Grow the packet back to its original form */
/* Can't check for exceeding the size - some people pad. */
len= sizeof(struct arphdr) + (2 * arp1->ar_hln) + (2 * arp1->ar_pln) + dev->hard_header_len;
if(len>skb->len)
{
printk("Received runt ARP request!\n");
kfree_skb(skb,FREE_READ);
return 1;
}
skb->mem_addr = skb;
skb->len = sizeof(struct arphdr) + (2 * arp1->ar_hln) +
(2 * arp1->ar_pln) + dev->hard_header_len;
skb->mem_len = sizeof(struct sk_buff) + skb->len;
skb->len = len;
hlen = dev->hard_header(skb->data, dev, ETH_P_ARP, src, dst, skb->len);
if (hlen < 0) {
printk("ARP: cannot create HW frame header for REPLY !\n");
kfree_skb(skb, FREE_WRITE);
......@@ -578,8 +587,7 @@ arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* Yes, it is for us.
* Allocate, fill in and send an ARP REPLY packet.
*/
ret = arp_response(arp, dev, addr_hint);
kfree_skb(skb, FREE_READ);
ret = arp_response(skb,arp, dev, addr_hint);
return(ret);
}
......@@ -608,14 +616,12 @@ arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
/* Fill in the request. */
skb->sk = NULL;
skb->mem_addr = skb;
skb->len = sizeof(struct arphdr) +
dev->hard_header_len + (2 * dev->addr_len) + 8;
skb->mem_len = sizeof(struct sk_buff) + skb->len;
skb->arp = 1;
skb->dev = dev;
skb->next = NULL;
skb->free = 1;
skb->next = NULL;
tmp = dev->hard_header(skb->data, dev, ETH_P_ARP, 0, saddr, skb->len);
if (tmp < 0) {
kfree_skb(skb,FREE_WRITE);
......
......@@ -324,10 +324,10 @@ destroy_sock(struct sock *sk)
delete_timer(sk);
if (sk->send_tmp != NULL)
while ((skb = tcp_dequeue_partial(sk)) != NULL)
{
IS_SKB(sk->send_tmp);
kfree_skb(sk->send_tmp, FREE_WRITE);
IS_SKB(skb);
kfree_skb(skb, FREE_WRITE);
}
/* Cleanup up the write buffer. */
......@@ -869,7 +869,7 @@ inet_create(struct socket *sock, int protocol)
sk->state = TCP_CLOSE;
sk->dead = 0;
sk->ack_timed = 0;
sk->send_tmp = NULL;
sk->partial = NULL;
sk->user_mss = 0;
sk->debug = 0;
......
......@@ -89,7 +89,8 @@ struct sock {
struct sk_buff *volatile send_tail;
struct sk_buff *volatile send_head;
struct sk_buff *volatile back_log;
struct sk_buff *send_tmp;
struct sk_buff *partial;
struct timer_list partial_timer;
long retransmits;
struct sk_buff *volatile wback,
*volatile wfront,
......
......@@ -648,43 +648,52 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
}
}
static struct sk_buff * dequeue_partial(struct sock * sk)
struct sk_buff * tcp_dequeue_partial(struct sock * sk)
{
struct sk_buff * skb;
unsigned long flags;
save_flags(flags);
cli();
skb = sk->send_tmp;
sk->send_tmp = NULL;
skb = sk->partial;
if (skb) {
sk->partial = NULL;
del_timer(&sk->partial_timer);
}
restore_flags(flags);
return skb;
}
static void enqueue_partial(struct sk_buff * skb, struct sock * sk)
static void tcp_send_partial(struct sock *sk)
{
struct sk_buff *skb;
if (sk == NULL)
return;
while ((skb = tcp_dequeue_partial(sk)) != NULL)
tcp_send_skb(sk, skb);
}
void tcp_enqueue_partial(struct sk_buff * skb, struct sock * sk)
{
struct sk_buff * tmp;
unsigned long flags;
save_flags(flags);
cli();
tmp = sk->send_tmp;
sk->send_tmp = skb;
tmp = sk->partial;
if (tmp)
del_timer(&sk->partial_timer);
sk->partial = skb;
sk->partial_timer.expires = 5*HZ;
sk->partial_timer.function = (void (*)(unsigned long)) tcp_send_partial;
sk->partial_timer.data = (unsigned long) sk;
add_timer(&sk->partial_timer);
restore_flags(flags);
if (tmp)
tcp_send_skb(sk, tmp);
}
static void tcp_send_partial(struct sock *sk)
{
struct sk_buff *skb;
if (sk == NULL)
return;
while ((skb = dequeue_partial(sk)) != NULL)
tcp_send_skb(sk, skb);
}
/* This routine sends an ack and also updates the window. */
static void
......@@ -897,7 +906,7 @@ tcp_write(struct sock *sk, unsigned char *from,
*/
/* Now we need to check if we have a half built packet. */
if ((skb = dequeue_partial(sk)) != NULL) {
if ((skb = tcp_dequeue_partial(sk)) != NULL) {
int hdrlen;
/* IP header + TCP header */
......@@ -920,10 +929,12 @@ tcp_write(struct sock *sk, unsigned char *from,
len -= copy;
sk->send_seq += copy;
}
enqueue_partial(skb, sk);
if ((skb->len - hdrlen) >= sk->mss || (flags & MSG_OOB)) {
tcp_send_partial(sk);
}
if ((skb->len - hdrlen) >= sk->mss ||
(flags & MSG_OOB) ||
!sk->packets_out)
tcp_send_skb(sk, skb);
else
tcp_enqueue_partial(skb, sk);
continue;
}
......@@ -949,7 +960,8 @@ tcp_write(struct sock *sk, unsigned char *from,
copy = min(copy, len);
/* We should really check the window here also. */
if (sk->packets_out && copy < sk->mss && !(flags & MSG_OOB)) {
send_tmp = NULL;
if (copy < sk->mss && !(flags & MSG_OOB)) {
/* We will release the socket incase we sleep here. */
release_sock(sk);
/* NB: following must be mtu, because mss can be increased.
......@@ -962,7 +974,6 @@ tcp_write(struct sock *sk, unsigned char *from,
release_sock(sk);
skb = prot->wmalloc(sk, copy + prot->max_header + sizeof(*skb), 0, GFP_KERNEL);
sk->inuse = 1;
send_tmp = NULL;
}
/* If we didn't get any memory, we need to sleep. */
......@@ -1041,8 +1052,8 @@ tcp_write(struct sock *sk, unsigned char *from,
skb->free = 0;
sk->send_seq += copy;
if (send_tmp != NULL) {
enqueue_partial(send_tmp, sk);
if (send_tmp != NULL && sk->packets_out) {
tcp_enqueue_partial(send_tmp, sk);
continue;
}
tcp_send_skb(sk, skb);
......@@ -1057,7 +1068,7 @@ tcp_write(struct sock *sk, unsigned char *from,
*/
/* Avoid possible race on send_tmp - c/o Johannes Stille */
if(sk->send_tmp &&
if(sk->partial &&
((!sk->packets_out)
/* If not nagling we can send on the before case too.. */
|| (sk->nonagle && before(sk->send_seq , sk->window_seq))
......@@ -1585,7 +1596,8 @@ tcp_shutdown(struct sock *sk, int how)
sk->inuse = 1;
/* Clear out any half completed packets. */
if (sk->send_tmp) tcp_send_partial(sk);
if (sk->partial)
tcp_send_partial(sk);
prot =(struct proto *)sk->prot;
th =(struct tcphdr *)&sk->dummy_th;
......@@ -1898,7 +1910,7 @@ tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->intr = 0;
newsk->proc = 0;
newsk->done = 0;
newsk->send_tmp = NULL;
newsk->partial = NULL;
newsk->pair = NULL;
newsk->wmem_alloc = 0;
newsk->rmem_alloc = 0;
......@@ -2081,7 +2093,7 @@ tcp_close(struct sock *sk, int timeout)
sk->rqueue = NULL;
/* Get rid off any half-completed packets. */
if (sk->send_tmp) {
if (sk->partial) {
tcp_send_partial(sk);
}
......@@ -2565,7 +2577,7 @@ tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long saddr, int len)
}
}
if (sk->packets_out == 0 && sk->send_tmp != NULL &&
if (sk->packets_out == 0 && sk->partial != NULL &&
sk->wfront == NULL && sk->send_head == NULL) {
flag |= 1;
tcp_send_partial(sk);
......
......@@ -124,5 +124,8 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev,
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
extern struct sk_buff * tcp_dequeue_partial(struct sock *);
#endif /* _TCP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment