diff -u --recursive --new-file v2.0.5/linux/Makefile linux/Makefile --- v2.0.5/linux/Makefile Wed Jul 10 15:20:24 1996 +++ linux/Makefile Wed Jul 10 15:32:30 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 5 +SUBLEVEL = 6 ARCH = i386 diff -u --recursive --new-file v2.0.5/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile --- v2.0.5/linux/arch/alpha/lib/Makefile Wed Apr 24 17:00:33 1996 +++ linux/arch/alpha/lib/Makefile Fri Jul 12 12:29:45 1996 @@ -3,7 +3,7 @@ # OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \ - checksum.o strlen.o + checksum.o csum_partial_copy.o strlen.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff -u --recursive --new-file v2.0.5/linux/arch/alpha/lib/checksum.c linux/arch/alpha/lib/checksum.c --- v2.0.5/linux/arch/alpha/lib/checksum.c Mon Jul 10 16:59:58 1995 +++ linux/arch/alpha/lib/checksum.c Fri Jul 12 12:29:46 1996 @@ -139,28 +139,6 @@ } /* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -unsigned int csum_partial_copy(char *src, char *dst, int len, int sum) -{ - /* - * The whole idea is to do the copy and the checksum at - * the same time, but we do it the easy way now. - * - * At least csum on the source, not destination, for cache - * reasons.. - */ - sum = csum_partial(src, len, sum); - memcpy(dst, src, len); - return sum; -} - -/* * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ diff -u --recursive --new-file v2.0.5/linux/arch/alpha/lib/csum_partial_copy.c linux/arch/alpha/lib/csum_partial_copy.c --- v2.0.5/linux/arch/alpha/lib/csum_partial_copy.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/lib/csum_partial_copy.c Fri Jul 12 12:29:46 1996 @@ -0,0 +1,292 @@ +/* + * csum_partial_copy - do IP checksumming and copy + * + * (C) Copyright 1996 Linus Torvalds + * + * Don't look at this too closely - you'll go mad. The things + * we do for performance.. + */ + +#define ldq_u(x,y) \ +__asm__("ldq_u %0,%1":"=r" (x):"m" (*(unsigned long *)(y))) + +#define stq_u(x,y) \ +__asm__("stq_u %1,%0":"=m" (*(unsigned long *)(y)):"r" (x)) + +#define extql(x,y,z) \ +__asm__ __volatile__("extql %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define extqh(x,y,z) \ +__asm__ __volatile__("extqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define mskql(x,y,z) \ +__asm__ __volatile__("mskql %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define mskqh(x,y,z) \ +__asm__ __volatile__("mskqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define insql(x,y,z) \ +__asm__ __volatile__("insql %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define insqh(x,y,z) \ +__asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +/* + * Ok. This isn't fun, but this is the EASY case. + */ +static inline unsigned long csum_partial_copy_aligned( + unsigned long *src, unsigned long *dst, + long len, unsigned long checksum) +{ + unsigned long word, carry = 0; + + len -= 8; + word = *src; + while (len >= 0) { + checksum += carry; + src++; + checksum += word; + len -= 8; + carry = checksum < word; + *dst = word; + word = *src; + dst++; + } + len += 8; + checksum += carry; + if (len) { + unsigned long tmp = *dst; + mskql(word, len, word); + checksum += word; + mskqh(tmp, len, tmp); + carry = checksum < word; + *dst = word | tmp; + checksum += carry; + } + return checksum; +} + +/* + * This is even less fun, but this is still reasonably + * easy. + */ +static inline unsigned long csum_partial_copy_dest_aligned( + unsigned long *src, unsigned long *dst, + unsigned long soff, + long len, unsigned long checksum) +{ + unsigned long first, word, carry = 0; + + len -= 8; + first = src[0]; + while (len >= 0) { + unsigned long second; + + second = src[1]; + extql(first, soff, word); + len -= 8; + extqh(second, soff, first); + src++; + word |= first; + checksum += carry; + first = second; + checksum += word; + *dst = word; + carry = checksum < word; + dst++; + } + len += 8; + checksum += carry; + if (len) { + unsigned long tmp; + unsigned long second; + second = src[1]; + tmp = *dst; + extql(first, soff, word); + extqh(second, soff, first); + word |= first; + mskql(word, len, word); + checksum += word; + mskqh(tmp, len, tmp); + carry = checksum < word; + *dst = word | tmp; + checksum += carry; + } + return checksum; +} + +/* + * This is slightly less fun than the above.. + */ +static inline unsigned long csum_partial_copy_src_aligned( + unsigned long *src, unsigned long *dst, + unsigned long doff, + long len, unsigned long checksum) +{ + unsigned long word, carry = 0; + unsigned long partial_dest; + + partial_dest = *dst; + len -= 8; + mskql(partial_dest, doff, partial_dest); + word = *src; + while (len >= 0) { + unsigned long second_dest; + + len -= 8; + checksum += carry; + src++; + checksum += word; + insql(word, doff, second_dest); + *dst = partial_dest | second_dest; + insqh(word, doff, partial_dest); + carry = checksum < word; + word = *src; + dst++; + } + len += doff; + checksum += carry; + if (len >= 0) { + unsigned long second_dest; + + mskql(word, len-doff, word); + len -= 8; + src++; + checksum += word; + insql(word, doff, second_dest); + *dst = partial_dest | second_dest; + insqh(word, doff, partial_dest); + carry = checksum < word; + word = *src; + dst++; + checksum += carry; + } else if (len & 7) { + unsigned long second_dest; + second_dest = *dst; + mskql(word, len-doff, word); + checksum += word; + mskqh(second_dest, len, second_dest); + carry = checksum < word; + insql(word, doff, word); + *dst = partial_dest | word | second_dest; + checksum += carry; + } + return checksum; +} + +/* + * This is so totally un-fun that it's frightening. Don't + * look at this too closely, you'll go blind. + */ +static inline unsigned long csum_partial_copy_unaligned( + unsigned long * src, unsigned long * dst, + unsigned long soff, unsigned long doff, + long len, unsigned long checksum) +{ + unsigned long first, carry = 0; + unsigned long partial_dest; + + partial_dest = dst[0]; + len -= 8; + first = src[0]; + mskql(partial_dest, doff, partial_dest); + while (len >= 0) { + unsigned long second, word; + unsigned long second_dest; + + second = src[1]; + extql(first, soff, word); + len -= 8; + checksum += carry; + src++; + extqh(second, soff, first); + word |= first; + first = second; + checksum += word; + insql(word, doff, second_dest); + *dst = partial_dest | second_dest; + carry = checksum < word; + insqh(word, doff, partial_dest); + dst++; + } + len += doff; + checksum += carry; + if (len >= 0) { + unsigned long second, word; + unsigned long second_dest; + + second = src[1]; + extql(first, soff, word); + len -= 8; + src++; + extqh(second, soff, first); + word |= first; + first = second; + mskql(word, len-doff, word); + checksum += word; + insql(word, doff, second_dest); + *dst = partial_dest | second_dest; + carry = checksum < word; + insqh(word, doff, partial_dest); + dst++; + } else if (len & 7) { + unsigned long second, word; + unsigned long second_dest; + second = src[1]; + extql(first, soff, word); + extqh(second, soff, first); + word |= first; + second_dest = *dst; + mskql(word, len-doff, word); + checksum += word; + mskqh(second_dest, len, second_dest); + carry = checksum < word; + insql(word, doff, word); + *dst = partial_dest | word | second_dest; + checksum += carry; + } + return checksum; +} + +unsigned int csum_partial_copy(char *src, char *dst, int len, int sum) +{ + unsigned long checksum = (unsigned) sum; + unsigned long soff = 7 & (unsigned long) src; + unsigned long doff = 7 & (unsigned long) dst; + + src = (char *) (~7UL & (unsigned long) src); + dst = (char *) (~7UL & (unsigned long) dst); + if (len) { + if (!soff) { + if (!doff) + checksum = csum_partial_copy_aligned( + (unsigned long *) src, + (unsigned long *) dst, + len, checksum); + else + checksum = csum_partial_copy_src_aligned( + (unsigned long *) src, + (unsigned long *) dst, + doff, len, checksum); + } else { + if (!doff) + checksum = csum_partial_copy_dest_aligned( + (unsigned long *) src, + (unsigned long *) dst, + soff, len, checksum); + else + checksum = csum_partial_copy_unaligned( + (unsigned long *) src, + (unsigned long *) dst, + soff, doff, len, checksum); + } + /* 64 -> 33 bits */ + checksum = (checksum & 0xffffffff) + (checksum >> 32); + /* 33 -> < 32 bits */ + checksum = (checksum & 0xffff) + (checksum >> 16); + /* 32 -> 16 bits */ + checksum = (checksum & 0xffff) + (checksum >> 16); + checksum = (checksum & 0xffff) + (checksum >> 16); + } + return checksum; +} diff -u --recursive --new-file v2.0.5/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.0.5/linux/drivers/pci/pci.c Mon Jul 8 16:09:54 1996 +++ linux/drivers/pci/pci.c Thu Jul 11 13:45:47 1996 @@ -226,9 +226,10 @@ DEVICE( INTEL, INTEL_82437, "82437"), DEVICE( INTEL, INTEL_82371_0, "82371 Triton PIIX"), DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"), + DEVICE( INTEL, INTEL_82441, "82441FX Natoma"), DEVICE( INTEL, INTEL_82439, "82439HX Triton II"), - DEVICE( INTEL, INTEL_82371SB_0,"82371SB Triton II PIIX"), - DEVICE( INTEL, INTEL_82371SB_1,"82371SB Triton II PIIX"), + DEVICE( INTEL, INTEL_82371SB_0,"82371SB Natoma/Triton II PIIX"), + DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX"), DEVICE( INTEL, INTEL_P6, "Orion P6"), DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"), DEVICE( ADAPTEC, ADAPTEC_7855, "AIC-7855"), diff -u --recursive --new-file v2.0.5/linux/drivers/scsi/README.ncr53c8xx linux/drivers/scsi/README.ncr53c8xx --- v2.0.5/linux/drivers/scsi/README.ncr53c8xx Wed Jul 10 15:20:26 1996 +++ linux/drivers/scsi/README.ncr53c8xx Thu Jul 11 08:19:59 1996 @@ -43,10 +43,10 @@ Wolfgang Stanglmeier Stefan Esser -You can find technical informations about the NCR 8xx family in the PCI-HOWTO +You can find technical information about the NCR 8xx family in the PCI-HOWTO written by Michael Will and in the SCSI-HOWTO written by Drew Eckhardt. -Informations about new chips is available at SYMBIOS web server: +Information about new chips is available at SYMBIOS web server: http://www.symbios.com This short documentation only describes the features of the NCR53C8XX driver, @@ -153,16 +153,16 @@ However, if the driver has been made as module, the number of the host is incremented each time the driver is loaded. -In order to display profiling informations, just enter: +In order to display profiling information, just enter: cat /proc/scsi/ncr53c8xx/0 and you will get something like the following text: ------------------------------------------------------- -General informations: +General information: Chip NCR53C810, device id 0x1, revision id 0x2 IO port address 0x6000, IRQ number 10 Using memory mapped IO at virtual address 0x282c000 -Profiling informations: +Profiling information: num_trans = 18014 num_kbytes = 671314 num_disc = 25763 @@ -175,8 +175,8 @@ ms_post = 1320 ------------------------------------------------------- -General informations are easy to understand. The device id and the -revision id identify the scsi chip as follow: +General information is easy to understand. The device id and the +revision id identify the scsi chip as follows: Chip Device id Revision Id ---- --------- ----------- @@ -188,7 +188,7 @@ 825A 0x3 >= 0x10 875 0xf -The profiling informations are updated upon completion of scsi commands. +The profiling information is updated upon completion of scsi commands. The data structure is allocated and zeroed when the host adapter is attached. So, if the driver is a module, the profile counters are cleared each time the driver is loaded. @@ -316,10 +316,10 @@ result: print sense data on CHECK CONDITION status scatter: print infos about the scatter process scripts: print infos about the script binding process - tiny: print minimal debugging informations - timing: print timing informations of the ncr chip. - nego: print informations about scsi negotiations - phase: print informations on script interruptions + tiny: print minimal debugging information + timing: print timing information of the ncr chip. + nego: print information about scsi negotiations + phase: print information on script interruptions 8.6 Clear profile counters @@ -399,7 +399,7 @@ If defined, scsi parity checking is disabled. SCSI_NCR_PROFILE (default: defined) - If defined, profile informations are gathered + If defined, profile information are gathered SCSI_NCR_MAX_SCATTER (default: 128) Scatter list size of the driver ccb. diff -u --recursive --new-file v2.0.5/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.0.5/linux/drivers/scsi/ncr53c8xx.c Wed Jul 10 15:20:26 1996 +++ linux/drivers/scsi/ncr53c8xx.c Thu Jul 11 08:19:59 1996 @@ -8086,7 +8086,7 @@ } /* -** Copy formatted profile informations into the input buffer. +** Copy formatted profile information into the input buffer. */ static int ncr_host_info(ncb_p np, char *ptr, off_t offset, int len) @@ -8098,7 +8098,7 @@ info.offset = offset; info.pos = 0; - copy_info(&info, "General informations:\n"); + copy_info(&info, "General information:\n"); copy_info(&info, " Chip NCR53C%03d, ", np->chip); copy_info(&info, "device id 0x%x, ", np->device_id); copy_info(&info, "revision id 0x%x\n", np->revision_id); @@ -8113,7 +8113,7 @@ #endif #ifdef SCSI_NCR_PROFILE - copy_info(&info, "Profiling informations:\n"); + copy_info(&info, "Profiling information:\n"); copy_info(&info, " %-12s = %lu\n", "num_trans",np->profile.num_trans); copy_info(&info, " %-12s = %lu\n", "num_kbytes",np->profile.num_kbytes); copy_info(&info, " %-12s = %lu\n", "num_disc", np->profile.num_disc); diff -u --recursive --new-file v2.0.5/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c --- v2.0.5/linux/drivers/scsi/qlogicfas.c Mon May 20 08:21:02 1996 +++ linux/drivers/scsi/qlogicfas.c Thu Jul 11 07:41:25 1996 @@ -18,7 +18,7 @@ Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994 (you can reference it, but it is incomplete and inaccurate in places) - Version 0.44 5/7/96 - kernel 1.2.0+, pcmcia 2.5.4+ + Version 0.45 6/9/96 - kernel 1.2.0+ Functions as standalone, loadable, and PCMCIA driver, the latter from Dave Hind's PCMCIA package. @@ -612,7 +612,7 @@ if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogicfas", NULL)) host->can_queue = 1; #endif - request_region( qbase , 0x10 ,"qlogic"); + request_region( qbase , 0x10 ,"qlogicfas"); hreg = scsi_register( host , 0 ); /* no host data */ hreg->io_port = qbase; hreg->n_io_port = 16; @@ -620,7 +620,7 @@ if( qlirq != -1 ) hreg->irq = qlirq; - sprintf(qinfo, "Qlogicfas Driver version 0.44, chip %02X at %03X, IRQ %d, TPdma:%d", + sprintf(qinfo, "Qlogicfas Driver version 0.45, chip %02X at %03X, IRQ %d, TPdma:%d", qltyp, qbase, qlirq, QL_TURBO_PDMA ); host->name = qinfo; diff -u --recursive --new-file v2.0.5/linux/drivers/scsi/qlogicfas.h linux/drivers/scsi/qlogicfas.h --- v2.0.5/linux/drivers/scsi/qlogicfas.h Mon May 20 08:21:02 1996 +++ linux/drivers/scsi/qlogicfas.h Thu Jul 11 07:41:25 1996 @@ -19,13 +19,13 @@ NULL, \ NULL, \ NULL, \ - qlogicfas_detect, \ + qlogicfas_detect, \ NULL, \ qlogicfas_info, \ qlogicfas_command, \ qlogicfas_queuecommand, \ - qlogicfas_abort, \ - qlogicfas_reset, \ + qlogicfas_abort, \ + qlogicfas_reset, \ NULL, \ qlogicfas_biosparam, \ 0, \ diff -u --recursive --new-file v2.0.5/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c --- v2.0.5/linux/drivers/sound/sb_common.c Wed Jul 10 15:20:27 1996 +++ linux/drivers/sound/sb_common.c Thu Jul 11 18:22:34 1996 @@ -642,9 +642,12 @@ sb_dsp_init (struct address_info *hw_config) { sb_devc *devc; - int n; char name[100]; +#ifndef NO_SB_IRQ_TEST + int n; +#endif + /* * Check if we had detected a SB device earlier */ @@ -701,12 +704,13 @@ } } +#ifndef NO_SB_IRQ_TEST for (n = 0; n < 3 && devc->irq_ok == 0; n++) if (sb_dsp_command (devc, 0xf2)) /* Cause interrupt immediately */ { int i; - for (i = 0; !devc->irq_ok && i < 10000000; i++); + for (i = 0; !devc->irq_ok && i < 10000; i++); } if (!devc->irq_ok) @@ -719,6 +723,7 @@ { DDB (printk ("IRQ test OK (IRQ%d)\n", devc->irq)); } +#endif request_region (hw_config->io_base, 16, "sound blaster"); diff -u --recursive --new-file v2.0.5/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.0.5/linux/drivers/sound/soundcard.c Sat Jul 6 14:51:28 1996 +++ linux/drivers/sound/soundcard.c Thu Jul 11 18:22:34 1996 @@ -289,7 +289,7 @@ size, dmap->bytes_in_use); } - if (remap_page_range (vma_get_start (vma), dmap->raw_buf_phys, + if (remap_page_range (vma_get_start (vma), virt_to_phys(dmap->raw_buf), vma_get_end (vma) - vma_get_start (vma), vma_get_page_prot (vma))) return -EAGAIN; @@ -487,6 +487,10 @@ snd_set_irq_handler (int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp) { int retcode; + unsigned long flags; + + save_flags (flags); + cli (); retcode = request_irq (interrupt_level, iproc, 0 /* SA_INTERRUPT */ , name, NULL); if (retcode < 0) @@ -496,6 +500,7 @@ else irqs |= (1ul << interrupt_level); + restore_flags (flags); return retcode; } diff -u --recursive --new-file v2.0.5/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c --- v2.0.5/linux/fs/smbfs/proc.c Sat Jul 6 12:07:13 1996 +++ linux/fs/smbfs/proc.c Thu Jul 11 13:52:06 1996 @@ -1739,7 +1739,7 @@ DPRINTK("smb_proc_connect: Server wants %s protocol.\n", prots[i].name); - if (server->protocol > PROTOCOL_LANMAN1) { + if (server->protocol >= PROTOCOL_LANMAN1) { word passlen = strlen(server->m.password); word userlen = strlen(server->m.username); diff -u --recursive --new-file v2.0.5/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.0.5/linux/include/linux/pci.h Mon Jul 8 16:09:57 1996 +++ linux/include/linux/pci.h Thu Jul 11 13:45:47 1996 @@ -547,6 +547,7 @@ #define PCI_DEVICE_ID_INTEL_82437 0x122d #define PCI_DEVICE_ID_INTEL_82371_0 0x122e #define PCI_DEVICE_ID_INTEL_82371_1 0x1230 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82439 0x1250 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 diff -u --recursive --new-file v2.0.5/linux/mm/memory.c linux/mm/memory.c --- v2.0.5/linux/mm/memory.c Fri May 17 15:32:19 1996 +++ linux/mm/memory.c Thu Jul 11 13:39:31 1996 @@ -298,10 +298,8 @@ return error; } -static inline void forget_pte(pte_t page) +static inline void free_pte(pte_t page) { - if (pte_none(page)) - return; if (pte_present(page)) { unsigned long addr = pte_page(page); if (addr >= high_memory || PageReserved(mem_map+MAP_NR(addr))) @@ -315,10 +313,17 @@ swap_free(pte_val(page)); } +static inline void forget_pte(pte_t page) +{ + if (!pte_none(page)) { + printk("forget_pte: old mapping existed!\n"); + free_pte(page); + } +} + static inline void zap_pte_range(pmd_t * pmd, unsigned long address, unsigned long size) { pte_t * pte; - unsigned long end; if (pmd_none(*pmd)) return; @@ -329,16 +334,21 @@ } pte = pte_offset(pmd, address); address &= ~PMD_MASK; - end = address + size; - if (end >= PMD_SIZE) - end = PMD_SIZE; - do { - pte_t page = *pte; - pte_clear(pte); - forget_pte(page); - address += PAGE_SIZE; + if (address + size > PMD_SIZE) + size = PMD_SIZE - address; + size >>= PAGE_SHIFT; + for (;;) { + pte_t page; + if (!size) + break; + page = *pte; pte++; - } while (address < end); + size--; + if (pte_none(page)) + continue; + pte_clear(pte-1); + free_pte(page); + } } static inline void zap_pmd_range(pgd_t * dir, unsigned long address, unsigned long size) @@ -934,7 +944,7 @@ force_sig(SIGBUS, current); flush_cache_page(vma, address); put_page(page_table, BAD_PAGE); - flush_tlb_page(vma, address); + /* no need to invalidate, wasn't present */ return; } /* @@ -955,7 +965,7 @@ entry = pte_wrprotect(entry); flush_cache_page(vma, address); put_page(page_table, entry); - flush_tlb_page(vma, address); + /* no need to invalidate: a not-present page shouldn't be cached */ } /* diff -u --recursive --new-file v2.0.5/linux/net/ipv4/ip_sockglue.c linux/net/ipv4/ip_sockglue.c --- v2.0.5/linux/net/ipv4/ip_sockglue.c Wed Jul 10 15:20:28 1996 +++ linux/net/ipv4/ip_sockglue.c Thu Jul 11 08:54:18 1996 @@ -295,8 +295,8 @@ */ if((rt=ip_rt_route(mreq.imr_multiaddr.s_addr,0))!=NULL) { - dev=rt->u.dst.dev; - atomic_dec(&rt->u.dst.use); + dev=rt->rt_dev; + atomic_dec(&rt->rt_use); ip_rt_put(rt); } } @@ -347,8 +347,8 @@ { if((rt=ip_rt_route(mreq.imr_multiaddr.s_addr,0))!=NULL) { - dev=rt->u.dst.dev; - atomic_dec(&rt->u.dst.use); + dev=rt->rt_dev; + atomic_dec(&rt->rt_use); ip_rt_put(rt); } } diff -u --recursive --new-file v2.0.5/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v2.0.5/linux/net/ipv4/tcp_output.c Wed Jul 3 22:05:23 1996 +++ linux/net/ipv4/tcp_output.c Thu Jul 11 14:56:06 1996 @@ -878,24 +878,12 @@ */ void tcp_send_delayed_ack(struct sock * sk, int max_timeout, unsigned long timeout) { - unsigned long now; - static int delack_guard=0; - - if(delack_guard) - return; - - delack_guard++; - /* Calculate new timeout */ - now = jiffies; if (timeout > max_timeout) timeout = max_timeout; - timeout += now; - if (sk->bytes_rcv >= sk->max_unacked) { - tcp_send_ack(sk); - delack_guard--; - return; - } + if (sk->bytes_rcv >= sk->max_unacked) + timeout = 0; + timeout += jiffies; /* Use new timeout only if there wasn't a older one earlier */ if (!del_timer(&sk->delack_timer) || timeout < sk->delack_timer.expires) @@ -903,7 +891,6 @@ sk->ack_backlog++; add_timer(&sk->delack_timer); - delack_guard--; }