home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 31 / CDASC_31_1996_juillet_aout.iso / vrac / prept209.zip / PREPT209.GZ / PREPT209
Text File  |  1996-05-29  |  40KB  |  1,363 lines

  1. diff -u --recursive --new-file pre2.0.8/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
  2. --- pre2.0.8/linux/Documentation/ioctl-number.txt    Fri May 17 15:32:10 1996
  3. +++ linux/Documentation/ioctl-number.txt    Tue May 28 07:39:18 1996
  4. @@ -55,7 +55,6 @@
  5.  Ioctl    Include File        Comments
  6.  ========================================================
  7.  0x00    linux/fs.h        only FIBMAP, FIGETBSZ
  8. -0x00    linux/mc146818rtc.h    conflict!
  9.  0x02    linux/fd.h
  10.  0x03    linux/hdreg.h
  11.  0x04    linux/umsdos_fs.h
  12. @@ -90,6 +89,7 @@
  13.  'm'    linux/mtio.h        conflict!
  14.  'm'    linux/soundcard.h    conflict!
  15.  'n'    linux/ncp_fs.h
  16. +'p'    linux/mc146818rtc.h
  17.  'r'    linux/msdos_fs.h
  18.  's'    linux/cdk.h
  19.  't'    linux/if_ppp.h        no conflict
  20. diff -u --recursive --new-file pre2.0.8/linux/MAINTAINERS linux/MAINTAINERS
  21. --- pre2.0.8/linux/MAINTAINERS    Sun May 12 22:54:22 1996
  22. +++ linux/MAINTAINERS    Wed May 29 09:51:41 1996
  23. @@ -68,6 +68,12 @@
  24.              it has been replaced by a better system and you
  25.              should be using that.
  26.  
  27. +EXT2 FILE SYSTEM
  28. +P:    Remy Card
  29. +M:    Remy.Card@linux.org
  30. +L:    linux-kernel@vger.rutgers.edu
  31. +S:    Maintained
  32. +
  33.  3C501 NETWORK DRIVER
  34.  P:    Alan Cox
  35.  M:    net-patches@lxorguk.ukuu.org.uk
  36. diff -u --recursive --new-file pre2.0.8/linux/Makefile linux/Makefile
  37. --- pre2.0.8/linux/Makefile    Tue May 28 08:09:54 1996
  38. +++ linux/Makefile    Tue May 28 07:39:47 1996
  39. @@ -1,6 +1,6 @@
  40.  VERSION = 1
  41.  PATCHLEVEL = 99
  42. -SUBLEVEL = 8
  43. +SUBLEVEL = 9
  44.  
  45.  ARCH = i386
  46.  
  47. diff -u --recursive --new-file pre2.0.8/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
  48. --- pre2.0.8/linux/arch/i386/kernel/time.c    Tue May  7 16:22:17 1996
  49. +++ linux/arch/i386/kernel/time.c    Tue May 28 10:14:17 1996
  50. @@ -10,6 +10,8 @@
  51.   * 1995-03-26    Markus Kuhn
  52.   *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
  53.   *      precision CMOS clock update
  54. + * 1996-05-03    Ingo Molnar
  55. + *      fixed time warps in do_[slow|fast]_gettimeoffset()
  56.   */
  57.  #include <linux/errno.h>
  58.  #include <linux/sched.h>
  59. @@ -31,57 +33,102 @@
  60.  
  61.  #ifndef    CONFIG_APM    /* cycle counter may be unreliable */
  62.  /* Cycle counter value at the previous timer interrupt.. */
  63. -static unsigned long long last_timer_cc = 0;
  64. -static unsigned long long init_timer_cc = 0;
  65. +static struct {
  66. +    unsigned long low;
  67. +    unsigned long high;
  68. +} init_timer_cc, last_timer_cc;
  69.  
  70. +/*
  71. + * This is more assembly than C, but it's also rather
  72. + * timing-critical and we have to use assembler to get
  73. + * reasonable 64-bit arithmetic
  74. + */
  75.  static unsigned long do_fast_gettimeoffset(void)
  76.  {
  77. -    unsigned long time_low, time_high;
  78. -    unsigned long quotient, remainder;
  79. +    register unsigned long eax asm("ax");
  80. +    register unsigned long edx asm("dx");
  81. +    unsigned long tmp, quotient, low_timer, missing_time;
  82. +
  83. +    /* Last jiffie when do_fast_gettimeoffset() was called.. */
  84. +    static unsigned long last_jiffies=0;
  85. +
  86. +    /* Cached "clocks per usec" value.. */
  87. +    static unsigned long cached_quotient=0;
  88. +
  89. +    /* The "clocks per usec" value is calculated once each jiffie */
  90. +    tmp = jiffies;
  91. +    quotient = cached_quotient;
  92. +    low_timer = last_timer_cc.low;
  93. +    missing_time = 0;
  94. +    if (last_jiffies != tmp) {
  95. +        last_jiffies = tmp;
  96. +        /*
  97. +         * test for hanging bottom handler (this means xtime is not 
  98. +         * updated yet)
  99. +         */
  100. +        if (test_bit(TIMER_BH, &bh_active) )
  101. +        {
  102. +            missing_time = 997670/HZ;
  103. +        }
  104.  
  105. -    /* Get last timer tick in absolute kernel time */
  106. -    __asm__("subl %2,%0\n\t"
  107. -        "sbbl %3,%1"
  108. -        :"=r" (time_low), "=r" (time_high)
  109. -        :"m" (*(0+(long *)&init_timer_cc)),
  110. -         "m" (*(1+(long *)&init_timer_cc)),
  111. -         "0" (*(0+(long *)&last_timer_cc)),
  112. -         "1" (*(1+(long *)&last_timer_cc)));
  113. -    /*
  114. -     * Divide the 64-bit time with the 32-bit jiffy counter,
  115. -     * getting the quotient in clocks.
  116. -     *
  117. -     * Giving quotient = "average internal clocks per jiffy"
  118. -     */
  119. -    __asm__("divl %2"
  120. -        :"=a" (quotient), "=d" (remainder)
  121. -        :"r" (jiffies),
  122. -         "0" (time_low), "1" (time_high));
  123. +        /* Get last timer tick in absolute kernel time */
  124. +        eax = low_timer;
  125. +        edx = last_timer_cc.high;
  126. +        __asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t"
  127. +            "sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1"
  128. +            :"=a" (eax), "=d" (edx)
  129. +            :"0" (eax), "1" (edx));
  130. +
  131. +        /*
  132. +         * Divide the 64-bit time with the 32-bit jiffy counter,
  133. +         * getting the quotient in clocks.
  134. +         *
  135. +         * Giving quotient = "average internal clocks per usec"
  136. +         */
  137. +        __asm__("divl %2"
  138. +            :"=a" (eax), "=d" (edx)
  139. +            :"r" (tmp),
  140. +             "0" (eax), "1" (edx));
  141. +
  142. +        edx = 997670/HZ;
  143. +        tmp = eax;
  144. +        eax = 0;
  145. +
  146. +        __asm__("divl %2"
  147. +            :"=a" (eax), "=d" (edx)
  148. +            :"r" (tmp),
  149. +             "0" (eax), "1" (edx));
  150. +        cached_quotient = eax;
  151. +        quotient = eax;
  152. +    }
  153.  
  154.      /* Read the time counter */
  155.      __asm__(".byte 0x0f,0x31"
  156. -        :"=a" (time_low), "=d" (time_high));
  157. +        :"=a" (eax), "=d" (edx));
  158.  
  159.      /* .. relative to previous jiffy (32 bits is enough) */
  160. -    time_low -= (unsigned long) last_timer_cc;
  161. +    edx = 0;
  162. +    eax -= low_timer;
  163.  
  164.      /*
  165. -     * Time offset = (1000000/HZ * remainder) / quotient.
  166. +     * Time offset = (997670/HZ * time_low) / quotient.
  167.       */
  168. -    __asm__("mull %1\n\t"
  169. -        "divl %2"
  170. -        :"=a" (quotient), "=d" (remainder)
  171. +
  172. +    __asm__("mull %2"
  173. +        :"=a" (eax), "=d" (edx)
  174.          :"r" (quotient),
  175. -         "0" (time_low), "1" (1000000/HZ));
  176. +         "0" (eax), "1" (edx));
  177.  
  178.      /*
  179. -     * Due to rounding errors (and jiffies inconsistencies),
  180. +      * Due to rounding errors (and jiffies inconsistencies),
  181.       * we need to check the result so that we'll get a timer
  182.       * that is monotonous.
  183.       */
  184. -    if (quotient >= 1000000/HZ)
  185. -        quotient = 1000000/HZ-1;
  186. -    return quotient;
  187. +    if (edx >= 997670/HZ)
  188. +        edx = 997670/HZ-1;
  189. +
  190. +    eax = edx + missing_time;
  191. +    return eax;
  192.  }
  193.  #endif
  194.  
  195. @@ -122,21 +169,63 @@
  196.  static unsigned long do_slow_gettimeoffset(void)
  197.  {
  198.      int count;
  199. +    static int count_p = 0;
  200.      unsigned long offset = 0;
  201. +    static unsigned long jiffies_p = 0;
  202. +
  203. +    /*
  204. +     * cache volatile jiffies temporaly, we have IRQs turned off. 
  205. +     */
  206. +    unsigned long jiffies_t;
  207.  
  208.      /* timer count may underflow right here */
  209.      outb_p(0x00, 0x43);    /* latch the count ASAP */
  210.      count = inb_p(0x40);    /* read the latched count */
  211.      count |= inb(0x40) << 8;
  212. -    /* we know probability of underflow is always MUCH less than 1% */
  213. -    if (count > (LATCH - LATCH/100)) {
  214. -        /* check for pending timer interrupt */
  215. -        outb_p(0x0a, 0x20);
  216. -        if (inb(0x20) & 1)
  217. -            offset = TICK_SIZE;
  218. -    }
  219. +
  220. +     jiffies_t = jiffies;
  221. +
  222. +    /*
  223. +     * avoiding timer inconsistencies (they are rare, but they happen)...
  224. +     * there are three kinds of problems that must be avoided here:
  225. +     *  1. the timer counter underflows
  226. +     *  2. hardware problem with the timer, not giving us continuous time,
  227. +     *     the counter does small "jumps" upwards on some Pentium systems,
  228. +     *     thus causes time warps
  229. +     *  3. we are after the timer interrupt, but the bottom half handler
  230. +     *     hasn't executed yet.
  231. +     */
  232. +    if( count > count_p ) {
  233. +        if( jiffies_t == jiffies_p ) {
  234. +            if( count > LATCH-LATCH/100 )
  235. +                offset = TICK_SIZE;
  236. +            else
  237. +                /*
  238. +                 * argh, the timer is bugging we cant do nothing 
  239. +                 * but to give the previous clock value.
  240. +                 */
  241. +                count = count_p;
  242. +        } else {
  243. +            if( test_bit(TIMER_BH, &bh_active) ) {
  244. +                /*
  245. +                 * we have detected a counter underflow.
  246. +                  */
  247. +                offset = TICK_SIZE;
  248. +                count_p = count;        
  249. +            } else {
  250. +                count_p = count;
  251. +                jiffies_p = jiffies_t;
  252. +            }
  253. +        }
  254. +    } else {
  255. +        count_p = count;
  256. +        jiffies_p = jiffies_t;
  257. +     }
  258. +
  259. +
  260.      count = ((LATCH-1) - count) * TICK_SIZE;
  261.      count = (count + LATCH/2) / LATCH;
  262. +
  263.      return offset + count;
  264.  }
  265.  
  266. @@ -283,8 +372,8 @@
  267.  {
  268.      /* read Pentium cycle counter */
  269.      __asm__(".byte 0x0f,0x31"
  270. -        :"=a" (((unsigned long *) &last_timer_cc)[0]),
  271. -         "=d" (((unsigned long *) &last_timer_cc)[1]));
  272. +        :"=a" (last_timer_cc.low),
  273. +         "=d" (last_timer_cc.high));
  274.      timer_interrupt(irq, NULL, regs);
  275.  }
  276.  #endif
  277. @@ -375,8 +464,8 @@
  278.          do_gettimeoffset = do_fast_gettimeoffset;
  279.          /* read Pentium cycle counter */
  280.          __asm__(".byte 0x0f,0x31"
  281. -            :"=a" (((unsigned long *) &init_timer_cc)[0]),
  282. -             "=d" (((unsigned long *) &init_timer_cc)[1]));
  283. +            :"=a" (init_timer_cc.low),
  284. +             "=d" (init_timer_cc.high));
  285.          irq0.handler = pentium_timer_interrupt;
  286.      }
  287.  #endif
  288. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/boot/mk_type41.c linux/arch/ppc/boot/mk_type41.c
  289. --- pre2.0.8/linux/arch/ppc/boot/mk_type41.c    Tue May 28 08:09:54 1996
  290. +++ linux/arch/ppc/boot/mk_type41.c    Tue May 28 07:46:04 1996
  291. @@ -40,7 +40,7 @@
  292.      }
  293.      if ((out_fd = creat(argv[2], 0666)) < 0)
  294.      {
  295. -        fprintf(stderr, "Can't create outpue file: '%s': %s\n", argv[2], strerror(errno));
  296. +        fprintf(stderr, "Can't create output file: '%s': %s\n", argv[2], strerror(errno));
  297.          exit(2);
  298.      }
  299.      if (fstat(in_fd, &info) < 0)
  300. @@ -185,7 +185,7 @@
  301.       * the next two.
  302.       *   - size of the diskette is (assumed to be)
  303.       *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
  304. -     *   - unlike the above sector nunbers, the beginning sector is zero-based!
  305. +     *   - unlike the above sector numbers, the beginning sector is zero-based!
  306.       */
  307.  #if 0     
  308.      pe->beginning_sector  = LeDword(1);
  309. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/include/elf/ChangeLog linux/arch/ppc/kernel/include/elf/ChangeLog
  310. --- pre2.0.8/linux/arch/ppc/kernel/include/elf/ChangeLog    Tue May 28 08:09:55 1996
  311. +++ linux/arch/ppc/kernel/include/elf/ChangeLog    Tue May 28 07:46:04 1996
  312. @@ -9,7 +9,7 @@
  313.  
  314.  Tue Feb 14 13:59:13 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
  315.  
  316. -    * common.h (EM_PPC): Use offical value of 20, not 17.
  317. +    * common.h (EM_PPC): Use official value of 20, not 17.
  318.      (EM_PPC_OLD): Define this to be the old value of EM_PPC.
  319.  
  320.  
  321. @@ -108,7 +108,7 @@
  322.      * common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
  323.      * external.h (Elf_External_Dyn): New type.
  324.  
  325. -    * internal.h (Elf_Intenral_Shdr): New field `size'.
  326. +    * internal.h (Elf_Internal_Shdr): New field `size'.
  327.      (Elf_Internal_Dyn): New type.
  328.  
  329.  Tue Apr 20 16:03:45 1993  Fred Fish  (fnf@cygnus.com)
  330. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/ppc_machine.h linux/arch/ppc/kernel/ppc_machine.h
  331. --- pre2.0.8/linux/arch/ppc/kernel/ppc_machine.h    Tue May 28 08:09:55 1996
  332. +++ linux/arch/ppc/kernel/ppc_machine.h    Tue May 28 07:46:04 1996
  333. @@ -10,7 +10,7 @@
  334.  #define MSR_TGPR    (1<<17)        /* TLB Update registers in use */
  335.  #define MSR_ILE        (1<<16)        /* Interrupt Little-Endian enable */
  336.  #define MSR_EE        (1<<15)        /* External Interrupt enable */
  337. -#define MSR_PR        (1<<14)        /* Supervisor/User privelege */
  338. +#define MSR_PR        (1<<14)        /* Supervisor/User privilege */
  339.  #define MSR_FP        (1<<13)        /* Floating Point enable */
  340.  #define MSR_ME        (1<<12)        /* Machine Check enable */
  341.  #define MSR_FE0        (1<<11)        /* Floating Exception mode 0 */
  342. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
  343. --- pre2.0.8/linux/arch/ppc/kernel/process.c    Tue May 28 08:09:55 1996
  344. +++ linux/arch/ppc/kernel/process.c    Tue May 28 07:46:04 1996
  345. @@ -2,7 +2,7 @@
  346.   *  linux/arch/ppc/kernel/process.c
  347.   *
  348.   *  Copyright (C) 1995  Linus Torvalds
  349. - *  Adapted for PowerPC by Gary THomas
  350. + *  Adapted for PowerPC by Gary Thomas
  351.   */
  352.  
  353.  /*
  354. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/support.c linux/arch/ppc/kernel/support.c
  355. --- pre2.0.8/linux/arch/ppc/kernel/support.c    Tue May 28 08:09:55 1996
  356. +++ linux/arch/ppc/kernel/support.c    Tue May 28 07:46:04 1996
  357. @@ -1,5 +1,5 @@
  358.  /*
  359. - * Miscallaneous support routines
  360. + * Miscellaneous support routines
  361.   */
  362.  
  363.  #include <asm/bitops.h>
  364. diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
  365. --- pre2.0.8/linux/arch/ppc/kernel/syscalls.c    Tue May 28 08:09:55 1996
  366. +++ linux/arch/ppc/kernel/syscalls.c    Tue May 28 07:46:04 1996
  367. @@ -19,7 +19,7 @@
  368.  
  369.  /*
  370.   * sys_pipe() is the normal C calling standard for creating
  371. - * a pipe. It's not the way unix tranditionally does this, though.
  372. + * a pipe. It's not the way unix traditionally does this, though.
  373.   */
  374.  asmlinkage int sys_pipe(unsigned long * fildes)
  375.  {
  376. diff -u --recursive --new-file pre2.0.8/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
  377. --- pre2.0.8/linux/drivers/char/rtc.c    Sun May 12 10:16:07 1996
  378. +++ linux/drivers/char/rtc.c    Tue May 28 07:39:18 1996
  379. @@ -30,11 +30,10 @@
  380.   *
  381.   */
  382.  
  383. -#define RTC_VERSION        "1.06"
  384. +#define RTC_VERSION        "1.07"
  385.  
  386.  #define RTC_IRQ     8    /* Can't see this changing soon.    */
  387. -#define RTC_IO_BASE    0x70    /* Or this...                */
  388. -#define RTC_IO_EXTENT    0x10    /* Only really 0x70 to 0x71, but...    */
  389. +#define RTC_IO_EXTENT    0x10    /* Only really two ports, but...    */
  390.  
  391.  /*
  392.   *    Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
  393. @@ -539,7 +538,7 @@
  394.      }
  395.      misc_register(&rtc_dev);
  396.      /* Check region? Naaah! Just snarf it up. */
  397. -    request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc");
  398. +    request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
  399.      init_timer(&rtc_irq_timer);
  400.      rtc_irq_timer.function = rtc_dropped_irq;
  401.      rtc_wait = NULL;
  402. diff -u --recursive --new-file pre2.0.8/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
  403. --- pre2.0.8/linux/drivers/net/eexpress.c    Tue May  7 16:22:27 1996
  404. +++ linux/drivers/net/eexpress.c    Wed May 29 09:49:25 1996
  405. @@ -1,4 +1,4 @@
  406. -/* $Id: eexpress.c,v 1.12 1996/04/15 17:27:30 phil Exp $
  407. +/* $Id: eexpress.c,v 1.13 1996/05/19 15:59:51 phil Exp $
  408.   *
  409.   * Intel EtherExpress device driver for Linux
  410.   *
  411. @@ -86,7 +86,7 @@
  412.  
  413.  static char version[] = 
  414.  "eexpress.c: v0.10 04-May-95 John Sullivan <js10039@cam.ac.uk>\n"
  415. -"            v0.13 10-Apr-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
  416. +"            v0.14 19-May-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
  417.  
  418.  #include <linux/module.h>
  419.  
  420. @@ -103,6 +103,7 @@
  421.  #include <asm/bitops.h>
  422.  #include <asm/io.h>
  423.  #include <asm/dma.h>
  424. +#include <linux/delay.h>
  425.  #include <linux/errno.h>
  426.  
  427.  #include <linux/netdevice.h>
  428. @@ -1060,15 +1061,25 @@
  429.          printk("%s: eexp_hw_init586()\n", dev->name);
  430.  #endif
  431.  
  432. -    PRIV(dev)->started = 0;
  433. +    lp->started = 0;
  434.      set_loopback;
  435.  
  436.      outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
  437.      outb_p(i586_RST,ioaddr+EEPROM_Ctrl);
  438. +    udelay(2000);  /* delay 20ms */
  439. +        {
  440. +        unsigned short ofs, i;
  441. +        for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
  442. +            outw_p(ofs, ioaddr+SM_PTR);
  443. +            for (i = 0; i < 16; i++) {
  444. +                outw_p(0, ioaddr+SM_ADDR(i<<1));
  445. +            }
  446. +        }
  447. +    }
  448.  
  449.      outw_p(lp->rx_buf_end,ioaddr+WRITE_PTR);
  450.      start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):(start_code[28] & ~1);
  451. -    PRIV(dev)->promisc = dev->flags & IFF_PROMISC;
  452. +    lp->promisc = dev->flags & IFF_PROMISC;
  453.      /* We may die here */
  454.      outsw(ioaddr, start_code, sizeof(start_code)>>1);
  455.      outw(CONF_HW_ADDR,ioaddr+WRITE_PTR);
  456. @@ -1205,8 +1216,8 @@
  457.  
  458.  static struct device dev_eexp[EEXP_MAX_CARDS] = 
  459.  {
  460. -        NULL,         /* will allocate dynamically */
  461. -    0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe 
  462. +        { NULL,         /* will allocate dynamically */
  463. +      0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },  
  464.  };
  465.  
  466.  int irq[EEXP_MAX_CARDS] = {0, };
  467. diff -u --recursive --new-file pre2.0.8/linux/drivers/net/ne.c linux/drivers/net/ne.c
  468. --- pre2.0.8/linux/drivers/net/ne.c    Tue May  7 16:22:29 1996
  469. +++ linux/drivers/net/ne.c    Tue May 28 07:39:18 1996
  470. @@ -229,6 +229,12 @@
  471.      }
  472.      }
  473.  
  474. +    /* We should have a "dev" from Space.c or the static module table. */
  475. +    if (dev == NULL) {
  476. +    printk(KERN_ERR "ne.c: Passed a NULL device.\n");
  477. +    dev = init_etherdev(0, 0);
  478. +    }
  479. +
  480.      if (ei_debug  &&  version_printed++ == 0)
  481.      printk(version);
  482.  
  483. @@ -344,12 +350,6 @@
  484.      return ENXIO;
  485.  #endif
  486.  
  487. -    }
  488. -
  489. -    /* We should have a "dev" from Space.c or the static module table. */
  490. -    if (dev == NULL) {
  491. -    printk("ne.c: Passed a NULL device.\n");
  492. -    dev = init_etherdev(0, 0);
  493.      }
  494.  
  495.      if (pci_irq_line) {
  496. diff -u --recursive --new-file pre2.0.8/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
  497. --- pre2.0.8/linux/drivers/net/ppp.c    Mon May 20 08:21:01 1996
  498. +++ linux/drivers/net/ppp.c    Wed May 29 07:32:38 1996
  499. @@ -6,7 +6,7 @@
  500.   *  Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
  501.   *  ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
  502.   *
  503. - *  ==FILEVERSION 960303==
  504. + *  ==FILEVERSION 960528==
  505.   *
  506.   *  NOTE TO MAINTAINERS:
  507.   *     If you modify this file at all, please set the number above to the
  508. diff -u --recursive --new-file pre2.0.8/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
  509. --- pre2.0.8/linux/drivers/scsi/scsi.c    Wed May 15 11:01:15 1996
  510. +++ linux/drivers/scsi/scsi.c    Wed May 29 09:49:26 1996
  511. @@ -580,7 +580,7 @@
  512.    printk("\n");
  513.  #endif
  514.  
  515. -if (host_byte(SCpnt->result) != DID_OK) {
  516. +  if (SCpnt->result) {
  517.      if (((driver_byte (SCpnt->result) & DRIVER_SENSE) ||
  518.           (status_byte (SCpnt->result) & CHECK_CONDITION)) &&
  519.          ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
  520. @@ -1569,9 +1569,15 @@
  521.              case SUGGEST_IS_OK:
  522.              break;
  523.              case SUGGEST_REMAP:
  524. +#ifdef DEBUG
  525. +            printk("SENSE SUGGEST REMAP - status = FINISHED\n");
  526. +#endif
  527. +            status = FINISHED;
  528. +            exit = DRIVER_SENSE | SUGGEST_ABORT;
  529. +            break;
  530.              case SUGGEST_RETRY:
  531.  #ifdef DEBUG
  532. -            printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
  533. +            printk("SENSE SUGGEST RETRY - status = MAYREDO\n");
  534.  #endif
  535.              status = MAYREDO;
  536.              exit = DRIVER_SENSE | SUGGEST_RETRY;
  537. @@ -1606,6 +1612,9 @@
  538.              status = REDO;
  539.              break;
  540.          case SUGGEST_REMAP:
  541. +            status = FINISHED;
  542. +            exit =  DRIVER_SENSE | SUGGEST_ABORT;
  543. +            break;
  544.          case SUGGEST_RETRY:
  545.              status = MAYREDO;
  546.              exit = DRIVER_SENSE | SUGGEST_RETRY;
  547. diff -u --recursive --new-file pre2.0.8/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
  548. --- pre2.0.8/linux/drivers/scsi/scsi_ioctl.c    Mon May 20 08:21:02 1996
  549. +++ linux/drivers/scsi/scsi_ioctl.c    Wed May 29 09:49:25 1996
  550. @@ -150,7 +150,7 @@
  551.      result = SCpnt->result;
  552.      SCpnt->request.rq_status = RQ_INACTIVE;
  553.  
  554. -    if(SCpnt->device->scsi_request_fn)
  555. +    if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
  556.      (*SCpnt->device->scsi_request_fn)();
  557.  
  558.      wake_up(&SCpnt->device->device_wait);
  559. diff -u --recursive --new-file pre2.0.8/linux/fs/isofs/util.c linux/fs/isofs/util.c
  560. --- pre2.0.8/linux/fs/isofs/util.c    Wed Nov  8 12:26:10 1995
  561. +++ linux/fs/isofs/util.c    Wed May 29 07:26:48 1996
  562. @@ -6,7 +6,7 @@
  563.   *  convert numbers according to section 7.3.3, etc.
  564.   *
  565.   *  isofs special functions.  This file was lifted in its entirety from
  566. - * the bsd386 iso9660 filesystem, by Pace Williamson.
  567. + *  the 386bsd iso9660 filesystem, by Pace Willisson <pace@blitz.com>.
  568.   */
  569.  
  570.  int
  571. diff -u --recursive --new-file pre2.0.8/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
  572. --- pre2.0.8/linux/fs/nfs/dir.c    Sat Apr 27 15:19:58 1996
  573. +++ linux/fs/nfs/dir.c    Tue May 28 07:45:19 1996
  574. @@ -476,8 +476,12 @@
  575.      sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
  576.      error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
  577.          name, &sattr, &fhandle, &fattr);
  578. -    if (!error)
  579. -        nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  580. +    if (!error) {
  581. +        if (fattr.fileid == dir->i_ino)
  582. +            printk("Sony NewsOS 4.1R buggy nfs server?\n");
  583. +        else
  584. +            nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  585. +    }
  586.      iput(dir);
  587.      return error;
  588.  }
  589. diff -u --recursive --new-file pre2.0.8/linux/fs/read_write.c linux/fs/read_write.c
  590. --- pre2.0.8/linux/fs/read_write.c    Fri May 17 15:32:18 1996
  591. +++ linux/fs/read_write.c    Wed May 29 15:43:55 1996
  592. @@ -100,7 +100,7 @@
  593.      return 0;
  594.  }
  595.  
  596. -asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
  597. +asmlinkage int sys_read(unsigned int fd,char * buf,int count)
  598.  {
  599.      int error;
  600.      struct file * file;
  601. @@ -112,7 +112,7 @@
  602.          return -EBADF;
  603.      if (!file->f_op || !file->f_op->read)
  604.          return -EINVAL;
  605. -    if (!count)
  606. +    if (count <= 0)
  607.          return 0;
  608.      error = locks_verify_area(FLOCK_VERIFY_READ,inode,file,file->f_pos,count);
  609.      if (error)
  610. diff -u --recursive --new-file pre2.0.8/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
  611. --- pre2.0.8/linux/include/asm-alpha/bitops.h    Sun Apr 21 12:39:02 1996
  612. +++ linux/include/asm-alpha/bitops.h    Wed May 29 18:47:38 1996
  613. @@ -31,7 +31,7 @@
  614.          :"=&r" (temp),
  615.           "=m" (*m),
  616.           "=&r" (oldbit)
  617. -        :"r" (1UL << (nr & 31)),
  618. +        :"Ir" (1UL << (nr & 31)),
  619.           "m" (*m));
  620.      return oldbit != 0;
  621.  }
  622. @@ -54,7 +54,7 @@
  623.          :"=&r" (temp),
  624.           "=m" (*m),
  625.           "=&r" (oldbit)
  626. -        :"r" (1UL << (nr & 31)),
  627. +        :"Ir" (1UL << (nr & 31)),
  628.           "m" (*m));
  629.      return oldbit != 0;
  630.  }
  631. @@ -75,7 +75,7 @@
  632.          :"=&r" (temp),
  633.           "=m" (*m),
  634.           "=&r" (oldbit)
  635. -        :"r" (1UL << (nr & 31)),
  636. +        :"Ir" (1UL << (nr & 31)),
  637.           "m" (*m));
  638.      return oldbit != 0;
  639.  }
  640. diff -u --recursive --new-file pre2.0.8/linux/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h
  641. --- pre2.0.8/linux/include/asm-i386/checksum.h    Sun May  5 08:52:04 1996
  642. +++ linux/include/asm-i386/checksum.h    Tue May 28 12:27:59 1996
  643. @@ -46,7 +46,7 @@
  644.                        unsigned int ihl) {
  645.      unsigned int sum;
  646.  
  647. -    __asm__("
  648. +    __asm__ __volatile__("
  649.          movl (%1), %0
  650.          subl $4, %2
  651.          jbe 2f
  652. diff -u --recursive --new-file pre2.0.8/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
  653. --- pre2.0.8/linux/include/asm-i386/system.h    Fri Apr  5 13:35:28 1996
  654. +++ linux/include/asm-i386/system.h    Wed May 29 18:06:39 1996
  655. @@ -199,18 +199,21 @@
  656.      switch (size) {
  657.          case 1:
  658.              __asm__("xchgb %b0,%1"
  659. -                :"=&q" (x), "=m" (*__xg(ptr))
  660. -                :"0" (x), "m" (*__xg(ptr)));
  661. +                :"=q" (x)
  662. +                :"m" (*__xg(ptr)), "0" (x)
  663. +                :"memory");
  664.              break;
  665.          case 2:
  666.              __asm__("xchgw %w0,%1"
  667. -                :"=&r" (x), "=m" (*__xg(ptr))
  668. -                :"0" (x), "m" (*__xg(ptr)));
  669. +                :"=r" (x)
  670. +                :"m" (*__xg(ptr)), "0" (x)
  671. +                :"memory");
  672.              break;
  673.          case 4:
  674.              __asm__("xchgl %0,%1"
  675. -                :"=&r" (x), "=m" (*__xg(ptr))
  676. -                :"0" (x), "m" (*__xg(ptr)));
  677. +                :"=r" (x)
  678. +                :"m" (*__xg(ptr)), "0" (x)
  679. +                :"memory");
  680.              break;
  681.      }
  682.      return x;
  683. diff -u --recursive --new-file pre2.0.8/linux/include/asm-ppc/posix_types.h linux/include/asm-ppc/posix_types.h
  684. --- pre2.0.8/linux/include/asm-ppc/posix_types.h    Tue May 28 08:09:57 1996
  685. +++ linux/include/asm-ppc/posix_types.h    Tue May 28 07:46:04 1996
  686. @@ -1,5 +1,5 @@
  687.  #ifndef _PPC_POSIX_TYPES_H
  688. -#define _PPc_POSIX_TYPES_H
  689. +#define _PPC_POSIX_TYPES_H
  690.  
  691.  /*
  692.   * This file is generally used by user-level software, so you need to
  693. @@ -95,4 +95,4 @@
  694.  
  695.  #endif /* __GNUC__ */
  696.  
  697. -#endif /* _PPc_POSIX_TYPES_H */
  698. +#endif /* _PPC_POSIX_TYPES_H */
  699. diff -u --recursive --new-file pre2.0.8/linux/include/linux/mc146818rtc.h linux/include/linux/mc146818rtc.h
  700. --- pre2.0.8/linux/include/linux/mc146818rtc.h    Tue May  7 16:22:38 1996
  701. +++ linux/include/linux/mc146818rtc.h    Tue May 28 07:39:19 1996
  702. @@ -107,25 +107,7 @@
  703.  #endif
  704.  
  705.  /*
  706. - * ioctl calls that are permitted to the /dev/rtc interface, if 
  707. - * CONFIG_RTC was enabled.
  708. - */
  709. -
  710. -#define RTC_AIE_ON    0x01        /* Alarm int. enable on        */
  711. -#define RTC_AIE_OFF    0x02        /* ... off            */
  712. -#define RTC_UIE_ON    0x03        /* Update int. enable on    */
  713. -#define RTC_UIE_OFF    0x04        /* ... off            */
  714. -#define RTC_PIE_ON    0x05        /* Periodic int. enable on    */
  715. -#define RTC_PIE_OFF    0x06        /* ... off            */
  716. -#define RTC_ALM_SET    0x07        /* Set alarm (struct tm)    */
  717. -#define RTC_ALM_READ    0x08        /* Read alarm (struct tm)    */
  718. -#define RTC_RD_TIME    0x09        /* Read RTC time (struct tm)    */
  719. -#define RTC_SET_TIME    0x0a        /* Set time of RTC (not used)    */
  720. -#define RTC_IRQP_READ    0x0b        /* Read periodic IRQ rate (Hz)    */
  721. -#define RTC_IRQP_SET    0x0c        /* Set periodic IRQ rate (Hz)    */
  722. -
  723. -/*
  724. - * The struct used to pass data via the above ioctl. Similar to the
  725. + * The struct used to pass data via the following ioctl. Similar to the
  726.   * struct tm in <time.h>, but it needs to be here so that the kernel 
  727.   * source is self contained, allowing cross-compiles, etc. etc.
  728.   */
  729. @@ -141,5 +123,25 @@
  730.      int tm_yday;
  731.      int tm_isdst;
  732.  };
  733. +
  734. +/*
  735. + * ioctl calls that are permitted to the /dev/rtc interface, if 
  736. + * CONFIG_RTC was enabled.
  737. + */
  738. +
  739. +#define RTC_AIE_ON    _IO('p', 0x01)    /* Alarm int. enable on        */
  740. +#define RTC_AIE_OFF    _IO('p', 0x02)    /* ... off            */
  741. +#define RTC_UIE_ON    _IO('p', 0x03)    /* Update int. enable on    */
  742. +#define RTC_UIE_OFF    _IO('p', 0x04)    /* ... off            */
  743. +#define RTC_PIE_ON    _IO('p', 0x05)    /* Periodic int. enable on    */
  744. +#define RTC_PIE_OFF    _IO('p', 0x06)    /* ... off            */
  745. +
  746. +#define RTC_ALM_SET    _IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
  747. +#define RTC_ALM_READ    _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
  748. +#define RTC_RD_TIME    _IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
  749. +#define RTC_SET_TIME    _IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
  750. +#define RTC_IRQP_READ    _IOR('p', 0x0b, unsigned long)     /* Read IRQ rate   */
  751. +#define RTC_IRQP_SET    _IOW('p', 0x0c, unsigned long)     /* Set IRQ rate    */
  752. +
  753.  
  754.  #endif /* _MC146818RTC_H */
  755. diff -u --recursive --new-file pre2.0.8/linux/kernel/ksyms.c linux/kernel/ksyms.c
  756. --- pre2.0.8/linux/kernel/ksyms.c    Tue May 21 19:52:39 1996
  757. +++ linux/kernel/ksyms.c    Wed May 29 16:42:27 1996
  758. @@ -163,7 +163,6 @@
  759.      X(__bforget),
  760.      X(ll_rw_block),
  761.      X(__wait_on_buffer),
  762. -    X(__wait_on_page),
  763.      X(mark_buffer_uptodate),
  764.      X(unlock_buffer),
  765.      X(dcache_lookup),
  766. diff -u --recursive --new-file pre2.0.8/linux/mm/filemap.c linux/mm/filemap.c
  767. --- pre2.0.8/linux/mm/filemap.c    Tue May 21 19:52:39 1996
  768. +++ linux/mm/filemap.c    Wed May 29 16:44:11 1996
  769. @@ -42,6 +42,19 @@
  770.   */
  771.  
  772.  /*
  773. + * This is a special fast page-free routine that _only_ works
  774. + * on page-cache pages that we are currently using. We can
  775. + * just decrement the page count, because we know that the page
  776. + * has a count > 1 (the page cache itself counts as one, and
  777. + * we're currently using it counts as one). So we don't need
  778. + * the full free_page() stuff..
  779. + */
  780. +static inline void release_page(struct page * page)
  781. +{
  782. +    atomic_dec(&page->count);
  783. +}
  784. +
  785. +/*
  786.   * Invalidate the pages of an inode, removing all pages that aren't
  787.   * locked down (those are sure to be up-to-date anyway, so we shouldn't
  788.   * invalidate them).
  789. @@ -228,12 +241,9 @@
  790.              len = count;
  791.          page = find_page(inode, pos);
  792.          if (page) {
  793. -            unsigned long addr;
  794. -
  795.              wait_on_page(page);
  796. -            addr = page_address(page);
  797. -            memcpy((void *) (offset + addr), buf, len);
  798. -            free_page(addr);
  799. +            memcpy((void *) (offset + page_address(page)), buf, len);
  800. +            release_page(page);
  801.          }
  802.          count -= len;
  803.          buf += len;
  804. @@ -273,7 +283,7 @@
  805.  #if 1
  806.      page = find_page(inode, offset);
  807.      if (page) {
  808. -        page->count--;
  809. +        release_page(page);
  810.          return page_cache;
  811.      }
  812.      /*
  813. @@ -291,12 +301,15 @@
  814.  
  815.  /* 
  816.   * Wait for IO to complete on a locked page.
  817. + *
  818. + * This must be called with the caller "holding" the page,
  819. + * ie with increased "page->count" so that the page won't
  820. + * go away during the wait..
  821.   */
  822.  void __wait_on_page(struct page *page)
  823.  {
  824.      struct wait_queue wait = { current, NULL };
  825.  
  826. -    page->count++;
  827.      add_wait_queue(&page->wait, &wait);
  828.  repeat:
  829.      run_task_queue(&tq_disk);
  830. @@ -306,7 +319,6 @@
  831.          goto repeat;
  832.      }
  833.      remove_wait_queue(&page->wait, &wait);
  834. -    page->count--;
  835.      current->state = TASK_RUNNING;
  836.  }
  837.  
  838. @@ -558,9 +570,6 @@
  839.      unsigned long pos, ppos, page_cache;
  840.      int reada_ok;
  841.  
  842. -    if (count <= 0)
  843. -        return 0;
  844. -
  845.      error = 0;
  846.      read = 0;
  847.      page_cache = 0;
  848. @@ -608,45 +617,18 @@
  849.  
  850.      for (;;) {
  851.          struct page *page;
  852. -        unsigned long offset, addr, nr;
  853.  
  854.          if (pos >= inode->i_size)
  855.              break;
  856. -        offset = pos & ~PAGE_MASK;
  857. -        nr = PAGE_SIZE - offset;
  858. -        /*
  859. -         * Try to find the data in the page cache..
  860. -         */
  861. -        page = find_page(inode, pos & PAGE_MASK);
  862. -        if (page)
  863. -            goto found_page;
  864.  
  865.          /*
  866. -         * Ok, it wasn't cached, so we need to create a new
  867. -         * page..
  868. -         */
  869. -        if (page_cache)
  870. -            goto new_page;
  871. -
  872. -        error = -ENOMEM;
  873. -        page_cache = __get_free_page(GFP_KERNEL);
  874. -        if (!page_cache)
  875. -            break;
  876. -        error = 0;
  877. -
  878. -        /*
  879. -         * That could have slept, so we need to check again..
  880. +         * Try to find the data in the page cache..
  881.           */
  882. -        if (pos >= inode->i_size)
  883. -            break;
  884.          page = find_page(inode, pos & PAGE_MASK);
  885.          if (!page)
  886. -            goto new_page;
  887. +            goto no_cached_page;
  888.  
  889.  found_page:
  890. -        addr = page_address(page);
  891. -        if (nr > count)
  892. -            nr = count;
  893.  /*
  894.   * Try to read ahead only if the current page is filled or being filled.
  895.   * Otherwise, if we were reading ahead, decrease max read ahead size to
  896. @@ -659,15 +641,27 @@
  897.          else if (reada_ok && filp->f_ramax > MIN_READAHEAD)
  898.                  filp->f_ramax = MIN_READAHEAD;
  899.  
  900. -        if (PageLocked(page))
  901. -            __wait_on_page(page);
  902. +        wait_on_page(page);
  903.  
  904.          if (!PageUptodate(page))
  905. -            goto read_page;
  906. +            goto page_read_error;
  907. +
  908. +success:
  909. +        /*
  910. +         * Ok, we have the page, it's up-to-date and ok,
  911. +         * so now we can finally copy it to user space...
  912. +         */
  913. +    {
  914. +        unsigned long offset, nr;
  915. +        offset = pos & ~PAGE_MASK;
  916. +        nr = PAGE_SIZE - offset;
  917. +        if (nr > count)
  918. +            nr = count;
  919. +
  920.          if (nr > inode->i_size - pos)
  921.              nr = inode->i_size - pos;
  922. -        memcpy_tofs(buf, (void *) (addr + offset), nr);
  923. -        free_page(addr);
  924. +        memcpy_tofs(buf, (void *) (page_address(page) + offset), nr);
  925. +        release_page(page);
  926.          buf += nr;
  927.          pos += nr;
  928.          read += nr;
  929. @@ -675,13 +669,28 @@
  930.          if (count)
  931.              continue;
  932.          break;
  933. -    
  934. +    }
  935. +
  936. +no_cached_page:
  937. +        /*
  938. +         * Ok, it wasn't cached, so we need to create a new
  939. +         * page..
  940. +         */
  941. +        if (!page_cache) {
  942. +            page_cache = __get_free_page(GFP_KERNEL);
  943. +            /*
  944. +             * That could have slept, so go around to the
  945. +             * very beginning..
  946. +             */
  947. +            if (page_cache)
  948. +                continue;
  949. +            error = -ENOMEM;
  950. +            break;
  951. +        }
  952.  
  953. -new_page:
  954.          /*
  955.           * Ok, add the new page to the hash-queues...
  956.           */
  957. -        addr = page_cache;
  958.          page = mem_map + MAP_NR(page_cache);
  959.          page_cache = 0;
  960.          add_to_page_cache(page, inode, pos & PAGE_MASK);
  961. @@ -694,7 +703,6 @@
  962.           * identity of the reader can decide if we can read the
  963.           * page or not..
  964.           */
  965. -read_page:
  966.  /*
  967.   * We have to read the page.
  968.   * If we were reading ahead, we had previously tried to read this page,
  969. @@ -706,12 +714,25 @@
  970.              filp->f_ramax = MIN_READAHEAD;
  971.  
  972.          error = inode->i_op->readpage(inode, page);
  973. +        if (!error)
  974. +            goto found_page;
  975. +        release_page(page);
  976. +        break;
  977. +
  978. +page_read_error:
  979. +        /*
  980. +         * We found the page, but it wasn't up-to-date.
  981. +         * Try to re-read it _once_. We do this synchronously,
  982. +         * because this happens only if there were errors.
  983. +         */
  984. +        error = inode->i_op->readpage(inode, page);
  985.          if (!error) {
  986. -            if (!PageError(page))
  987. -                goto found_page;
  988. -            error = -EIO;
  989. +            wait_on_page(page);
  990. +            if (PageUptodate(page) && !PageError(page))
  991. +                goto success;
  992. +            error = -EIO; /* Some unspecified error occurred.. */
  993.          }
  994. -        free_page(addr);
  995. +        release_page(page);
  996.          break;
  997.      }
  998.  
  999. @@ -729,78 +750,125 @@
  1000.  }
  1001.  
  1002.  /*
  1003. - * Find a cached page and wait for it to become up-to-date, return
  1004. - * the page address.  Increments the page count.
  1005. + * Semantics for shared and private memory areas are different past the end
  1006. + * of the file. A shared mapping past the last page of the file is an error
  1007. + * and results in a SIGBUS, while a private mapping just maps in a zero page.
  1008. + *
  1009. + * The goto's are kind of ugly, but this streamlines the normal case of having
  1010. + * it in the page cache, and handles the special cases reasonably without
  1011. + * having a lot of duplicated code.
  1012.   */
  1013. -static inline unsigned long fill_page(struct inode * inode, unsigned long offset)
  1014. +static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
  1015.  {
  1016. +    unsigned long offset;
  1017.      struct page * page;
  1018. -    unsigned long new_page;
  1019. +    struct inode * inode = area->vm_inode;
  1020. +    unsigned long old_page, new_page;
  1021. +
  1022. +    new_page = 0;
  1023. +    offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
  1024. +    if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
  1025. +        goto no_page;
  1026.  
  1027. +    /*
  1028. +     * Do we have something in the page cache already?
  1029. +     */
  1030.      page = find_page(inode, offset);
  1031. -    if (page)
  1032. -        goto found_page_dont_free;
  1033. +    if (!page)
  1034. +        goto no_cached_page;
  1035. +
  1036. +found_page:
  1037. +    /*
  1038. +     * Ok, found a page in the page cache, now we need to check
  1039. +     * that it's up-to-date
  1040. +     */
  1041. +    wait_on_page(page);
  1042. +    if (!PageUptodate(page))
  1043. +        goto page_read_error;
  1044. +
  1045. +success:
  1046. +    /*
  1047. +     * Found the page, need to check sharing and possibly
  1048. +     * copy it over to another page..
  1049. +     */
  1050. +    old_page = page_address(page);
  1051. +    if (!no_share) {
  1052. +        /*
  1053. +         * Ok, we can share the cached page directly.. Get rid
  1054. +         * of any potential extra pages.
  1055. +         */
  1056. +        if (new_page)
  1057. +            free_page(new_page);
  1058. +
  1059. +        flush_page_to_ram(old_page);
  1060. +        return old_page;
  1061. +    }
  1062. +
  1063. +    /*
  1064. +     * Check that we have another page to copy it over to..
  1065. +     */
  1066. +    if (!new_page) {
  1067. +        new_page = __get_free_page(GFP_KERNEL);
  1068. +        if (!new_page)
  1069. +            goto failure;
  1070. +    }
  1071. +    memcpy((void *) new_page, (void *) old_page, PAGE_SIZE);
  1072. +    flush_page_to_ram(new_page);
  1073. +    release_page(page);
  1074. +    return new_page;
  1075. +
  1076. +no_cached_page:
  1077.      new_page = __get_free_page(GFP_KERNEL);
  1078. +    if (!new_page)
  1079. +        goto no_page;
  1080. +
  1081. +    /*
  1082. +     * During getting the above page we might have slept,
  1083. +     * so we need to re-check the situation with the page
  1084. +     * cache.. The page we just got may be useful if we
  1085. +     * can't share, so don't get rid of it here.
  1086. +     */
  1087.      page = find_page(inode, offset);
  1088.      if (page)
  1089.          goto found_page;
  1090. -    if (!new_page)
  1091. -        goto failure;
  1092. +
  1093. +    /*
  1094. +     * Now, create a new page-cache page from the page we got
  1095. +     */
  1096.      page = mem_map + MAP_NR(new_page);
  1097.      new_page = 0;
  1098.      add_to_page_cache(page, inode, offset);
  1099. -    inode->i_op->readpage(inode, page);
  1100. +
  1101. +    if (inode->i_op->readpage(inode, page) != 0)
  1102. +        goto failure;
  1103. +
  1104. +    /*
  1105. +     * Do a very limited read-ahead if appropriate
  1106. +     */
  1107.      if (PageLocked(page))
  1108.          new_page = try_to_read_ahead(inode, offset + PAGE_SIZE, 0);
  1109. -found_page:
  1110. -    if (new_page)
  1111. -        free_page(new_page);
  1112. -found_page_dont_free:
  1113. -    wait_on_page(page);
  1114. -    if (PageUptodate(page)) {
  1115. -success:    
  1116. -        return page_address(page);
  1117. -    }
  1118. -    /* If not marked as error, try _once_ to read it again */
  1119. -    if (!PageError(page)) {
  1120. -        inode->i_op->readpage(inode, page);
  1121. -        wait_on_page(page);
  1122. -        if (PageUptodate(page))
  1123. -            goto success;
  1124. -    }
  1125. -    page->count--;
  1126. -failure:
  1127. -    return 0;
  1128. -}
  1129. -
  1130. -/*
  1131. - * Semantics for shared and private memory areas are different past the end
  1132. - * of the file. A shared mapping past the last page of the file is an error
  1133. - * and results in a SIGBUS, while a private mapping just maps in a zero page.
  1134. - */
  1135. -static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
  1136. -{
  1137. -    unsigned long offset;
  1138. -    struct inode * inode = area->vm_inode;
  1139. -    unsigned long page;
  1140. +    goto found_page;
  1141.  
  1142. -    offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
  1143. -    if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
  1144. -        return 0;
  1145. +page_read_error:
  1146. +    /*
  1147. +     * Umm, take care of errors if the page isn't up-to-date.
  1148. +     * Try to re-read it _once_.
  1149. +     */
  1150. +    if (inode->i_op->readpage(inode, page) != 0)
  1151. +        goto failure;
  1152. +    if (PageError(page))
  1153. +        goto failure;
  1154. +    if (PageUptodate(page))
  1155. +        goto success;
  1156.  
  1157. -    page = fill_page(inode, offset);
  1158. -    if (page && no_share) {
  1159. -        unsigned long new_page = __get_free_page(GFP_KERNEL);
  1160. -        if (new_page) {
  1161. -            memcpy((void *) new_page, (void *) page, PAGE_SIZE);
  1162. -            flush_page_to_ram(new_page);
  1163. -        }
  1164. -        free_page(page);
  1165. -        return new_page;
  1166. -    }
  1167. -    if (page)
  1168. -        flush_page_to_ram(page);
  1169. -    return page;
  1170. +    /*
  1171. +     * Uhhuh.. Things didn't work out. Return zero to tell the
  1172. +     * mm layer so, possibly freeing the page cache page first.
  1173. +     */
  1174. +failure:
  1175. +    release_page(page);
  1176. +no_page:
  1177. +    return 0;
  1178.  }
  1179.  
  1180.  /*
  1181. diff -u --recursive --new-file pre2.0.8/linux/mm/kmalloc.c linux/mm/kmalloc.c
  1182. --- pre2.0.8/linux/mm/kmalloc.c    Fri Apr  5 13:35:28 1996
  1183. +++ linux/mm/kmalloc.c    Wed May 29 17:59:34 1996
  1184. @@ -171,6 +171,38 @@
  1185.  #define BLOCKSIZE(order)        (blocksize[order])
  1186.  #define AREASIZE(order)        (PAGE_SIZE<<(sizes[order].gfporder))
  1187.  
  1188. +/*
  1189. + * Create a small cache of page allocations: this helps a bit with
  1190. + * those pesky 8kB+ allocations for NFS when we're temporarily
  1191. + * out of memory..
  1192. + *
  1193. + * This is a _truly_ small cache, we just cache one single page
  1194. + * order (for orders 0, 1 and 2, that is  4, 8 and 16kB on x86).
  1195. + */
  1196. +#define MAX_CACHE_ORDER 3
  1197. +struct page_descriptor * kmalloc_cache[MAX_CACHE_ORDER];
  1198. +
  1199. +static inline struct page_descriptor * get_kmalloc_pages(unsigned long priority,
  1200. +    unsigned long order, int dma)
  1201. +{
  1202. +    struct page_descriptor * tmp;
  1203. +
  1204. +    tmp = (struct page_descriptor *) __get_free_pages(priority, order, dma);
  1205. +    if (!tmp && !dma && order < MAX_CACHE_ORDER)
  1206. +        tmp = xchg(kmalloc_cache+order, tmp);
  1207. +    return tmp;
  1208. +}
  1209. +
  1210. +static inline void free_kmalloc_pages(struct page_descriptor * page,
  1211. +    unsigned long order, int dma)
  1212. +{
  1213. +    if (!dma && order < MAX_CACHE_ORDER) {
  1214. +        page = xchg(kmalloc_cache+order, page);
  1215. +        if (!page)
  1216. +            return;
  1217. +    }
  1218. +    free_pages((unsigned long) page, order);
  1219. +}
  1220.  
  1221.  long kmalloc_init(long start_mem, long end_mem)
  1222.  {
  1223. @@ -260,8 +292,7 @@
  1224.          /* sz is the size of the blocks we're dealing with */
  1225.          sz = BLOCKSIZE(order);
  1226.  
  1227. -        page = (struct page_descriptor *) __get_free_pages(priority,
  1228. -                sizes[order].gfporder, dma);
  1229. +        page = get_kmalloc_pages(priority, sizes[order].gfporder, dma);
  1230.  
  1231.          if (!page)
  1232.              goto no_free_page;
  1233. @@ -322,7 +353,7 @@
  1234.  
  1235.  void kfree(void *ptr)
  1236.  {
  1237. -    int size;
  1238. +    int size, dma;
  1239.      unsigned long flags;
  1240.      int order;
  1241.      register struct block_header *p;
  1242. @@ -331,10 +362,12 @@
  1243.      if (!ptr)
  1244.          return;
  1245.      p = ((struct block_header *) ptr) - 1;
  1246. +    dma = 0;
  1247.      page = PAGE_DESC(p);
  1248.      order = page->order;
  1249.      pg = &sizes[order].firstfree;
  1250.      if (p->bh_flags == MF_DMA) {
  1251. +        dma = 1;
  1252.          p->bh_flags = MF_USED;
  1253.          pg = &sizes[order].dmafree;
  1254.      }
  1255. @@ -378,7 +411,7 @@
  1256.              pg = &tmp->next;
  1257.          }
  1258.          sizes[order].npages--;
  1259. -        free_pages((long) page, sizes[order].gfporder);
  1260. +        free_kmalloc_pages(page, sizes[order].gfporder, dma);
  1261.      }
  1262.      sizes[order].nfrees++;
  1263.      sizes[order].nbytesmalloced -= size;
  1264. diff -u --recursive --new-file pre2.0.8/linux/mm/page_io.c linux/mm/page_io.c
  1265. --- pre2.0.8/linux/mm/page_io.c    Tue Apr 23 13:57:14 1996
  1266. +++ linux/mm/page_io.c    Wed May 29 16:52:31 1996
  1267. @@ -76,10 +76,10 @@
  1268.      else
  1269.          kstat.pswpout++;
  1270.      page = mem_map + MAP_NR(buf);
  1271. +    atomic_inc(&page->count);
  1272.      wait_on_page(page);
  1273.      if (p->swap_device) {
  1274.          if (!wait) {
  1275. -            page->count++;
  1276.              set_bit(PG_free_after, &page->flags);
  1277.              set_bit(PG_decr_after, &page->flags);
  1278.              set_bit(PG_swap_unlock_after, &page->flags);
  1279. @@ -87,6 +87,11 @@
  1280.              nr_async_pages++;
  1281.          }
  1282.          ll_rw_page(rw,p->swap_device,offset,buf);
  1283. +        /*
  1284. +         * NOTE! We don't decrement the page count if we
  1285. +         * don't wait - that will happen asynchronously
  1286. +         * when the IO completes.
  1287. +         */
  1288.          if (!wait)
  1289.              return;
  1290.          wait_on_page(page);
  1291. @@ -130,6 +135,7 @@
  1292.          ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
  1293.      } else
  1294.          printk("rw_swap_page: no swap file or device\n");
  1295. +    atomic_dec(&page->count);
  1296.      if (offset && !clear_bit(offset,p->swap_lockmap))
  1297.          printk("rw_swap_page: lock already cleared\n");
  1298.      wake_up(&lock_queue);
  1299. diff -u --recursive --new-file pre2.0.8/linux/mm/swapfile.c linux/mm/swapfile.c
  1300. --- pre2.0.8/linux/mm/swapfile.c    Tue May  7 16:22:40 1996
  1301. +++ linux/mm/swapfile.c    Tue May 28 07:39:18 1996
  1302. @@ -318,12 +318,13 @@
  1303.      struct inode * inode;
  1304.      struct file filp;
  1305.      int i, type, prev;
  1306. +    int err;
  1307.  
  1308.      if (!suser())
  1309.          return -EPERM;
  1310. -    i = namei(specialfile,&inode);
  1311. -    if (i)
  1312. -        return i;
  1313. +    err = namei(specialfile,&inode);
  1314. +    if (err)
  1315. +        return err;
  1316.      prev = -1;
  1317.      for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
  1318.          p = swap_info + type;
  1319. @@ -353,13 +354,21 @@
  1320.          swap_list.next = swap_list.head;
  1321.      }
  1322.      p->flags = SWP_USED;
  1323. -    i = try_to_unuse(type);
  1324. -    if (i) {
  1325. +    err = try_to_unuse(type);
  1326. +    if (err) {
  1327.          iput(inode);
  1328. +        /* re-insert swap space back into swap_list */
  1329. +        for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
  1330. +            if (p->prio >= swap_info[i].prio)
  1331. +                break;
  1332. +        p->next = i;
  1333. +        if (prev < 0)
  1334. +            swap_list.head = swap_list.next = p - swap_info;
  1335. +        else
  1336. +            swap_info[prev].next = p - swap_info;
  1337.          p->flags = SWP_WRITEOK;
  1338. -        return i;
  1339. +        return err;
  1340.      }
  1341. -
  1342.      if(p->swap_device){
  1343.          memset(&filp, 0, sizeof(filp));        
  1344.          filp.f_inode = inode;
  1345. diff -u --recursive --new-file pre2.0.8/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
  1346. --- pre2.0.8/linux/net/ipv4/ip_fw.c    Tue May 28 08:10:01 1996
  1347. +++ linux/net/ipv4/ip_fw.c    Wed May 29 14:24:12 1996
  1348. @@ -541,7 +541,13 @@
  1349.  #ifdef CONFIG_IP_TRANSPARENT_PROXY
  1350.              if (policy&IP_FW_F_REDIR) {
  1351.                  if (redirport)
  1352. -                    *redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp]);
  1353. +                    if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
  1354. +                        /* Wildcard redirection.
  1355. +                         * Note that redirport will become
  1356. +                         * 0xFFFF for non-TCP/UDP packets.
  1357. +                         */
  1358. +                        *redirport = dst_port;
  1359. +                    }
  1360.                  answer = FW_REDIRECT;
  1361.              } else
  1362.  #endif
  1363.