## Automatically generated incremental diff
## From:   linux-2.4.20-rc2
## To:     linux-2.4.20-rc3
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.4.20-rc2/Documentation/kbuild/makefiles.txt linux-2.4.20-rc3/Documentation/kbuild/makefiles.txt
--- linux-2.4.20-rc2/Documentation/kbuild/makefiles.txt	Tue Feb 13 14:13:42 2001
+++ linux-2.4.20-rc3/Documentation/kbuild/makefiles.txt	Fri Nov 22 12:14:26 2002
@@ -20,9 +20,8 @@
   6  The structure of a subdirectory Makefile
      6.1  Comments
      6.2  Goal definitions
-     6.3  Adapter section
-     6.4  Rules.make section
-     6.5  Special rules
+     6.3  Rules.make section
+     6.4  Special rules
   7  Rules.make variables
      7.1  Subdirectories
      7.2  Object file goals
@@ -34,8 +33,7 @@
   8  New-style variables
      8.1  New variables
      8.2  Converting to old-style
-  9  Compatibility with Linux Kernel 2.2
- 10  Credits
+  9  Credits
 
 
 === 1 Overview
@@ -100,15 +98,15 @@
 
 === 3 Makefile language
 
-The kernel Makefiles are designed to run with Gnu Make.  The Makefiles
-use only the documented features of Gnu Make, but they do use many
-Gnu extensions.
+The kernel Makefiles are designed to run with GNU Make.  The Makefiles
+use only the documented features of GNU Make, but they do use many
+GNU extensions.
 
-Gnu Make supports elementary list-processing functions.  The kernel
+GNU Make supports elementary list-processing functions.  The kernel
 Makefiles use a novel style of list building and manipulation with few
 "if" statements.
 
-Gnu Make has two assignment operators, ":=" and "=".  ":=" performs
+GNU Make has two assignment operators, ":=" and "=".  ":=" performs
 immediate evaluation of the right-hand side and stores an actual string
 into the left-hand side.  "=" is like a formula definition; it stores the
 right-hand side in an unevaluated form and then evaluates this form each
@@ -192,7 +190,7 @@
 	$(DRIVERS), and $(LIBS).  The arch Makefile defines $(HEAD)
 	and $(LINKFLAGS), and extends $(CORE_FILES) and $(LIBS).
 
-	Note: there are more names here than necessary.  $(NETWORKS),
+	Note: there are more variables here than necessary.  $(NETWORKS),
 	$(DRIVERS), and even $(LIBS) could be subsumed into $(CORE_FILES).
 
     CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP
@@ -290,12 +288,12 @@
 
     MAKE, MAKEFILES
 
-	Some variables internal to Gnu Make.
+	Some variables internal to GNU Make.
 
 	$(MAKEFILES) in particular is used to force the arch Makefiles
 	and subdirectory Makefiles to read $(TOPDIR)/.config without
-	including it explicitly.  (This was an implementation hack and
-	could be fixed).
+	including it explicitly.  (This was an implementational hack
+	and could be fixed).
 
 
 
@@ -339,7 +337,7 @@
 	extends them.
 
 	Many arch Makefiles dynamically run the target C compiler to
-	probe what options it supports:
+	probe supported options:
 
 		# arch/i386/Makefile
 
@@ -376,7 +374,7 @@
 
 --- 5.2 Vmlinux build variables
 
-An arch Makefile co-operates with the top Makefile to define variables
+An arch Makefile cooperates with the top Makefile to define variables
 which specify how to build the vmlinux file.  Note that there is no
 corresponding arch-specific section for modules; the module-building
 machinery is all architecture-independent.
@@ -466,17 +464,15 @@
 
 === 6 The structure of a subdirectory Makefile
 
-A subdirectory Makefile has five sections.
+A subdirectory Makefile has four sections.
 
 
 
 --- 6.1 Comments
 
-The first section is a comment header.  Just write what you would
-write if you were editing a C source file, but use "# ..." instead of
-"/* ... */".  Historically, many anonymous people have edited kernel
-Makefiles without leaving any change histories in the header; comments
-from them would have been valuable.
+The first section is a comment header. Historically, many anonymous
+people have edited kernel Makefiles without leaving any change
+histories in the header; comments from them would have been valuable.
 
 
 
@@ -488,20 +484,7 @@
 entered.  The declarations in these lines depend heavily on the kernel
 configuration variables (CONFIG_* symbols).
 
-In some Makefiles ("old-style Makefiles"), the second section looks
-like this:
-
-	# drivers/parport/Makefile
-	ifeq ($(CONFIG_PARPORT_PC),y)
-	  LX_OBJS += parport_pc.o
-	else
-	  ifeq ($(CONFIG_PARPORT_PC),m)
-	    MX_OBJS += parport_pc.o
-	  endif
-	endif
-
-In most Makefiles ("new-style Makefiles"), the second section looks
-like this:
+The second section looks like this:
 
 	# drivers/block/Makefile
 	obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
@@ -509,35 +492,18 @@
 	obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
 	obj-$(CONFIG_ATARI_FLOPPY)	+= ataflop.o
 
-The new-style Makefiles are more compact and easier to get correct
-for certain features (such as CONFIG_* options that enable more than
-one file).  If you have a choice, please write a new-style Makefile.
-
-
-
---- 6.3 Adapter section
 
-The third section is an adapter section.  In old-style Makefiles, this
-third section is not present.  In new-style Makefiles, the third section
-contains boilerplate code which converts from new-style variables to
-old-style variables.  This is because Rules.make processes only the
-old-style variables.
+--- 6.3 Rules.make section
 
-See section 8.2 ("Converting to old-style") for examples.
-
-
-
---- 6.4 Rules.make section
-
-The fourth section is the single line:
+The third section is the single line:
 
 	include $(TOPDIR)/Rules.make
 
 
 
---- 6.5 Special rules
+--- 6.4 Special rules
 
-The fifth section contains any special Makefile rules needed that are
+The fourth section contains any special Makefile rules needed that are
 not available through the common rules in Rules.make.
 
 
@@ -550,352 +516,166 @@
 
 --- 7.1 Subdirectories
 
-    ALL_SUB_DIRS, SUB_DIRS, MOD_IN_SUB_DIRS, MOD_SUB_DIRS
+A Makefile is only responsible for building objects in its own
+directory. Files in subdirectories should be taken care of by
+Makefiles in the these subdirs. The build system will automatically
+invoke make recursively in subdirectories, provided you let it know of
+them.
 
-	$(ALL_SUB_DIRS) is an unconditional list of *all* the
-	subdirectories in a given directory.  This list should not depend
-	on the kernel configuration.
-
-	$(SUB_DIRS) is a list of subdirectories which may contribute code
-	to vmlinux.  This list may depend on the kernel configuration.
-
-	$(MOD_SUB_DIRS) and $(MOD_IN_SUB_DIRS) are lists of subdirectories
-	which may build kernel modules.  Both names have exactly the
-	same meaning.  (In version 2.2 and earlier kernels, these
-	variables had different meanings -- hence the different names).
+To do so, use the subdir-{y,m,n,} variables:
 
-	For new code, $(MOD_SUB_DIRS) is recommended and $(MOD_IN_SUB_DIRS)
-	is deprecated.
+	subdir-$(CONFIG_ISDN)                   += i4l
+	subdir-$(CONFIG_ISDN_CAPI)              += capi
 
-	Example:
+When building the actual kernel, i.e. vmlinux ("make
+{vmlinux,bzImage,...}"), make will recursively descend into
+directories listed in $(subdir-y).
 
-		# fs/Makefile
-		ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs \
-			       umsdos ntfs hpfs sysv smbfs ncpfs ufs efs affs \
-			       romfs autofs hfs lockd nfsd nls devpts devfs \
-			       adfs partitions qnx4 udf bfs cramfs openpromfs \
-			       autofs4 ramfs jffs
-		SUB_DIRS :=
+When building modules ("make modules"), make will recursively descend
+into directories listed in $(subdir-m).
 
-		...
+When building the dependencies ("make dep") make needs to visit every
+subdir, so it'll descend into every directory listed in 
+$(subdir-y), $(subdir-m), $(subdir-n), $(subdir-).
 
-		ifeq ($(CONFIG_EXT2_FS),y)
-		SUB_DIRS += ext2
-		else
-		  ifeq ($(CONFIG_EXT2_FS),m)
-		  MOD_SUB_DIRS += ext2
-		  endif
-		endif
+You may encounter the case where a config option may be set to "y", but
+you still want to possibly build modules in that subdirectory.
 
-		ifeq ($(CONFIG_CRAMFS),y)
-		SUB_DIRS += cramfs
-		else
-		  ifeq ($(CONFIG_CRAMFS),m)
-		  MOD_SUB_DIRS += cramfs
-		  endif
-		endif
-
-	Example:
+For example, drivers/isdn/capi/Makefile has
 
-		# drivers/net/Makefile
-		SUB_DIRS     := 
-		MOD_SUB_DIRS :=
-		MOD_IN_SUB_DIRS :=
-		ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring \
-				wan sk98lin arcnet skfp tulip appletalk
+	obj-$(CONFIG_ISDN_CAPI)                 += kernelcapi.o capiutil.o
+	obj-$(CONFIG_ISDN_CAPI_CAPI20)          += capi.o
 
-		...
+where it's possible that CONFIG_ISDN_CAPI=y, but
+CONFIG_ISDN_CAPI_CAPI20=m.
 
-		ifeq ($(CONFIG_IRDA),y)
-		SUB_DIRS += irda
-		MOD_IN_SUB_DIRS += irda
-		else
-		  ifeq ($(CONFIG_IRDA),m)
-		  MOD_IN_SUB_DIRS += irda
-		  endif
-		endif
+This is expressed by the following construct in the parent Makefile
+drivers/isdn/Makefile:
 
-		ifeq ($(CONFIG_TR),y)
-		SUB_DIRS += tokenring
-		MOD_IN_SUB_DIRS += tokenring
-		else
-		  ifeq ($(CONFIG_TR),m)
-		  MOD_IN_SUB_DIRS += tokenring
-		  endif
-		endif
+	mod-subdirs                             := i4l hisax capi eicon
+	subdir-$(CONFIG_ISDN_CAPI)              += capi
 
+Having a subdir ("capi") listed in the variable $(mod-subdirs) will
+make the build system enter the specified subdirectory during "make
+modules" also, even though the subdir ("capi") is listed only in
+$(subdir-y), not $(subdir-m).
 
 
 --- 7.2 Object file goals
 
-    O_TARGET, O_OBJS, OX_OBJS
+    O_TARGET, obj-y
 
-	The subdirectory Makefile specifies object files for vmlinux in
-	the lists $(O_OBJS) and $(OX_OBJS).  These lists depend on the
-	kernel configuration.
-
-	The "X" in "OX_OBJS" stands for "eXport".  Files in $(OX_OBJS)
-	may use the EXPORT_SYMBOL macro to define public symbols which
-	loadable kernel modules can see.  Files in $(O_OBJS) may not use
-	EXPORT_SYMBOL (and you will get a funky error message if you try).
-
-	[Yes, it's kludgy to do this by hand.  Yes, you can define all
-	your objects as $(OX_OBJS) whether they define symbols or not;
-	but then you will notice a lot of extra compiles when you edit
-	any source file.  Blame CONFIG_MODVERSIONS for this.]
-
-	Data that is passed to other objects via registration functions
-	(e.g. pci_register_driver, pm_register) does not need to be marked
-	as EXPORT_SYMBOL.  The objects that pass data via registration
-	functions do not need to be marked as OX_OBJS, unless they also have
-	exported symbols.
-
-	Rules.make compiles all the $(O_OBJS) and $(OX_OBJS) files.
-	It then calls "$(LD) -r" to merge these files into one .o file
-	with the name $(O_TARGET).  This $(O_TARGET) name also appears
-	in the top Makefile.
-
-	The order of files in $(O_OBJS) and $(OX_OBJS) is significant.
-	All $(OX_OBJS) files come first, in the order listed, followed by
-	all $(O_OBJS) files, in the order listed.  Duplicates in the lists
-	are allowed: the first instance will be linked into $(O_TARGET)
-	and succeeding instances will be ignored.  (Note: Rules.make may
-	emit warning messages for duplicates, but this is harmless).
+	The subdirectory Makefile specifies object files for vmlinux
+	in the lists $(obj-y).  These lists depend on the kernel
+	configuration.
 
-	Example:
+	Rules.make compiles all the $(obj-y) files.  It then calls
+	"$(LD) -r" to merge these files into one .o file with the name
+	$(O_TARGET).  This $(O_TARGET) is later linked into vmlinux by 
+	a parent Makefile.
 
-		# arch/alpha/kernel/Makefile
-		O_TARGET := kernel.o
-		O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o \
-			    irq_alpha.o signal.o setup.o ptrace.o time.o \
-			    semaphore.o
-		OX_OBJS  := alpha_ksyms.o
+	The order of files in $(obj-y) is significant.  Duplicates in
+	the lists are allowed: the first instance will be linked into
+	$(O_TARGET) and succeeding instances will be ignored.
 
-		ifdef CONFIG_SMP
-		O_OBJS   += smp.o irq_smp.o
-		endif
+	Link order is significant, because certain functions
+	(module_init() / __initcall) will be called during boot in the
+	order they appear. So keep in mind that changing the link
+	order may e.g.  change the order in which your SCSI
+	controllers are detected, and thus you disks are renumbered.
 
-		ifdef CONFIG_PCI
-		O_OBJS   += pci.o pci_iommu.o
-		endif
-
-	Even if a subdirectory Makefile has an $(O_TARGET), the .config
-	options still control whether or not its $(O_TARGET) goes into
-	vmlinux.  See the $(M_OBJS) example below.
-
-	Sometimes the ordering of all $(OX_OBJS) files before all
-	$(O_OBJS) files can be a problem, particularly if both
-	$(O_OBJS) files and $(OX_OBJS) files contain __initcall
-	declarations where order is important.   To avoid this imposed
-	ordering, the use of $(OX_OBJS) can be dropped altogether and
-	$(MIX_OBJS) used instead.
-
-	If this approach is used, then:
-	 - All objects to be linked into vmlinux should be listed in
-	   $(O_OBJS) in the desired order.
-	 - All objects to be created as modules should be listed in
-	   $(M_OBJS)
-	 - All objects that export symbols should also be listed in
-	   $(MIX_OBJS).
-
-	This has the same effect as maintaining the
-	exported/non-exported split, except that there is more control
-	over the ordering of object files in vmlinux.
-	
+	Example:
 
+	    # Makefile for the kernel ISDN subsystem and device drivers.
 
---- 7.3 Library file goals
+	    # The target object and module list name.
 
-    L_TARGET, L_OBJS, LX_OBJS
+	    O_TARGET        := vmlinux-obj.o
 
-	These names are similar to the O_* names.  Once again, $(L_OBJS)
-	and $(LX_OBJS) specify object files for the resident kernel;
-	once again, the lists depend on the current configuration; and
-	once again, the files that call EXPORT_SYMBOL go on the "X" list.
-
-	The difference is that "L" stands for "Library".  After making
-	$(L_OBJS) and $(LX_OBJS), Rules.make uses the "$(AR) rcs" command
-	to put these files into an archive file (a library) with the
-	name $(L_TARGET).  This name also appears in the top Makefile.
+	    # Each configuration option enables a list of files.
 
-	Example:
+	    obj-$(CONFIG_ISDN)                      += isdn.o
+	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
 
-		# arch/i386/lib/Makefile
-		L_TARGET = lib.a
-		L_OBJS  = checksum.o old-checksum.o delay.o \
-			usercopy.o getuser.o putuser.o iodebug.o
+	    # The global Rules.make.
 
-		ifdef CONFIG_X86_USE_3DNOW
-		L_OBJS += mmx.o
-		endif
+	    include $(TOPDIR)/Rules.make
 
-		ifdef CONFIG_HAVE_DEC_LOCK
-		L_OBJS += dec_and_lock.o
-		endif
+--- 7.3 Library file goals
 
-	The order of files in $(L_OBJS) and $(LX_OBJS) is not significant.
-	Duplicates in the lists are allowed.  (Note: Rules.make may emit
-	warning messages for duplicates, but this is harmless).
-
-	A subdirectory Makefile can specify either an $(O_TARGET),
-	an $(L_TARGET), or both.  Here is a discussion of the differences.
-
-	All of the files in an $(O_TARGET) are guaranteed to appear in
-	the resident vmlinux image.  In an $(L_TARGET), only the files
-	that satisfy undefined symbol references from other files will
-	appear in vmlinux.
-
-	In a conventional link process, the linker processes some
-	object files and creates a list of unresolved external symbols.
-	The linker then looks in a set of libraries to resolve these
-	symbols.  Indeed, the Linux kernel used to be linked this way,
-	with the bulk of the code stored in libraries.
-
-	But vmlinux contains two types of object files that cannot be
-	fetched out of libraries this way:
-
-	    (1) object files that are purely EXPORT_SYMBOL definitions
-	    (2) object files that use module_init or __initcall initializers
-		(instead of an initialization routine called externally)
-
-	These files contain autonomous initializer sections which provide
-	code and data without being explicitly called.	If these files
-	were stored in $(L_TARGET) libraries, the linker would fail
-	to include them in vmlinux.  Thus, most subdirectory Makefiles
-	specify an $(O_TARGET) and do not use $(L_TARGET).
-
-	Other considerations: $(O_TARGET) leads to faster re-link times
-	during development activity, but $(L_TARGET) gives better error
-	messages for unresolved symbols.
+    L_TARGET
 
+	Instead of building an O_TARGET object file, you may also
+	build an archive which again contains objects listed in
+	$(obj-y). This is normally not necessary and only used in
+	the lib, arch/$(ARCH)/lib directories.
 
 
 --- 7.4 Loadable module goals
 
-    M_OBJS, MX_OBJS
+    obj-m
 
-	$(M_OBJS) and $(MX_OBJS) specify object files which are built
-	as loadable kernel modules.  As usual, the "X" in $(MX_OBJS)
-	stands for "eXport"; source files that use EXPORT_SYMBOL must
-	appear on an $(MX_OBJS) list.
+	$(obj-m) specify object files which are built as loadable
+	kernel modules.
 
 	A module may be built from one source file or several source
-	files.	In the case of one source file, the subdirectory
-	Makefile simply adds the file to either $(M_OBJS) or $(MX_OBJS),
-	as appropriate.
+	files. In the case of one source file, the subdirectory
+	Makefile simply adds the file to $(obj-m)
 
 	Example:
 
-		# drivers/net/irda/Makefile
-		ifeq ($(CONFIG_IRTTY_SIR),y)
-		L_OBJS += irtty.o
-		else
-		  ifeq ($(CONFIG_IRTTY_SIR),m)
-		  M_OBJS += irtty.o
-		  endif
-		endif
+	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
 
-		ifeq ($(CONFIG_IRPORT_SIR),y)
-		LX_OBJS += irport.o
-		else
-		  ifeq ($(CONFIG_IRPORT_SIR),m)
-		  MX_OBJS += irport.o
-		  endif
-		endif
+	If a kernel module is built from several source files, you specify
+	that you want to build a module in the same way as above.
 
-	If a kernel module is built from several source files, there
-	are two ways to specify the set of source files.  One way is to
-	build a single module for the entire subdirectory.  This way is
-	popular in the file system and network protocol stacks.
+	However, the build system of course needs to know which the parts
+	are that you want to build your module of, so you have to tell it
+	by setting an $(<module_name>-objs) variable.
 
 	Example:
 
-		# fs/ext2/Makefile
-		O_TARGET := ext2.o
-		O_OBJS   := acl.o balloc.o bitmap.o dir.o file.o fsync.o \
-			    ialloc.o inode.o ioctl.o namei.o super.o symlink.o \
-			    truncate.o
-		M_OBJS   := $(O_TARGET)
-
-	In this example, the module name will be ext2.o.  Because this
-	file has the same name has $(O_TARGET), Rules.make will use
-	the $(O_TARGET) rule to build ext2.o: it will run "$(LD) -r"
-	on the list of $(O_OBJS) files.
-
-	Note that this subdirectory Makefile defines both an $(O_TARGET)
-	and an $(M_OBJS).  The control code, up in fs/Makefile, will
-	select between these two.  If CONFIG_EXT2_FS=y, then fs/Makefile
-	will build $(O_TARGET); and if CONFIG_EXT_FS=m, then fs/Makefile
-	will build $(M_OBJS) instead.  (Yes, this is a little delicate
-	and a little confusing).
+	    obj-$(CONFIG_ISDN)                      += isdn.o
+
+	    isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o
+
+	In this example, the module name will be isdn.o. Rules.make
+	will compile the objects listed in $(isdn-objs) and then run
+	"$(LD) -r" on the list of these files to generate isdn.o
+
+	Note: Of course, when you are building objects into the kernel,
+	the syntax above will also work. So, if you have CONFIG_ISDN=y,
+	the build system will build an isdn.o for you out of the individual
+	parts and then link this into the $(O_TARGET), as you'd expect.
+
 
+--- 7.5 Objects which export symbols
 
+    export-objs
+
+	When using loadable modules, not every global symbol in the
+	kernel / other modules is automatically available, only those
+	explicitly exported are available for your module.
 
---- 7.5 Multi-part modules
-
-    MI_OBJS, MIX_OBJS
-
-	Some kernel modules are composed of several object files
-	linked together, but do not include every object file in their
-	subdirectory.  $(MI_OBJS) and $(MIX_OBJS) are for this case.
-
-	"M" stands for Module.
-	"I" stands for Intermediate.
-	"X", as usual, stands for "eXport symbol".
+	To make a symbol available for use in modules, to "export" it,
+	use the EXPORT_SYMBOL(<symbol>) directive in your source. In
+	addition, you need to list all object files which export symbols
+	(i.e. their source contains an EXPORT_SYMBOL() directive) in the
+	Makefile variable $(export-objs).
 
 	Example:
 
-		# drivers/sound/Makefile
-		gus-objs  := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
-		pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-		sb-objs	  := sb_card.o
-
-		gus.o: $(gus-objs)
-			$(LD) -r -o $@ $(gus-objs)
-
-		pas2.o: $(pas2-objs)
-			$(LD) -r -o $@ $(pas2-objs)
-
-		sb.o: $(sb-objs)
-			$(LD) -r -o $@ $(sb-objs)
-
-	The kernel modules gus.o, pas2.o, and sb.o are the *composite
-	files*.  The object files gus_card.o, gus_midi.o, gus_vol.o,
-	gus_wave.o, ics2101.o, pas2_card.o, pas2_midi.o, pas2_mixer.o,
-	pas2_pcm.o, and sb_card.o are *component files*.  The component
-	files are also called *intermediate files*.
-
-	In another part of drivers/sound/Makefile (not shown), all of
-	the component files are split out.  For the resident drivers:
-	the component object files go onto $(O_OBJS) and $(OX_OBJS)
-	lists, depending on whether they export symbols or not; and the
-	composite files are never built.  For the kernel modules: the
-	component object files go onto $(MI_OBJS) and $(MIX_OBJS);
-	the composite files go onto $(M_OBJS).
-
-	The subdirectory Makefile must also specify the linking rule
-	for a multi-object-file module:
-
-		# drivers/sound/Makefile
-
-		gus.o: $(gus-objs)
-			$(LD) -r -o $@ $(gus-objs)
-
-		pas2.o: $(pas2-objs)
-			$(LD) -r -o $@ $(pas2-objs)
-
-		sb.o: $(sb-objs)
-			$(LD) -r -o $@ $(sb-objs)
-
-
-	As is mentioned in section 7.2 ("Object file goals"),
-	$(MIX_OBJS) can also be used simply to list all objects that
-	export any symbols.  If this approach is taken, then
-	$(O_OBJS), $(L_OBJS), $(M_OBJS) and $(MI_OBJS) should simply
-	lists all of the vmlinux object files, library object files,
-	module object files and intermediate module files
-	respectively.  Duplication between $(MI_OBJS) and $(MIX_OBJS)
-	is not a problem.
+	    # Objects that export symbols.
+
+	    export-objs     := isdn_common.o
+
+	since isdn_common.c contains
+
+	    EXPORT_SYMBOL(register_isdn);
+
+	which makes the function register_isdn available to
+	low-level ISDN drivers.
+	    
 
 --- 7.6 Compilation flags
 
@@ -1013,6 +793,10 @@
 
 === 8 New-style variables
 
+[ This sections dates back from a time where the way to write Makefiles
+  described above was "new-style". I'm leaving it in as it describes the
+  same thing in other words, so it may be of some use ]
+
 The "new-style variables" are simpler and more powerful than the
 "old-style variables".  As a result, many subdirectory Makefiles shrank
 more than 60%.  This author hopes that, in time, all arch Makefiles and
@@ -1040,7 +824,7 @@
 		obj-$(CONFIG_ATARI_FLOPPY)      += ataflop.o
 
 	Notice the use of $(CONFIG_...) substitutions on the left hand
-	side of an assignment operator.  This gives Gnu Make the power
+	side of an assignment operator.  This gives GNU Make the power
 	of associative indexing!  Each of these assignments replaces
 	eight lines of code in an old-style Makefile.
 
@@ -1053,9 +837,8 @@
 	$(obj-n) and $(obj-) are ignored.
 
 	Each list may contain duplicates items; duplicates are
-	automatically removed later.  Also, if a file appears in both
-	$(obj-y) and $(obj-m), it will automatically be removed from
-	the $(obj-m) list.
+	automatically removed later.  Duplicates in both $(obj-y) and
+	$(obj-m) will automatically be removed from the $(obj-m) list.
 
 	Example:
 
@@ -1099,16 +882,14 @@
 	$(export-objs) list in a new-style Makefile is simpler and easier
 	to audit.
 
-    list-multi
     $(foo)-objs
 
 	Some kernel modules are composed of multiple object files linked
-	together.  $(list-multi) is a list of such kernel modules.
-	This is a static list; it does not depend on the configuration.
+	together.
 
-	For each kernel module in $(list-multi) there is another list
-	of all the object files which make up that module.  For a kernel
-	module named foo.o, its object file list is foo-objs.
+	For each multi-part kernel modul there is a list of all the
+	object files which make up that module.  For a kernel module
+	named foo.o, its object file list is foo-objs.
 
 	Example:
 
@@ -1135,44 +916,16 @@
 		obj-$(CONFIG_SCSI_INIA100)	+= a100u2w.o
 
 	Suppose that CONFIG_SCSI=y.  Then vmlinux needs to link in all
-	14 components of scsi_mod.o, so these components will go onto
-	$(O_OBJS) and $(OX_OBJS).  The composite file scsi_mod.o will
-	never be created.  The boilerplate conversion code produces this
-	result with a few lines of list processing commands.
+	14 components of scsi_mod.o.
 
 	Suppose that CONFIG_BLK_DEV_SR=m.  Then the 3 components
-	of sr_mod.o will linked together with "$(LD) -r" to make the
-	kernel module sr_mod.o, so these 3 components need to go onto
-	the $(MI_OBJS) and $(MIX_OBJS) lists; the composite file sr_mod.o
-	goes onto $(M_OBJS).  The boilerplate conversion code takes care
-	of this, too.
-
-	And suppose CONFIG_SCSI_INITIO=n.  Then initio.o goes onto the
-	$(obj-n) list and that's the end of it.  Its component files
-	are not compiled, and the composite file is not created.
+	of sr_mod.o will be linked together with "$(LD) -r" to make the
+	kernel module sr_mod.o.
 
-	Finally, the subdirectory Makefile needs to define rules to
-	build each multi-object kernel module from its component list.
-	Example:
-
-		# drivers/scsi/Makefile
+	Also suppose CONFIG_SCSI_INITIO=n.  Then initio.o goes onto
+	the $(obj-n) list and that's the end of it.  Its component
+	files are not compiled, and the composite file is not created.
 
-		scsi_mod.o: $(scsi_mod-objs)
-			$(LD) -r -o $@ $(scsi_mod-objs)
-
-		sr_mod.o: $(sr_mod-objs)
-			$(LD) -r -o $@ $(sr_mod-objs)
-
-		initio.o: $(initio-objs)
-			$(LD) -r -o $@ $(initio-objs)
-
-		a100u2w.o: $(a100u2w-objs)
-			$(LD) -r -o $@ $(a100u2w-objs)
-
-	These rules are very regular; it would be nice for the boilerplate
-	code or Rules.make to synthesize these rules automatically.
-	But until that happens, the subdirectory Makefile needs to define
-	these rules explicitly.
 
     subdir-y subdir-m subdir-n subdir-
 
@@ -1190,9 +943,9 @@
 	These variables work similar to obj-*, but are used for
 	subdirectories instead of object files.
 
-	After executing all of the assignments, the subdirectory
-	Makefile has built up four lists: $(subdir-y), $(subdir-m),
-	$(subdir-n), and $(subdir-).
+	After executing all assignments, the subdirectory Makefile has
+	built up four lists: $(subdir-y), $(subdir-m), $(subdir-n),
+	and $(subdir-).
 
 	$(subdir-y) is a list of directories that should be entered
 		for making vmlinux.
@@ -1217,72 +970,7 @@
 	This means nls should be added to (subdir-y) and $(subdir-m) if
 	CONFIG_NFS = y.
 
---- 8.2 Converting to old-style
-
-	The following example is taken from drivers/usb/Makefile.
-	Note that this uses MIX_OBJS to avoid the need for OX_OBJS and
-	MX_OBJS and thus to maintain the ordering of objects in $(obj-y)
-
-		# Translate to Rules.make lists.
-		multi-used	:= $(filter $(list-multi), $(obj-y) $(obj-m))
-		multi-objs	:= $(foreach m, $(multi-used), $($(basename $(m))-objs))
-		active-objs	:= $(sort $(multi-objs) $(obj-y) $(obj-m))
-
-		O_OBJS		:= $(obj-y)
-		M_OBJS		:= $(obj-m)
-		MIX_OBJS	:= $(filter $(export-objs), $(active-objs))
-
-	An example for libraries from drivers/acorn/scsi/Makefile:
-
-		# Translate to Rules.make lists.
-
-		L_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-		LX_OBJS		:= $(filter     $(export-objs), $(obj-y))
-		M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-		MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
-
-	As ordering is not so important in libraries, this still uses
-	LX_OBJS and MX_OBJS, though (presumably) it could be changed to
-	use MIX_OBJS as follows:
-
-		active-objs	:= $(sort $(obj-y) $(obj-m))
-		L_OBJS		:= $(obj-y)
-		M_OBJS		:= $(obj-m)
-		MIX_OBJS	:= $(filter $(export-objs), $(active-objs))
-		
-
-	which is clearly shorted and arguably clearer.
-
-=== 9 Compatibility with Linux Kernel 2.2
-
-Most of the information in this document also applies to 2.2, although
-there is no indication of which things have changed when.  Here are some
-hints for writing subdirectory Makefiles that are compatible with Linux
-kernel 2.2.
-
-You can write either an old-style Makefile or a new-style Makefile
-with a boilerplate adapter section.  See the 2.2 version of
-drivers/sound/Makefile for a copy of the boilerplate code.
-
-In 2.2, Rules.make makes a distinction between $(MOD_SUB_DIRS)
-and $(MOD_IN_SUB_DIRS).  If you have a single directory with no
-subdirectories, this will not matter to you.  If you have a whole
-tree, then you need to know the difference between $(MOD_SUB_DIRS)
-and $(MOD_IN_SUB_DIRS).  For example code: $(MOD_SUB_DIRS) is used
-extensively in fs/Makefile; $(MOD_IN_SUB_DIRS) is used extensively in
-drivers/net/Makefile.
-
-If you are already using MOD_LIST_NAME, go ahead and keep using it.
-If you don't already have a MOD_LIST_NAME, go ahead and keep not using
-one; your module will be a 'misc' module in 2.2.
-
-Assembly language rules were a mess in 2.2.  If you have assembly language
-files, this author recommends that you write your own explicit rules
-for each file by name.
-
-
-
-=== 10 Credits
+=== 9 Credits
 
 Thanks to the members of the linux-kbuild mailing list for reviewing
 drafts of this document, with particular thanks to Peter Samuelson
diff -urN linux-2.4.20-rc2/Makefile linux-2.4.20-rc3/Makefile
--- linux-2.4.20-rc2/Makefile	Fri Nov 22 12:14:19 2002
+++ linux-2.4.20-rc3/Makefile	Fri Nov 22 12:14:26 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 20
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.20-rc2/arch/i386/kernel/pci-dma.c linux-2.4.20-rc3/arch/i386/kernel/pci-dma.c
--- linux-2.4.20-rc2/arch/i386/kernel/pci-dma.c	Fri Nov 22 12:14:19 2002
+++ linux-2.4.20-rc3/arch/i386/kernel/pci-dma.c	Fri Nov 22 12:14:26 2002
@@ -19,7 +19,7 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (hwdev == NULL || ((u32)hwdev->dma_mask != 0xffffffff))
+	if (hwdev == NULL || ((u32)hwdev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 
diff -urN linux-2.4.20-rc2/drivers/char/Makefile linux-2.4.20-rc3/drivers/char/Makefile
--- linux-2.4.20-rc2/drivers/char/Makefile	Fri Nov 22 12:14:22 2002
+++ linux-2.4.20-rc3/drivers/char/Makefile	Fri Nov 22 12:14:29 2002
@@ -231,6 +231,7 @@
 obj-$(CONFIG_DS1620) += ds1620.o
 obj-$(CONFIG_INTEL_RNG) += i810_rng.o
 obj-$(CONFIG_AMD_RNG) += amd768_rng.o
+obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
 
 obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
diff -urN linux-2.4.20-rc2/drivers/char/mk712.c linux-2.4.20-rc3/drivers/char/mk712.c
--- linux-2.4.20-rc2/drivers/char/mk712.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-rc3/drivers/char/mk712.c	Fri Nov 22 12:14:29 2002
@@ -439,7 +439,7 @@
                 mk712_irq = irq;
 #endif
 
-	if(request_region(mk712_io, 8, "mk712_touchscreen"))
+	if(!request_region(mk712_io, 8, "mk712_touchscreen"))
 	{
 		printk("mk712: unable to get IO region\n");
 		return -ENODEV;
diff -urN linux-2.4.20-rc2/drivers/isdn/isdn_ppp.c linux-2.4.20-rc3/drivers/isdn/isdn_ppp.c
--- linux-2.4.20-rc2/drivers/isdn/isdn_ppp.c	Fri Nov 22 12:14:22 2002
+++ linux-2.4.20-rc3/drivers/isdn/isdn_ppp.c	Fri Nov 22 12:14:30 2002
@@ -1137,7 +1137,7 @@
 	isdn_net_dev *nd;
 	unsigned int proto = PPP_IP;     /* 0x21 */
 	struct ippp_struct *ipt,*ipts;
-	int slot;
+	int slot, retval = 0;
 
 	mlp = (isdn_net_local *) (netdev->priv);
 	nd = mlp->netdev;       /* get master lp */
@@ -1147,14 +1147,15 @@
 		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
 			mlp->ppp_slot);
 		kfree_skb(skb);
-		return 0;
+		goto unlock;
 	}
 	ipts = ippp_table[slot];
 
 	if (!(ipts->pppcfg & SC_ENABLE_IP)) {	/* PPP connected ? */
 		if (ipts->debug & 0x1)
 			printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
-		return 1;
+		retval = 1;
+		goto unlock;
 	}
 
 	switch (ntohs(skb->protocol)) {
@@ -1168,13 +1169,14 @@
 			printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n", 
 			       skb->protocol);
 			dev_kfree_skb(skb);
-			return 0;
+			goto unlock;
 	}
 
 	lp = isdn_net_get_locked_lp(nd);
 	if (!lp) {
 		printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
-		return 1;
+		retval = 1;
+		goto unlock;
 	}
 	/* we have our lp locked from now on */
 
@@ -1183,7 +1185,7 @@
 		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
 			lp->ppp_slot);
 		kfree_skb(skb);
-		return 0;
+		goto unlock;
 	}
 	ipt = ippp_table[slot];
 	lp->huptimer = 0;
@@ -1334,7 +1336,7 @@
 
  unlock:
 	spin_unlock_bh(&lp->xmit_lock);
-	return 0;
+	return retval;
 }
 
 #ifdef CONFIG_ISDN_MPP
diff -urN linux-2.4.20-rc2/drivers/net/tg3.c linux-2.4.20-rc3/drivers/net/tg3.c
--- linux-2.4.20-rc2/drivers/net/tg3.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/drivers/net/tg3.c	Fri Nov 22 12:14:31 2002
@@ -2367,6 +2367,7 @@
 	unsigned int i;
 	u32 len, entry, base_flags, mss;
 	int would_hit_hwbug;
+	unsigned long flags;
 
 	len = (skb->len - skb->data_len);
 
@@ -2389,12 +2390,12 @@
 	 * So we really do need to disable interrupts when taking
 	 * tx_lock here.
 	 */
-	spin_lock_irq(&tp->tx_lock);
+	spin_lock_irqsave(&tp->tx_lock, flags);
 
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
-		spin_unlock_irq(&tp->tx_lock);
+		spin_unlock_irqrestore(&tp->tx_lock, flags);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
 		return 1;
@@ -2535,7 +2536,7 @@
 		netif_stop_queue(dev);
 
 out_unlock:
-	spin_unlock_irq(&tp->tx_lock);
+	spin_unlock_irqrestore(&tp->tx_lock, flags);
 
 	dev->trans_start = jiffies;
 
@@ -2547,6 +2548,7 @@
 	struct tg3 *tp = dev->priv;
 	dma_addr_t mapping;
 	u32 len, entry, base_flags, mss;
+	unsigned long flags;
 
 	len = (skb->len - skb->data_len);
 
@@ -2569,12 +2571,12 @@
 	 * So we really do need to disable interrupts when taking
 	 * tx_lock here.
 	 */
-	spin_lock_irq(&tp->tx_lock);
+	spin_lock_irqsave(&tp->tx_lock, flags);
 
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
-		spin_unlock_irq(&tp->tx_lock);
+		spin_unlock_irqrestore(&tp->tx_lock, flags);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
 		return 1;
@@ -2665,7 +2667,7 @@
 	if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
-	spin_unlock_irq(&tp->tx_lock);
+	spin_unlock_irqrestore(&tp->tx_lock, flags);
 
 	dev->trans_start = jiffies;
 
diff -urN linux-2.4.20-rc2/drivers/pci/pci.c linux-2.4.20-rc3/drivers/pci/pci.c
--- linux-2.4.20-rc2/drivers/pci/pci.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/drivers/pci/pci.c	Fri Nov 22 12:14:31 2002
@@ -1386,7 +1386,7 @@
 		/* The PCI-to-PCI bridge spec requires that subtractive
 		   decoding (i.e. transparent) bridge must have programming
 		   interface code of 0x01. */ 
-		dev->transparent = ((class & 0xff) == 1);
+		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
 		break;
 
diff -urN linux-2.4.20-rc2/drivers/scsi/scsi_merge.c linux-2.4.20-rc3/drivers/scsi/scsi_merge.c
--- linux-2.4.20-rc2/drivers/scsi/scsi_merge.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/drivers/scsi/scsi_merge.c	Fri Nov 22 12:14:32 2002
@@ -835,7 +835,7 @@
 	 * case.
  	 */
 	if (count == 1 && !SCpnt->host->highmem_io) {
-		this_count = req->current_nr_sectors;
+		this_count = req->nr_sectors;
 		goto single_segment;
 	}
 
diff -urN linux-2.4.20-rc2/drivers/sound/i810_audio.c linux-2.4.20-rc3/drivers/sound/i810_audio.c
--- linux-2.4.20-rc2/drivers/sound/i810_audio.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/drivers/sound/i810_audio.c	Fri Nov 22 12:14:33 2002
@@ -113,6 +113,12 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO	0x01b1
 #endif
+#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
+#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO	0x006a
+#endif
+#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
+#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO	0x00da
+#endif
 #ifndef PCI_DEVICE_ID_AMD_768_AUDIO
 #define PCI_DEVICE_ID_AMD_768_AUDIO	0x7445
 #endif
@@ -273,6 +279,10 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012},
 	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
+	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
+	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
 	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768_AUDIO,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768},
 	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AC97,
diff -urN linux-2.4.20-rc2/fs/buffer.c linux-2.4.20-rc3/fs/buffer.c
--- linux-2.4.20-rc2/fs/buffer.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/buffer.c	Fri Nov 22 12:14:34 2002
@@ -1617,8 +1617,20 @@
 	 * Zero out any newly allocated blocks to avoid exposing stale
 	 * data.  If BH_New is set, we know that the block was newly
 	 * allocated in the above loop.
+	 *
+	 * Details the buffer can be new and uptodate because:
+	 * 1) hole in uptodate page, get_block(create) allocate the block,
+	 *    so the buffer is new and additionally we also mark it uptodate
+	 * 2) The buffer is not mapped and uptodate due a previous partial read.
+	 *
+	 * We can always ignore uptodate buffers here, if you mark a buffer
+	 * uptodate you must make sure it contains the right data first.
+	 *
+	 * We must stop the "undo/clear" fixup pass not at the caller "to"
+	 * but at the last block that we successfully arrived in the main loop.
 	 */
 	bh = head;
+	to = block_start; /* stop at the last successfully handled block */
 	block_start = 0;
 	do {
 		block_end = block_start+blocksize;
@@ -1626,10 +1638,9 @@
 			goto next_bh;
 		if (block_start >= to)
 			break;
-		if (buffer_new(bh)) {
-			if (buffer_uptodate(bh))
-				printk(KERN_ERR "%s: zeroing uptodate buffer!\n", __FUNCTION__);
+		if (buffer_new(bh) && !buffer_uptodate(bh)) {
 			memset(kaddr+block_start, 0, bh->b_size);
+			flush_dcache_page(page);
 			set_bit(BH_Uptodate, &bh->b_state);
 			mark_buffer_dirty(bh);
 		}
diff -urN linux-2.4.20-rc2/fs/ext2/inode.c linux-2.4.20-rc3/fs/ext2/inode.c
--- linux-2.4.20-rc2/fs/ext2/inode.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/ext2/inode.c	Fri Nov 22 12:14:34 2002
@@ -408,9 +408,13 @@
 		unlock_buffer(bh);
 		mark_buffer_dirty_inode(bh, inode);
 		/* We used to sync bh here if IS_SYNC(inode).
-		 * But we now rely upon generic_osync_inode()
+		 * But for S_ISREG files we now rely upon generic_osync_inode()
 		 * and b_inode_buffers
 		 */
+		if (S_ISDIR(inode->i_mode) && IS_SYNC(inode)) {
+			ll_rw_block (WRITE, 1, &bh);
+			wait_on_buffer (bh);
+		}
 		parent = nr;
 	}
 	if (n == num)
@@ -469,8 +473,13 @@
 	inode->i_ctime = CURRENT_TIME;
 
 	/* had we spliced it onto indirect block? */
-	if (where->bh)
+	if (where->bh) {
 		mark_buffer_dirty_inode(where->bh, inode);
+		if (S_ISDIR(inode->i_mode) && IS_SYNC(inode)) {
+			ll_rw_block(WRITE, 1, &where->bh);
+			wait_on_buffer(where->bh);
+		}
+	}
 
 	mark_inode_dirty(inode);
 	return 0;
diff -urN linux-2.4.20-rc2/fs/intermezzo/dcache.c linux-2.4.20-rc3/fs/intermezzo/dcache.c
--- linux-2.4.20-rc2/fs/intermezzo/dcache.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/intermezzo/dcache.c	Fri Nov 22 12:14:34 2002
@@ -48,7 +48,7 @@
 
 #include <linux/intermezzo_fs.h>
 
-static kmem_cache_t * presto_dentry_slab;
+kmem_cache_t * presto_dentry_slab;
 
 /* called when a cache lookup succeeds */
 static int presto_d_revalidate(struct dentry *de, int flag)
diff -urN linux-2.4.20-rc2/fs/jffs2/file.c linux-2.4.20-rc3/fs/jffs2/file.c
--- linux-2.4.20-rc2/fs/jffs2/file.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/jffs2/file.c	Fri Nov 22 12:14:34 2002
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: file.c,v 1.58.2.3 2002/10/07 12:25:55 dwmw2 Exp $
+ * $Id: file.c,v 1.58.2.6 2002/11/12 13:17:01 dwmw2 Exp $
  *
  */
 
@@ -276,23 +276,28 @@
 			continue;
 		} else {
 			__u32 readlen;
-			readlen = min(frag->size, end - offset);
-			D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs, frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
-			ret = jffs2_read_dnode(c, frag->node, pg_buf, frag->ofs - frag->node->ofs, readlen);
+			__u32 fragofs; /* offset within the frag to start reading */
+
+			fragofs = offset - frag->ofs;
+			readlen = min(frag->size - fragofs, end - offset);
+			D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs, 
+				  fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
+			ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen);
 			D2(printk(KERN_DEBUG "node read done\n"));
 			if (ret) {
 				D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));
-				memset(pg_buf, 0, frag->size);
+				memset(pg_buf, 0, readlen);
 				ClearPageUptodate(pg);
 				SetPageError(pg);
 				kunmap(pg);
 				return ret;
 			}
+		
+			pg_buf += readlen;
+			offset += readlen;
+			frag = frag->next;
+			D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
 		}
-		pg_buf += frag->size;
-		offset += frag->size;
-		frag = frag->next;
-		D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
 	}
 	D2(printk(KERN_DEBUG "readpage finishing\n"));
 	SetPageUptodate(pg);
@@ -331,7 +336,6 @@
 	__u32 pageofs = pg->index << PAGE_CACHE_SHIFT;
 	int ret = 0;
 
-	down(&f->sem);
 	D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));
 
 	if (pageofs > inode->i_size) {
@@ -345,10 +349,10 @@
 			  (unsigned int)inode->i_size, pageofs));
 
 		ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
-		if (ret) {
-			up(&f->sem);
+		if (ret)
 			return ret;
-		}
+
+		down(&f->sem);
 		memset(&ri, 0, sizeof(ri));
 
 		ri.magic = JFFS2_MAGIC_BITMASK;
@@ -391,14 +395,17 @@
 			return ret;
 		}
 		inode->i_size = pageofs;
+		up(&f->sem);
 	}
 	
 
 	/* Read in the page if it wasn't already present, unless it's a whole page */
-	if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE))
+	if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
+		down(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
+		up(&f->sem);
+	}
 	D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags));
-	up(&f->sem);
 	return ret;
 }
 
diff -urN linux-2.4.20-rc2/fs/nfs/nfs2xdr.c linux-2.4.20-rc3/fs/nfs/nfs2xdr.c
--- linux-2.4.20-rc2/fs/nfs/nfs2xdr.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/nfs/nfs2xdr.c	Fri Nov 22 12:14:34 2002
@@ -232,6 +232,7 @@
 static int
 nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
 {
+	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
 	struct iovec *iov = req->rq_rvec;
 	int	status, count, recvd, hdrlen;
 
@@ -240,25 +241,33 @@
 	p = xdr_decode_fattr(p, res->fattr);
 
 	count = ntohl(*p++);
+	res->eof = 0;
+	if (rcvbuf->page_len) {
+		u32 end = page_offset(rcvbuf->pages[0]) + rcvbuf->page_base + count;
+		if (end >= res->fattr->size)
+			res->eof = 1;
+	}
 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len > hdrlen) {
+	if (iov->iov_len < hdrlen) {
+		printk(KERN_WARNING "NFS: READ reply header overflowed:"
+				"length %d > %Zu\n", hdrlen, iov->iov_len);
+		return -errno_NFSERR_IO;
+	} else if (iov->iov_len != hdrlen) {
 		dprintk("NFS: READ header is short. iovec will be shifted.\n");
 		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
 	}
 
-	recvd = req->rq_rlen - hdrlen;
+	recvd = req->rq_received - hdrlen;
 	if (count > recvd) {
 		printk(KERN_WARNING "NFS: server cheating in read reply: "
 			"count %d > recvd %d\n", count, recvd);
 		count = recvd;
+		res->eof = 0;
 	}
 
 	dprintk("RPC:      readres OK count %d\n", count);
-	if (count < res->count) {
+	if (count < res->count)
 		res->count = count;
-		res->eof = 1;  /* Silly NFSv3ism which can't be helped */
-	} else
-		res->eof = 0;
 
 	return count;
 }
@@ -383,7 +392,7 @@
 	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
 	struct iovec *iov = rcvbuf->head;
 	struct page **page;
-	int hdrlen;
+	int hdrlen, recvd;
 	int status, nr;
 	unsigned int len, pglen;
 	u32 *end, *entry;
@@ -392,17 +401,24 @@
 		return -nfs_stat_to_errno(status);
 
 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len > hdrlen) {
+	if (iov->iov_len < hdrlen) {
+		printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
+				"length %d > %Zu\n", hdrlen, iov->iov_len);
+		return -errno_NFSERR_IO;
+	} else if (iov->iov_len != hdrlen) {
 		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
 		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
 	}
 
 	pglen = rcvbuf->page_len;
+	recvd = req->rq_received - hdrlen;
+	if (pglen > recvd)
+		pglen = recvd;
 	page = rcvbuf->pages;
 	p = kmap(*page);
+	entry = p;
 	end = (u32 *)((char *)p + pglen);
 	for (nr = 0; *p++; nr++) {
-		entry = p - 1;
 		if (p + 2 > end)
 			goto short_pkt;
 		p++; /* fileid */
@@ -415,14 +431,21 @@
 		}
 		if (p + 2 > end)
 			goto short_pkt;
+		entry = p;
 	}
+	if (!nr && (entry[0] != 0 || entry[1] == 0))
+		goto short_pkt;
+ out:
 	kunmap(*page);
 	return nr;
  short_pkt:
-	printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");
 	entry[0] = entry[1] = 0;
-	kunmap(*page);
-	return nr;
+	/* truncate listing ? */
+	if (!nr) {
+		printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
+		entry[1] = 1;
+	}
+	goto out;
 err_unmap:
 	kunmap(*page);
 	return -errno_NFSERR_IO;
diff -urN linux-2.4.20-rc2/fs/nfs/nfs3xdr.c linux-2.4.20-rc3/fs/nfs/nfs3xdr.c
--- linux-2.4.20-rc2/fs/nfs/nfs3xdr.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/nfs/nfs3xdr.c	Fri Nov 22 12:14:34 2002
@@ -503,7 +503,7 @@
 	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
 	struct iovec *iov = rcvbuf->head;
 	struct page **page;
-	int hdrlen;
+	int hdrlen, recvd;
 	int status, nr;
 	unsigned int len, pglen;
 	u32 *entry, *end;
@@ -522,17 +522,24 @@
 	}
 
 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len > hdrlen) {
+	if (iov->iov_len < hdrlen) {
+		printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
+				"length %d > %Zu\n", hdrlen, iov->iov_len);
+		return -errno_NFSERR_IO;
+	} else if (iov->iov_len != hdrlen) {
 		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
 		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
 	}
 
 	pglen = rcvbuf->page_len;
+	recvd = req->rq_received - hdrlen;
+	if (pglen > recvd)
+		pglen = recvd;
 	page = rcvbuf->pages;
 	p = kmap(*page);
 	end = (u32 *)((char *)p + pglen);
+	entry = p;
 	for (nr = 0; *p++; nr++) {
-		entry = p - 1;
 		if (p + 3 > end)
 			goto short_pkt;
 		p += 2;				/* inode # */
@@ -569,15 +576,21 @@
 
 		if (p + 2 > end)
 			goto short_pkt;
+		entry = p;
 	}
+	if (!nr && (entry[0] != 0 || entry[1] == 0))
+		goto short_pkt;
+ out:
 	kunmap(*page);
 	return nr;
  short_pkt:
-	printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");
-	/* truncate listing */
 	entry[0] = entry[1] = 0;
-	kunmap(*page);
-	return nr;
+	/* truncate listing ? */
+	if (!nr) {
+		printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
+		entry[1] = 1;
+	}
+	goto out;
 err_unmap:
 	kunmap(*page);
 	return -errno_NFSERR_IO;
@@ -794,16 +807,21 @@
 	}
 
 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len > hdrlen) {
+	if (iov->iov_len < hdrlen) {
+		printk(KERN_WARNING "NFS: READ reply header overflowed:"
+				"length %d > %Zu\n", hdrlen, iov->iov_len);
+		return -errno_NFSERR_IO;
+	} else if (iov->iov_len != hdrlen) {
 		dprintk("NFS: READ header is short. iovec will be shifted.\n");
 		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
 	}
 
-	recvd = req->rq_rlen - hdrlen;
+	recvd = req->rq_received - hdrlen;
 	if (count > recvd) {
 		printk(KERN_WARNING "NFS: server cheating in read reply: "
 			"count %d > recvd %d\n", count, recvd);
 		count = recvd;
+		res->eof = 0;
 	}
 
 	if (count < res->count)
diff -urN linux-2.4.20-rc2/fs/nfs/read.c linux-2.4.20-rc3/fs/nfs/read.c
--- linux-2.4.20-rc2/fs/nfs/read.c	Fri Nov 22 12:14:23 2002
+++ linux-2.4.20-rc3/fs/nfs/read.c	Fri Nov 22 12:14:34 2002
@@ -418,9 +418,14 @@
 				memset(p + count, 0, PAGE_CACHE_SIZE - count);
 				kunmap(page);
 				count = 0;
-			} else
+				if (data->res.eof)
+					SetPageUptodate(page);
+				else
+					SetPageError(page);
+			} else {
 				count -= PAGE_CACHE_SIZE;
-			SetPageUptodate(page);
+				SetPageUptodate(page);
+			}
 		} else
 			SetPageError(page);
 		flush_dcache_page(page);
diff -urN linux-2.4.20-rc2/mm/memory.c linux-2.4.20-rc3/mm/memory.c
--- linux-2.4.20-rc2/mm/memory.c	Fri Nov 22 12:14:24 2002
+++ linux-2.4.20-rc3/mm/memory.c	Fri Nov 22 12:14:35 2002
@@ -586,6 +586,8 @@
  * occurs, the number of bytes read into memory may be less than the
  * size of the kiobuf, so we have to stop marking pages dirty once the
  * requested byte count has been reached.
+ *
+ * Must be called from process context - set_page_dirty() takes VFS locks.
  */
 
 void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes)
@@ -603,7 +605,7 @@
 		page = iobuf->maplist[index];
 		
 		if (!PageReserved(page))
-			SetPageDirty(page);
+			set_page_dirty(page);
 
 		remaining -= (PAGE_SIZE - offset);
 		offset = 0;
diff -urN linux-2.4.20-rc2/mm/vmalloc.c linux-2.4.20-rc3/mm/vmalloc.c
--- linux-2.4.20-rc2/mm/vmalloc.c	Fri Nov 22 12:14:24 2002
+++ linux-2.4.20-rc3/mm/vmalloc.c	Fri Nov 22 12:14:35 2002
@@ -176,9 +176,13 @@
 	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
 	if (!area)
 		return NULL;
+
 	size += PAGE_SIZE;
-	if(!size)
+	if (!size) {
+		kfree (area);
 		return NULL;
+	}
+
 	addr = VMALLOC_START;
 	write_lock(&vmlist_lock);
 	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
