diff options
| author | Andy Grover <agrover@groveronline.com> | 2003-02-04 19:22:39 -0800 |
|---|---|---|
| committer | Andy Grover <agrover@groveronline.com> | 2003-02-04 19:22:39 -0800 |
| commit | 263cc27fa141984aed0e6de7474fc813449d02a3 (patch) | |
| tree | b22302cd0039b993cfba9adf39e33280912a8d9f | |
| parent | a9b3ee51be65cde06e65cb2915adb89751511623 (diff) | |
| parent | cf5ba9c8989c8451afd1364e46168c180efee124 (diff) | |
Merge groveronline.com:/root/bk/linux-2.5
into groveronline.com:/root/bk/linux-acpi
463 files changed, 6479 insertions, 5216 deletions
diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt index 53e171c1fe98..83a85037f223 100644 --- a/Documentation/filesystems/jfs.txt +++ b/Documentation/filesystems/jfs.txt @@ -28,8 +28,6 @@ JFS TODO list: Plans for our near term development items - enhance support for logfile on dedicated partition - - get access control list functionality operational - - get extended attributes functionality operational Longer term work items @@ -37,7 +35,7 @@ Longer term work items - add quota support - add support for block sizes (512,1024,2048) -Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com. +Please send bugs, comments, cards and letters to shaggy@austin.ibm.com. The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/. diff --git a/Documentation/kbuild/00-INDEX b/Documentation/kbuild/00-INDEX index 50584534eaa2..03db5e5d208d 100644 --- a/Documentation/kbuild/00-INDEX +++ b/Documentation/kbuild/00-INDEX @@ -1,10 +1,10 @@ 00-INDEX - this file: info on the kernel build process -bug-list.txt - - known bugs in kbuild programs commands.txt - overview of kbuild commands kconfig-language.txt - specification of Config Language, the language in Kconfig files +random.txt + - description of generic config targets makefiles.txt - developer information for linux kernel makefiles diff --git a/Documentation/kbuild/bug-list.txt b/Documentation/kbuild/bug-list.txt deleted file mode 100644 index 0a9e0ec55a46..000000000000 --- a/Documentation/kbuild/bug-list.txt +++ /dev/null @@ -1,22 +0,0 @@ -Bug List -21 January 1999 -Michael Elizabeth Chastain, <mailto:mec@shout.net> - -- If a variable has a value of "m" in the previous .config file, - and a type of bool in the Config script, then all the interpreters - get confused. This happens frequently when someone changes a - tristate option to a bool option and people in the field have - .config files with a value of 'm'. For example: CONFIG_PSMOUSE. - -- CONFIG_MODVERSIONS has incorrect dependencies. If you have a - problem building the kernel, and you have CONFIG_MODVERSIONS turned - on, do a 'make dep' followed by 'make clean' before you try anything - else. - -- 'make dep' uses multistage dependencies, so the .hdepend file contains - 'touch' commands. As a result, building a kernel often touches files - in include/linux/*.h. This messes up CVS and other systems which like - to rely on file dates. - -- 'make dep' fails for C files which include other C files, such as - drivers/cdrom/sbpcd2.c. diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index b3c00ed92451..2d0a4de89302 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -1,74 +1,76 @@ Linux Kernel Makefiles -2000-September-14 -Michael Elizabeth Chastain, <mec@shout.net> - - - -=== Table of Contents This document describes the Linux kernel Makefiles. - 1 Overview - 2 Who does what - 3 Makefile language - 4 Variables passed down from the top - 5 The structure of an arch Makefile - 5.1 Architecture-specific variables - 5.2 Vmlinux build variables - 5.3 Post-vmlinux goals - 5.4 Mandatory arch-specific goals - 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 - 7 Rules.make variables - 7.1 Subdirectories - 7.2 Object file goals - 7.3 Library file goals - 7.4 Loadable module goals - 7.5 Multi-part modules - 7.6 Compilation flags - 7.7 Miscellaneous variables - 8 New-style variables - 8.1 New variables - 8.2 Converting to old-style - 9 Credits +=== Table of Contents + === 1 Overview + === 2 Who does what + === 3 The kbuild Makefiles + --- 3.1 Goal definitions + --- 3.2 Built-in object goals - obj-y + --- 3.3 Loadable module goals - obj-m + --- 3.4 Objects which export symbols - export-objs + --- 3.5 Library file goals - L_TARGET + --- 3.6 Descending down in directories + --- 3.7 Compilation flags + --- 3.8 Command line dependency + --- 3.9 Dependency tracking + --- 3.10 Special Rules + + === 4 Host Program support + --- 4.1 Simple Host Program + --- 4.2 Composite Host Programs + --- 4.3 Defining shared libraries + --- 4.4 Using C++ for host programs + --- 4.5 Controlling compiler options for host programs + --- 4.6 When host programs are actually built + + === 5 Kbuild clean infrastructure + + === 6 Architecture Makefiles + --- 6.1 Set variables to tweak the build to the architecture + --- 6.2 Add prerequisites to prepare: + --- 6.3 List directories to visit when descending + --- 6.4 Architecture specific boot images + --- 6.5 Building non-kbuild targets + --- 6.6 Commands useful for building a boot image + --- 6.7 Custom kbuild commands + + === 7 Kbuild Variables + === 8 Makefile language + === 9 Credits + === 10 TODO === 1 Overview The Makefiles have five parts: - Makefile: the top Makefile. - .config: the kernel configuration file. - arch/*/Makefile: the arch Makefiles. - Subdirectory Makefiles: there are about 300 of these. - Rules.make: the common rules for all subdirectory Makefiles. + Makefile the top Makefile. + .config the kernel configuration file. + arch/$(ARCH)/Makefile the arch Makefile. + scripts/Makefile.* common rules etc. for all kbuild Makefiles. + kbuild Makefiles there are about 500 of these. -The top Makefile reads the .config file, which comes from the -kernel configuration process. +The top Makefile reads the .config file, which comes from the kernel +configuration process. The top Makefile is responsible for building two major products: vmlinux -(the resident kernel image) and modules (any module files). It builds -these goals by recursively descending into the subdirectories of the -kernel source tree. The list of subdirectories which are visited depends -upon the kernel configuration. - -The top Makefile textually includes an arch Makefile with the name -arch/$(ARCH)/Makefile. The arch Makefile supplies architecture-specific -information to the top Makefile. +(the resident kernel image) and modules (any module files). +It builds these goals by recursively descending into the subdirectories of +the kernel source tree. +The list of subdirectories which are visited depends upon the kernel +configuration. The top Makefile textually includes an arch Makefile +with the name arch/$(ARCH)/Makefile. The arch Makefile supplies +architecture-specific information to the top Makefile. -Each subdirectory has a Makefile which carries out the commands passed -down from above. The subdirectory Makefile uses information from the -.config file to construct various file lists, and then it textually -includes the common rules in Rules.make. - -Rules.make defines rules which are common to all the subdirectory -Makefiles. It has a public interface in the form of certain variable -lists. It then declares rules based on those lists. +Each subdirectory has a kbuild Makefile which carries out the commands +passed down from above. The kbuild Makefile uses information from the +.config file to construct various file lists used by kbuild to build +any built-in or modular targets. +scripts/Makefile.* contains all the definitions/rules etc. that +are used to build the kernel based on the kbuild makefiles. === 2 Who does what @@ -76,19 +78,19 @@ lists. It then declares rules based on those lists. People have four different relationships with the kernel Makefiles. *Users* are people who build kernels. These people type commands such as -"make menuconfig" or "make bzImage". They usually do not read or edit +"make menuconfig" or "make". They usually do not read or edit any kernel Makefiles (or any other source files). *Normal developers* are people who work on features such as device drivers, file systems, and network protocols. These people need to -maintain the subdirectory Makefiles for the subsystem that they are +maintain the kbuild Makefiles for the subsystem that they are working on. In order to do this effectively, they need some overall knowledge about the kernel Makefiles, plus detailed knowledge about the -public interface for Rules.make. +public interface for kbuild. *Arch developers* are people who work on an entire architecture, such -as sparc or ia64. Arch developers need to know about the arch Makefiles -as well as subdirectory Makefiles. +as sparc or ia64. Arch developers need to know about the arch Makefile +as well as kbuild Makefiles. *Kbuild developers* are people who work on the kernel build system itself. These people need to know about all aspects of the kernel Makefiles. @@ -96,883 +98,895 @@ These people need to know about all aspects of the kernel Makefiles. This document is aimed towards normal developers and arch developers. +=== 3 The kbuild Makefiles -=== 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. - -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 -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 -time the left-hand side is used. - -There are some cases where "=" is appropriate. Usually, though, ":=" -is the right choice. - -All of the examples in this document were drawn from actual kernel -sources. The examples have been reformatted (white space changed, lines -split), but are otherwise exactly the same. - - - -=== 4 Variables passed down from the top - -The top Makefile exports the following variables: - - VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION - - These variables define the current kernel version. A few arch - Makefiles actually use these values directly; they should use - $(KERNELRELEASE) instead. - - $(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic - three-part version number, such as "2", "4", and "0". These three - values are always numeric. - - $(EXTRAVERSION) defines an even tinier sublevel for pre-patches - or additional patches. It is usually some non-numeric string - such as "-pre4", and is often blank. - - KERNELRELEASE - - $(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable - for constructing installation directory names or showing in - version strings. Some arch Makefiles use it for this purpose. +Most Makefiles within the kernel are kbuild Makefiles that use the +kbuild infrastructure. This chapter introduce the syntax used in the +kbuild makefiles. - ARCH +Section 3.1 "Goal definitions" is a quick intro, further chapters provide +more details, with real examples. - This variable defines the target architecture, such as "i386", - "arm", or "sparc". Many subdirectory Makefiles test $(ARCH) - to determine which files to compile. +--- 3.1 Goal definitions - By default, the top Makefile sets $(ARCH) to be the same as the - host system system architecture. For a cross build, a user may - override the value of $(ARCH) on the command line: - - make ARCH=m68k ... - - TOPDIR, HPATH - - $(TOPDIR) is the path to the top of the kernel source tree. - Subdirectory Makefiles need this so that they can include - $(TOPDIR)/Rules.make. + Goal definitions are the main part (heart) of the kbuild Makefile. + These lines define the files to be built, any special compilation + options, and any subdirectories to be entered recursively. - $(HPATH) is equal to $(TOPDIR)/include. A few arch Makefiles - need to use this to do special things using include files. - - SUBDIRS - - $(SUBDIRS) is a list of directories which the top Makefile - enters in order to build either vmlinux or modules. The actual - directories in $(SUBDIRS) depend on the kernel configuration. - The top Makefile defines this variable, and the arch Makefile - extends it. - - HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS - LINKFLAGS - - $(HEAD), $(CORE_FILES), $(NETWORKS), $(DRIVERS), and $(LIBS) - specify lists of object files and libraries to be linked into - vmlinux. - - The files in $(HEAD) are linked first in vmlinux. + The most simple kbuild makefile contains one line: - $(LINKFLAGS) specifies the flags to build vmlinux. + Example: + obj-y += foo.o - The top Makefile and the arch Makefile jointly define these - variables. The top Makefile defines $(CORE_FILES), $(NETWORKS), - $(DRIVERS), and $(LIBS). The arch Makefile defines $(HEAD) - and $(LINKFLAGS), and extends $(CORE_FILES) and $(LIBS). + This tell kbuild that there is one object in that directory named + foo.o. foo.o will be build from foo.c or foo.S. - Note: there are more variables here than necessary. $(NETWORKS), - $(DRIVERS), and even $(LIBS) could be subsumed into $(CORE_FILES). + If foo.o shall be built as a module, the variable obj-m is used. + Therefore the following pattern is often used: - CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP - CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS - PERL - GENKSYMS + Example: + obj-$(CONFIG_FOO) += foo.o - These variables specify the commands and flags that Rules.make - uses to build goal files from source files. + $(CONFIG_FOO) evaluates to either y (for built-in) or m (for module). + If CONFIG_FOO is neither y nor m, then the file will not be compiled + nor linked. - $(CFLAGS_KERNEL) contains extra C compiler flags used to compile - resident kernel code. +--- 3.2 Built-in object goals - obj-y - $(MODFLAGS) contains extra C compiler flags used to compile code - for loadable kernel modules. In the future, this flag may be - renamed to the more regular name $(CFLAGS_MODULE). + The kbuild Makefile specifies object files for vmlinux + in the lists $(obj-y). These lists depend on the kernel + configuration. - $(AFLAGS) contains assembler flags. + Kbuild compiles all the $(obj-y) files. It then calls + "$(LD) -r" to merge these files into one built-in.o file. + built-in.o is later linked into vmlinux by the parent Makefile. - $(GENKSYMS) contains the command used to generate kernel symbol - signatures when CONFIG_MODVERSIONS is enabled. The genksyms - command comes from the module-init-tools package. + The order of files in $(obj-y) is significant. Duplicates in + the lists are allowed: the first instance will be linked into + built-in.o and succeeding instances will be ignored. - CROSS_COMPILE + 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. - This variable is a prefix path for other variables such as $(CC), - $(AS), and $(LD). The arch Makefiles sometimes use and set this - variable explicitly. Subdirectory Makefiles don't need to worry - about it. + Example: + #drivers/isdn/i4l/Makefile + # Makefile for the kernel ISDN subsystem and device drivers. + # Each configuration option enables a list of files. + obj-$(CONFIG_ISDN) += isdn.o + obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o - The user may override $(CROSS_COMPILE) on the command line if - desired. +--- 3.3 Loadable module goals - obj-m - HOSTCC, HOSTCFLAGS + $(obj-m) specify object files which are built as loadable + kernel modules. - These variables define the C compiler and C compiler flags to - be used for compiling host side programs. These are separate - variables because the target architecture can be different from - the host architecture. + A module may be built from one source file or several source + files. In the case of one source file, the kbuild makefile + simply adds the file to $(obj-m). - If your Makefile compiles and runs a program that is executed - during the course of building the kernel, then it should use - $(HOSTCC) and $(HOSTCFLAGS). + Example: + #drivers/isdn/i4l/Makefile + obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o - For example, the subdirectory drivers/pci has a helper program - named gen-devlist.c. This program reads a list of PCI ID's and - generates C code in the output files classlist.h and devlist.h. + Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm' - Suppose that a user has an i386 computer and wants to build a - kernel for an ia64 machine. Then the user would use an ia64 - cross-compiler for most of the compilation, but would use a - native i386 host compiler to compile drivers/pci/gen-devlist.c. + 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. - For another example, kbuild helper programs such as - scripts/mkdep.c and scripts/lxdialog/*.c are compiled with - $(HOSTCC) rather than $(CC). + Kbuild needs to know which the parts that you want to build your + module from, so you have to tell it by setting an + $(<module_name>-objs) variable. - ROOT_DEV, SVGA_MODE, RAMDISK + Example: + #drivers/isdn/i4l/Makefile + obj-$(CONFIG_ISDN) += isdn.o + isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o - End users edit these variables to specify certain information - about the configuration of their kernel. These variables - are ancient! They are also specific to the i386 architecture. - They really should be replaced with CONFIG_* options. + In this example, the module name will be isdn.o. Kbuild will + compile the objects listed in $(isdn-objs) and then run + "$(LD) -r" on the list of these files to generate isdn.o. - MAKEBOOT + Kbuild recognises objects used for composite objects by the suffix + -objs, and the suffix -y. This allows the Makefiles to use + the value of a CONFIG_ symbol to determine if an object is part + of a composite object. - This variable is defined and used only inside the main arch - Makefiles. The top Makefile should not export it. + Example: + #fs/ext2/Makefile + obj-$(CONFIG_EXT2_FS) += ext2.o + ext2-y := balloc.o bitmap.o + ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o + + In this example xattr.o is only part of the composite object + ext2.o, if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'. - INSTALL_PATH + Note: Of course, when you are building objects into the kernel, + the syntax above will also work. So, if you have CONFIG_EXT2_FS=y, + kbuild will build an ext2.o file for you out of the individual + parts and then link this into built-in.o, as you would expect. - This variable defines a place for the arch Makefiles to install - the resident kernel image and System.map file. +--- 3.4 Objects which export symbols - export-objs - INSTALL_MOD_PATH, MODLIB + 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. - $(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module - installation. This variable is not defined in the Makefile but - may be passed in by the user if desired. + 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). - $(MODLIB) specifies the directory for module installation. - The top Makefile defines $(MODLIB) to - $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may - override this value on the command line if desired. + Example: + #drivers/isdn/i4l/Makefile + # Objects that export symbols. + export-objs := isdn_common.o - CONFIG_SHELL + since isdn_common.c contains - This variable is private between Makefile and Rules.make. - Arch makefiles and subdirectory Makefiles should never use this. + EXPORT_SYMBOL(register_isdn); - MODVERFILE + which makes the function register_isdn available to + low-level ISDN drivers. + There exist a EXPORT_SYMBOL_GPL() variant with similar functionality, + but more restrictive with what may use that symbol. The requirement + to list the .o file in export-objs is the same. - An internal variable. This doesn't need to be exported, as it - is never used outside of the top Makefile. +--- 3.5 Library file goals - L_TARGET - MAKE, MAKEFILES + Instead of building a built-in.o file, you may also + build an archive which again contains objects listed in $(obj-y). + This is normally not necessary and only used in lib/ and + arch/$(ARCH)/lib directories. + Only the name lib.a is allowed. - Some variables internal to GNU Make. + Example: + #arch/i386/lib/Makefile + L_TARGET := lib.a + obj-y := checksum.o delay.o - $(MAKEFILES) in particular is used to force the arch Makefiles - and subdirectory Makefiles to read $(TOPDIR)/.config without - including it explicitly. (This was an implementational hack - and could be fixed). + This will create a library lib.a based on checksum.o and delay.o. +--- 3.6 Descending down in directories + A Makefile is only responsible for building objects in its own + directory. Files in subdirectories should be taken care of by + Makefiles in these subdirs. The build system will automatically + invoke make recursively in subdirectories, provided you let it know of + them. -=== 5 The structure of an arch Makefile + To do so obj-y and obj-m are used. + ext2 lives in a separate directory, and the Makefile present in fs/ + tells kbuild to descend down using the following assignment. + Example: + #fs/Makefile + obj-$(CONfIG_EXT2_FS) += ext2/ + If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular) + the corresponding obj- variable will be set, and kbuild will descend + down in the ext2 directory. + Kbuild only uses this information to decide that it needs to visit + the directory, it is the Makefile in the subdirectory that + specifies what is modules and what is built-in. ---- 5.1 Architecture-specific variables + It is good practice to use a CONFIG_ variable when assigning directory + names. This allows kbuild to totally skip the directory if the + corresponding CONFIG_ option is neither 'y' nor 'm'. -The top Makefile includes one arch Makefile file, arch/$(ARCH)/Makefile. -This section describes the functions of the arch Makefile. +--- 3.7 Compilation flags -An arch Makefile extends some of the top Makefile's variables with -architecture-specific values. + EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS - SUBDIRS + All the EXTRA_ variables apply only to the kbuild makefile + where they are assigned. The EXTRA_ variables apply to all + commands executed in the kbuild makefile. - The top Makefile defines $(SUBDIRS). The arch Makefile extends - $(SUBDIRS) with a list of architecture-specific directories. + $(EXTRA_CFLAGS) specifies options for compiling C files with + $(CC). Example: - - # arch/alpha/Makefile - - SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm \ - arch/alpha/lib arch/alpha/math-emu - - This list may depend on the configuration: - - # arch/arm/Makefile - - ifeq ($(CONFIG_ARCH_ACORN),y) - SUBDIRS += drivers/acorn - ... + # drivers/sound/emu10k1/Makefile + EXTRA_CFLAGS += -I$(obj) + ifdef DEBUG + EXTRA_CFLAGS += -DEMU10K1_DEBUG endif - CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP - CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS - - The top Makefile defines these variables, and the arch Makefile - extends them. - Many arch Makefiles dynamically run the target C compiler to - probe supported options: - - # arch/i386/Makefile - - # prevent gcc from keeping the stack 16 byte aligned - CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 \ - -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-mpreferred-stack-boundary=2"; fi) - - And, of course, $(CFLAGS) can depend on the configuration: - - # arch/i386/Makefile - - ifdef CONFIG_M386 - CFLAGS += -march=i386 - endif + This variable is necessary because the top Makefile owns the + variable $(CFLAGS) and uses it for compilation flags for the + entire tree. - ifdef CONFIG_M486 - CFLAGS += -march=i486 - endif + $(EXTRA_AFLAGS) is a similar string for per-directory options + when compiling assembly language source. - ifdef CONFIG_M586 - CFLAGS += -march=i586 - endif + Example: + #arch/x86_64/kernel/Makefile + EXTRA_AFLAGS := -traditional - Some arch Makefiles redefine the compilation commands in order - to add architecture-specific flags: - # arch/s390/Makefile + $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for + per-directory options to $(LD) and $(AR). - LD=$(CROSS_COMPILE)ld -m elf_s390 - OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S + Example: + #arch/m68k/fpsp040/Makefile + EXTRA_LDFLAGS := -x + CFLAGS_$@, AFLAGS_$@ + CFLAGS_$@ and AFLAGS_$@ only apply to commands in current + kbuild makefile. ---- 5.2 Vmlinux build variables + $(CFLAGS_$@) specifies per-file options for $(CC). The $@ + part has a literal value which specifies the file that it is for. -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. + Example: + # drivers/scsi/Makefile + CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF + CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ + -DGDTH_STATISTICS + CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM - HEAD, CORE_FILES, LIBS - LINKFLAGS + These three lines specify compilation flags for aha152x.o, + gdth.o, and seagate.o - The top Makefile defines the architecture-independent core of - thse variables, and the arch Makefile extends them. Note that the - arch Makefile defines (not just extends) $(HEAD) and $(LINKFLAGS). + $(AFLAGS_$@) is a similar feature for source files in assembly + languages. Example: + # arch/arm/kernel/Makefile + AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional + AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional - # arch/m68k/Makefile +--- 3.9 Dependency tracking - ifndef CONFIG_SUN3 - LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux.lds - else - LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux-sun3.lds -N - endif + Kbuild track dependencies on the following: + 1) All prerequisite files (both *.c and *.h) + 2) CONFIG_ options used in all prerequisite files + 3) Command-line used to compile target - ... + Thus, if you change an option to $(CC) all affected files will + be re-compiled. - ifndef CONFIG_SUN3 - HEAD := arch/m68k/kernel/head.o - else - HEAD := arch/m68k/kernel/sun3-head.o - endif +--- 3.10 Special Rules - SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib - CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES) - LIBS += arch/m68k/lib/lib.a + Special rules are used when the kbuild infrastructure does + not provide the required support. A typical example is + header files generated during the build process. + Another example is the architecture specific Makefiles which + needs special rules to prepare boot images etc. + Special rules are written as normal Make rules. + Kbuild is not executing in the directory where the Makefile is + located, so all special rules shall provide a relative + path to prerequisite files and target files. + Two variables are used when defining special rules: ---- 5.3 Post-vmlinux goals + $(src) + $(src) is a relative path which points to the directory + where the Makefile is located. Always use $(src) when + referring to files located in the src tree. -An arch Makefile specifies goals that take the vmlinux file, compress -it, wrap it in bootstrapping code, and copy the resulting files somewhere. -This includes various kinds of installation commands. + $(obj) + $(obj) is a relative path which points to the directory + where the target is saved. Always use $(obj) when + referring to generated files. -These post-vmlinux goals are not standardized across different -architectures. Here is a list of these goals and the architectures -that support each of them (as of kernel version 2.4.0-test6-pre5): + Example: + #drivers/scsi/Makefile + $(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl + $(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl - balo mips - bootimage alpha - bootpfile alpha, ia64 - bzImage i386, m68k - bzdisk i386 - bzlilo i386 - compressed i386, m68k, mips, mips64, sh - dasdfmt s390 - Image arm - image s390 - install arm, i386 - lilo m68k - msb alpha, ia64 - my-special-boot alpha, ia64 - orionboot mips - rawboot alpha - silo s390 - srmboot alpha - tftpboot.img sparc, sparc64 - vmlinux.64 mips64 - vmlinux.aout sparc64 - zImage arm, i386, m68k, mips, mips64, ppc, sh - zImage.initrd ppc - zdisk i386, mips, mips64, sh - zinstall arm - zlilo i386 - znetboot.initrd ppc + This is a special rule, following the normal syntax + required by make. + The target file depends on two prerequisite files. References + to the target file are prefixed with $(obj), references + to prerequisites are referenced with $(src) (because they are not + generated files). +=== 4 Host Program support ---- 5.4 Mandatory arch-specific goals +Kbuild supports building executables on the host for use during the +compilation stage. +Two steps are required in order to use a host executable. -An arch Makefile must define the following arch-specific goals. -These goals provide arch-specific actions for the corresponding goals -in the top Makefile: +The first step is to tell kbuild that a host program exists. This is +done utilising the variable host-prog. - archclean clean - archdep dep - archmrproper mrproper +The second step is to add an explicit dependency to the executable. +This can be done in two ways. Either add the dependency in a rule, +or utilise the variable build-targets. +Both possibilities are described in the following. +--- 4.1 Simple Host Program + In some cases there is a need to compile and run a program on the + computer where the build is running. + The following line tells kbuild that the program bin2hex shall be + built on the build host. -=== 6 The structure of a subdirectory Makefile + Example: + host-progs := bin2hex -A subdirectory Makefile has four sections. + Kbuild assumes in the above example that bin2hex is made from a single + c-source file named bin2hex.c located in the same directory as + the Makefile. + +--- 4.2 Composite Host Programs + Host programs can be made up based on composite objects. + The syntax used to define composite objetcs for host programs is + similar to the syntax used for kernel objects. + $(<executeable>-objs) list all objects used to link the final + executable. + Example: + #scripts/lxdialog/Makefile + host-progs := lxdialog + lxdialog-objs := checklist.o lxdialog.o + + Objects with extension .o are compiled from the corresponding .c + files. In the above example checklist.c is compiled to checklist.o + and lxdialog.c is compiled to lxdialog.o. + Finally the two .o files are linked to the executable, lxdialog. + Note: The syntax <executable>-y is not permitted for host-programs. + +--- 4.3 Defining shared libraries + + Objects with extension .so are considered shared libraries, and + will be compiled as position independent objects. + Kbuild provides support for shared libraries, but the usage + shall be restricted. + In the following example the libkconfig.so shared library is used + to link the executable conf. ---- 6.1 Comments + Example: + #scripts/kconfig/Makefile + host-progs := conf + conf-objs := conf.o libkconfig.so + libkconfig-objs := expr.o type.o + + Shared libraries always require a corresponding -objs line, and + in the example above the shared library libkconfig is composed by + the two objects expr.o and type.o. + expr.o and type.o will be built as position independent code and + linked as a shared library libkconfig.so. C++ is not supported for + shared libraries. + +--- 4.4 Using C++ for host programs + + kbuild offers support for host programs written in C++. This was + introduced solely to support kconfig, and is not recommended + for general use. -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. + Example: + #scripts/kconfig/Makefile + host-progs := qconf + qconf-cxxobjs := qconf.o + In the example above the executable is composed of the C++ file + qconf.cc - identified by $(qconf-cxxobjs). + + If qconf is composed by a mixture of .c and .cc files, then an + additional line can be used to identify this. + Example: + #scripts/kconfig/Makefile + host-progs := qconf + qconf-cxxobjs := qconf.o + qconf-objs := check.o + +--- 4.5 Controlling compiler options for host programs ---- 6.2 Goal definitions + When compiling host programs, it is possible to set specific flags. + The programs will always be compiled utilising $(HOSTCC) passed + the options specified in $(HOSTCFLAGS). + To set flags that will take effect for all host programs created + in that Makefile use the variable HOST_EXTRACFLAGS. -The second section is a bunch of definitions that are the heart of the -subdirectory Makefile. These lines define the files to be built, any -special compilation options, and any subdirectories to be recursively -entered. The declarations in these lines depend heavily on the kernel -configuration variables (CONFIG_* symbols). + Example: + #scripts/lxdialog/Makefile + HOST_EXTRACFLAGS += -I/usr/include/ncurses + + To set specific flags for a single file the following construction + is used: -The second section looks like this: + Example: + #arch/ppc64/boot/Makefile + HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE) + + It is also possible to specify additional options to the linker. + + Example: + #scripts/kconfig/Makefile + HOSTLOADLIBES_qconf := -L$(QTDIR)/lib - # drivers/block/Makefile - obj-$(CONFIG_MAC_FLOPPY) += swim3.o - obj-$(CONFIG_BLK_DEV_FD) += floppy.o - obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o - obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o + When linking qconf it will be passed the extra option "-L$(QTDIR)/lib". + +--- 4.6 When host programs are actually built + Kbuild will only build host-programs when they are referenced + as a prerequisite. + This is possible in two ways: ---- 6.4 Rules.make section + (1) List the prerequisite explicitly in a special rule. -The third section is the single line: + Example: + #drivers/pci/Makefile + host-progs := gen-devlist + $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist + ( cd $(obj); ./gen-devlist ) < $< - include $(TOPDIR)/Rules.make + The target $(obj)/devlist.h will not be built before + $(obj)/gen-devlist is updated. Note that references to + the host programs in special rules must be prefixed with $(obj). + (2) Use $(build-targets) + When there is no suitable special rule, and the host program + shall be built when a makefile is entered, the $(build-targets) + variable shall be used. + Example: + #scripts/lxdialog/Makefile + host-progs := lxdialog + build-targets := $(host-progs) ---- 6.5 Special rules + This will tell kbuild to build lxdialog even if not referenced in + any rule. -The fourth section contains any special Makefile rules needed that are -not available through the common rules in Rules.make. +=== 5 Kbuild clean infrastructure +"make clean" deletes most generated files in the src tree where the kernel +is compiled. This includes generated files such as host programs. +Kbuild knows targets listed in $(host-progs) and $(EXTRA_TARGETS) and +they are all deleted during "make clean". +Files matching the patterns "*.[oas]", "*.ko", plus some additional files +generated by kbuild are deleted all over the kernel src tree when +"make clean" is executed. +Additional files can be specified by means of $(clean-files). -=== 7 Rules.make variables + Example: + #drivers/pci/Makefile + clean-files := devlist.h classlist.h -The public interface of Rules.make consists of the following variables: +When executing "make clean", the two files "devlist.h classlist.h" will +be deleted. Kbuild knows that files specified by $(clean-files) are +located in the same directory as the makefile. +Usually kbuild descends down in subdirectories due to "obj-* := dir/", +but in the architecture makefiles where the kbuild infrastructure +is not sufficent this sometimes needs to be explicit. + Example: + #arch/i386/boot/Makefile + subdir- := compressed/ ---- 7.1 Subdirectories +The above assignment instructs kbuild to descend down in the +directory compressed/ when "make clean" is executed. -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. +To support the clean infrastructure in the Makefiles that builds the +final bootimage there is an optional target named archclean: -To do so, use the subdir-{y,m,n,} variables: + Example: + #arch/i386/Makefile + archclean: + $(Q)$(MAKE) $(clean)=arch/i386/boot + +When "make clean" is executed, make will descend down in arch/i386/boot, +and clean as usual. The Makefile located in arch/i386/boot/ may use +the subdir- trick to descend further down. + +Note 1: arch/$(ARCH)/Makefile cannot use "subdir-", because that file is +included in the top level makefile, and the kbuild infrastructure +is not operational at that point. + +Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will +be visited during "make clean". + +=== 6 Architecture Makefiles + +The top level Makefile sets up the environment and does the preparation, +before starting to descend down in the individual directories. +The top level makefile contains the generic part, whereas the +arch/$(ARCH)/Makefile contains what is required to set-up kbuild +to the said architecture. +To do so arch/$(ARCH)/Makefile sets a number of variables, and defines +a few targets. + +When kbuild executes the following steps are followed (roughly): +1) Configuration of the kernel => produced .config +2) Store kernel version in include/linux/version.h +3) Symlink include/asm to include/asm-$(ARCH) +4) Updating all other prerequisites to the target prepare: + - Additional prerequisites are specified in arch/$(ARCH)/Makefile +5) Recursively descend down in all directories listed in + init-* core* drivers-* net-* libs-* and build all targets. + - The value of the above variables are extended in arch/$(ARCH)/Makefile. +6) All object files are then linked and the resulting file vmlinux is + located at the root of the src tree. + The very first objects linked are listed in head-y, assigned by + arch/$(ARCH)/Makefile. +7) Finally the architecture specific part does any required post processing + and builds the final bootimage. + - This includes building boot records + - Preparing initrd images and the like + + +--- 6.1 Set variables to tweak the build to the architecture + + LDFLAGS Generic $(LD) options + + Flags used for all invocations of the linker. + Often specifying the emulation is sufficient. - subdir-$(CONFIG_ISDN) += i4l - subdir-$(CONFIG_ISDN_CAPI) += capi + Example: + #arch/s390/Makefile + LDFLAGS := -m elf_s390 + Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise + the flags used. See chapter 7. + + LDFLAGS_MODULE Options for $(LD) when linking modules -When building the actual kernel, i.e. vmlinux ("make -{vmlinux,bzImage,...}"), make will recursively descend into -directories listed in $(subdir-y). + LDFLAGS_MODULE is used to set specific flags for $(LD) when + linking the .ko files used for modules. + Default is "-r", for relocatable output. -When building modules ("make modules"), make will recursively descend -into directories listed in $(subdir-m). + LDFLAGS_vmlinux Options for $(LD) when linking vmlinux -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-). + LDFLAGS_vmlinux is used to specify additional flags to pass to + the linker when linking the final vmlinux. + LDFLAGS_vmlinux uses the LDFLAGS_$@ support. -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. + Example: + #arch/i386/Makefile + LDFLAGS_vmlinux := -e stext -For example, drivers/isdn/capi/Makefile has + LDFLAGS_BLOB Options for $(LD) when linking the initramfs blob - obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o capiutil.o - obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o + The image used for initramfs is made during the build process. + LDFLAGS_BLOB is used to specify additional flags to be used when + creating the initramfs_data.o file. + Example: + #arch/i386/Makefile + LDFLAGS_BLOB := --format binary --oformat elf32-i386 -where it's possible that CONFIG_ISDN_CAPI=y, but -CONFIG_ISDN_CAPI_CAPI20=m. + OBJCOPYFLAGS objcopy flags -This is expressed by the following construct in the parent Makefile -drivers/isdn/Makefile: + When $(call if_changed,objcopy) is used to translate a .o file, + then the flags specified in OBJCOPYFLAGS will be used. + $(call if_changed,objcopy) is often used to generate raw binaries on + vmlinux. - mod-subdirs := i4l hisax capi eicon - subdir-$(CONFIG_ISDN_CAPI) += capi + Example: + #arch/s390/Makefile + OBJCOPYFLAGS := -O binary -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). + #arch/s390/boot/Makefile + $(obj)/image: vmlinux FORCE + $(call if_changed,objcopy) + In this example the binary $(obj)/image is a binary version of + vmlinux. The usage of $(call if_changed,xxx) will be described later. ---- 7.2 Object file goals + AFLAGS $(AS) assembler flags - O_TARGET, obj-y + Default value - see top level Makefile + Append or modify as required per architecture. - The subdirectory Makefile specifies object files for vmlinux - in the lists $(obj-y). These lists depend on the kernel - configuration. + Example: + #arch/sparc64/Makefile + AFLAGS += -m64 -mcpu=ultrasparc - 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. + CFLAGS $(CC) compiler flags - 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. + Default value - see top level Makefile + Append or modify as required per architecture. - 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. + Often the CFLAGS variable depends on the configuration. Example: + #arch/i386/Makefile + cflags-$(CONFIG_M386) += -march=i386 + CFLAGS += $(cflags-y) - # Makefile for the kernel ISDN subsystem and device drivers. + Many arch Makefiles dynamically run the target C compiler to + probe supported options: - # The target object and module list name. + #arch/i386/Makefile + check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc \ + /dev/null\ > /dev/null 2>&1; then echo "$(1)"; \ + else echo "$(2)"; fi) + cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,\ + -march=c3,-march=i486) - O_TARGET := vmlinux-obj.o + CFLAGS += $(cflags-y) - # Each configuration option enables a list of files. + The above examples both utilise the trick that a config option expands + to 'y' when selected. - obj-$(CONFIG_ISDN) += isdn.o - obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o + CFLAGS_KERNEL $(CC) options specific for built-in - # The global Rules.make. + $(CFLAGS_KERNEL) contains extra C compiler flags used to compile + resident kernel code. - include $(TOPDIR)/Rules.make + CFLAGS_MODULE $(CC) options specific for modules ---- 7.3 Library file goals + $(CFLAGS_MODULE) contains extra C compiler flags used to compile code + for loadable kernel modules. - L_TARGET + +--- 6.2 Add prerequisites to prepare: - 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. + The prepare: rule is used to list prerequisites that needs to be + built before starting to descend down in the subdirectories. + This is usual header files containing assembler constants. + Example: + #arch/s390/Makefile + prepare: include/asm-$(ARCH)/offsets.h ---- 7.4 Loadable module goals + In this example the file include/asm-$(ARCH)/offsets.h will + be built before descending down in the subdirectories. + See also chapter XXX-TODO that describe how kbuild supports + generating offset header files. - obj-m - $(obj-m) specify object files which are built as loadable - kernel modules. +--- 6.3 List directories to visit when descending - 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 $(obj-m) + 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. - Example: + + head-y, init-y, core-y, libs-y, drivers-y, net-y - obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o + $(head-y) list objects to be linked first in vmlinux. + $(libs-y) list directories where a libs.a archive can be located. + The rest list directories where a built-in.o object file can be located. - 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. + $(init-y) objects will be located after $(head-y). + Then the rest follows in this order: + $(core-y), $(libs-y), $(drivers-y) and $(net-y). - 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. + The top level Makefile define values for all generic directories, + and arch/$(ARCH)/Makefile only adds architecture specific directories. Example: + #arch/sparc64/Makefile + core-y += arch/sparc64/kernel/ + libs-y += arch/sparc64/prom/ arch/sparc64/lib/ + drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ - 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 +--- 6.4 Architecture specific boot images - 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 + An arch Makefile specifies goals that take the vmlinux file, compress + it, wrap it in bootstrapping code, and copy the resulting files + somewhere. This includes various kinds of installation commands. + The actual goals are not standardized across architectures. - export-objs + It is common to locate any additional processing in a boot/ + directory below arch/$(ARCH)/. - 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. + Kbuild does not provide any smart way to support building a + target specified in boot/. Therefore arch/$(ARCH)/Makefile shall + call make manually to build a target in boot/. - 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). + The recommended approach is to include shortcuts in + arch/$(ARCH)/Makefile, and use the full path when calling down + into the arch/$(ARCH)/boot/Makefile. Example: + #arch/i386/Makefile + boot := arch/i386/boot + bzImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - # Objects that export symbols. + "$(Q)$(MAKE) $(build)=<dir>" is the recommended way to invoke + make in a subdirectory. - 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 - - EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS - - $(EXTRA_CFLAGS) specifies options for compiling C files with - $(CC). The options in this variable apply to all $(CC) commands - for files in the current directory. + There are no rules for naming of the architecture specific targets, + but executing "make help" will list all relevant targets. + To support this $(archhelp) must be defined. Example: + #arch/i386/Makefile + define archhelp + echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)' + endef + + When make is executed without arguments, the first goal encountered + will be built. In the top level Makefile the first goal present + is all:. + An architecture shall always per default build a bootable image. + In "make help" the default goal is highlighted with a '*'. + Add a new prerequisite to all: to select a default goal different + from vmlinux. - # drivers/sound/emu10k1/Makefile - EXTRA_CFLAGS += -I. - ifdef DEBUG - EXTRA_CFLAGS += -DEMU10K1_DEBUG - endif - - $(EXTRA_CFLAGS) does not apply to subdirectories of the current - directory. Also, it does not apply to files compiled with - $(HOSTCC). + Example: + #arch/i386/Makefile + all: bzImage - This variable is necessary because the top Makefile owns the - variable $(CFLAGS) and uses it for compilation flags for the - entire tree. + When "make" is executed without arguments, bzImage will be built. - $(EXTRA_AFLAGS) is a similar string for per-directory options - when compiling assembly language source. +--- 6.5 Building non-kbuild targets - Example: at the time of writing, there were no examples of - $(EXTRA_AFLAGS) in the kernel corpus. + EXTRA_TARGETS - $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for - per-directory options to $(LD) and $(AR). + EXTRA_TARGETS specify additional targets created in current + directory, in addition to any targets specified by obj-*. - Example: at the time of writing, there were no examples of - $(EXTRA_LDFLAGS) or $(EXTRA_ARFLAGS) in the kernel corpus. - - CFLAGS_$@, AFLAGS_$@ - - $(CFLAGS_$@) specifies per-file options for $(CC). The $@ - part has a literal value which specifies the file that it's for. + Listing all targets in EXTRA_TARGETS is required for three purposes: + 1) Avoid that the target is linked in as part of built-in.o + 2) Enable kbuild to check changes in command lines + - When $(call if_changed,xxx) is used + 3) kbuild knows what file to delete during "make clean" Example: + #arch/i386/kernel/Makefile + EXTRA_TARGETS := head.o init_task.o - # drivers/scsi/Makefile - CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF - CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ - -DGDTH_STATISTICS - CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM - - These three lines specify compilation flags for aha152x.o, - gdth.o, and seagate.o - - $(AFLAGS_$@) is a similar feature for source files in assembly - languages. + In this example EXTRA_TARGETS is used to list object files that + shall be built, but shall not be linked as part of built-in.o. Example: + #arch/i386/boot/Makefile + EXTRA_TARGETS := vmlinux.bin bootsect bootsect.o - # arch/arm/kernel/Makefile - AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional - AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional - - Rules.make has a feature where an object file depends on the - value of $(CFLAGS_$@) that was used to compile it. (It also - depends on the values of $(CFLAGS) and $(EXTRA_CFLAGS)). Thus, - if you change the value of $(CFLAGS_$@) for a file, either by - editing the Makefile or overriding the value some other way, - Rules.make will do the right thing and re-compile your source - file with the new options. - - Note: because of a deficiency in Rules.make, assembly language - files do not have flag dependencies. If you edit $(AFLAGS_$@) - for such a file, you will have to remove the object file in order - to re-build from source. - - LD_RFLAG - - This variable is used, but never defined. It appears to be a - vestige of some abandoned experiment. - - - ---- 7.7 Miscellaneous variables - - IGNORE_FLAGS_OBJS - - $(IGNORE_FLAGS_OBJS) is a list of object files which will not have - their flag dependencies automatically tracked. This is a hackish - feature, used to kludge around a problem in the implementation - of flag dependencies. (The problem is that flag dependencies - assume that a %.o file is built from a matching %.S or %.c file. - This is sometimes not true). - - USE_STANDARD_AS_RULE - - This is a transition variable. If $(USE_STANDARD_AS_RULE) - is defined, then Rules.make will provide standard rules for - assembling %.S files into %.o files or %.s files (%.s files - are useful only to developers). - - If $(USE_STANDARD_AS_RULE) is not defined, then Rules.make - will not provide these standard rules. In this case, the - subdirectory Makefile must provide its own private rules for - assembling %.S files. - - In the past, all Makefiles provided private %.S rules. Newer - Makefiles should define USE_STANDARD_AS_RULE and use the standard - Rules.make rules. As soon as all the Makefiles across all - architectures have been converted to USE_STANDARD_AS_RULE, then - Rules.make can drop the conditional test on USE_STANDARD_AS_RULE. - After that, all the other Makefiles can drop the definition of - USE_STANDARD_AS_RULE. - - - -=== 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 -subdirectory Makefiles will convert to the new style. + In this example EXTRA_TARGETS is used to list all intermediate + targets, and all final targets. + The targets are added to EXTRA_TARGETS to enable 2) and 3) above. + +--- 6.6 Commands useful for building a boot image -Rules.make does not understand new-style variables. Thus, each new-style -Makefile has a section of boilerplate code that converts the new-style -variables into old-style variables. There is also some mixing, where -people define most variables using "new style" but then fall back to -"old style" for a few lines. + Kbuild provide a few macros that are useful when building a + boot image. ---- 8.1 New variables + if_changed - obj-y obj-m obj-n obj- + if_changed is the infrastructure used for the following commands. - These variables replace $(O_OBJS), $(OX_OBJS), $(M_OBJS), - and $(MX_OBJS). + Usage: + target: source(s) FORCE + $(call if_changed,ld/objcopy/gzip) - Example: + When the rule is evaluated it is checked to see if any files + needs an update, or the commandline has changed since last + invocation. The latter will force a rebuild if any options + to the executable have changed. + Any target that utilises if_changed must be listed in EXTRA_TARGETS, + otherwise the command line check will fail, and the target will + always be built. + if_changed may be used in conjunction with custom commands as + defined in 6.7 "Custom kbuild commands". + Note: It is a typical mistake to forget the FORCE prerequisite. - # drivers/block/Makefile - obj-$(CONFIG_MAC_FLOPPY) += swim3.o - obj-$(CONFIG_BLK_DEV_FD) += floppy.o - obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o - obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o + ld + Link target. Often LDFLAGS_$@ is used to set specific options to ld. + + objcopy + Copy binary. Uses OBJCOPYFLAGS usually specified in + arch/$(ARCH)/Makefile. - Notice the use of $(CONFIG_...) substitutions on the left hand - 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. + gzip + Compress target. Use maximum compression to compress target. - After executing all of the assignments, the subdirectory - Makefile has built up four lists: $(obj-y), $(obj-m), $(obj-n), - and $(obj-). - $(obj-y) is a list of files to include in vmlinux. - $(obj-m) is a list of files to build as single-file modules. - $(obj-n) and $(obj-) are ignored. +--- 6.7 Custom kbuild commands - Each list may contain duplicates items; duplicates are - automatically removed later. Duplicates in both $(obj-y) and - $(obj-m) will automatically be removed from the $(obj-m) list. + When kbuild is executing with KBUILD_VERBOSE=0 then only a shorthand + of a command is normally displayed. + To enable this behaviour for custom commands kbuild requires + two variables to be set: + quiet_cmd_<command> - what shall be echoed + cmd_<command> - the command to execute Example: + # + quiet_cmd_image = BUILD $@ + cmd_image = $(obj)/tools/build $(BUILDFLAGS) \ + $(obj)/vmlinux.bin > $@ - # drivers/net/Makefile - - ... - obj-$(CONFIG_OAKNET) += oaknet.o 8390.o - ... - obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o - ... - obj-$(CONFIG_STNIC) += stnic.o 8390.o - ... - obj-$(CONFIG_MAC8390) += daynaport.o 8390.o - ... - - In this example, four different drivers require the code in - 8390.o. If one or more of these four drivers are built into - vmlinux, then 8390.o will also be built into vmlinux, and will - *not* be built as a module -- even if another driver which needs - 8390.o is built as a module. (The modular driver is able to - use services of the 8390.o code in the resident vmlinux image). - - export-objs - - $(export-objs) is a list of all the files in the subdirectory - which potentially export symbols. The canonical way to construct - this list is: - - grep -l EXPORT_SYMBOL *.c + $(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE + $(call if_changed,image) + @echo 'Kernel: $@ is ready' - (but watch out for sneaky files that call EXPORT_SYMBOL from an - included header file!) + When updating the $(obj)/bzImage target the line: - This is a potential list, independent of the kernel configuration. - All files that export symbols go into $(export-objs). The - boilerplate code then uses the $(export-objs) list to separate - the real file lists into $(*_OBJS) and $(*X_OBJS). + BUILD arch/i386/boot/bzImage - Experience has shown that maintaining the proper X's in an - old-style Makefile is difficult and error-prone. Maintaining the - $(export-objs) list in a new-style Makefile is simpler and easier - to audit. + will be displayed with "make KBUILD_VERBOSE=0". + - $(foo)-objs +=== 7 Kbuild Variables - Some kernel modules are composed of multiple object files linked - together. +The top Makefile exports the following variables: - 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. + VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION - Example: + These variables define the current kernel version. A few arch + Makefiles actually use these values directly; they should use + $(KERNELRELEASE) instead. - # drivers/scsi/Makefile - list-multi := scsi_mod.o sr_mod.o initio.o a100u2w.o + $(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic + three-part version number, such as "2", "4", and "0". These three + values are always numeric. - ... + $(EXTRAVERSION) defines an even tinier sublevel for pre-patches + or additional patches. It is usually some non-numeric string + such as "-pre4", and is often blank. - scsi_mod-objs := hosts.o scsi.o scsi_ioctl.o constants.o \ - scsicam.o scsi_proc.o scsi_error.o \ - scsi_obsolete.o scsi_queue.o scsi_lib.o \ - scsi_merge.o scsi_dma.o scsi_scan.o \ - scsi_syms.o - sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o - initio-objs := ini9100u.o i91uscsi.o - a100u2w-objs := inia100.o i60uscsi.o + KERNELRELEASE - The subdirectory Makefile puts the modules onto obj-* lists in - the usual configuration-dependent way: + $(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable + for constructing installation directory names or showing in + version strings. Some arch Makefiles use it for this purpose. - obj-$(CONFIG_SCSI) += scsi_mod.o - obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o - obj-$(CONFIG_SCSI_INITIO) += initio.o - obj-$(CONFIG_SCSI_INIA100) += a100u2w.o + ARCH - Suppose that CONFIG_SCSI=y. Then vmlinux needs to link in all - 14 components of scsi_mod.o. + This variable defines the target architecture, such as "i386", + "arm", or "sparc". Some kbuild Makefiles test $(ARCH) to + determine which files to compile. - Suppose that CONFIG_BLK_DEV_SR=m. Then the 3 components - of sr_mod.o will be linked together with "$(LD) -r" to make the - kernel module sr_mod.o. + By default, the top Makefile sets $(ARCH) to be the same as the + host system architecture. For a cross build, a user may + override the value of $(ARCH) on the command line: - 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. + make ARCH=m68k ... - subdir-y subdir-m subdir-n subdir- + INSTALL_PATH - These variables replace $(ALL_SUB_DIRS), $(SUB_DIRS) and - $(MOD_SUB_DIRS). + This variable defines a place for the arch Makefiles to install + the resident kernel image and System.map file. + Use this for architecture specific install targets. - Example: + INSTALL_MOD_PATH, MODLIB - # drivers/Makefile - subdir-$(CONFIG_PCI) += pci - subdir-$(CONFIG_PCMCIA) += pcmcia - subdir-$(CONFIG_MTD) += mtd - subdir-$(CONFIG_SBUS) += sbus + $(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module + installation. This variable is not defined in the Makefile but + may be passed in by the user if desired. - These variables work similar to obj-*, but are used for - subdirectories instead of object files. + $(MODLIB) specifies the directory for module installation. + The top Makefile defines $(MODLIB) to + $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may + override this value on the command line if desired. - After executing all assignments, the subdirectory Makefile has - built up four lists: $(subdir-y), $(subdir-m), $(subdir-n), - and $(subdir-). +=== 8 Makefile language - $(subdir-y) is a list of directories that should be entered - for making vmlinux. - $(subdir-m) is a list of directories that should be entered - for making modules. - $(subdir-n) and $(subdir-) are only used for collecting a list - of all subdirectories of this directory. +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. - Each list besides subdir-y may contain duplicates items; duplicates - are automatically removed later. +GNU Make supports elementary list-processing functions. The kernel +Makefiles use a novel style of list building and manipulation with few +"if" statements. - mod-subdirs +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 +time the left-hand side is used. - $(mod-subdirs) is a list of all the subdirectories that should - be added to $(subdir-m), too if they appear in $(subdir-y) +There are some cases where "=" is appropriate. Usually, though, ":=" +is the right choice. - Example: +=== 9 Credits - # fs/Makefile - mod-subdirs := nls +Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net> +Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> +Updates by Sam Ravnborg <sam@ravnborg.org> - This means nls should be added to (subdir-y) and $(subdir-m) if - CONFIG_NFS = y. +=== 10 TODO -=== 9 Credits +- Describe how kbuild support shipped files with _shipped. +- Generating offset header files. +- Add more variables to section 7? -Thanks to the members of the linux-kbuild mailing list for reviewing -drafts of this document, with particular thanks to Peter Samuelson -and Thomas Molina. diff --git a/Documentation/modules.txt b/Documentation/modules.txt index e30516d41121..61f2733d2e56 100644 --- a/Documentation/modules.txt +++ b/Documentation/modules.txt @@ -9,20 +9,13 @@ modules packages aren't aware of some of the newer modular features that the kernel now supports. The current required version is listed in the file linux/Documentation/Changes. -* * * NOTE * * * -The kernel has been changed to remove kerneld support and use -the new kmod support. Keep this in mind when reading this file. Kmod -does the exact same thing as kerneld, but doesn't require an external -program (see Documentation/kmod.txt) - In the beginning... ------------------- Anyway, your first step is to compile the kernel, as explained in the file linux/README. It generally goes like: - make config - make dep + make *config <= usually menuconfig or xconfig make clean make zImage or make zlilo @@ -39,15 +32,16 @@ You will generally select the minimal resident set that is needed to boot: plus those things that you just can't live without... The set of modules is constantly increasing, and you will be able to select -the option "m" in "make config" for those features that the current kernel +the option "m" in "make menuconfig" for those features that the current kernel can offer as loadable modules. You also have a possibility to create modules that are less dependent on -the kernel version. This option can be selected during "make config", by +the kernel version. This option can be selected during "make *config", by enabling CONFIG_MODVERSIONS, and is most useful on "stable" kernel versions, -such as the kernels from the 1.2 and 2.0 series. +such as the kernels from the 2.<even number> series. If you have modules that are based on sources that are not included in the official kernel sources, you will certainly like this option... +See below how to compile modules outside the official kernel. Here is a sample of the available modules included in the kernel sources: @@ -83,22 +77,45 @@ When you have made the kernel, you create the modules by doing: make modules -This will compile all modules and update the linux/modules directory. -In this directory you will then find a bunch of symbolic links, -pointing to the various object files in the kernel tree. +This will compile all modules. A module is identified by the +extension .ko, for kernel object. Now, after you have created all your modules, you should also do: make modules_install This will copy all newly made modules into subdirectories under "/lib/modules/kernel_release/", where "kernel_release" is something -like 2.0.1, or whatever the current kernel version is... +like 2.5.54, or whatever the current kernel version is. +Note: Installing modules may require root privileges. As soon as you have rebooted the newly made kernel, you can install and remove modules at will with the utilities: "insmod" and "rmmod". After reading the man-page for insmod, you will also know how easy it is to configure a module when you do "insmod" (hint: symbol=value). +Installing modules in a non-standard location +--------------------------------------------- +When the modules needs to be installed under another directory +the INSTALL_MOD_PATH can be used to prefix "/lib/modules" as seen +in the following example: + +make INSTALL_MOD_PATH=/frodo modules_install + +This will install the modules in the directory /frodo/lib/modules. +/frodo can be a NFS mounted filesystem on another machine, allowing +out-of-the-box support for installation on remote machines. + + +Compiling modules outside the official kernel +--------------------------------------------- +Often modules are developed outside the official kernel. +To keep up with changes in the build system the most portable way +to compile a module outside the kernel is to use the following command-line: + +make -C path/to/kernel/src SUBDIRS=$PWD modules + +This requires that a makefile exits made in accordance to +Documentation/kbuild/makefiles.txt. Nifty features: --------------- @@ -54,7 +54,7 @@ CROSS_COMPILE = # That's our default target when none is given on the command line -all: vmlinux +all: vmlinux modules # Decide whether to build built-in, modular, or both. # Normally, just do built-in. @@ -183,6 +183,8 @@ export CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE +export MODVERDIR := .tmp_versions + # The temporary file to save gcc -MD generated dependencies must not # contain a comma depfile = $(subst $(comma),_,$(@D)/.$(@F).d) @@ -190,7 +192,7 @@ depfile = $(subst $(comma),_,$(@D)/.$(@F).d) noconfig_targets := xconfig menuconfig config oldconfig randconfig \ defconfig allyesconfig allnoconfig allmodconfig \ clean mrproper distclean \ - help tags TAGS sgmldocs psdocs pdfdocs htmldocs \ + help tags TAGS cscope sgmldocs psdocs pdfdocs htmldocs \ checkconfig checkhelp checkincludes RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o @@ -256,14 +258,22 @@ ifdef include_config -include .config.cmd -ifdef CONFIG_MODULES -export EXPORT_FLAGS := -DEXPORT_SYMTAB -endif - ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are uptodate before we record them. + +ifdef CONFIG_MODVERSIONS +ifeq ($(KBUILD_MODULES),1) +ifneq ($(KBUILD_BUILTIN),1) + KBUILD_BUILTIN := 1 +endif +endif +endif + # # INSTALL_PATH specifies where to place the updated kernel and system map # images. Uncomment if you want to place them anywhere other than root. @@ -289,12 +299,12 @@ export MODLIB # normal descending-into-subdirs phase, since at that time # we cannot yet know if we will need to relink vmlinux. # So we descend into init/ inside the rule for vmlinux again. - -vmlinux-objs := $(HEAD) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) +head-y += $(HEAD) +vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) quiet_cmd_vmlinux__ = LD $@ define cmd_vmlinux__ - $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(HEAD) $(init-y) \ + $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(head-y) $(init-y) \ --start-group \ $(core-y) \ $(libs-y) \ @@ -384,7 +394,7 @@ $(sort $(vmlinux-objs)): $(SUBDIRS) ; # Handle descending into subdirectories listed in $(SUBDIRS) .PHONY: $(SUBDIRS) -$(SUBDIRS): .hdepend prepare +$(SUBDIRS): prepare $(Q)$(MAKE) $(build)=$@ # Things we need done before we descend to build or make @@ -392,6 +402,16 @@ $(SUBDIRS): .hdepend prepare .PHONY: prepare prepare: include/linux/version.h include/asm include/config/MARKER +ifdef CONFIG_MODVERSIONS +ifdef KBUILD_MODULES +ifeq ($(origin SUBDIRS),file) + $(Q)rm -rf $(MODVERDIR) +else + @echo '*** Warning: Overriding SUBDIRS on the command line can cause' + @echo '*** inconsistencies with module symbol versions' +endif +endif +endif @echo ' Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)' # We need to build init/vermagic.o before descending since all modules @@ -424,6 +444,8 @@ targets += arch/$(ARCH)/vmlinux.lds.s $(Q)$(MAKE) $(build)=$(@D) $@ %.o: %.c scripts FORCE $(Q)$(MAKE) $(build)=$(@D) $@ +%/: scripts prepare FORCE + $(Q)$(MAKE) $(build)=$(@D) %.ko: scripts FORCE $(Q)$(MAKE) $(build)=$(@D) $@ %.lst: %.c scripts FORCE @@ -475,61 +497,11 @@ include/linux/version.h: Makefile ) > $@.tmp @$(update-if-changed) -# Generate module versions # --------------------------------------------------------------------------- -# The targets are still named depend / dep for traditional -# reasons, but the only thing we do here is generating -# the module version checksums. - -.PHONY: depend dep $(patsubst %,_sfdep_%,$(SUBDIRS)) - -depend dep: .hdepend - -# .hdepend is our (misnomed) marker for whether we've -# generated module versions - -make-versions := $(strip $(if $(filter dep depend,$(MAKECMDGOALS)),1) \ - $(if $(wildcard .hdepend),,1)) - -.hdepend: prepare FORCE -ifneq ($(make-versions),) - @$(MAKE) include/linux/modversions.h - @touch $@ -endif - -ifdef CONFIG_MODVERSIONS - -# Update modversions.h, but only if it would change. - -.PHONY: __rm_tmp_export-objs -__rm_tmp_export-objs: - @rm -rf .tmp_export-objs - -include/linux/modversions.h: $(patsubst %,_modver_%,$(SUBDIRS)) - @echo -n ' Generating $@' - @( echo "#ifndef _LINUX_MODVERSIONS_H";\ - echo "#define _LINUX_MODVERSIONS_H"; \ - echo "#include <linux/modsetver.h>"; \ - cd .tmp_export-objs >/dev/null; \ - for f in `find modules -name \*.ver -print | sort`; do \ - echo "#include <linux/$${f}>"; \ - done; \ - echo "#endif"; \ - ) > $@.tmp; \ - $(update-if-changed) - -.PHONY: $(patsubst %, _modver_%, $(SUBDIRS)) -$(patsubst %, _modver_%, $(SUBDIRS)): __rm_tmp_export-objs - $(Q)$(MAKE) -f scripts/Makefile.modver obj=$(patsubst _modver_%,%,$@) - -else # !CONFIG_MODVERSIONS - -.PHONY: include/linux/modversions.h - -include/linux/modversions.h: - -endif # CONFIG_MODVERSIONS +.PHONY: depend dep +depend dep: + @echo '*** Warning: make $@ is unnecessary now.' # --------------------------------------------------------------------------- # Modules @@ -538,12 +510,16 @@ ifdef CONFIG_MODULES # Build modules +.PHONY: modules __modversions +modules: $(SUBDIRS) __modversions + ifdef CONFIG_MODVERSIONS -MODFLAGS += -include include/linux/modversions.h -endif -.PHONY: modules -modules: $(SUBDIRS) +__modversions: vmlinux $(SUBDIRS) + @echo ' Recording module symbol versions.'; + $(Q)$(MAKE) -rR -f scripts/Makefile.modver + +endif # Install modules @@ -574,6 +550,7 @@ _modinst_post: .PHONY: $(patsubst %, _modinst_%, $(SUBDIRS)) $(patsubst %, _modinst_%, $(SUBDIRS)) : $(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@) + else # CONFIG_MODULES # Modules not configured @@ -624,7 +601,7 @@ spec: rpm: clean spec find . $(RCS_FIND_IGNORE) \ - \( -size 0 -o -name .depend -o -name .hdepend \) \ + \( -size 0 -o -name .depend -o -name .hdepend\) \ -type f -print | xargs rm -f set -e; \ cd $(TOPDIR)/.. ; \ @@ -718,25 +695,26 @@ MRPROPER_FILES += \ .menuconfig.log \ include/asm \ .hdepend include/linux/modversions.h \ - tags TAGS kernel.spec \ + tags TAGS cscope kernel.spec \ .tmp* # Directories removed with 'make mrproper' MRPROPER_DIRS += \ + $(MODVERDIR) \ .tmp_export-objs \ include/config \ include/linux/modules # clean - Delete all intermediate files # -clean-dirs += $(ALL_SUBDIRS) Documentation/DocBook scripts - -$(addprefix _clean_,$(clean-dirs)): +clean-dirs += $(addprefix _clean_,$(ALL_SUBDIRS) Documentation/DocBook scripts) +.PHONY: $(clean-dirs) clean archclean mrproper archmrproper distclean +$(clean-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) quiet_cmd_rmclean = RM $$(CLEAN_FILES) cmd_rmclean = rm -f $(CLEAN_FILES) -clean: archclean $(addprefix _clean_,$(clean-dirs)) +clean: archclean $(clean-dirs) $(call cmd,rmclean) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ @@ -775,6 +753,9 @@ define all-sources -name '*.[chS]' -print ) endef +quiet_cmd_cscope = MAKE $@ +cmd_cscope = $(all-sources) | cscope -k -b -i - + quiet_cmd_TAGS = MAKE $@ cmd_TAGS = $(all-sources) | etags - @@ -787,6 +768,9 @@ define cmd_tags $(all-sources) | xargs ctags $$CTAGSF -a endef +cscope: FORCE + $(call cmd,cscope) + TAGS: FORCE $(call cmd,TAGS) diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index f8a3ad80f5cc..66049f3804e4 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -458,6 +458,11 @@ config ALPHA_SRM If unsure, say N. +config EARLY_PRINTK + bool + depends on ALPHA_GENERIC || ALPHA_SRM + default y + config ALPHA_EISA bool depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index e7b10749f573..1623dc4162f1 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -90,7 +90,7 @@ endif # BWX is most important, but we don't really want any emulation ever. CFLAGS += $(cflags-y) -Wa,-mev6 -HEAD := arch/alpha/kernel/head.o +head-y := arch/alpha/kernel/head.o core-y += arch/alpha/kernel/ arch/alpha/mm/ core-$(CONFIG_MATHEMU) += arch/alpha/math-emu/ @@ -125,8 +125,6 @@ include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=$(boot) -archmrproper: - CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h.tmp \ include/asm-$(ARCH)/asm_offsets.h diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index ebabe031d418..73ee17261de8 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -6,8 +6,6 @@ EXTRA_TARGETS := head.o EXTRA_AFLAGS := $(CFLAGS) -export-objs := alpha_ksyms.o core_marvel.o core_titan.o - obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \ alpha_ksyms.o systbls.o err_common.o @@ -35,8 +33,13 @@ obj-y += err_titan.o err_marvel.o obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o +obj-y += srmcons.o + else +# Misc support +obj-$(CONFIG_ALPHA_SRM) += srmcons.o + # Core logic support obj-$(CONFIG_ALPHA_APECS) += core_apecs.o obj-$(CONFIG_ALPHA_CIA) += core_cia.o diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 0689cfcca9d3..ec9ed49c79fe 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -40,7 +40,6 @@ extern struct hwrpb_struct *hwrpb; extern void dump_thread(struct pt_regs *, struct user *); -extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); extern spinlock_t rtc_lock; /* these are C runtime functions with special calling conventions: */ @@ -144,7 +143,9 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); #endif EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(dump_elf_thread); +EXPORT_SYMBOL(dump_elf_task); +EXPORT_SYMBOL(dump_elf_task_fp); EXPORT_SYMBOL(hwrpb); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(alpha_read_fp_reg); diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index 1709838729a6..4aabddb49485 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -27,13 +27,11 @@ #include <asm/core_irongate.h> #undef __EXTERN_INLINE +#include <linux/bootmem.h> + #include "proto.h" #include "pci_impl.h" -#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */ - -#define IRONGATE_DEFAULT_AGP_APER_SIZE (256*1024*1024) /* 256MB */ - /* * BIOS32-style PCI interface: */ @@ -46,6 +44,7 @@ # define DBG_CFG(args) #endif +igcsr32 *IronECC; /* * Given a bus, device, and function number, compute resulting @@ -165,143 +164,6 @@ struct pci_ops irongate_pci_ops = .write = irongate_write_config, }; -#ifdef DEBUG_IRONGATE -static void -irongate_register_dump(const char *function_name) -{ - printk("%s: Irongate registers:\n" - "\tFunction 0:\n" - "\tdev_vendor\t0x%08x\n" - "\tstat_cmd\t0x%08x\n" - "\tclass\t\t0x%08x\n" - "\tlatency\t\t0x%08x\n" - "\tbar0\t\t0x%08x\n" - "\tbar1\t\t0x%08x\n" - "\tbar2\t\t0x%08x\n" - "\trsrvd0[0]\t0x%08x\n" - "\trsrvd0[1]\t0x%08x\n" - "\trsrvd0[2]\t0x%08x\n" - "\trsrvd0[3]\t0x%08x\n" - "\trsrvd0[4]\t0x%08x\n" - "\trsrvd0[5]\t0x%08x\n" - "\tcapptr\t\t0x%08x\n" - "\trsrvd1[0]\t0x%08x\n" - "\trsrvd1[1]\t0x%08x\n" - "\tbacsr10\t\t0x%08x\n" - "\tbacsr32\t\t0x%08x\n" - "\tbacsr54\t\t0x%08x\n" - "\trsrvd2[0]\t0x%08x\n" - "\tdrammap\t\t0x%08x\n" - "\tdramtm\t\t0x%08x\n" - "\tdramms\t\t0x%08x\n" - "\trsrvd3[0]\t0x%08x\n" - "\tbiu0\t\t0x%08x\n" - "\tbiusip\t\t0x%08x\n" - "\trsrvd4[0]\t0x%08x\n" - "\trsrvd4[1]\t0x%08x\n" - "\tmro\t\t0x%08x\n" - "\trsrvd5[0]\t0x%08x\n" - "\trsrvd5[1]\t0x%08x\n" - "\trsrvd5[2]\t0x%08x\n" - "\twhami\t\t0x%08x\n" - "\tpciarb\t\t0x%08x\n" - "\tpcicfg\t\t0x%08x\n" - "\trsrvd6[0]\t0x%08x\n" - "\trsrvd6[1]\t0x%08x\n" - "\trsrvd6[2]\t0x%08x\n" - "\trsrvd6[3]\t0x%08x\n" - "\trsrvd6[4]\t0x%08x\n" - "\tagpcap\t\t0x%08x\n" - "\tagpstat\t\t0x%08x\n" - "\tagpcmd\t\t0x%08x\n" - "\tagpva\t\t0x%08x\n" - "\tagpmode\t\t0x%08x\n" - - "\n\tFunction 1:\n" - "\tdev_vendor:\t0x%08x\n" - "\tcmd_status:\t0x%08x\n" - "\trevid_etc :\t0x%08x\n" - "\thtype_etc :\t0x%08x\n" - "\trsrvd0[0] :\t0x%08x\n" - "\trsrvd0[1] :\t0x%08x\n" - "\tbus_nmbers:\t0x%08x\n" - "\tio_baselim:\t0x%08x\n" - "\tmem_bselim:\t0x%08x\n" - "\tpf_baselib:\t0x%08x\n" - "\trsrvd1[0] :\t0x%08x\n" - "\trsrvd1[1] :\t0x%08x\n" - "\tio_baselim:\t0x%08x\n" - "\trsrvd2[0] :\t0x%08x\n" - "\trsrvd2[1] :\t0x%08x\n" - "\tinterrupt :\t0x%08x\n", - - function_name, - IRONGATE0->dev_vendor, - IRONGATE0->stat_cmd, - IRONGATE0->class, - IRONGATE0->latency, - IRONGATE0->bar0, - IRONGATE0->bar1, - IRONGATE0->bar2, - IRONGATE0->rsrvd0[0], - IRONGATE0->rsrvd0[1], - IRONGATE0->rsrvd0[2], - IRONGATE0->rsrvd0[3], - IRONGATE0->rsrvd0[4], - IRONGATE0->rsrvd0[5], - IRONGATE0->capptr, - IRONGATE0->rsrvd1[0], - IRONGATE0->rsrvd1[1], - IRONGATE0->bacsr10, - IRONGATE0->bacsr32, - IRONGATE0->bacsr54, - IRONGATE0->rsrvd2[0], - IRONGATE0->drammap, - IRONGATE0->dramtm, - IRONGATE0->dramms, - IRONGATE0->rsrvd3[0], - IRONGATE0->biu0, - IRONGATE0->biusip, - IRONGATE0->rsrvd4[0], - IRONGATE0->rsrvd4[1], - IRONGATE0->mro, - IRONGATE0->rsrvd5[0], - IRONGATE0->rsrvd5[1], - IRONGATE0->rsrvd5[2], - IRONGATE0->whami, - IRONGATE0->pciarb, - IRONGATE0->pcicfg, - IRONGATE0->rsrvd6[0], - IRONGATE0->rsrvd6[1], - IRONGATE0->rsrvd6[2], - IRONGATE0->rsrvd6[3], - IRONGATE0->rsrvd6[4], - IRONGATE0->agpcap, - IRONGATE0->agpstat, - IRONGATE0->agpcmd, - IRONGATE0->agpva, - IRONGATE0->agpmode, - IRONGATE1->dev_vendor, - IRONGATE1->stat_cmd, - IRONGATE1->class, - IRONGATE1->htype, - IRONGATE1->rsrvd0[0], - IRONGATE1->rsrvd0[1], - IRONGATE1->busnos, - IRONGATE1->io_baselim_regs, - IRONGATE1->mem_baselim, - IRONGATE1->pfmem_baselim, - IRONGATE1->rsrvd1[0], - IRONGATE1->rsrvd1[1], - IRONGATE1->io_baselim, - IRONGATE1->rsrvd2[0], - IRONGATE1->rsrvd2[1], - IRONGATE1->interrupt ); -} -#else -#define irongate_register_dump(x) -#endif - int irongate_pci_clr_err(void) { @@ -315,11 +177,11 @@ again: mb(); IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */ - IRONGATE_jd = IRONGATE0->dramms; - printk("Iron dramms %x\n", IRONGATE_jd); - IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */ + IRONGATE_jd = *IronECC; + printk("Iron ECC %x\n", IRONGATE_jd); + *IronECC = IRONGATE_jd; /* write again clears error bits */ mb(); - IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */ + IRONGATE_jd = *IronECC; /* re-read to force write */ /* Clear ALI NMI */ nmi_ctl = inb(0x61); @@ -328,28 +190,88 @@ again: nmi_ctl &= ~0x0c; outb(nmi_ctl, 0x61); - IRONGATE_jd = IRONGATE0->dramms; + IRONGATE_jd = *IronECC; if (IRONGATE_jd & 0x300) goto again; return 0; } +#define IRONGATE_3GB 0xc0000000UL + +/* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some + memory for PCI. At this point we just reserve memory above 3Gb. Most + of this memory will be freed after PCI setup is done. */ +static void __init +albacore_init_arch(void) +{ + unsigned long memtop = max_low_pfn << PAGE_SHIFT; + unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL; + struct percpu_struct *cpu; + int pal_rev, pal_var; + + cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); + pal_rev = cpu->pal_revision & 0xffff; + pal_var = (cpu->pal_revision >> 16) & 0xff; + + /* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up + the CPU incorrectly (leave speculative stores enabled), + which causes memory corruption under certain conditions. + Issue a warning for such consoles. */ + if (alpha_using_srm && + (pal_rev < 0x13e || (pal_rev == 0x13e && pal_var < 2))) + printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 " + "or later\n"); + + if (pci_mem > IRONGATE_3GB) + pci_mem = IRONGATE_3GB; + IRONGATE0->pci_mem = pci_mem; + alpha_mv.min_mem_address = pci_mem; + if (memtop > pci_mem) { +#ifdef CONFIG_BLK_DEV_INITRD + extern unsigned long initrd_start, initrd_end; + extern void *move_initrd(unsigned long); + + /* Move the initrd out of the way. */ + if (initrd_end && __pa(initrd_end) > pci_mem) { + unsigned long size; + + size = initrd_end - initrd_start; + free_bootmem(__pa(initrd_start), PAGE_ALIGN(size)); + if (!move_initrd(pci_mem)) + printk("irongate_init_arch: initrd too big " + "(%ldK)\ndisabling initrd\n", + size / 1024); + } +#endif + reserve_bootmem(pci_mem, memtop - pci_mem); + printk("irongate_init_arch: temporarily reserving " + "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1); + } +} + +static void __init +irongate_setup_agp(void) +{ + /* Disable the GART window. AGPGART doesn't work due to yet + unresolved memory coherency issues... */ + IRONGATE0->agpva = IRONGATE0->agpva & ~0xf; + alpha_agpgart_size = 0; +} + void __init irongate_init_arch(void) { struct pci_controller *hose; + int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */ + + IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms; - IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100; irongate_pci_clr_err(); - irongate_register_dump(__FUNCTION__); - /* - * HACK: set AGP aperture size to 256MB. - * This should really be changed during PCI probe, when the - * size of the aperture the AGP card wants is known. - */ - printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva); - IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007; + if (amd761) + albacore_init_arch(); + + irongate_setup_agp(); /* * Create our single hose. @@ -380,89 +302,9 @@ irongate_init_arch(void) * IO map and AGP support */ #include <linux/vmalloc.h> -#include <asm/pgalloc.h> - -static inline void -irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - unsigned long pfn; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - pfn = phys_addr >> PAGE_SHIFT; - do { - if (!pte_none(*pte)) { - printk("irongate_remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, pfn_pte(pfn, - __pgprot(_PAGE_VALID | _PAGE_ASM | - _PAGE_KRE | _PAGE_KWE | flags))); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int -irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); - do { - pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); - if (!pte) - return -ENOMEM; - irongate_remap_area_pte(pte, address, end - address, - address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -static int -irongate_remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset(&init_mm, address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); - if (!pmd) - return -ENOMEM; - if (irongate_remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - return -ENOMEM; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - return 0; -} - #include <linux/agp_backend.h> #include <linux/agpgart.h> +#include <asm/pgalloc.h> #define GET_PAGE_DIR_OFF(addr) (addr >> 22) #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr)) @@ -477,15 +319,13 @@ irongate_ioremap(unsigned long addr, unsigned long size) unsigned long vaddr; unsigned long baddr, last; u32 *mmio_regs, *gatt_pages, *cur_gatt, pte; - unsigned long gart_bus_addr, gart_aper_size; + unsigned long gart_bus_addr; - gart_bus_addr = (unsigned long)IRONGATE0->bar0 & - PCI_BASE_ADDRESS_MEM_MASK; - - if (!gart_bus_addr) /* FIXME - there must be a better way!!! */ + if (!alpha_agpgart_size) return addr + IRONGATE_MEM; - gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */ + gart_bus_addr = (unsigned long)IRONGATE0->bar0 & + PCI_BASE_ADDRESS_MEM_MASK; /* * Check for within the AGP aperture... @@ -495,7 +335,7 @@ irongate_ioremap(unsigned long addr, unsigned long size) * Check the AGP area */ if (addr >= gart_bus_addr && addr + size - 1 < - gart_bus_addr + gart_aper_size) + gart_bus_addr + alpha_agpgart_size) break; /* @@ -549,8 +389,8 @@ irongate_ioremap(unsigned long addr, unsigned long size) cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1); pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1; - if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr), - pte, PAGE_SIZE, 0)) { + if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), + pte, PAGE_SIZE, 0)) { printk("AGP ioremap: FAILED to map...\n"); vfree(area->addr); return (unsigned long)NULL; diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 075ed7631122..0ecfee1a2ddd 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -732,21 +732,6 @@ marvel_iounmap(unsigned long addr) EXPORT_SYMBOL(marvel_ioremap); EXPORT_SYMBOL(marvel_iounmap); #endif - -/* - * SRMCons support - * - * Marvel doesn't have a real serial console -- it's either graphics or - * server management based. If we're running on the server management based - * console, allow the srmcons callback driver to be a console device. - */ -int -marvel_srmcons_allowed(void) -{ - u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); - - return (pu64[7] == 2); -} /* @@ -874,8 +859,6 @@ marvel_node_mem_size(int nid) #include <linux/slab.h> #include <linux/delay.h> -#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024) - struct marvel_agp_aperture { struct pci_iommu_arena *arena; long pg_start; @@ -887,11 +870,14 @@ marvel_agp_setup(alpha_agp_info *agp) { struct marvel_agp_aperture *aper; + if (!alpha_agpgart_size) + return -ENOMEM; + aper = kmalloc(sizeof(*aper), GFP_KERNEL); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; - aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_count = alpha_agpgart_size / PAGE_SIZE; aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, aper->pg_count - 1); diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index d5619bbc4add..f16036455fa9 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -580,8 +580,6 @@ EXPORT_SYMBOL(titan_iounmap); #include <linux/slab.h> #include <linux/delay.h> -#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024) - struct titan_agp_aperture { struct pci_iommu_arena *arena; long pg_start; @@ -593,12 +591,15 @@ titan_agp_setup(alpha_agp_info *agp) { struct titan_agp_aperture *aper; + if (!alpha_agpgart_size) + return -ENOMEM; + aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; - aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_count = alpha_agpgart_size / PAGE_SIZE; aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, aper->pg_count - 1); if (aper->pg_start < 0) { diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index cd9d6454c6d2..b10ae89943dd 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -534,7 +534,7 @@ show_interrupts(struct seq_file *p, void *v) #else for (j = 0; j < NR_CPUS; j++) if (cpu_online(j)) - seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]); + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %c%s", diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index eadf77848709..68448627b226 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -71,6 +71,8 @@ struct pci_iommu_arena; #define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024) +#define DEFAULT_AGP_APER_SIZE (64*1024*1024) + /* * A small note about bridges and interrupts. The DECchip 21050 (and * later) adheres to the PCI-PCI bridge specification. This says that @@ -153,6 +155,8 @@ extern struct pci_controller *pci_isa_hose; /* Indicate that we trust the console to configure things properly. */ extern int pci_probe_only; +extern unsigned long alpha_agpgart_size; + extern void common_init_pci(void); extern u8 common_swizzle(struct pci_dev *, u8 *); extern struct pci_controller *alloc_pci_controller(void); diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 196a016657ed..85b45eee2868 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -313,7 +313,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, } /* - * fill in the user structure for a core dump.. + * Fill in the user structure for an ECOFF core dump. */ void dump_thread(struct pt_regs * pt, struct user * dump) @@ -373,12 +373,81 @@ dump_thread(struct pt_regs * pt, struct user * dump) memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8); } -int -dump_fpu(struct pt_regs * regs, elf_fpregset_t *r) +/* + * Fill in the user structure for a ELF core dump. + */ +void +dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) { /* switch stack follows right below pt_regs: */ - struct switch_stack * sw = ((struct switch_stack *) regs) - 1; - memcpy(r, sw->fp, 32 * 8); + struct switch_stack * sw = ((struct switch_stack *) pt) - 1; + + dest[ 0] = pt->r0; + dest[ 1] = pt->r1; + dest[ 2] = pt->r2; + dest[ 3] = pt->r3; + dest[ 4] = pt->r4; + dest[ 5] = pt->r5; + dest[ 6] = pt->r6; + dest[ 7] = pt->r7; + dest[ 8] = pt->r8; + dest[ 9] = sw->r9; + dest[10] = sw->r10; + dest[11] = sw->r11; + dest[12] = sw->r12; + dest[13] = sw->r13; + dest[14] = sw->r14; + dest[15] = sw->r15; + dest[16] = pt->r16; + dest[17] = pt->r17; + dest[18] = pt->r18; + dest[19] = pt->r19; + dest[20] = pt->r20; + dest[21] = pt->r21; + dest[22] = pt->r22; + dest[23] = pt->r23; + dest[24] = pt->r24; + dest[25] = pt->r25; + dest[26] = pt->r26; + dest[27] = pt->r27; + dest[28] = pt->r28; + dest[29] = pt->gp; + dest[30] = rdusp(); + dest[31] = pt->pc; + + /* Once upon a time this was the PS value. Which is stupid + since that is always 8 for usermode. Usurped for the more + useful value of the thread's UNIQUE field. */ + dest[32] = ti->pcb.unique; +} + +int +dump_elf_task(elf_greg_t *dest, struct task_struct *task) +{ + struct thread_info *ti; + struct pt_regs *pt; + + ti = task->thread_info; + pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; + + dump_elf_thread(dest, pt, ti); + + return 1; +} + +int +dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) +{ + struct thread_info *ti; + struct pt_regs *pt; + struct switch_stack *sw; + + ti = task->thread_info; + pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; + sw = (struct switch_stack *)pt - 1; + + memcpy(dest, sw->fp, 32 * 8); + return 1; } diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index bb0adcbcb317..d67cf07ffdec 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -53,7 +53,6 @@ extern int marvel_pa_to_nid(unsigned long); extern int marvel_cpuid_to_nid(int); extern unsigned long marvel_node_mem_start(int); extern unsigned long marvel_node_mem_size(int); -extern int marvel_srmcons_allowed(void); extern struct _alpha_agp_info *marvel_agp_info(void); struct io7 *marvel_find_io7(int pe); struct io7 *marvel_next_io7(struct io7 *prev); @@ -109,9 +108,15 @@ extern unsigned long wildfire_node_mem_size(int); /* setup.c */ extern unsigned long srm_hae; extern int boot_cpuid; -extern int srmcons_output; + +/* srmcons.c */ +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) extern void register_srm_console(void); extern void unregister_srm_console(void); +#else +#define register_srm_console() +#define unregister_srm_console() +#endif /* smp.c */ extern void setup_smp(void); diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index dbc762fd43e3..496e1355a057 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -102,7 +102,9 @@ get_reg_addr(struct task_struct * task, unsigned long regno) if (regno == 30) { addr = &task->thread_info->pcb.usp; - } else if (regno == 31 || regno > 64) { + } else if (regno == 65) { + addr = &task->thread_info->pcb.unique; + } else if (regno == 31 || regno > 65) { zero = 0; addr = &zero; } else { diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index e8719e356065..ededddb6551c 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -77,18 +77,25 @@ int boot_cpuid; * "srmcons" specified in the boot command arguments allows us to * see kernel messages during the period of time before the true - * console device is "registered" during console_init(). As of this - * version (2.4.10), time_init() is the last Alpha-specific code - * called before console_init(), so we put "unregister" code - * there to prevent schizophrenic console behavior later... ;-} + * console device is "registered" during console_init(). + * As of this version (2.5.59), console_init() will call + * disable_early_printk() as the last action before initializing + * the console drivers. That's the last possible time srmcons can be + * unregistered without interfering with console behavior. * - * By default, OFF; set it with a bootcommand arg of "srmcons". + * By default, OFF; set it with a bootcommand arg of "srmcons" or + * "console=srm". The meaning of these two args is: + * "srmcons" - early callback prints + * "console=srm" - full callback based console, including early prints */ int srmcons_output = 0; /* Enforce a memory size limit; useful for testing. By default, none. */ unsigned long mem_size_limit = 0; +/* Set AGP GART window size (0 means disabled). */ +unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE; + #ifdef CONFIG_ALPHA_GENERIC struct alpha_machine_vector alpha_mv; int alpha_using_srm; @@ -461,57 +468,6 @@ page_is_ram(unsigned long pfn) #undef PFN_PHYS #undef PFN_MAX -#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) -/* - * Manage the SRM callbacks as a "console". - */ -static struct console srmcons; - -void __init register_srm_console(void) -{ - register_console(&srmcons); -} - -void __init unregister_srm_console(void) -{ - unregister_console(&srmcons); -} - -static void srm_console_write(struct console *co, const char *s, - unsigned count) -{ - srm_printk(s); -} - -static kdev_t srm_console_device(struct console *c) -{ - /* Huh? */ - return mk_kdev(TTY_MAJOR, 64 + c->index); -} - -static int __init srm_console_setup(struct console *co, char *options) -{ - return 1; -} - -static struct console srmcons = { - .name = "srm0", - .write = srm_console_write, - .device = srm_console_device, - .setup = srm_console_setup, - .flags = CON_PRINTBUFFER | CON_ENABLED, /* fake it out */ - .index = -1, -}; - -#else -void __init register_srm_console(void) -{ -} -void __init unregister_srm_console(void) -{ -} -#endif - void __init setup_arch(char **cmdline_p) { @@ -574,7 +530,16 @@ setup_arch(char **cmdline_p) continue; } if (strncmp(p, "srmcons", 7) == 0) { - srmcons_output = 1; + srmcons_output |= 1; + continue; + } + if (strncmp(p, "console=srm", 11) == 0) { + srmcons_output |= 2; + continue; + } + if (strncmp(p, "gartsize=", 9) == 0) { + alpha_agpgart_size = + get_mem_size_limit(p+9) << PAGE_SHIFT; continue; } } @@ -585,6 +550,13 @@ setup_arch(char **cmdline_p) /* If we want SRM console printk echoing early, do it now. */ if (alpha_using_srm && srmcons_output) { register_srm_console(); + + /* + * If "console=srm" was specified, clear the srmcons_output + * flag now so that time.c won't unregister_srm_console + */ + if (srmcons_output & 2) + srmcons_output = 0; } #ifdef CONFIG_MAGIC_SYSRQ @@ -688,6 +660,15 @@ setup_arch(char **cmdline_p) paging_init(); } +void __init +disable_early_printk(void) +{ + if (alpha_using_srm && srmcons_output) { + unregister_srm_console(); + srmcons_output = 0; + } +} + static char sys_unknown[] = "Unknown"; static char systype_names[][16] = { "0", diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 46eff5eeb857..a1ed17628934 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -544,9 +544,6 @@ smp_prepare_cpus(unsigned int max_cpus) smp_tune_scheduling(boot_cpuid); smp_setup_percpu_timer(boot_cpuid); - /* We have already have the boot CPU online.. */ - set_bit(boot_cpuid, &cpu_online_map); - /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { cpu_present_mask = 1UL << boot_cpuid; @@ -574,7 +571,11 @@ smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { + /* + * Mark the boot cpu (current cpu) as both present and online + */ set_bit(smp_processor_id(), &cpu_present_mask); + set_bit(smp_processor_id(), &cpu_online_map); } int __devinit diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c new file mode 100644 index 000000000000..29c5a04414b7 --- /dev/null +++ b/arch/alpha/kernel/srmcons.c @@ -0,0 +1,361 @@ +/* + * linux/arch/alpha/kernel/srmcons.c + * + * Callback based driver for SRM Console console device. + * (TTY driver and console driver) + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/timer.h> +#include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/tty_flip.h> + +#include <asm/console.h> +#include <asm/uaccess.h> + + +static spinlock_t srmcons_callback_lock = SPIN_LOCK_UNLOCKED; +static int srm_is_registered_console = 0; + +/* + * The TTY driver + */ +#define MAX_SRM_CONSOLE_DEVICES 1 /* only support 1 console device */ + +static int srmcons_refcount; +static struct tty_struct *srmcons_table[MAX_SRM_CONSOLE_DEVICES]; +static struct termios *srmcons_termios[MAX_SRM_CONSOLE_DEVICES]; +static struct termios *srmcons_termios_locked[MAX_SRM_CONSOLE_DEVICES]; + +struct srmcons_private { + struct tty_struct *tty; + struct timer_list timer; + spinlock_t lock; +}; + +typedef union _srmcons_result { + struct { + unsigned long c :61; + unsigned long status :3; + } bits; + long as_long; +} srmcons_result; + +/* called with callback_lock held */ +static int +srmcons_do_receive_chars(struct tty_struct *tty) +{ + srmcons_result result; + int count = 0, loops = 0; + + do { + result.as_long = callback_getc(0); + if (result.bits.status < 2) { + tty_insert_flip_char(tty, (char)result.bits.c, 0); + count++; + } + } while((result.bits.status & 1) && (++loops < 10)); + + if (count) + tty_schedule_flip(tty); + + return count; +} + +static void +srmcons_receive_chars(unsigned long data) +{ + struct srmcons_private *srmconsp = (struct srmcons_private *)data; + unsigned long flags; + int incr = 10; + + local_irq_save(flags); + if (spin_trylock(&srmcons_callback_lock)) { + if (!srmcons_do_receive_chars(srmconsp->tty)) + incr = 100; + spin_unlock(&srmcons_callback_lock); + } + + spin_lock(&srmconsp->lock); + if (srmconsp->tty) { + srmconsp->timer.expires = jiffies + incr; + add_timer(&srmconsp->timer); + } + spin_unlock(&srmconsp->lock); + + local_irq_restore(flags); +} + +/* called with callback_lock held */ +static int +srmcons_do_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + unsigned char *str_cr = "\r"; + long c, remaining = count; + srmcons_result result; + unsigned char *cur; + int need_cr; + + for (cur = (unsigned char *)buf; remaining > 0; ) { + need_cr = 0; + /* + * Break it up into reasonable size chunks to allow a chance + * for input to get in + */ + for (c = 0; c < min_t(long, 128L, remaining) && !need_cr; c++) + if (cur[c] == '\n') + need_cr = 1; + + while (c > 0) { + result.as_long = callback_puts(0, cur, c); + c -= result.bits.c; + remaining -= result.bits.c; + cur += result.bits.c; + + /* + * Check for pending input iff a tty was provided + */ + if (tty) + srmcons_do_receive_chars(tty); + } + + while (need_cr) { + result.as_long = callback_puts(0, str_cr, 1); + if (result.bits.c > 0) + need_cr = 0; + } + } + return count; +} + +static int +srmcons_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count) +{ + unsigned long flags; + + if (from_user) { + unsigned char tmp[512]; + int ret = 0; + size_t c; + + while ((c = count) > 0) { + if (c > sizeof(tmp)) + c = sizeof(tmp); + + c -= copy_from_user(tmp, buf, c); + + if (!c) { + printk("%s: EFAULT (count %d)\n", + __FUNCTION__, count); + return -EFAULT; + } + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(tty, tmp, c); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); + + buf += c; + count -= c; + ret += c; + } + + return ret; + } + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(tty, buf, count); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); + + return count; +} + +static int +srmcons_write_room(struct tty_struct *tty) +{ + return 512; +} + +static int +srmcons_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + +static int +srmcons_get_private_struct(struct srmcons_private **ps) +{ + static struct srmcons_private *srmconsp = NULL; + static spinlock_t srmconsp_lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&srmconsp_lock, flags); + + do { + if (srmconsp != NULL) { + *ps = srmconsp; + break; + } + + srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); + if (srmconsp == NULL) { + retval = -ENOMEM; + break; + } + + srmconsp->tty = NULL; + srmconsp->lock = SPIN_LOCK_UNLOCKED; + init_timer(&srmconsp->timer); + + *ps = srmconsp; + } while(0); + + spin_unlock_irqrestore(&srmconsp_lock, flags); + + return retval; +} + +static int +srmcons_open(struct tty_struct *tty, struct file *filp) +{ + struct srmcons_private *srmconsp; + unsigned long flags; + int retval; + + retval = srmcons_get_private_struct(&srmconsp); + if (retval) + return retval; + + spin_lock_irqsave(&srmconsp->lock, flags); + + if (!srmconsp->tty) { + tty->driver_data = srmconsp; + + srmconsp->tty = tty; + srmconsp->timer.function = srmcons_receive_chars; + srmconsp->timer.data = (unsigned long)srmconsp; + srmconsp->timer.expires = jiffies + 10; + add_timer(&srmconsp->timer); + } + + spin_unlock_irqrestore(&srmconsp->lock, flags); + + return 0; +} + +static void +srmcons_close(struct tty_struct *tty, struct file *filp) +{ + struct srmcons_private *srmconsp = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&srmconsp->lock, flags); + + if (tty->count == 1) { + srmconsp->tty = NULL; + del_timer(&srmconsp->timer); + } + + spin_unlock_irqrestore(&srmconsp->lock, flags); +} + + +static struct tty_driver srmcons_driver = { + .driver_name = "srm", + .name = "srm", + .magic = TTY_DRIVER_MAGIC, + .major = 0, /* dynamic */ + .minor_start = 0, + .num = MAX_SRM_CONSOLE_DEVICES, + .type = TTY_DRIVER_TYPE_SYSTEM, + .subtype = SYSTEM_TYPE_SYSCONS, + + .table = srmcons_table, + .termios = srmcons_termios, + .termios_locked = srmcons_termios_locked, + .refcount = &srmcons_refcount, + + .open = srmcons_open, + .close = srmcons_close, + .write = srmcons_write, + .write_room = srmcons_write_room, + .chars_in_buffer= srmcons_chars_in_buffer, +}; + +static int __init +srmcons_init(void) +{ + if (srm_is_registered_console) { + srmcons_driver.init_termios = tty_std_termios; + return tty_register_driver(&srmcons_driver); + } + + return -ENODEV; +} + +module_init(srmcons_init); + + +/* + * The console driver + */ +static void +srm_console_write(struct console *co, const char *s, unsigned count) +{ + unsigned long flags; + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(NULL, s, count); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); +} + +static kdev_t +srm_console_device(struct console *co) +{ + return mk_kdev(srmcons_driver.major, + srmcons_driver.minor_start + co->index); +} + +static int __init +srm_console_setup(struct console *co, char *options) +{ + return 0; +} + +static struct console srmcons = { + .name = "srm", + .write = srm_console_write, + .device = srm_console_device, + .setup = srm_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +void __init +register_srm_console(void) +{ + if (!srm_is_registered_console) { + callback_open_console(); + register_console(&srmcons); + srm_is_registered_console = 1; + } +} + +void __init +unregister_srm_console(void) +{ + if (srm_is_registered_console) { + callback_close_console(); + unregister_console(&srmcons); + srm_is_registered_console = 0; + } +} diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 4bdd7fc94920..030f9b216fa9 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -31,6 +31,7 @@ #include <linux/pci.h> #include <linux/init.h> #include <linux/reboot.h> +#include <linux/bootmem.h> #include <asm/ptrace.h> #include <asm/system.h> @@ -163,7 +164,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr, } printk(KERN_CRIT "NAUTILUS Machine check 0x%lx " - "[%s System Machine Check (NMI)]\n", + "[%s System Machine Check (NMI)]\n", vector, mchk_class); naut_sys_machine_check(vector, la_ptr, regs); @@ -174,6 +175,70 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr, mb(); } +extern void free_reserved_mem(void *, void *); + +void __init +nautilus_init_pci(void) +{ + struct pci_controller *hose = hose_head; + struct pci_bus *bus; + struct pci_dev *irongate; + unsigned long saved_io_start, saved_io_end; + unsigned long saved_mem_start, saved_mem_end; + unsigned long bus_align, bus_size, pci_mem; + unsigned long memtop = max_low_pfn << PAGE_SHIFT; + + /* Scan our single hose. */ + bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); + hose->bus = bus; + hose->last_busno = bus->subordinate; + + /* We're going to size the root bus, so we must + - have a non-NULL PCI device associated with the bus + - preserve hose resources. */ + irongate = pci_find_slot(0, 0); + bus->self = irongate; + saved_io_start = bus->resource[0]->start; + saved_io_end = bus->resource[0]->end; + saved_mem_start = bus->resource[1]->start; + saved_mem_end = bus->resource[1]->end; + + pci_bus_size_bridges(bus); + + /* Don't care about IO. */ + bus->resource[0]->start = saved_io_start; + bus->resource[0]->end = saved_io_end; + + bus_align = bus->resource[1]->start; + bus_size = bus->resource[1]->end + 1 - bus_align; + /* Align to 16Mb. */ + if (bus_align < 0x1000000UL) + bus_align = 0x1000000UL; + + /* Restore hose MEM resource. */ + bus->resource[1]->start = saved_mem_start; + bus->resource[1]->end = saved_mem_end; + + pci_mem = (0x100000000UL - bus_size) & -bus_align; + + if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) { + free_reserved_mem(__va(alpha_mv.min_mem_address), + __va(pci_mem)); + printk("nautilus_init_arch: %ldk freed\n", + (pci_mem - alpha_mv.min_mem_address) >> 10); + } + + alpha_mv.min_mem_address = pci_mem; + if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */ + IRONGATE0->pci_mem = pci_mem; + + pci_bus_assign_resources(bus); + + /* To break the loop in common_swizzle() */ + bus->self = NULL; + + pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); +} /* * The System Vectors @@ -196,7 +261,7 @@ struct alpha_machine_vector nautilus_mv __initmv = { .init_arch = irongate_init_arch, .init_irq = nautilus_init_irq, .init_rtc = common_init_rtc, - .init_pci = common_init_pci, + .init_pci = nautilus_init_pci, .kill_arch = nautilus_kill_arch, .pci_map_irq = nautilus_map_irq, .pci_swizzle = common_swizzle, diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 03fed82384dd..1525d25de0e3 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -383,21 +383,6 @@ time_init(void) /* Startup the timer source. */ alpha_mv.init_rtc(); - - /* - * If we had wanted SRM console printk echoing early, undo it now. - * - * "srmcons" specified in the boot command arguments allows us to - * see kernel messages during the period of time before the true - * console device is "registered" during console_init(). As of this - * version (2.4.10), time_init() is the last Alpha-specific code - * called before console_init(), so we put this "unregister" code - * here to prevent schizophrenic console behavior later... ;-} - */ - if (alpha_using_srm && srmcons_output) { - unregister_srm_console(); - srmcons_output = 0; - } } /* diff --git a/arch/arm/Makefile b/arch/arm/Makefile index af2c30238a85..62d268e87c2f 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -61,7 +61,7 @@ DATAADDR := . ifeq ($(CONFIG_CPU_26),y) PROCESSOR := armo -HEAD := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o +head-y := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o LDFLAGS_BLOB += --oformat elf26-littlearm ifeq ($(CONFIG_ROM_KERNEL),y) DATAADDR := 0x02080000 @@ -73,7 +73,7 @@ endif ifeq ($(CONFIG_CPU_32),y) PROCESSOR := armv -HEAD := arch/arm/kernel/head.o arch/arm/kernel/init_task.o +head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o LDFLAGS_BLOB += --oformat elf32-littlearm textaddr-y := 0xC0008000 endif @@ -181,7 +181,6 @@ MRPROPER_FILES += \ include/asm-arm/mach-types.h # We use MRPROPER_FILES and CLEAN_FILES now -archmrproper: archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 2c35c81e8d8c..e7d2d17552ac 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -export-objs := sa1111.o sa1111-pcibuf.o sa1111-pcipool.o - obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index fba9201d9204..330d84024c07 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,8 +15,6 @@ obj-m := obj-n := obj- := -export-objs := armksyms.o apm.o dma.o ecard.o fiq.o io.o time.o - obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o diff --git a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile index ceb67e82a5e7..d8c1959e9483 100644 --- a/arch/arm/mach-adifcc/Makefile +++ b/arch/arm/mach-adifcc/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-anakin/Makefile b/arch/arm/mach-anakin/Makefile index d74c691fb244..d8c1959e9483 100644 --- a/arch/arm/mach-anakin/Makefile +++ b/arch/arm/mach-anakin/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-arc/Makefile b/arch/arm/mach-arc/Makefile index 81aeec1dea2b..ba89043c32c8 100644 --- a/arch/arm/mach-arc/Makefile +++ b/arch/arm/mach-arc/Makefile @@ -10,8 +10,6 @@ obj-m := obj-n := obj- := -export-objs := oldlatches.o - obj-$(CONFIG_DEBUG_LL) += debug.o EXTRA_TARGETS := head.o diff --git a/arch/arm/mach-clps7500/Makefile b/arch/arm/mach-clps7500/Makefile index 2e012e12fc7e..4bd8ebd70e7b 100644 --- a/arch/arm/mach-clps7500/Makefile +++ b/arch/arm/mach-clps7500/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile index 1504bbe04749..6520ac835802 100644 --- a/arch/arm/mach-ebsa110/Makefile +++ b/arch/arm/mach-ebsa110/Makefile @@ -9,6 +9,4 @@ obj-m := obj-n := obj- := -export-objs := io.o - obj-$(CONFIG_LEDS) += leds.o diff --git a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile index 7027c899c7d3..24fbd7d3a3c1 100644 --- a/arch/arm/mach-epxa10db/Makefile +++ b/arch/arm/mach-epxa10db/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index a414f0c93e8f..d011b2df2dbe 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -9,8 +9,6 @@ obj-m := obj-n := obj- := -export-objs := arch.o netwinder-hw.o - pci-$(CONFIG_ARCH_CATS) += cats-pci.o pci-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o diff --git a/arch/arm/mach-ftvpci/Makefile b/arch/arm/mach-ftvpci/Makefile index 928077f9b821..8b1ad14a256c 100644 --- a/arch/arm/mach-ftvpci/Makefile +++ b/arch/arm/mach-ftvpci/Makefile @@ -9,7 +9,5 @@ obj-m := obj-n := obj- := -export-objs := - obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_LEDS) += leds.o diff --git a/arch/arm/mach-iop310/Makefile b/arch/arm/mach-iop310/Makefile index 4034db635839..f8ea687ee8a0 100644 --- a/arch/arm/mach-iop310/Makefile +++ b/arch/arm/mach-iop310/Makefile @@ -10,8 +10,6 @@ obj-m := obj-n := obj- := -export-objs := - obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o ifneq ($(CONFIG_XSCALE_PMU_TIMER),y) diff --git a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile index 2e012e12fc7e..4bd8ebd70e7b 100644 --- a/arch/arm/mach-l7200/Makefile +++ b/arch/arm/mach-l7200/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 9c3895f28eda..095debde02c8 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -export-objs := generic.o irq.o dma.o sa1111.o - # Common support (must be linked before board specific support) obj-y += generic.o irq.o dma.o obj-$(CONFIG_SA1111) += sa1111.o diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile index f1f4f63354f3..aa77bc9efbbb 100644 --- a/arch/arm/mach-rpc/Makefile +++ b/arch/arm/mach-rpc/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index 5f60f1e88f4f..dbcc33dd5ac2 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -9,8 +9,6 @@ obj-n := obj- := led-y := leds.o -export-objs := dma.o generic.o pm.o - # This needs to be cleaned up. We probably need to have SA1100 # and SA1110 config symbols. ifeq ($(CONFIG_CPU_FREQ),y) @@ -26,12 +24,10 @@ obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o led-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o obj-$(CONFIG_SA1100_ASSABET) += assabet.o -export-objs += assabet.o led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o obj-$(CONFIG_SA1100_BADGE4) += badge4.o -export-objs += badge4.o led-$(CONFIG_SA1100_BADGE4) += leds-badge4.o obj-$(CONFIG_SA1100_BRUTUS) += brutus.o @@ -43,12 +39,9 @@ led-$(CONFIG_SA1100_CERF) += leds-cerf.o obj-$(CONFIG_SA1100_EMPEG) += empeg.o obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o -export-objs += flexanet.o led-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o -export-objs += freebird.o - obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o led-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o @@ -56,13 +49,11 @@ obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o led-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o obj-$(CONFIG_SA1100_H3600) += h3600.o -export-objs += h3600.o obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o -export-objs += huw_webpanel.o obj-$(CONFIG_SA1100_ITSY) += itsy.o @@ -93,15 +84,12 @@ obj-$(CONFIG_SA1100_SIMPAD) += simpad.o led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o obj-$(CONFIG_SA1100_STORK) += stork.o -export-objs += stork.o obj-$(CONFIG_SA1100_TRIZEPS) += trizeps.o -export-objs += trizeps.o obj-$(CONFIG_SA1100_XP860) += xp860.o obj-$(CONFIG_SA1100_YOPY) += yopy.o -export-objs += yopy.o # LEDs support obj-$(CONFIG_LEDS) += $(led-y) diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile index d1ef343f8c80..45be9b04e7ba 100644 --- a/arch/arm/mach-shark/Makefile +++ b/arch/arm/mach-shark/Makefile @@ -9,6 +9,4 @@ obj-m := obj-n := obj- := -export-objs := - obj-$(CONFIG_LEDS) += leds.o diff --git a/arch/arm/mach-tbox/Makefile b/arch/arm/mach-tbox/Makefile index 2e012e12fc7e..4bd8ebd70e7b 100644 --- a/arch/arm/mach-tbox/Makefile +++ b/arch/arm/mach-tbox/Makefile @@ -9,4 +9,3 @@ obj-m := obj-n := obj- := -export-objs := diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 1d64f382e93f..1be14732d61b 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -8,8 +8,6 @@ obj-y := init.o extable.o fault-common.o obj-m := obj-n := obj- := -export-objs := proc-syms.o discontig.o - ifeq ($(CONFIG_CPU_32),y) obj-y += consistent.o fault-armv.o ioremap.o mm-armv.o obj-$(CONFIG_MODULES) += proc-syms.o diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index 6d0e6c6f7b05..59d939779ae6 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile @@ -5,8 +5,6 @@ EXTRA_TARGETS := head.o -export-objs := ksyms.o - obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o setup.o time.o sys_cris.o shadows.o \ debugport.o semaphore.o diff --git a/arch/i386/Makefile b/arch/i386/Makefile index dfa5ced00a7d..f3dc1e4c4e4f 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -3,8 +3,7 @@ # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions -# for "archclean" and "archdep" for cleaning up and making dependencies for -# this architecture +# for "archclean" cleaning up for this architecture. # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -76,7 +75,7 @@ mcore-$(CONFIG_X86_SUMMIT) := mach-default # default subarch .h files mflags-y += -Iinclude/asm-i386/mach-default -HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o +head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o libs-y += arch/i386/lib/ core-y += arch/i386/kernel/ \ @@ -92,8 +91,7 @@ AFLAGS += $(mflags-y) boot := arch/i386/boot -.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \ - clean archclean archmrproper +.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install all: bzImage diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 386e061795eb..9cfcd16ff9f8 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := mca.o i386_ksyms.o time.o - obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o @@ -34,5 +32,4 @@ obj-y += sysenter.o EXTRA_AFLAGS := -traditional -export-objs += scx200.o obj-$(CONFIG_SCx200) += scx200.o diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile index 421a2d892ec3..a25b701ab84e 100644 --- a/arch/i386/kernel/cpu/mtrr/Makefile +++ b/arch/i386/kernel/cpu/mtrr/Makefile @@ -3,4 +3,3 @@ obj-y += amd.o obj-y += cyrix.o obj-y += centaur.o -export-objs := main.o diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 09954f83b483..40bd0c4e42ca 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -792,8 +792,8 @@ ENTRY(sys_call_table) .long sys_io_getevents .long sys_io_submit .long sys_io_cancel - .long sys_ni_syscall /* 250 sys_alloc_hugepages - reuse this */ - .long sys_ni_syscall /* was sys_free_hugepages - reuse this */ + .long sys_fadvise64 /* 250 */ + .long sys_ni_syscall .long sys_exit_group .long sys_lookup_dcookie .long sys_epoll_create diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 4db7f942440f..5a8183a31eea 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -266,6 +266,41 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg } /* + * Lost tick detection and compensation + */ +static inline void detect_lost_tick(void) +{ + /* read time since last interrupt */ + unsigned long delta = timer->get_offset(); + static unsigned long dbg_print; + + /* check if delta is greater then two ticks */ + if(delta >= 2*(1000000/HZ)){ + + /* + * only print debug info first 5 times + */ + /* + * AKPM: disable this for now; it's nice, but irritating. + */ + if (0 && dbg_print < 5) { + printk(KERN_WARNING "\nWarning! Detected %lu " + "micro-second gap between interrupts.\n", + delta); + printk(KERN_WARNING " Compensating for %lu lost " + "ticks.\n", + delta/(1000000/HZ)-1); + dump_stack(); + dbg_print++; + } + /* calculate number of missed ticks */ + delta = delta/(1000000/HZ)-1; + jiffies += delta; + } + +} + +/* * This is the same as the above, except we _also_ save the current * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. @@ -281,6 +316,7 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ write_lock(&xtime_lock); + detect_lost_tick(); timer->mark_offset(); do_timer_interrupt(irq, NULL, regs); diff --git a/arch/i386/mach-voyager/Makefile b/arch/i386/mach-voyager/Makefile index 7f4b561243fb..2ef96cc528d0 100644 --- a/arch/i386/mach-voyager/Makefile +++ b/arch/i386/mach-voyager/Makefile @@ -8,8 +8,6 @@ # Note 2! The CFLAGS definitions are now in the main makefile... EXTRA_CFLAGS += -I../kernel -export-objs := - obj-y := setup.o voyager_basic.o voyager_thread.o obj-$(CONFIG_SMP) += voyager_smp.o voyager_cat.o diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile index dafd5de15b70..183d802bf494 100644 --- a/arch/i386/mm/Makefile +++ b/arch/i386/mm/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux i386-specific parts of the memory manager. # -export-objs := pageattr.o - obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 1663e7730a18..2dc1534f420d 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -283,8 +283,8 @@ int try_to_free_low(int count) break; } page = list_entry(p, struct page, list); - if ((page_zone(page))->name[0] != 'H') // Look for non-Highmem - map = page; + if (!PageHighMem(page)) + map = page; } if (map) { list_del(&map->list); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 331f950a1251..1508df6b376f 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -508,20 +508,36 @@ void __init mem_init(void) #endif } -#if CONFIG_X86_PAE -struct kmem_cache_s *pae_pgd_cachep; +#include <linux/slab.h> + +kmem_cache_t *pmd_cache; +kmem_cache_t *pgd_cache; + +void pmd_ctor(void *, kmem_cache_t *, unsigned long); +void pgd_ctor(void *, kmem_cache_t *, unsigned long); void __init pgtable_cache_init(void) { + if (PTRS_PER_PMD > 1) { + pmd_cache = kmem_cache_create("pae_pmd", + PTRS_PER_PMD*sizeof(pmd_t), + 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, + pmd_ctor, + NULL); + + if (!pmd_cache) + panic("pgtable_cache_init(): cannot create pmd cache"); + } + /* * PAE pgds must be 16-byte aligned: */ - pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0, - SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL); - if (!pae_pgd_cachep) - panic("init_pae(): Cannot alloc pae_pgd SLAB cache"); + pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, pgd_ctor, NULL); + if (!pgd_cache) + panic("pgtable_cache_init(): Cannot create pgd cache"); } -#endif /* Put this after the callers, so that it cannot be inlined */ static int do_test_wp_bit(void) diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 30315f207078..82285741b6c0 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -166,61 +166,60 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) return pte; } -#if CONFIG_X86_PAE +extern kmem_cache_t *pmd_cache; +extern kmem_cache_t *pgd_cache; -pgd_t *pgd_alloc(struct mm_struct *mm) +void pmd_ctor(void *__pmd, kmem_cache_t *pmd_cache, unsigned long flags) { - int i; - pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL); - - if (pgd) { - for (i = 0; i < USER_PTRS_PER_PGD; i++) { - unsigned long pmd = __get_free_page(GFP_KERNEL); - if (!pmd) - goto out_oom; - clear_page(pmd); - set_pgd(pgd + i, __pgd(1 + __pa(pmd))); - } - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return pgd; -out_oom: - for (i--; i >= 0; i--) - free_page((unsigned long)__va(pgd_val(pgd[i])-1)); - kmem_cache_free(pae_pgd_cachep, pgd); - return NULL; + clear_page(__pmd); } -void pgd_free(pgd_t *pgd) +void pgd_ctor(void *__pgd, kmem_cache_t *pgd_cache, unsigned long flags) { - int i; + pgd_t *pgd = __pgd; - for (i = 0; i < USER_PTRS_PER_PGD; i++) - free_page((unsigned long)__va(pgd_val(pgd[i])-1)); - kmem_cache_free(pae_pgd_cachep, pgd); + if (PTRS_PER_PMD == 1) + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); } -#else - pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); - - if (pgd) { - memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + int i; + pgd_t *pgd = kmem_cache_alloc(pgd_cache, SLAB_KERNEL); + + if (PTRS_PER_PMD == 1) + return pgd; + else if (!pgd) + return NULL; + + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + pmd_t *pmd = kmem_cache_alloc(pmd_cache, SLAB_KERNEL); + if (!pmd) + goto out_oom; + set_pgd(pgd + i, __pgd(1 + __pa((unsigned long long)((unsigned long)pmd)))); } return pgd; + +out_oom: + for (i--; i >= 0; --i) + kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + kmem_cache_free(pgd_cache, (void *)pgd); + return NULL; } void pgd_free(pgd_t *pgd) { - free_page((unsigned long)pgd); -} + int i; -#endif /* CONFIG_X86_PAE */ + if (PTRS_PER_PMD > 1) { + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + set_pgd(pgd + i, __pgd(0)); + } + } + kmem_cache_free(pgd_cache, (void *)pgd); +} diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index ee87c6516dda..91ac89227f03 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -31,7 +31,7 @@ cflags-$(CONFIG_ITANIUM_BSTEP_SPECIFIC) += -mb-step cflags-$(CONFIG_IA64_SGI_SN) += -DBRINGUP CFLAGS += $(cflags-y) -HEAD := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o +head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o libs-y += arch/ia64/lib/ core-y += arch/ia64/kernel/ arch/ia64/mm/ @@ -51,14 +51,13 @@ drivers-$(CONFIG_IA64_SGI_SN) += arch/ia64/sn/fakeprom/ makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/boot $(1) maketool =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/tools $(1) -.PHONY: boot compressed archclean archmrproper include/asm-ia64/offsets.h +.PHONY: boot compressed include/asm-ia64/offsets.h all compressed: vmlinux.gz vmlinux.gz: vmlinux $(call makeboot,vmlinux.gz) -archmrproper: archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/ia64/boot diff --git a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile index 2c3ca6b2b6f9..e7c7133c7ca7 100644 --- a/arch/ia64/hp/common/Makefile +++ b/arch/ia64/hp/common/Makefile @@ -5,6 +5,4 @@ # Copyright (C) Alex Williamson (alex_williamson@hp.com) # -export-objs := sba_iommu.o - obj-y := sba_iommu.o diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 6cc51e574f66..7d466721ecca 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := ia64_ksyms.o - obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o \ irq.o irq_ia64.o irq_lsapic.o ivt.o \ machvec.o pal.o process.o perfmon.o ptrace.o sal.o \ diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 4bc67c5bcc57..ab8b2cd1e76e 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -4,8 +4,6 @@ L_TARGET = lib.a -export-objs := swiotlb.o - obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ checksum.o clear_page.o csum_partial_copy.o copy_page.o \ diff --git a/arch/ia64/sn/io/Makefile b/arch/ia64/sn/io/Makefile index 117d1482f22b..24beaee2c4ac 100644 --- a/arch/ia64/sn/io/Makefile +++ b/arch/ia64/sn/io/Makefile @@ -13,8 +13,6 @@ ifdef CONFIG_IA64_SGI_SN2 EXTRA_CFLAGS += -DSHUB_SWAP_WAR endif -export-objs := hcl.o pci_dma.o - obj-$(CONFIG_IA64_SGI_SN) += stubs.o sgi_if.o xswitch.o klgraph_hack.o \ hcl.o labelcl.o invent.o sgi_io_sim.o \ klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \ diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile index 048aa577698e..5a2873be6382 100644 --- a/arch/ia64/sn/kernel/Makefile +++ b/arch/ia64/sn/kernel/Makefile @@ -38,8 +38,6 @@ EXTRA_CFLAGS := -DLITTLE_ENDIAN .S.o: $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< -export-objs = sn_ksyms.o iomv.o - obj-y = probe.o setup.o sn_asm.o sv.o bte.o iomv.o obj-$(CONFIG_IA64_SGI_SN1) += irq.o mca.o obj-$(CONFIG_IA64_SGI_SN2) += irq.o mca.o diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 8bf52e30794c..45aaa7379a0b 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -54,9 +54,9 @@ CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g endif ifndef CONFIG_SUN3 -HEAD := arch/m68k/kernel/head.o +head-y := arch/m68k/kernel/head.o else -HEAD := arch/m68k/kernel/sun3-head.o +head-y := arch/m68k/kernel/sun3-head.o endif core-y += arch/m68k/kernel/ arch/m68k/mm/ @@ -113,5 +113,3 @@ endif archclean: rm -f vmlinux.gz vmlinux.bz2 rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d - -archmrproper: diff --git a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile index 458ac3710861..8b415651edee 100644 --- a/arch/m68k/amiga/Makefile +++ b/arch/m68k/amiga/Makefile @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/amiga source directory # -export-objs := amiga_ksyms.o - obj-y := config.o amiints.o cia.o chipram.o amisound.o amiga_ksyms.o obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile index 19547753a5d5..8cb6236b39db 100644 --- a/arch/m68k/atari/Makefile +++ b/arch/m68k/atari/Makefile @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/atari source directory # -export-objs := atari_ksyms.o - obj-y := config.o time.o debug.o ataints.o stdma.o \ atasound.o stram.o atari_ksyms.o diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 334658311f79..9ab6bc3cac77 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -8,8 +8,6 @@ else EXTRA_TARGETS := sun3-head.o endif -export-objs := setup.o m68k_ksyms.o - obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o diff --git a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile index b47f70ca54a3..995a09d912f5 100644 --- a/arch/m68k/mac/Makefile +++ b/arch/m68k/mac/Makefile @@ -2,7 +2,5 @@ # Makefile for Linux arch/m68k/mac source directory # -export-objs := mac_ksyms.o - obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \ baboon.o macboing.o debug.o misc.o mac_ksyms.o diff --git a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile index cad032c477fe..5129f56b64a3 100644 --- a/arch/m68k/mvme16x/Makefile +++ b/arch/m68k/mvme16x/Makefile @@ -2,6 +2,4 @@ # Makefile for Linux arch/m68k/mvme16x source directory # -export-objs := mvme16x_ksyms.o - obj-y := config.o 16xints.o rtc.o mvme16x_ksyms.o diff --git a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile index 1f1c62d8f7ed..de3867d02b21 100644 --- a/arch/m68k/sun3/Makefile +++ b/arch/m68k/sun3/Makefile @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/sun3 source directory # -export-objs := sun3_ksyms.o - obj-y := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o \ diff --git a/arch/m68k/sun3x/Makefile b/arch/m68k/sun3x/Makefile index fcd38aa48aca..be5776d9a01e 100644 --- a/arch/m68k/sun3x/Makefile +++ b/arch/m68k/sun3x/Makefile @@ -2,6 +2,4 @@ # Makefile for Linux arch/m68k/sun3x source directory # -export-objs := sun3x_ksyms.o - obj-y := config.o time.o dvma.o prom.o diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile index 2057fc85bf5b..78828e79ea39 100644 --- a/arch/m68knommu/Makefile +++ b/arch/m68knommu/Makefile @@ -84,7 +84,7 @@ CFLAGS += -DUTS_SYSNAME=\"uClinux\" LDFLAGS_BLOB := --format binary --oformat elf32-m68k -HEAD := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o +head-y := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h.tmp \ include/asm-$(ARCH)/asm-offsets.h \ @@ -98,8 +98,6 @@ libs-y += arch/m68knommu/lib/ prepare: include/asm-$(ARCH)/asm-offsets.h -archmrproper: - archclean: $(call descend arch/$(ARCH)/boot, subdirclean) diff --git a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile index e5bd8f7c0f77..694227753497 100644 --- a/arch/m68knommu/kernel/Makefile +++ b/arch/m68knommu/kernel/Makefile @@ -2,8 +2,6 @@ # Makefile for arch/m68knommu/kernel. # -export-objs := m68k_ksyms.o - obj-y += entry.o init_task.o ints.o m68k_ksyms.o process.o ptrace.o \ semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o \ traps.o diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 849aeab0d965..43ce5b7d2a22 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -256,7 +256,7 @@ endif AFLAGS_vmlinux.lds.o := -DLOADADDR=$(LOADADDR) -HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o +head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o SUBDIRS := arch/mips/tools diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile index 2402db3f5897..660ffa1a69c3 100644 --- a/arch/mips/au1000/common/Makefile +++ b/arch/mips/au1000/common/Makefile @@ -6,8 +6,6 @@ # Makefile for the Alchemy Au1000 CPU, generic files. # -export-objs := serial.o - obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o obj-$(CONFIG_AU1000_UART) += serial.o diff --git a/arch/mips/baget/Makefile b/arch/mips/baget/Makefile index 4924e2960dba..ca58035331a3 100644 --- a/arch/mips/baget/Makefile +++ b/arch/mips/baget/Makefile @@ -3,7 +3,6 @@ # under Linux. # -export-objs := vacserial.o obj-y := baget.o print.o setup.o time.o irq.o bagetIRQ.o \ reset.o wbflush.o obj-$(CONFIG_SERIAL) += vacserial.o diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile index 8d29ef819010..f6731f0bbeda 100644 --- a/arch/mips/dec/Makefile +++ b/arch/mips/dec/Makefile @@ -2,8 +2,6 @@ # Makefile for the DECstation family specific parts of the kernel # -export-objs := wbflush.o - obj-y := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 6d9e093e8c69..a68de9935eac 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -5,8 +5,6 @@ # EXTRA_AFLAGS = -mips3 -mcpu=r4000 # not used? EXTRA_TARGETS := head.o init_task.o -export-objs := mips_ksyms.o - obj-y += branch.o process.o signal.o entry.o \ traps.o ptrace.o vm86.o ioport.o reset.o \ semaphore.o setup.o syscall.o sysmips.o \ diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 3c7e850c13d7..ac9a37c624ab 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -2,7 +2,6 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -export-objs += ioremap.o umap.o obj-y += extable.o init.o ioremap.o fault.o loadmmu.o obj-$(CONFIG_CPU_R3000) += r2300.o diff --git a/arch/mips64/Makefile b/arch/mips64/Makefile index 6d016da59cec..1dce4733c2d1 100644 --- a/arch/mips64/Makefile +++ b/arch/mips64/Makefile @@ -128,7 +128,7 @@ endif LDFLAGS_vmlinux += -Ttext $(LOADADDR) -HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o +head-y := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o SUBDIRS := arch/mips64/tools $(SUBDIRS) core-y += arch/mips64/kernel/ arch/mips64/mm/ diff --git a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile index 3013ed2673bf..809a5631f607 100644 --- a/arch/mips64/kernel/Makefile +++ b/arch/mips64/kernel/Makefile @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := mips64_ksyms.o - obj-y := branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \ r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \ scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \ diff --git a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile index 13ac18824b46..2792c71224d7 100644 --- a/arch/mips64/mm/Makefile +++ b/arch/mips64/mm/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -export-objs += umap.o - obj-y := extable.o init.o fault.o loadmmu.o obj-$(CONFIG_CPU_R4300) += r4xx0.o diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 7cbaf621ea33..973d26aeabd9 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -33,10 +33,10 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align OBJCOPY_FLAGS =-O binary -R .note -R .comment -S -cflags-y := -D__linux__ -pipe -fno-strength-reduce +cflags-y := -pipe -# These should be on for older toolchains or SOM toolchains that don't -# enable them by default. +# These flags should be implied by an hppa-linux configuration, but they +# are not in gcc 3.2. cflags-y += -mno-space-regs -mfast-indirect-calls # No fixed-point multiply @@ -56,7 +56,6 @@ head-y := arch/parisc/kernel/head.o head-$(CONFIG_PARISC64) := arch/parisc/kernel/head64.o CFLAGS += $(cflags-y) -HEAD := $(head-y) core-y += $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \ mm/ kernel/ hpux/ math-emu/ kernel/init_task.o ) @@ -96,9 +95,6 @@ include/asm-parisc/offsets.h: arch/parisc/kernel/asm-offsets.s @$(generate-asm-offsets.h) < $< > $@.tmp @$(update-if-changed) -archclean: -archmrproper: - CLEAN_FILES += palo.conf lifimage include/asm-parisc/offsets.h \ include/asm-parisc/offsets.h.tmp diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 9d64b35b5909..709d1db4b93b 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -9,8 +9,6 @@ EXTRA_TARGETS := init_task.o pdc_cons.o process.o unaligned.o $(head-y) AFLAGS_entry.o := -traditional AFLAGS_pacache.o := -traditional -export-objs := parisc_ksyms.o - obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o semaphore.o \ diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index f09a9419796a..4abe55cdd129 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -243,7 +243,7 @@ int show_interrupts(struct seq_file *p, void *v) for (i = 0; i <= MAX_CPU_IRQ; i++) { struct irqaction *action = ®ion->action[i]; unsigned int irq_no = IRQ_FROM_REGION(regnr) + i; - int j=0; + int j = 0; if (!action->handler) continue; @@ -251,7 +251,7 @@ int show_interrupts(struct seq_file *p, void *v) #ifdef CONFIG_SMP for (; j < NR_CPUS; j++) #endif - seq_printf(p, "%10u ", kstat_cpu(j).irqs[regnr][irq_no]); + seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]); seq_printf(p, " %14s", region->data.name ? region->data.name : "N/A"); @@ -388,7 +388,7 @@ void do_irq(struct irqaction *action, int irq, struct pt_regs * regs) int cpu = smp_processor_id(); irq_enter(); - ++kstat_cpu(cpu).irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)]; + ++kstat_cpu(cpu).irqs[irq]; DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq))); diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index c995e0329558..b8e33137ccff 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -13,6 +13,12 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + (c) 2003 Randolph Chung <tausq@debian.org> + + The best reference for this stuff is probably the Processor- + Specific ELF Supplement for PA-RISC: + http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf */ #include <linux/moduleloader.h> #include <linux/elf.h> @@ -21,19 +27,92 @@ #include <linux/string.h> #include <linux/kernel.h> -#if 0 +#if 1 #define DEBUGP printk #else #define DEBUGP(fmt...) #endif -enum parisc_fsel { - e_fsel, - e_lsel, - e_rsel, - e_lrsel, - e_rrsel + +#ifndef __LP64__ +struct got_entry { + Elf32_Addr addr; +}; + +struct fdesc_entry { + Elf32_Addr gp; + Elf32_Addr addr; +}; + +struct stub_entry { + Elf32_Word insns[2]; /* each stub entry has two insns */ +}; +#else +struct got_entry { + Elf64_Addr addr; +}; + +struct fdesc_entry { + Elf64_Addr dummy[2]; + Elf64_Addr gp; + Elf64_Addr addr; +}; + +struct stub_entry { + Elf64_Word insns[4]; /* each stub entry has four insns */ }; +#endif + +/* Field selection types defined by hppa */ +#define rnd(x) (((x)+0x1000)&~0x1fff) +/* fsel: full 32 bits */ +#define fsel(v,a) ((v)+(a)) +/* lsel: select left 21 bits */ +#define lsel(v,a) (((v)+(a))>>11) +/* rsel: select right 11 bits */ +#define rsel(v,a) (((v)+(a))&0x7ff) +/* lrsel with rounding of addend to nearest 8k */ +#define lrsel(v,a) (((v)+rnd(a))>>11) +/* rrsel with rounding of addend to nearest 8k */ +#define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a))) + +#define mask(x,sz) ((x) & ~((1<<(sz))-1)) + + +/* The reassemble_* functions prepare an immediate value for + insertion into an opcode. pa-risc uses all sorts of weird bitfields + in the instruction to hold the value. */ +static inline int reassemble_14(int as14) +{ + return (((as14 & 0x1fff) << 1) | + ((as14 & 0x2000) >> 13)); +} + +static inline int reassemble_17(int as17) +{ + return (((as17 & 0x10000) >> 16) | + ((as17 & 0x0f800) << 5) | + ((as17 & 0x00400) >> 8) | + ((as17 & 0x003ff) << 3)); +} + +static inline int reassemble_21(int as21) +{ + return (((as21 & 0x100000) >> 20) | + ((as21 & 0x0ffe00) >> 8) | + ((as21 & 0x000180) << 7) | + ((as21 & 0x00007c) << 14) | + ((as21 & 0x000003) << 12)); +} + +static inline int reassemble_22(int as22) +{ + return (((as22 & 0x200000) >> 21) | + ((as22 & 0x1f0000) << 5) | + ((as22 & 0x00f800) << 5) | + ((as22 & 0x000400) >> 8) | + ((as22 & 0x0003ff) << 3)); +} void *module_alloc(unsigned long size) { @@ -42,6 +121,81 @@ void *module_alloc(unsigned long size) return vmalloc(size); } +#ifndef __LP64__ +static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n) +{ + return 0; +} + +static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n) +{ + return 0; +} + +static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF32_R_TYPE(rela->r_info)) { + case R_PARISC_PCREL17F: + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} +#else +static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_LTOFF21L: + case R_PARISC_LTOFF14R: + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} + +static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 3; /* 3 for finalize */ + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_FPTR64: + cnt++; + } + } + + return cnt; +} + +static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} +#endif + /* Free memory returned from module_alloc */ void module_free(struct module *mod, void *module_region) @@ -51,35 +205,145 @@ void module_free(struct module *mod, void *module_region) table entries. */ } -/* We don't need anything special. */ -long module_core_size(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *secstrings, - struct module *module) +#define CONST +int module_frob_arch_sections(CONST Elf_Ehdr *hdr, + CONST Elf_Shdr *sechdrs, + CONST char *secstrings, + struct module *me) { - return module->core_size; + unsigned long gots = 0, fdescs = 0, stubs = 0; + unsigned int i; + + for (i = 1; i < hdr->e_shnum; i++) { + const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset; + unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels); + + if (sechdrs[i].sh_type != SHT_RELA) + continue; + + /* some of these are not relevant for 32-bit/64-bit + * we leave them here to make the code common. the + * compiler will do its thing and optimize out the + * stuff we don't need + */ + gots += count_gots(rels, nrels); + fdescs += count_fdescs(rels, nrels); + stubs += count_stubs(rels, nrels); + } + + /* align things a bit */ + me->core_size = ALIGN(me->core_size, 16); + me->arch.got_offset = me->core_size; + me->core_size += gots * sizeof(struct got_entry); + + me->core_size = ALIGN(me->core_size, 16); + me->arch.fdesc_offset = me->core_size; + me->core_size += stubs * sizeof(struct fdesc_entry); + + me->core_size = ALIGN(me->core_size, 16); + me->arch.stub_offset = me->core_size; + me->core_size += stubs * sizeof(struct stub_entry); + + return 0; } -long module_init_size(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *secstrings, - struct module *module) +static Elf_Addr get_got(struct module *me, unsigned long value, long addend) { - return module->init_size; + unsigned int i; + struct got_entry *got; + + value += addend; + + BUG_ON(value == 0); + + got = me->module_core + me->arch.got_offset; + for (i = 0; got[i].addr; i++) + if (got[i].addr == value) + return i * sizeof(struct got_entry); + + got[i].addr = value; + return i * sizeof(struct got_entry); } -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +static Elf_Addr get_fdesc(struct module *me, unsigned long value) { - /* parisc should not need this ... */ - printk(KERN_ERR "module %s: %s not yet implemented.\n", - mod->name, __FUNCTION__); - return 0; + struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset; + + if (!value) { + printk(KERN_ERR "%s: zero OPD requested!\n", me->name); + return 0; + } + + /* Look for existing fdesc entry. */ + while (fdesc->addr) { + if (fdesc->addr == value) + return (Elf_Addr)fdesc; + fdesc++; + } + + /* Create new one */ + fdesc->addr = value; + fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; + return (Elf_Addr)fdesc; } +static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, + int millicode) +{ + unsigned long i; + struct stub_entry *stub; + + i = me->arch.stub_count++; + stub = me->module_core + me->arch.stub_offset + + i * sizeof(struct stub_entry); + +#ifndef __LP64__ +/* for 32-bit the stub looks like this: + * ldil L'XXX,%r1 + * be,n R'XXX(%sr4,%r1) + */ + stub->insns[0] = 0x20200000; /* ldil L'XXX,%r1 */ + stub->insns[1] = 0xe0202002; /* be,n R'XXX(%sr4,%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); +#else +/* for 64-bit we have two kinds of stubs: + * for normal function calls: + * ldd 0(%dp),%dp + * ldd 10(%dp), %r1 + * bve (%r1) + * ldd 18(%dp), %dp + * + * for millicode: + * ldil 0, %r1 + * ldo 0(%r1), %r1 + * ldd 10(%r1), %r1 + * bve,n (%r1) + */ + if (!millicode) + { + stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ + stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ + stub->insns[2] = 0xe820d000; /* bve (%r1) */ + stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ + stub->insns[0] |= reassemble_21(get_got(me, value, addend)); + } + else + { + stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ + stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ + stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ + stub->insns[3] = 0xe820d002; /* bve,n (%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_14(rrsel(value, addend)); + } +#endif + + return (Elf_Addr)stub; +} int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, @@ -104,7 +368,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; Elf32_Word *loc; - Elf32_Addr value; + Elf32_Addr val; + Elf32_Sword addend; + Elf32_Addr dot; + register unsigned long dp asm ("r27"); DEBUGP("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -120,59 +387,81 @@ int apply_relocate_add(Elf_Shdr *sechdrs, me->name, strtab + sym->st_name); return -ENOENT; } + dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; - value = sym->st_value + rel[i].r_addend; + val = sym->st_value; + addend = rel[i].r_addend; - DEBUGP("Symbol %s loc 0x%lx value 0x%lx: ", +#if 0 +#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t : + DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n", strtab + sym->st_name, - (uint32_t)loc, value); + (uint32_t)loc, val, addend, + r(R_PARISC_PLABEL32) + r(R_PARISC_DIR32) + r(R_PARISC_DIR21L) + r(R_PARISC_DIR14R) + r(R_PARISC_SEGREL32) + r(R_PARISC_DPREL21L) + r(R_PARISC_DPREL14R) + r(R_PARISC_PCREL17F) + r(R_PARISC_PCREL22F) + "UNKNOWN"); +#undef r +#endif switch (ELF32_R_TYPE(rel[i].r_info)) { case R_PARISC_PLABEL32: /* 32-bit function address */ - DEBUGP("R_PARISC_PLABEL32\n"); + /* no function descriptors... */ + *loc = fsel(val, addend); break; case R_PARISC_DIR32: /* direct 32-bit ref */ - DEBUGP("R_PARISC_DIR32\n"); + *loc = fsel(val, addend); break; case R_PARISC_DIR21L: /* left 21 bits of effective address */ - DEBUGP("R_PARISC_DIR21L\n"); + *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend)); break; case R_PARISC_DIR14R: /* right 14 bits of effective address */ - DEBUGP("R_PARISC_DIR14R\n"); + *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend)); break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ - DEBUGP("R_PARISC_SEGREL32\n"); + val -= (uint32_t)me->module_core; + *loc = fsel(val, addend); break; case R_PARISC_DPREL21L: /* left 21 bit of relative address */ - DEBUGP("R_PARISC_DPREL21L\n"); + val -= dp; + *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend) - dp); break; case R_PARISC_DPREL14R: /* right 14 bit of relative address */ - DEBUGP("R_PARISC_DPREL14R\n"); + val -= dp; + *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend) - dp); break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - DEBUGP("R_PARISC_PCREL17F\n"); + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: - /* 22-bit PC relative address */ - DEBUGP("R_PARISC_PCREL22F\n"); + /* 22-bit PC relative address; only defined for pa20 */ + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x3ff1ffd) | reassemble_22(val); break; default: - printk(KERN_ERR "module %s: Unknown relocation: %Lu\n", + printk(KERN_ERR "module %s: Unknown relocation: %u\n", me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } } - return -ENOEXEC; + return 0; } #else @@ -186,7 +475,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf64_Sym *sym; Elf64_Word *loc; - Elf64_Addr value; + Elf64_Addr val; + Elf64_Sxword addend; + Elf64_Addr dot; DEBUGP("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -202,38 +493,56 @@ int apply_relocate_add(Elf_Shdr *sechdrs, me->name, strtab + sym->st_name); return -ENOENT; } + dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; - value = sym->st_value + rel[i].r_addend; + val = sym->st_value; + addend = rel[i].r_addend; - DEBUGP("Symbol %s loc 0x%Lx value 0x%Lx: ", +#if 1 +#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t : + DEBUGP("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n", strtab + sym->st_name, - (uint64_t)loc, value); + loc, val, addend, + r(R_PARISC_LTOFF14R) + r(R_PARISC_LTOFF21L) + r(R_PARISC_PCREL22F) + r(R_PARISC_DIR64) + r(R_PARISC_SEGREL32) + r(R_PARISC_FPTR64) + "UNKNOWN"); +#undef r +#endif switch (ELF64_R_TYPE(rel[i].r_info)) { - case R_PARISC_LTOFF14R: - /* LT-relative; right 14 bits */ - DEBUGP("R_PARISC_LTOFF14R\n"); - break; case R_PARISC_LTOFF21L: /* LT-relative; left 21 bits */ - DEBUGP("R_PARISC_LTOFF21L\n"); + *loc = mask(*loc, 21) | reassemble_21(get_got(me, val, addend)); + break; + case R_PARISC_LTOFF14R: + /* L(ltoff(val+addend)) */ + /* LT-relative; right 14 bits */ + *loc = mask(*loc, 14) | reassemble_14(get_got(me, val, addend)); break; case R_PARISC_PCREL22F: /* PC-relative; 22 bits */ - DEBUGP("R_PARISC_PCREL22F\n"); + if (strncmp(strtab + sym->st_name, "$$", 2) == 0) + val = get_stub(me, val, addend, 1) - dot - 8; + else + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x3ff1ffd) | reassemble_22(val); break; case R_PARISC_DIR64: /* 64-bit effective address */ - DEBUGP("R_PARISC_DIR64\n"); - *loc = value; + *loc = fsel(val, addend); break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ - DEBUGP("R_PARISC_SEGREL32\n"); + val -= (uint64_t)me->module_core; + *loc = fsel(val, addend); break; case R_PARISC_FPTR64: /* 64-bit function address */ - DEBUGP("R_PARISC_FPTR64\n"); + *loc = get_fdesc(me, val+addend); break; default: @@ -242,7 +551,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, return -ENOEXEC; } } - return -ENOEXEC; + return 0; } #endif @@ -250,5 +559,14 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { +#ifdef __LP64__ + me->init = (void *)get_fdesc(me, (Elf_Addr)me->init); +#ifdef CONFIG_MODULE_UNLOAD + if (me->cleanup) + me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup); + if (me->destroy) + me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy); +#endif +#endif return 0; } diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 63e7d7b5ff13..9813d4678790 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -31,10 +31,6 @@ EXPORT_SYMBOL(hppa_dma_ops); EXPORT_SYMBOL(get_pci_node_path); #endif -#ifdef CONFIG_IOMMU_CCIO -EXPORT_SYMBOL(ccio_get_fake); -#endif - #include <linux/sched.h> #include <asm/irq.h> EXPORT_SYMBOL(enable_irq); diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 0bb353f0733f..c1af9ab751c2 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -17,59 +17,6 @@ struct k_sigaction32 { struct sigaction32 sa; }; -typedef unsigned int old_sigset_t32; - -static int -put_old_sigset32(old_sigset_t32 *up, old_sigset_t *set) -{ - old_sigset_t32 set32 = *set; - return put_user(set32, up); -} - -static int -get_old_segset32(old_sigset_t32 *up, old_sigset_t *set) -{ - old_sigset_t32 set32; - int r; - - if ((r = get_user(set32, up)) == 0) - *set = set32; - - return r; -} - -long -sys32_sigpending(old_sigset_t32 *set) -{ - extern long sys_sigpending(old_sigset_t *set); - old_sigset_t pending; - int ret; - - KERNEL_SYSCALL(ret, sys_sigpending, &pending); - - /* can't put_user an old_sigset_t -- it is too big */ - if (put_old_sigset32(set, &pending)) - return -EFAULT; - - return ret; -} - -int sys32_sigprocmask(int how, old_sigset_t32 *set, - old_sigset_t32 *oset) -{ - extern int sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - old_sigset_t s; - int ret; - - if (set && get_old_segset32 (set, &s)) - return -EFAULT; - KERNEL_SYSCALL(ret, sys_sigprocmask, how, set ? &s : NULL, oset ? &s : NULL); - if (!ret && oset && put_old_sigset32(oset, &s)) - return -EFAULT; - return ret; -} - static inline void sigset_32to64(sigset_t *s64, sigset_t32 *s32) { diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 7d14a688e518..de994c1e6d1f 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -314,74 +314,6 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, return -ENOSYS; } -/* 32-bit user apps use struct statfs which uses 'long's */ -struct statfs32 { - __s32 f_type; - __s32 f_bsize; - __s32 f_blocks; - __s32 f_bfree; - __s32 f_bavail; - __s32 f_files; - __s32 f_ffree; - __kernel_fsid_t f_fsid; - __s32 f_namelen; - __s32 f_spare[6]; -}; - -/* convert statfs struct to statfs32 struct and copy result to user */ -static unsigned long statfs32_to_user(struct statfs32 *ust32, struct statfs *st) -{ - struct statfs32 st32; -#undef CP -#define CP(a) st32.a = st->a - CP(f_type); - CP(f_bsize); - CP(f_blocks); - CP(f_bfree); - CP(f_bavail); - CP(f_files); - CP(f_ffree); - CP(f_fsid); - CP(f_namelen); - return copy_to_user(ust32, &st32, sizeof st32); -} - -/* The following statfs calls are copies of code from linux/fs/open.c and - * should be checked against those from time to time */ -asmlinkage long sys32_statfs(const char * path, struct statfs32 * buf) -{ - struct nameidata nd; - int error; - - error = user_path_walk(path, &nd); - if (!error) { - struct statfs tmp; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); - if (!error && statfs32_to_user(buf, &tmp)) - error = -EFAULT; - path_release(&nd); - } - return error; -} - -asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 * buf) -{ - struct file * file; - struct statfs tmp; - int error; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); - if (!error && statfs32_to_user(buf, &tmp)) - error = -EFAULT; - fput(file); -out: - return error; -} - extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 02f676ee84e6..acde743c0fb0 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -425,30 +425,27 @@ sys_call_table: /* I don't like this */ ENTRY_UHOH(sgetmask) ENTRY_UHOH(ssetmask) - ENTRY_SAME(setreuid) /* 70 */ + ENTRY_SAME(setreuid) /* 70 */ ENTRY_SAME(setregid) ENTRY_SAME(mincore) - ENTRY_DIFF(sigpending) + ENTRY_COMP(sigpending) ENTRY_SAME(sethostname) /* Following 3 have linux-common-code structs containing longs -( */ - ENTRY_DIFF(setrlimit) /* 75 */ + ENTRY_DIFF(setrlimit) /* 75 */ ENTRY_DIFF(getrlimit) ENTRY_DIFF(getrusage) /* struct timeval and timezone are maybe?? consistent wide and narrow */ ENTRY_DIFF(gettimeofday) ENTRY_DIFF(settimeofday) - ENTRY_SAME(getgroups) /* 80 */ + ENTRY_SAME(getgroups) /* 80 */ ENTRY_SAME(setgroups) /* struct socketaddr... */ ENTRY_SAME(sendto) ENTRY_SAME(symlink) /* see stat comment */ ENTRY_COMP(newlstat) - ENTRY_SAME(readlink) /* 85 */ - /* suspect we'll need some work for narrow shlibs on wide kernel */ - /* NOTE this doesn't get used when I boot 32-bit userspace */ - /* containing working shlib apps -- can this be nuked? */ - ENTRY_UHOH(uselib) + ENTRY_SAME(readlink) /* 85 */ + ENTRY_SAME(ni_syscall) /* was uselib */ ENTRY_SAME(swapon) ENTRY_SAME(reboot) ENTRY_SAME(mmap2) @@ -461,17 +458,15 @@ sys_call_table: ENTRY_SAME(getpriority) ENTRY_SAME(setpriority) ENTRY_SAME(recv) - ENTRY_DIFF(statfs) - ENTRY_DIFF(fstatfs) /* 100 */ + ENTRY_COMP(statfs) + ENTRY_COMP(fstatfs) /* 100 */ ENTRY_SAME(stat64) - /* don't think hppa glibc even provides an entry pt for this - * so disable for now */ - ENTRY_UHOH(socketcall) + ENTRY_SAME(ni_syscall) /* was socketcall */ ENTRY_SAME(syslog) /* even though manpage says struct timeval contains longs, ours has * time_t and suseconds_t -- both of which are safe wide/narrow */ ENTRY_COMP(setitimer) - ENTRY_COMP(getitimer) /* 105 */ + ENTRY_COMP(getitimer) /* 105 */ ENTRY_SAME(capget) ENTRY_SAME(capset) ENTRY_OURS(pread64) @@ -494,10 +489,10 @@ sys_call_table: ENTRY_SAME(recvfrom) /* struct timex contains longs */ ENTRY_DIFF(adjtimex) - ENTRY_SAME(mprotect) /* 125 */ + ENTRY_SAME(mprotect) /* 125 */ /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */ - ENTRY_DIFF(sigprocmask) - ENTRY_SAME(ni_syscall) /* create_module */ + ENTRY_COMP(sigprocmask) + ENTRY_SAME(ni_syscall) /* create_module */ ENTRY_SAME(init_module) ENTRY_SAME(delete_module) ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */ @@ -547,13 +542,13 @@ sys_call_table: ENTRY_COMP(nanosleep) ENTRY_SAME(mremap) ENTRY_SAME(setresuid) - ENTRY_SAME(getresuid) /* 165 */ + ENTRY_SAME(getresuid) /* 165 */ ENTRY_DIFF(sigaltstack_wrapper) ENTRY_SAME(ni_syscall) /* query_module */ ENTRY_SAME(poll) /* structs contain pointers and an in_addr... */ ENTRY_DIFF(nfsservctl) - ENTRY_SAME(setresgid) /* 170 */ + ENTRY_SAME(setresgid) /* 170 */ ENTRY_SAME(getresgid) ENTRY_SAME(prctl) /* signals need a careful review */ @@ -594,15 +589,9 @@ sys_call_table: ENTRY_OURS(ftruncate64) /* 200 */ ENTRY_SAME(getdents64) ENTRY_DIFF(fcntl64) -#ifdef CONFIG_XFS_FS - ENTRY_SAME(attrctl) - ENTRY_SAME(acl_get) - ENTRY_SAME(acl_set) /* 205 */ -#else ENTRY_SAME(ni_syscall) ENTRY_SAME(ni_syscall) ENTRY_SAME(ni_syscall) /* 205 */ -#endif ENTRY_SAME(gettid) ENTRY_SAME(readahead) ENTRY_SAME(ni_syscall) /* tkill */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 1ea93d50efcc..e04f3ed3810d 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -123,7 +123,11 @@ void dump_stack(void) } -static int kstack_depth_to_print = 48; +#ifndef __LP64__ +static int kstack_depth_to_print = 64 * 4; +#else +static int kstack_depth_to_print = 128 * 4; +#endif void show_stack(unsigned long *sp) { diff --git a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile index e34b71b778e8..7e5121912c10 100644 --- a/arch/ppc/8xx_io/Makefile +++ b/arch/ppc/8xx_io/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux MPC8xx ppc-specific parts of comm processor # -export-objs := fec.o - obj-y := commproc.o uart.o obj-$(CONFIG_FEC_ENET) += fec.o diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 24cabc2f5eef..eba801d82836 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -36,15 +36,12 @@ ifdef CONFIG_MORE_COMPILE_OPTIONS CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') endif -head-y := head.o -head-$(CONFIG_8xx) := head_8xx.o -head-$(CONFIG_4xx) := head_4xx.o -head-$(CONFIG_440) := head_44x.o +head-y := arch/ppc/kernel/head.o +head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o +head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o +head-$(CONFIG_440) := arch/ppc/kernel/head_44x.o -HEAD := arch/ppc/kernel/$(head-y) -ifdef CONFIG_6xx - HEAD += arch/ppc/kernel/idle_6xx.o -endif +head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ @@ -59,7 +56,7 @@ drivers-$(CONFIG_OCP) += arch/ppc/ocp/ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm -.PHONY: $(BOOT_TARGETS) clean archclean archmrproper +.PHONY: $(BOOT_TARGETS) all: zImage @@ -78,8 +75,6 @@ $(BOOT_TARGETS): vmlinux archclean: $(Q)$(MAKE) $(clean)=arch/ppc/boot -archmrproper: - prepare: include/asm-$(ARCH)/offsets.h checkbin arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \ diff --git a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile index 2eeb4c39bc34..59fec0a3ac8e 100644 --- a/arch/ppc/amiga/Makefile +++ b/arch/ppc/amiga/Makefile @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/amiga source directory # -export-objs := amiga_ksyms.o - obj-y := config.o amiints.o cia.o time.o bootinfo.o amisound.o \ chipram.o amiga_ksyms.o diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 899c74f2f38f..0017345edaad 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -17,8 +17,6 @@ HEAD-$(CONFIG_6xx) += idle_6xx.o EXTRA_TARGETS := $(HEAD-y) -export-objs := ppc_ksyms.o time.o - obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ semaphore.o syscalls.o setup.o \ diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 0dcebe67a8a6..e88e3cfe6b08 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -2,8 +2,6 @@ # Makefile for ppc-specific library files.. # -export-objs := dec_and_lock.o - obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o obj-$(CONFIG_SMP) += locks.o diff --git a/arch/ppc/ocp/Makefile b/arch/ppc/ocp/Makefile index 996b2aa86dc4..15cc57710f9a 100644 --- a/arch/ppc/ocp/Makefile +++ b/arch/ppc/ocp/Makefile @@ -9,6 +9,5 @@ # # NB: cribbed from the drivers/sbus/Makefile -- PMM -export-objs := ocp.o ocp-driver.o ocp-probe.o obj-y += ocp.o ocp-driver.o ocp-probe.o diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile index cd37f1bc49c8..e7233f9bd9ea 100644 --- a/arch/ppc/platforms/4xx/Makefile +++ b/arch/ppc/platforms/4xx/Makefile @@ -1,8 +1,6 @@ # # Makefile for the PowerPC 4xx linux kernel. -export-objs := ibm405lp.o - obj-$(CONFIG_ASH) += ash.o obj-$(CONFIG_BEECH) += beech.o obj-$(CONFIG_CEDAR) += cedar.o diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile index 582f826b2a99..8909d79ae8b7 100644 --- a/arch/ppc/platforms/Makefile +++ b/arch/ppc/platforms/Makefile @@ -12,8 +12,6 @@ endif # Extra CFLAGS so we don't have to do relative includes CFLAGS_pmac_setup.o += -I$(TOPDIR)/arch/$(ARCH)/mm -export-objs := prep_setup.o - obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) obj-$(CONFIG_PCI) += apus_pci.o diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index ebefa1c4d149..a21be9e25cff 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -12,8 +12,6 @@ endif CFLAGS_prom_init.o += -mrelocatable-lib CFLAGS_btext.o += -mrelocatable-lib -export-objs := ppc4xx_dma.o ppc4xx_pm.o - obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o ifeq ($(CONFIG_4xx),y) obj-$(CONFIG_4xx) += ppc4xx_pic.o diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 3ba80c9682cf..a4c3b522f375 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -22,7 +22,7 @@ CFLAGS += -msoft-float -pipe \ -Wno-uninitialized -mminimal-toc -mtraceback=full \ -finline-limit-2000 -mcpu=power4 -HEAD := arch/ppc64/kernel/head.o +head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 39f663f845b5..e7449e2aa5fc 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -4,8 +4,6 @@ EXTRA_CFLAGS += -mno-minimal-toc EXTRA_TARGETS := head.o -export-objs := ppc_ksyms.o - obj-y := setup.o entry.o traps.o irq.o idle.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ align.o semaphore.o bitops.o stab.o htab.o pacaData.o \ diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 441c4f989386..59f385e8fe8f 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -4,7 +4,5 @@ L_TARGET = lib.a -export-objs := dec_and_lock.o - obj-y := checksum.o dec_and_lock.o string.o strcase.o obj-y += copypage.o memcpy.o copyuser.o diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 67e82769a2f0..8985f66f3ddf 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -20,7 +20,7 @@ LDFLAGS_BLOB := --format binary --oformat elf32-s390 CFLAGS += -pipe -fno-strength-reduce -HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o +head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ libs-y += arch/$(ARCH)/lib/ @@ -38,7 +38,6 @@ listing image: vmlinux install: vmlinux $(call makeboot, $@) -archmrproper: archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 527a4febcc08..ac4839d89882 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -5,7 +5,6 @@ EXTRA_TARGETS := head.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o reipl.o s390_ext.o debug.o diff --git a/arch/s390x/Makefile b/arch/s390x/Makefile index fdb57f106e78..66f1b321f876 100644 --- a/arch/s390x/Makefile +++ b/arch/s390x/Makefile @@ -21,7 +21,7 @@ LDFLAGS_BLOB := --format binary --oformat elf64-s390 CFLAGS += -pipe -fno-strength-reduce -HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o +head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ libs-y += arch/$(ARCH)/lib/ @@ -38,7 +38,6 @@ listing image: vmlinux install: vmlinux $(call makeboot, $@) -archmrproper: archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot diff --git a/arch/s390x/kernel/Makefile b/arch/s390x/kernel/Makefile index f75b227f8071..1bd693d05f0f 100644 --- a/arch/s390x/kernel/Makefile +++ b/arch/s390x/kernel/Makefile @@ -5,9 +5,6 @@ EXTRA_TARGETS := head.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o \ - exec32.o - obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o reipl.o s390_ext.o debug.o diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 56f3d6ec6366..2fd1224ae8f7 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -53,7 +53,7 @@ endif # CFLAGS += -pipe -HEAD := arch/sh/kernel/head.o arch/sh/kernel/init_task.o +head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) @@ -81,5 +81,3 @@ archclean: $(MAKE) -C arch/$(ARCH)/stboards clean # $(MAKE) -C arch/$(ARCH)/tools clean -archmrproper: - diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 3c557afe19ac..6ca25bf30d8b 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -4,9 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := io.o io_generic.o io_hd64465.o setup_hd64465.o sh_ksyms.o \ - io_adx.o io_bigsur.o io_cat68701.o hd64465_gpio.o - obj-y := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ irq_imask.o io.o io_generic.o sh_ksyms.o diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index c3df9d40ef79..9e53c3875c1c 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -37,7 +37,8 @@ endif # Actual linking is done with "make image". LDFLAGS_vmlinux = -r -HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o +head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o +HEAD := $(head-y) core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ libs-y += arch/sparc/prom/ arch/sparc/lib/ @@ -61,8 +62,6 @@ image tftpboot.img: vmlinux archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot -archmrproper: - prepare: include/asm-$(ARCH)/asm_offsets.h arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \ diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 06a1371a97f7..64f1cade2378 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -6,7 +6,6 @@ EXTRA_TARGETS := head.o init_task.o EXTRA_AFLAGS := -ansi -export-objs := sparc_ksyms.o IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ process.o signal.o ioport.o setup.o idprom.o \ diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 9773bb5a4db5..d4c1e922b59f 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1808,6 +1808,15 @@ C_LABEL(fpload): retl nop + .globl C_LABEL(ndelay) +C_LABEL(ndelay): + save %sp, -REGWIN_SZ, %sp + mov %i0, %o0 + call .umul + mov 5, %o1 + ba delay_continue + nop + .globl C_LABEL(udelay) C_LABEL(udelay): save %sp, -REGWIN_SZ, %sp @@ -1815,6 +1824,7 @@ C_LABEL(udelay): sethi %hi(0x10c6), %o1 call .umul or %o1, %lo(0x10c6), %o1 +delay_continue: #ifndef CONFIG_SMP sethi %hi(C_LABEL(loops_per_jiffy)), %o3 call .umul diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index e72292b59349..e198ca77e863 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -151,6 +151,7 @@ EXPORT_SYMBOL(__cpu_logical_map); #endif EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(ndelay); EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); #if CONFIG_SUN_AUXIO diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index f4064a5ea142..197cbd5db2e3 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -61,7 +61,7 @@ ifeq ($(CONFIG_MCOUNT),y) CFLAGS := $(CFLAGS) -pg endif -HEAD := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o +head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o core-y += arch/sparc64/kernel/ arch/sparc64/mm/ core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/ @@ -74,10 +74,6 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ tftpboot.img vmlinux.aout: $(Q)$(MAKE) $(build)=arch/sparc64/boot arch/sparc64/boot/$@ -archclean: - -archmrproper: - define archhelp echo '* vmlinux - Standard sparc64 kernel' echo ' vmlinux.aout - a.out kernel for sparc64' diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index dcfab416133c..26324b58bc19 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -6,7 +6,6 @@ EXTRA_AFLAGS := -ansi EXTRA_TARGETS := head.o init_task.o -export-objs := sparc64_ksyms.o ebus.o obj-y := process.o setup.o cpu.o idprom.o \ traps.o devices.o auxio.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \ diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 8e72f9032ab6..8ea9ada4a721 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -20,8 +20,6 @@ ubd-objs := ubd_kern.o ubd_user.o port-objs := port_kern.o port_user.o harddog-objs := harddog_kern.o harddog_user.o -export-objs := mconsole_kern.o - obj-y = obj-$(CONFIG_SSL) += ssl.o obj-$(CONFIG_UML_NET_SLIP) += slip.o diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index de98110a7494..9f795283c40d 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -36,10 +36,6 @@ UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__ DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__ -export-objs-$(CONFIG_GPROF) += gprof_syms.o -export-objs-$(CONFIG_GCOV) += gmon_syms.o - -export-objs := ksyms.o process_kern.o signal_kern.o $(export-objs-y) CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ -I/usr/include -I../include diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 9b436c8ef1bb..ea519a34a4bc 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile @@ -9,8 +9,6 @@ obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o ksyms.o mem.o process_kern.o \ obj-$(CONFIG_PT_PROXY) += ptproxy/ -export-objs = ksyms.o - USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index bc0cbe6ba325..71b8817a4b1c 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -3,8 +3,6 @@ obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \ obj-$(CONFIG_HIGHMEM) += highmem.o -export-objs = ksyms.o - USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) diff --git a/arch/v850/Makefile b/arch/v850/Makefile index d8341af1300a..72ea1fb114d7 100644 --- a/arch/v850/Makefile +++ b/arch/v850/Makefile @@ -31,7 +31,7 @@ LDFLAGS_BLOB := -b binary --oformat elf32-little OBJCOPY_FLAGS_BLOB := -I binary -O elf32-little -B v850e -HEAD := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o +head-y := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o core-y += $(arch_dir)/kernel/ libs-y += $(arch_dir)/lib/ diff --git a/arch/v850/kernel/Makefile b/arch/v850/kernel/Makefile index 27efdf869221..e316b8472291 100644 --- a/arch/v850/kernel/Makefile +++ b/arch/v850/kernel/Makefile @@ -13,8 +13,6 @@ EXTRA_TARGETS := head.o init_task.o obj-y += intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \ signal.o irq.o mach.o ptrace.o bug.o -export-objs += v850_ksyms.o rte_mb_a_pci.o - obj-$(CONFIG_MODULES) += module.o v850_ksyms.o # chip-specific code obj-$(CONFIG_V850E_MA1) += ma.o nb85e_utils.o nb85e_timer_d.o diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index b23e06713e86..34100cd32426 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -48,7 +48,7 @@ CFLAGS += -fno-reorder-blocks CFLAGS += -finline-limit=2000 #CFLAGS += -g -HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o +head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o libs-y += arch/x86_64/lib/ core-y += arch/x86_64/kernel/ arch/x86_64/mm/ diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index 0fa49b5c536a..44bfccc85d01 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile @@ -2,8 +2,6 @@ # Makefile for the ia32 kernel emulation subsystem. # -export-objs := ia32_ioctl.o sys_ia32.o - obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ ia32_signal.o \ ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o syscall32.o diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index d0c9d25d5db9..c31251ba7c00 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o head64.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := x8664_ksyms.o pci-gart.o pci-dma.o - obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \ pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \ diff --git a/arch/x86_64/kernel/mtrr/Makefile b/arch/x86_64/kernel/mtrr/Makefile index 8b1e9352f838..6a7766264647 100644 --- a/arch/x86_64/kernel/mtrr/Makefile +++ b/arch/x86_64/kernel/mtrr/Makefile @@ -7,8 +7,6 @@ obj-y += amd.o obj-y += cyrix.o obj-y += centaur.o -export-objs := main.o - $(obj)/main.c: $(obj)/mtrr.h @ln -sf ../../../i386/kernel/cpu/mtrr/main.c $(obj)/main.c $(obj)/if.c: $(obj)/mtrr.h diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile index 6fa25727295c..8ed7e3f1139f 100644 --- a/arch/x86_64/lib/Makefile +++ b/arch/x86_64/lib/Makefile @@ -3,8 +3,6 @@ # L_TARGET := lib.a -export-objs := io.o csum-wrappers.o csum-partial.o - CFLAGS_csum-partial.o := -funroll-loops obj-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile index f05b91f34bc8..fb244bc0b6ba 100644 --- a/arch/x86_64/mm/Makefile +++ b/arch/x86_64/mm/Makefile @@ -2,7 +2,5 @@ # Makefile for the linux i386-specific parts of the memory manager. # -export-objs := pageattr.o - obj-y := init.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/crypto/Makefile b/crypto/Makefile index fa66d0d7ad91..8e7e3a8cf735 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -2,8 +2,6 @@ # Cryptographic API # -export-objs := api.o hmac.o - autoload-crypto-$(CONFIG_KMOD) = autoload.o proc-crypto-$(CONFIG_PROC_FS) = proc.o diff --git a/crypto/cipher.c b/crypto/cipher.c index fb6292ad2aa1..1f2fab6eade9 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -4,6 +4,7 @@ * Cipher operations. * * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> + * Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -16,12 +17,22 @@ #include <linux/errno.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/pagemap.h> #include <linux/highmem.h> #include <asm/scatterlist.h> #include "internal.h" typedef void (cryptfn_t)(void *, u8 *, const u8 *); -typedef void (procfn_t)(struct crypto_tfm *, u8 *, cryptfn_t, int enc); +typedef void (procfn_t)(struct crypto_tfm *, u8 *, u8*, cryptfn_t, int enc); + +struct scatter_walk { + struct scatterlist *sg; + struct page *page; + void *data; + unsigned int len_this_page; + unsigned int len_this_segment; + unsigned int offset; +}; static inline void xor_64(u8 *a, const u8 *b) { @@ -37,165 +48,191 @@ static inline void xor_128(u8 *a, const u8 *b) ((u32 *)a)[3] ^= ((u32 *)b)[3]; } -static inline unsigned int sglen(struct scatterlist *sg, unsigned int nsg) + +/* Define sg_next is an inline routine now in case we want to change + scatterlist to a linked list later. */ +static inline struct scatterlist *sg_next(struct scatterlist *sg) { - unsigned int i, n; - - for (i = 0, n = 0; i < nsg; i++) - n += sg[i].length; - - return n; + return sg + 1; } -/* - * Do not call this unless the total length of all of the fragments - * has been verified as multiple of the block size. - */ -static unsigned int copy_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, unsigned int sgidx, - unsigned int rlen, unsigned int *last, int in) +void *which_buf(struct scatter_walk *walk, unsigned int nbytes, void *scratch) { - unsigned int i, copied, coff, j, aligned; - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - - for (i = sgidx, j = copied = 0, aligned = 0 ; copied < bsize; i++) { - unsigned int len = sg[i].length; - unsigned int clen; - char *p; - - if (copied) { - coff = 0; - clen = min(len, bsize - copied); - - if (len == bsize - copied) - aligned = 1; /* last + right aligned */ - - } else { - coff = len - rlen; - clen = rlen; - } + if (nbytes <= walk->len_this_page && + (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <= + PAGE_CACHE_SIZE) + return walk->data; + else + return scratch; +} - p = crypto_kmap(sg[i].page) + sg[i].offset + coff; - - if (in) - memcpy(&buf[copied], p, clen); +static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) +{ + if (out) + memcpy(sgdata, buf, nbytes); + else + memcpy(buf, sgdata, nbytes); +} + +static void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) +{ + unsigned int rest_of_page; + + walk->sg = sg; + + walk->page = sg->page; + walk->len_this_segment = sg->length; + + rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1)); + walk->len_this_page = min(sg->length, rest_of_page); + walk->offset = sg->offset; +} + +static void scatterwalk_map(struct scatter_walk *walk, int out) +{ + walk->data = crypto_kmap(walk->page, out) + walk->offset; +} + +static void scatter_page_done(struct scatter_walk *walk, int out, + unsigned int more) +{ + /* walk->data may be pointing the first byte of the next page; + however, we know we transfered at least one byte. So, + walk->data - 1 will be a virutual address in the mapped page. */ + + if (out) + flush_dcache_page(walk->page); + + if (more) { + walk->len_this_segment -= walk->len_this_page; + + if (walk->len_this_segment) { + walk->page++; + walk->len_this_page = min(walk->len_this_segment, + (unsigned)PAGE_CACHE_SIZE); + walk->offset = 0; + } else - memcpy(p, &buf[copied], clen); - - crypto_kunmap(p); - *last = aligned ? 0 : clen; - copied += clen; + scatterwalk_start(walk, sg_next(walk->sg)); } - - return i - sgidx - 2 + aligned; } -static inline unsigned int gather_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, - unsigned int sgidx, unsigned int rlen, - unsigned int *last) +static void scatter_done(struct scatter_walk *walk, int out, int more) { - return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 1); + crypto_kunmap(walk->data, out); + if (walk->len_this_page == 0 || !more) + scatter_page_done(walk, out, more); } -static inline unsigned int scatter_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, - unsigned int sgidx, unsigned int rlen, - unsigned int *last) +/* + * Do not call this unless the total length of all of the fragments + * has been verified as multiple of the block size. + */ +static int copy_chunks(void *buf, struct scatter_walk *walk, + size_t nbytes, int out) { - return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 0); + if (buf != walk->data) { + while (nbytes > walk->len_this_page) { + memcpy_dir(buf, walk->data, walk->len_this_page, out); + buf += walk->len_this_page; + nbytes -= walk->len_this_page; + + crypto_kunmap(walk->data, out); + scatter_page_done(walk, out, 1); + scatterwalk_map(walk, out); + } + + memcpy_dir(buf, walk->data, nbytes, out); + } + + walk->offset += nbytes; + walk->len_this_page -= nbytes; + walk->len_this_segment -= nbytes; + return 0; } /* - * Generic encrypt/decrypt wrapper for ciphers. - * - * If we find a a remnant at the end of a frag, we have to encrypt or - * decrypt across possibly multiple page boundaries via a temporary - * block, then continue processing with a chunk offset until the end - * of a frag is block aligned. - * - * The code is further complicated by having to remap a page after - * processing a block then yielding. The data will be offset from the - * start of page at the scatterlist offset, the chunking offset (coff) - * and the block offset (boff). + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per block. */ -static int crypt(struct crypto_tfm *tfm, struct scatterlist *sg, - unsigned int nsg, cryptfn_t crfn, procfn_t prfn, int enc) +static int crypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, cryptfn_t crfn, procfn_t prfn, int enc) { - unsigned int i, coff; - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - u8 tmp[bsize]; + struct scatter_walk walk_in, walk_out; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + u8 tmp_src[nbytes > src->length ? bsize : 0]; + u8 tmp_dst[nbytes > dst->length ? bsize : 0]; - if (sglen(sg, nsg) % bsize) { + if (!nbytes) + return 0; + + if (nbytes % bsize) { tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; return -EINVAL; } - for (i = 0, coff = 0; i < nsg; i++) { - unsigned int n = 0, boff = 0; - unsigned int len = sg[i].length - coff; - char *p = crypto_kmap(sg[i].page) + sg[i].offset + coff; - - while (len) { - if (len < bsize) { - crypto_kunmap(p); - n = gather_chunks(tfm, tmp, sg, i, len, &coff); - prfn(tfm, tmp, crfn, enc); - scatter_chunks(tfm, tmp, sg, i, len, &coff); - crypto_yield(tfm); - goto unmapped; - } else { - prfn(tfm, p, crfn, enc); - crypto_kunmap(p); - crypto_yield(tfm); - - /* remap and point to recalculated offset */ - boff += bsize; - p = crypto_kmap(sg[i].page) - + sg[i].offset + coff + boff; - - len -= bsize; - - /* End of frag with no remnant? */ - if (coff && len == 0) - coff = 0; - } - } - crypto_kunmap(p); -unmapped: - i += n; + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + u8 *src_p, *dst_p; + + scatterwalk_map(&walk_in, 0); + scatterwalk_map(&walk_out, 1); + src_p = which_buf(&walk_in, bsize, tmp_src); + dst_p = which_buf(&walk_out, bsize, tmp_dst); + + nbytes -= bsize; + copy_chunks(src_p, &walk_in, bsize, 0); + + prfn(tfm, dst_p, src_p, crfn, enc); + + scatter_done(&walk_in, 0, nbytes); + + copy_chunks(dst_p, &walk_out, bsize, 1); + scatter_done(&walk_out, 1, nbytes); + + if (!nbytes) + return 0; + + crypto_yield(tfm); } - return 0; } static void cbc_process(struct crypto_tfm *tfm, - u8 *block, cryptfn_t fn, int enc) + u8 *dst, u8 *src, cryptfn_t fn, int enc) { /* Null encryption */ if (!tfm->crt_cipher.cit_iv) return; if (enc) { - tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, block); - fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv); - memcpy(tfm->crt_cipher.cit_iv, block, + tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, src); + fn(tfm->crt_ctx, dst, tfm->crt_cipher.cit_iv); + memcpy(tfm->crt_cipher.cit_iv, dst, crypto_tfm_alg_blocksize(tfm)); } else { - u8 buf[crypto_tfm_alg_blocksize(tfm)]; + const int need_stack = (src == dst); + u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0]; + u8 *buf = need_stack ? stack : dst; - fn(tfm->crt_ctx, buf, block); + fn(tfm->crt_ctx, buf, src); tfm->crt_u.cipher.cit_xor_block(buf, tfm->crt_cipher.cit_iv); - memcpy(tfm->crt_cipher.cit_iv, block, + memcpy(tfm->crt_cipher.cit_iv, src, crypto_tfm_alg_blocksize(tfm)); - memcpy(block, buf, crypto_tfm_alg_blocksize(tfm)); + if (buf != dst) + memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm)); } } -static void ecb_process(struct crypto_tfm *tfm, u8 *block, +static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, cryptfn_t fn, int enc) { - fn(tfm->crt_ctx, block, block); + fn(tfm->crt_ctx, dst, src); } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -211,35 +248,44 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) } static int ecb_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_encrypt, ecb_process, 1); } static int ecb_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_decrypt, ecb_process, 1); } static int cbc_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_encrypt, cbc_process, 1); } static int cbc_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_decrypt, cbc_process, 0); } static int nocrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { return -ENOSYS; } diff --git a/crypto/digest.c b/crypto/digest.c index 4db5f88ef38d..9e7c4bb417ab 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -28,10 +28,10 @@ static void update(struct crypto_tfm *tfm, unsigned int i; for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page) + sg[i].offset; + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, p, sg[i].length); - crypto_kunmap(p); + crypto_kunmap(p, 0); crypto_yield(tfm); } } @@ -49,10 +49,10 @@ static void digest(struct crypto_tfm *tfm, tfm->crt_digest.dit_init(tfm); for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page) + sg[i].offset; + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, p, sg[i].length); - crypto_kunmap(p); + crypto_kunmap(p, 0); crypto_yield(tfm); } crypto_digest_final(tfm, out); diff --git a/crypto/internal.h b/crypto/internal.h index eb4c92d3b47f..df34df2e6acc 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -16,17 +16,29 @@ #include <linux/init.h> #include <asm/hardirq.h> #include <asm/softirq.h> +#include <asm/kmap_types.h> -static inline void *crypto_kmap(struct page *page) +static enum km_type km_types[] = { + KM_USER0, + KM_USER1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, +}; + +static inline enum km_type crypto_kmap_type(int out) +{ + return km_types[(in_softirq() ? 2 : 0) + out]; +} + + +static inline void *crypto_kmap(struct page *page, int out) { - return kmap_atomic(page, in_softirq() ? - KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER); + return kmap_atomic(page, crypto_kmap_type(out)); } -static inline void crypto_kunmap(void *vaddr) +static inline void crypto_kunmap(void *vaddr, int out) { - kunmap_atomic(vaddr, in_softirq() ? - KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER); + kunmap_atomic(vaddr, crypto_kmap_type(out)); } static inline void crypto_yield(struct crypto_tfm *tfm) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index bcce9065242a..a45e574528f7 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -703,7 +703,7 @@ test_des(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -746,7 +746,7 @@ test_des(void) sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 2); + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -814,7 +814,7 @@ test_des(void) sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 3); + ret = crypto_cipher_encrypt(tfm, sg, sg, 32); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); @@ -890,7 +890,7 @@ test_des(void) sg[3].offset = ((long) p & ~PAGE_MASK); sg[3].length = 18; - ret = crypto_cipher_encrypt(tfm, sg, 4); + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); @@ -979,7 +979,7 @@ test_des(void) sg[4].offset = ((long) p & ~PAGE_MASK); sg[4].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 5); + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1078,7 +1078,7 @@ test_des(void) sg[7].offset = ((long) p & ~PAGE_MASK); sg[7].length = 1; - ret = crypto_cipher_encrypt(tfm, sg, 8); + ret = crypto_cipher_encrypt(tfm, sg, sg, 8); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1120,7 +1120,7 @@ test_des(void) sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("des_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1163,7 +1163,7 @@ test_des(void) sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; - ret = crypto_cipher_decrypt(tfm, sg, 2); + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1220,7 +1220,7 @@ test_des(void) sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 1; - ret = crypto_cipher_decrypt(tfm, sg, 3); + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1290,7 +1290,7 @@ test_des(void) crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1349,7 +1349,7 @@ test_des(void) crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 2); + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1398,7 +1398,7 @@ test_des(void) crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_blocksize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1450,7 +1450,7 @@ test_des(void) crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 2); + ret = crypto_cipher_decrypt(tfm, sg, sg, 8); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1518,7 +1518,7 @@ test_des3_ede(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1561,7 +1561,7 @@ test_des3_ede(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1624,7 +1624,7 @@ test_blowfish(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1666,7 +1666,7 @@ test_blowfish(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1719,7 +1719,7 @@ test_blowfish(void) crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1764,7 +1764,7 @@ test_blowfish(void) crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1829,7 +1829,7 @@ test_twofish(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1871,7 +1871,7 @@ test_twofish(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1924,7 +1924,7 @@ test_twofish(void) crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1970,7 +1970,7 @@ test_twofish(void) crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -2030,7 +2030,7 @@ test_serpent(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2070,7 +2070,7 @@ test_serpent(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2133,7 +2133,7 @@ test_aes(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2175,7 +2175,7 @@ test_aes(void) sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; diff --git a/drivers/acorn/scsi/Makefile b/drivers/acorn/scsi/Makefile index fe844899dcfd..aa143604372e 100644 --- a/drivers/acorn/scsi/Makefile +++ b/drivers/acorn/scsi/Makefile @@ -2,7 +2,6 @@ # Makefile for drivers/acorn/scsi # -export-objs := fas216.o queue.o msgqueue.o acornscsi_mod-objs := acornscsi.o acornscsi-io.o obj-$(CONFIG_SCSI_ACORNSCSI_3) += acornscsi_mod.o queue.o msgqueue.o diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index dc69339884e3..97871769c111 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -12,8 +12,6 @@ endif EXTRA_CFLAGS += $(ACPI_CFLAGS) -export-objs := acpi_ksyms.o processor.o - obj-y := acpi_ksyms.o # diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index a4a5b82556b5..415d2c4078af 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -4,7 +4,6 @@ EXTRA_CFLAGS := -g -export-objs := uPD98402.o suni.o idt77105.o fore_200e-objs := fore200e.o host-progs := fore200e_mkfirm diff --git a/drivers/base/Makefile b/drivers/base/Makefile index f953910ff586..3b4aa06f8a03 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -1,14 +1,8 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o interface.o power.o bus.o \ - driver.o class.o intf.o platform.o \ - cpu.o firmware.o - +obj-y := core.o sys.o interface.o power.o bus.o \ + driver.o class.o intf.o platform.o \ + cpu.o firmware.o obj-$(CONFIG_NUMA) += node.o memblk.o - -obj-y += fs/ - +obj-y += fs/ obj-$(CONFIG_HOTPLUG) += hotplug.o - -export-objs := core.o power.o sys.o bus.o driver.o \ - class.o intf.o platform.o firmware.o diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 84a85241ce8a..1c729154c10c 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -35,7 +35,7 @@ struct device_driver cpu_driver = { */ int __init register_cpu(struct cpu *cpu, int num, struct node *root) { - cpu->node_id = __cpu_to_node(num); + cpu->node_id = cpu_to_node(num); cpu->sysdev.name = "cpu"; cpu->sysdev.id = num; if (root) diff --git a/drivers/base/fs/Makefile b/drivers/base/fs/Makefile index ae7ccaa14359..e96bba31ee1c 100644 --- a/drivers/base/fs/Makefile +++ b/drivers/base/fs/Makefile @@ -1,3 +1,2 @@ obj-y := device.o -export-objs := device.o diff --git a/drivers/base/memblk.c b/drivers/base/memblk.c index bac6fb235086..a8f27d612fc4 100644 --- a/drivers/base/memblk.c +++ b/drivers/base/memblk.c @@ -36,7 +36,7 @@ struct device_driver memblk_driver = { */ int __init register_memblk(struct memblk *memblk, int num, struct node *root) { - memblk->node_id = __memblk_to_node(num); + memblk->node_id = memblk_to_node(num); memblk->sysdev.name = "memblk"; memblk->sysdev.id = num; if (root) diff --git a/drivers/base/node.c b/drivers/base/node.c index 6ec8e58b888c..261bf881da60 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -72,7 +72,7 @@ int __init register_node(struct node *node, int num, struct node *parent) { int error; - node->cpumap = __node_to_cpu_mask(num); + node->cpumap = node_to_cpumask(num); node->sysroot.id = num; if (parent) node->sysroot.dev.parent = &parent->sysroot.sysdev; diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index c28072cbb910..8881536cd7e0 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -267,10 +267,12 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller) } } if (Controller->FirmwareType == DAC960_V1_Controller) { + Command->cmd_sglist = Command->V1.ScatterList; Command->V1.ScatterGatherList = (DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU; Command->V1.ScatterGatherListDMA = ScatterGatherDMA; } else { + Command->cmd_sglist = Command->V2.ScatterList; Command->V2.ScatterGatherList = (DAC960_V2_ScatterGatherSegment_T *)ScatterGatherCPU; Command->V2.ScatterGatherListDMA = ScatterGatherDMA; @@ -3046,25 +3048,12 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command) DAC960_V1_ScatterGatherSegment_T *ScatterGatherList = Command->V1.ScatterGatherList; struct scatterlist *ScatterList = Command->V1.ScatterList; - int DmaDirection, SegCount; DAC960_V1_ClearCommand(Command); - if (Command->CommandType == DAC960_ReadCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request, - ScatterList); - /* pci_map_sg MAY change the value of SegCount */ - SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount, - DmaDirection); - Command->SegmentCount = SegCount; - - if (SegCount == 1) + if (Command->SegmentCount == 1) { - if (Command->CommandType == DAC960_ReadCommand) + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read; else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write; @@ -3079,7 +3068,7 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command) { int i; - if (Command->CommandType == DAC960_ReadCommand) + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather; else CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather; @@ -3089,9 +3078,9 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command) CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber; CommandMailbox->Type5.BusAddress = Command->V1.ScatterGatherListDMA; - CommandMailbox->Type5.ScatterGatherCount = SegCount; + CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount; - for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) { + for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { ScatterGatherList->SegmentDataPointer = (DAC960_BusAddress32_T)sg_dma_address(ScatterList); ScatterGatherList->SegmentByteCount = @@ -3112,25 +3101,12 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) DAC960_Controller_T *Controller = Command->Controller; DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; struct scatterlist *ScatterList = Command->V2.ScatterList; - int DmaDirection, SegCount; DAC960_V2_ClearCommand(Command); - if (Command->CommandType == DAC960_ReadCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request, - ScatterList); - /* pci_map_sg MAY change the value of SegCount */ - SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount, - DmaDirection); - Command->SegmentCount = SegCount; - CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10; CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost = - (Command->CommandType == DAC960_ReadCommand); + (Command->DmaDirection == PCI_DMA_FROMDEVICE); CommandMailbox->SCSI_10.DataTransferSize = Command->BlockCount << DAC960_BlockSizeBits; CommandMailbox->SCSI_10.RequestSenseBusAddress = Command->V2.RequestSenseDMA; @@ -3139,7 +3115,7 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) CommandMailbox->SCSI_10.RequestSenseSize = sizeof(DAC960_SCSI_RequestSense_T); CommandMailbox->SCSI_10.CDBLength = 10; CommandMailbox->SCSI_10.SCSI_CDB[0] = - (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A); + (Command->DmaDirection == PCI_DMA_FROMDEVICE ? 0x28 : 0x2A); CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24; CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16; CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8; @@ -3147,7 +3123,7 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8; CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount; - if (SegCount == 1) + if (Command->SegmentCount == 1) { CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0] @@ -3163,13 +3139,13 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) DAC960_V2_ScatterGatherSegment_T *ScatterGatherList; int i; - if (SegCount > 2) + if (Command->SegmentCount > 2) { ScatterGatherList = Command->V2.ScatterGatherList; CommandMailbox->SCSI_10.CommandControlBits .AdditionalScatterGatherListMemory = true; CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ExtendedScatterGather.ScatterGatherList0Length = SegCount; + .ExtendedScatterGather.ScatterGatherList0Length = Command->SegmentCount; CommandMailbox->SCSI_10.DataTransferMemoryAddress .ExtendedScatterGather.ScatterGatherList0Address = Command->V2.ScatterGatherListDMA; @@ -3178,7 +3154,7 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) ScatterGatherList = CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments; - for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) { + for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { ScatterGatherList->SegmentDataPointer = (DAC960_BusAddress64_T)sg_dma_address(ScatterList); ScatterGatherList->SegmentByteCount = @@ -3220,22 +3196,75 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller, DAC960_WaitForCommand(Controller); } - if (rq_data_dir(Request) == READ) + if (rq_data_dir(Request) == READ) { + Command->DmaDirection = PCI_DMA_FROMDEVICE; Command->CommandType = DAC960_ReadCommand; - else + } else { + Command->DmaDirection = PCI_DMA_TODEVICE; Command->CommandType = DAC960_WriteCommand; + } Command->Completion = Request->waiting; Command->LogicalDriveNumber = (int)Request->rq_disk->private_data; Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors; Command->Request = Request; blkdev_dequeue_request(Request); + Command->SegmentCount = blk_rq_map_sg(&Controller->RequestQueue, + Command->Request, Command->cmd_sglist); + /* pci_map_sg MAY change the value of SegCount */ + Command->SegmentCount = pci_map_sg(Command->PciDevice, Command->cmd_sglist, + Command->SegmentCount, Command->DmaDirection); + DAC960_QueueReadWriteCommand(Command); return true; } /* + DAC960_queue_partial_rw extracts one bio from the request already + associated with argument command, and construct a new command block to retry I/O + only on that bio. Queue that command to the controller. + + This function re-uses a previously-allocated Command, + there is no failure mode from trying to allocate a command. +*/ + +static void DAC960_queue_partial_rw(DAC960_Command_T *Command) +{ + DAC960_Controller_T *Controller = Command->Controller; + IO_Request_T *Request = Command->Request; + + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) + Command->CommandType = DAC960_ReadRetryCommand; + else + Command->CommandType = DAC960_WriteRetryCommand; + + /* + * We could be more efficient with these mapping requests + * and map only the portions that we need. But since this + * code should almost never be called, just go with a + * simple coding. + */ + (void)blk_rq_map_sg(&Controller->RequestQueue, Command->Request, + Command->cmd_sglist); + + (void)pci_map_sg(Command->PciDevice, Command->cmd_sglist, 1, + Command->DmaDirection); + /* + * Resubmitting the request sector at a time is really tedious. + * But, this should almost never happen. So, we're willing to pay + * this price so that in the end, as much of the transfer is completed + * successfully as possible. + */ + Command->SegmentCount = 1; + Command->BlockNumber = Request->sector; + Command->BlockCount = 1; + DAC960_QueueReadWriteCommand(Command); + return; +} + + +/* DAC960_ProcessRequests attempts to remove as many I/O Requests as possible from Controller's I/O Request Queue and queue them to the Controller. */ @@ -3276,43 +3305,30 @@ static void DAC960_RequestFunction(RequestQueue_T *RequestQueue) individual Buffer. */ -static inline void DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, +static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, boolean SuccessfulIO) { - DAC960_CommandType_T CommandType = Command->CommandType; IO_Request_T *Request = Command->Request; - int DmaDirection, UpToDate; + int UpToDate; UpToDate = 0; if (SuccessfulIO) UpToDate = 1; - /* - * We could save DmaDirection in the command structure - * and just reuse that information here. - */ - if (CommandType == DAC960_ReadCommand || - CommandType == DAC960_ReadRetryCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - pci_unmap_sg(Command->PciDevice, Command->V1.ScatterList, - Command->SegmentCount, DmaDirection); - /* - * BlockCount is redundant with nr_sectors in the request - * structure. Consider eliminating BlockCount from the - * command structure now that Command includes a pointer to - * the request. - */ - while (end_that_request_first(Request, UpToDate, Command->BlockCount)) - ; - end_that_request_last(Request); - - if (Command->Completion) { - complete(Command->Completion); - Command->Completion = NULL; + pci_unmap_sg(Command->PciDevice, Command->cmd_sglist, + Command->SegmentCount, Command->DmaDirection); + + if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { + + end_that_request_last(Request); + + if (Command->Completion) { + complete(Command->Completion); + Command->Completion = NULL; + } + return true; } + return false; } /* @@ -3384,46 +3400,65 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command) if (CommandType == DAC960_ReadCommand || CommandType == DAC960_WriteCommand) { - if (CommandStatus == DAC960_V1_NormalCompletion) - DAC960_ProcessCompletedRequest(Command, true); +#ifdef FORCE_RETRY_DEBUG + CommandStatus = DAC960_V1_IrrecoverableDataError; +#endif + + if (CommandStatus == DAC960_V1_NormalCompletion) { - else if (CommandStatus == DAC960_V1_IrrecoverableDataError || + if (!DAC960_ProcessCompletedRequest(Command, true)) + BUG(); + + } else if (CommandStatus == DAC960_V1_IrrecoverableDataError || CommandStatus == DAC960_V1_BadDataEncountered) { - /* - * Finish this later. - * - * We should call "complete_that_request_first()" - * to remove the first part of the request. Then, if there - * is still more I/O to be done, resubmit the request. - * - * We want to recalculate scatter/gather list, - * and requeue the command. - * - * For now, print a message on the console, and clone - * the code for "normal" completion. + * break the command down into pieces and resubmit each + * piece, hoping that some of them will succeed. */ - printk("V1_ProcessCompletedCommand: I/O error on read/write\n"); - - DAC960_ProcessCompletedRequest(Command, false); + DAC960_queue_partial_rw(Command); + return; } else { if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) DAC960_V1_ReadWriteError(Command); - DAC960_ProcessCompletedRequest(Command, false); + if (!DAC960_ProcessCompletedRequest(Command, false)) + BUG(); } } else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - /* - * We're not doing retry commands yet. - */ - printk("DAC960_ProcessCompletedCommand: RetryCommand not done yet\n"); + boolean normal_completion; +#ifdef FORCE_RETRY_FAILURE_DEBUG + static int retry_count = 1; +#endif + /* + Perform completion processing for the portion that was + retried, and submit the next portion, if any. + */ + normal_completion = true; + if (CommandStatus != DAC960_V1_NormalCompletion) { + normal_completion = false; + if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) + DAC960_V1_ReadWriteError(Command); + } + +#ifdef FORCE_RETRY_FAILURE_DEBUG + if (!(++retry_count % 10000)) { + printk("V1 error retry failure test\n"); + normal_completion = false; + DAC960_V1_ReadWriteError(Command); + } +#endif + + if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { + DAC960_queue_partial_rw(Command); + return; + } } else if (CommandType == DAC960_MonitoringCommand) @@ -4451,23 +4486,25 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) if (CommandType == DAC960_ReadCommand || CommandType == DAC960_WriteCommand) { - if (CommandStatus == DAC960_V2_NormalCompletion) - DAC960_ProcessCompletedRequest(Command, true); +#ifdef FORCE_RETRY_DEBUG + CommandStatus = DAC960_V2_AbormalCompletion; +#endif + Command->V2.RequestSense->SenseKey = DAC960_SenseKey_MediumError; + + if (CommandStatus == DAC960_V2_NormalCompletion) { - else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError) + if (!DAC960_ProcessCompletedRequest(Command, true)) + BUG(); + + } else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError) { - /* - * Don't know yet how to handle this case. - * See comments in DAC960_V1_ProcessCompletedCommand() - * - * For now, print a message on the console, and clone - * the code for "normal" completion. + * break the command down into pieces and resubmit each + * piece, hoping that some of them will succeed. */ - printk("V1_ProcessCompletedCommand: I/O error on read/write\n"); - - DAC960_ProcessCompletedRequest(Command, false); + DAC960_queue_partial_rw(Command); + return; } else { @@ -4476,13 +4513,40 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) /* Perform completion processing for all buffers in this I/O Request. */ - DAC960_ProcessCompletedRequest(Command, false); + (void)DAC960_ProcessCompletedRequest(Command, false); } } else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - printk("DAC960_V2_ProcessCompletedCommand: retries not coded yet\n"); + boolean normal_completion; + +#ifdef FORCE_RETRY_FAILURE_DEBUG + static int retry_count = 1; +#endif + /* + Perform completion processing for the portion that was + retried, and submit the next portion, if any. + */ + normal_completion = true; + if (CommandStatus != DAC960_V2_NormalCompletion) { + normal_completion = false; + if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady) + DAC960_V2_ReadWriteError(Command); + } + +#ifdef FORCE_RETRY_FAILURE_DEBUG + if (!(++retry_count % 10000)) { + printk("V2 error retry failure test\n"); + normal_completion = false; + DAC960_V2_ReadWriteError(Command); + } +#endif + + if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { + DAC960_queue_partial_rw(Command); + return; + } } else if (CommandType == DAC960_MonitoringCommand) { diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h index 1d3ea76554b9..f38145a54a67 100644 --- a/drivers/block/DAC960.h +++ b/drivers/block/DAC960.h @@ -2305,6 +2305,8 @@ typedef struct DAC960_Command unsigned int BlockNumber; unsigned int BlockCount; unsigned int SegmentCount; + int DmaDirection; + struct scatterlist *cmd_sglist; IO_Request_T *Request; struct pci_dev *PciDevice; union { diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 091b61c55852..c784d7554ece 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -8,9 +8,6 @@ # In the future, some of these should be built conditionally. # -export-objs := elevator.o ll_rw_blk.o loop.o genhd.o acsi.o \ - scsi_ioctl.o deadline-iosched.o - obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o deadline-iosched.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 36436a7aa57f..f8a4e7a81f4b 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -274,7 +274,7 @@ void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) init_emergency_isa_pool(); q->bounce_gfp = GFP_NOIO | GFP_DMA; } else - q->bounce_gfp = GFP_NOHIGHIO; + q->bounce_gfp = GFP_NOIO; /* * keep this for debugging for now... diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile index 5ba10d95cdb3..a539e004bb7a 100644 --- a/drivers/block/paride/Makefile +++ b/drivers/block/paride/Makefile @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := paride.o - obj-$(CONFIG_PARIDE) += paride.o obj-$(CONFIG_PARIDE_ATEN) += aten.o obj-$(CONFIG_PARIDE_BPCK) += bpck.o diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile index 00bf471c5d13..510d4b47d5d6 100644 --- a/drivers/cdrom/Makefile +++ b/drivers/cdrom/Makefile @@ -3,22 +3,6 @@ # 30 Jan 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := cdrom.o - - - -# Object file lists. - -obj-y := -obj-m := -obj-n := -obj- := - - - # Each configuration option enables a list of files. obj-$(CONFIG_BLK_DEV_IDECD) += cdrom.o diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 9c19e9e9a79d..87401e06d651 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -992,5 +992,12 @@ config RAW_DRIVER Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. See the raw(8) manpage for more details. +config HANGCHECK_TIMER + tristate "Hangcheck timer" + help + The hangcheck-timer module detects when the system has gone + out to lunch past a certain margin. It can reboot the system + or merely print a warning. + endmenu diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 62bb31774df7..3f8fe27d555f 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -9,13 +9,6 @@ FONTMAPFILE = cp437.uni obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := busmouse.o vt.o generic_serial.o ip2main.o consolemap.o\ - ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \ - selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o - obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o @@ -84,6 +77,7 @@ obj-$(CONFIG_DRM) += drm/ obj-$(CONFIG_PCMCIA) += pcmcia/ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ +obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile index 2ff6e33ffb4e..5c72210792a3 100644 --- a/drivers/char/agp/Makefile +++ b/drivers/char/agp/Makefile @@ -3,8 +3,6 @@ # space ioctl interface to use agp memory. It also adds a kernel interface # that other drivers could use to manipulate agp memory. -export-objs := backend.o - agpgart-y := backend.o frontend.o generic.o agpgart-$(CONFIG_AGP3) += generic-3.0.o agpgart-objs := $(agpgart-y) diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ff7ff2d815b9..268fa5cc5671 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -47,7 +47,7 @@ static void __attribute__((unused)) global_cache_flush(void) flush_agp_cache(); } #else -static void global_cache_flush(void) +static inline void global_cache_flush(void) { flush_agp_cache(); } diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c index 6f58ed077944..37c8fbaf247b 100644 --- a/drivers/char/ftape/compressor/zftape-compress.c +++ b/drivers/char/ftape/compressor/zftape-compress.c @@ -1196,11 +1196,7 @@ int zft_compressor_init(void) printk( KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n" -KERN_INFO "Compiled for kernel version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for kernel version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/char/ftape/lowlevel/Makefile b/drivers/char/ftape/lowlevel/Makefile index e8d2bde6cf3f..febab07ba427 100644 --- a/drivers/char/ftape/lowlevel/Makefile +++ b/drivers/char/ftape/lowlevel/Makefile @@ -23,8 +23,6 @@ # driver for Linux. # -export-objs := ftape_syms.o - obj-$(CONFIG_FTAPE) += ftape.o ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \ diff --git a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c index 70530a2bebd0..9ffe3de655c0 100644 --- a/drivers/char/ftape/lowlevel/ftape-init.c +++ b/drivers/char/ftape/lowlevel/ftape-init.c @@ -70,11 +70,7 @@ KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n" KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n" KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n" -KERN_INFO "Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/char/ftape/zftape/Makefile b/drivers/char/ftape/zftape/Makefile index d42152045f66..6d91c1f77c05 100644 --- a/drivers/char/ftape/zftape/Makefile +++ b/drivers/char/ftape/zftape/Makefile @@ -27,8 +27,6 @@ # ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should # leave this enabled for compatibility with taper. -export-objs := zftape_syms.o - obj-$(CONFIG_ZFTAPE) += zftape.o zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \ diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index 4e56739b6a32..b1c015254c6f 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c @@ -331,11 +331,7 @@ KERN_INFO KERN_INFO "and builtin compression (lzrw3 algorithm).\n" KERN_INFO -"Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +"Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c new file mode 100644 index 000000000000..4fc496279576 --- /dev/null +++ b/drivers/char/hangcheck-timer.c @@ -0,0 +1,127 @@ +/* + * hangcheck-timer.c + * + * Driver for a little io fencing timer. + * + * Copyright (C) 2002 Oracle Corporation. All rights reserved. + * + * Author: Joel Becker <joel.becker@oracle.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have recieved a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +/* + * The hangcheck-timer driver uses the TSC to catch delays that + * jiffies does not notice. A timer is set. When the timer fires, it + * checks whether it was delayed and if that delay exceeds a given + * margin of error. The hangcheck_tick module paramter takes the timer + * duration in seconds. The hangcheck_margin parameter defines the + * margin of error, in seconds. The defaults are 60 seconds for the + * timer and 180 seconds for the margin of error. IOW, a timer is set + * for 60 seconds. When the timer fires, the callback checks the + * actual duration that the timer waited. If the duration exceeds the + * alloted time and margin (here 60 + 180, or 240 seconds), the machine + * is restarted. A healthy machine will have the duration match the + * expected timeout very closely. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/reboot.h> +#include <linux/init.h> +#include <asm/uaccess.h> + + +#define VERSION_STR "0.5.0" + +#define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ +#define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ + +static int hangcheck_tick = DEFAULT_IOFENCE_TICK; +static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; +static int hangcheck_reboot; /* Defaults to not reboot */ + +/* Driver options */ +module_param(hangcheck_tick, int, 0); +MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); +module_param(hangcheck_margin, int, 0); +MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); +module_param(hangcheck_reboot, int, 0); +MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); + +MODULE_AUTHOR("Joel Becker"); +MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); +MODULE_LICENSE("GPL"); + + +/* Last time scheduled */ +static unsigned long long hangcheck_tsc, hangcheck_tsc_margin; + +static void hangcheck_fire(unsigned long); + +static struct timer_list hangcheck_ticktock = + TIMER_INITIALIZER(hangcheck_fire, 0, 0); + +static void hangcheck_fire(unsigned long data) +{ + unsigned long long cur_tsc, tsc_diff; + + cur_tsc = get_cycles(); + + if (cur_tsc > hangcheck_tsc) + tsc_diff = cur_tsc - hangcheck_tsc; + else + tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ + + if (tsc_diff > hangcheck_tsc_margin) { + if (hangcheck_reboot) { + printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); + machine_restart(NULL); + } else { + printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); + } + } + mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); + hangcheck_tsc = get_cycles(); +} + + +static int __init hangcheck_init(void) +{ + printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", + VERSION_STR, hangcheck_tick, hangcheck_margin); + + hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick; + hangcheck_tsc_margin *= HZ; + hangcheck_tsc_margin *= current_cpu_data.loops_per_jiffy; + + hangcheck_tsc = get_cycles(); + mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); + + return 0; +} + + +static void __exit hangcheck_exit(void) +{ + del_timer_sync(&hangcheck_ticktock); +} + +module_init(hangcheck_init); +module_exit(hangcheck_exit); diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 76da04b27c08..1f55b46a8188 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -2,8 +2,6 @@ # Makefile for the ipmi drivers. # -export-objs := ipmi_msghandler.o ipmi_watchdog.o - ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index bc1dfea7021d..8d59b8a25d21 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -918,7 +918,7 @@ static void kbd_bh(unsigned long dummy) DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); -#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) +#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) static unsigned short x86_keycodes[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, diff --git a/drivers/eisa/Makefile b/drivers/eisa/Makefile index 4755ab8e1151..2b9a65897a13 100644 --- a/drivers/eisa/Makefile +++ b/drivers/eisa/Makefile @@ -2,8 +2,6 @@ obj-$(CONFIG_EISA) += eisa-bus.o -export-objs := eisa-bus.o - clean-files:= devlist.h # Ugly hack to get DEVICE_NAME_SIZE value... diff --git a/drivers/fc4/Makefile b/drivers/fc4/Makefile index b9cf156fa294..0db3fbb553e9 100644 --- a/drivers/fc4/Makefile +++ b/drivers/fc4/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux Fibre Channel device drivers. # -export-objs := fc_syms.o - fc4-objs := fc.o fc_syms.o obj-$(CONFIG_FC4) += fc4.o diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 1455de63b5fd..82e3f6792bea 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c @@ -74,7 +74,7 @@ #endif #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) -#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->host->hostdata[0])) +#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) #define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp))) static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int); @@ -449,7 +449,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd } if (status_byte(rsp_status) == QUEUE_FULL) { - printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->channel, SCpnt->target, rsp_status); + printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->device->channel, SCpnt->device->id, rsp_status); } SCpnt->result = (host_status << 16) | (rsp_status & 0xff); @@ -771,10 +771,10 @@ static void fcp_scsi_done (Scsi_Cmnd *SCpnt) { unsigned long flags; - spin_lock_irqsave(SCpnt->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); if (FCP_CMND(SCpnt)->done) FCP_CMND(SCpnt)->done(SCpnt); - spin_unlock_irqrestore(SCpnt->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); } static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) @@ -799,8 +799,8 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i fc->cmd_slots[fcmd->token] = fcmd; if (SCpnt->device->tagged_supported) { - if (jiffies - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] > (5 * 60 * HZ)) { - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] = jiffies; + if (jiffies - fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] > (5 * 60 * HZ)) { + fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] = jiffies; fcp_cntl = FCP_CNTL_QTYPE_ORDERED; } else fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; @@ -916,9 +916,9 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt) unsigned long flags; SCpnt->result = DID_ABORT; - spin_lock_irqsave(SCpnt->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); fcmd->done(SCpnt); - spin_unlock_irqrestore(SCpnt->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); printk("FC: soft abort\n"); return SUCCESS; } else { @@ -932,7 +932,7 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) fc_channel *fc = FC_SCMND(SCpnt); fc->rst_pkt->eh_state = SCSI_STATE_FINISHED; - up(fc->rst_pkt->host->eh_action); + up(fc->rst_pkt->device->host->eh_action); } #define FCP_RESET_TIMEOUT (2*HZ) @@ -955,9 +955,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) cmd = fc->scsi_cmd_pool + 0; FCD(("Preparing rst packet\n")) fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd); - fc->rst_pkt->channel = SCpnt->channel; - fc->rst_pkt->target = SCpnt->target; - fc->rst_pkt->lun = 0; + fc->rst_pkt->device = SCpnt->device; fc->rst_pkt->cmd_len = 0; fc->cmd_slots[0] = fcmd; @@ -989,7 +987,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) * Set up the semaphore so we wait for the command to complete. */ - fc->rst_pkt->host->eh_action = &sem; + fc->rst_pkt->device->host->eh_action = &sem; fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY; fc->rst_pkt->done = fcp_scsi_reset_done; @@ -997,7 +995,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) down(&sem); - fc->rst_pkt->host->eh_action = NULL; + fc->rst_pkt->device->host->eh_action = NULL; del_timer(&fc->rst_pkt->eh_timeout); /* diff --git a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile index 47c08533f38c..336e7b9c3506 100644 --- a/drivers/hotplug/Makefile +++ b/drivers/hotplug/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux kernel pci hotplug controller drivers. # -export-objs := pci_hotplug_core.o pci_hotplug_util.o cpci_hotplug_core.o - obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 69595aa670e9..5d3253927c7a 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -2,9 +2,6 @@ # Makefile for the kernel i2c bus driver. # -export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ - i2c-algo-ite.o i2c-proc.o i2c-algo-ibm_ocp.o - obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index c08844b70152..13bc81139536 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -7,8 +7,6 @@ # Note : at this point, these files are compiled on all systems. # In the future, some of these should be built conditionally. # -export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o - # First come modules that register themselves with the core obj-$(CONFIG_BLK_DEV_IDEPCI) += pci/ diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile index 4645e2dbd791..a1db110ffb48 100644 --- a/drivers/ieee1394/Makefile +++ b/drivers/ieee1394/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux IEEE 1394 implementation # -export-objs := ieee1394_core.o ohci1394.o cmp.o - ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \ highlevel.o csr.o nodemgr.o oui.o dma.o iso.o diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 471aa6bff7c3..1a6ff4982f30 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -2,10 +2,6 @@ # Makefile for the input core drivers. # -# Objects that export symbols. - -export-objs := input.o - # Each configuration option enables a list of files. obj-$(CONFIG_INPUT) += input.o diff --git a/drivers/input/gameport/Makefile b/drivers/input/gameport/Makefile index 084ea95deaf5..5367b4267adf 100644 --- a/drivers/input/gameport/Makefile +++ b/drivers/input/gameport/Makefile @@ -2,10 +2,6 @@ # Makefile for the gameport drivers. # -# Objects that export symbols. - -export-objs := gameport.o - # Each configuration option enables a list of files. obj-$(CONFIG_GAMEPORT) += gameport.o diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index a24db5e01afe..36c24607ec75 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile @@ -2,10 +2,6 @@ # Makefile for the input core drivers. # -# Objects that export symbols. - -export-objs := serio.o - # Each configuration option enables a list of files. obj-$(CONFIG_SERIO) += serio.o diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile index 8b26c2f8be9c..b8265712e7ec 100644 --- a/drivers/isdn/capi/Makefile +++ b/drivers/isdn/capi/Makefile @@ -1,9 +1,5 @@ # Makefile for the CAPI subsystem. -# Objects that export symbols. - -export-objs := kcapi.o capiutil.o capilib.o capifs.o - # Ordering constraints: kernelcapi.o first # Each configuration option enables a list of files. diff --git a/drivers/isdn/eicon/Makefile b/drivers/isdn/eicon/Makefile index 1c60bf021356..fcde8d013922 100644 --- a/drivers/isdn/eicon/Makefile +++ b/drivers/isdn/eicon/Makefile @@ -1,9 +1,5 @@ # Makefile for the eicon ISDN device driver -# Objects that export symbols. - -export-objs := Divas_mod.o eicon_mod.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_EICON_OLD) += eicon.o diff --git a/drivers/isdn/hardware/avm/Makefile b/drivers/isdn/hardware/avm/Makefile index 316a3116a120..b540e8f2efb6 100644 --- a/drivers/isdn/hardware/avm/Makefile +++ b/drivers/isdn/hardware/avm/Makefile @@ -1,9 +1,5 @@ # Makefile for the AVM ISDN device drivers -# Objects that export symbols. - -export-objs := b1dma.o b1pcmcia.o b1.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA) += b1isa.o b1.o diff --git a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile index 67ded00b5eca..99fe876163fe 100644 --- a/drivers/isdn/hardware/eicon/Makefile +++ b/drivers/isdn/hardware/eicon/Makefile @@ -1,9 +1,5 @@ # Makefile for the Eicon DIVA ISDN drivers. -# Objects that export symbols. - -export-objs := diva_didd.o - # Multipart objects. divas-objs := divasmain.o divasfunc.o di.o io.o istream.o diva.o dlist.o divasproc.o diva_dma.o diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index b9ebe49ff7b4..8f5f1409d449 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -4,10 +4,6 @@ EXTRA_CFLAGS += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS) -# Objects that export symbols. - -export-objs := config.o hisax_isac.o hisax_hscx.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_HISAX) += hisax.o diff --git a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile index 4458d5d4478b..a76150977dcc 100644 --- a/drivers/isdn/i4l/Makefile +++ b/drivers/isdn/i4l/Makefile @@ -1,9 +1,5 @@ # Makefile for the kernel ISDN subsystem and device drivers. -# Objects that export symbols. - -export-objs := isdn_common.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN) += isdn.o diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index b296a45294ab..cc3a05d97ad7 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -2,17 +2,6 @@ # Makefile for the Macintosh-specific device drivers. # -# Objects that export symbols. - -export-objs := adb.o mac_hid.o via-pmu.o - -# Object file lists. - -obj-y := -obj-m := -obj-n := -obj- := - # Each configuration option enables a list of files. obj-$(CONFIG_PMAC_PBOOK) += mediabay.o diff --git a/drivers/mca/Makefile b/drivers/mca/Makefile index 1aad9751a345..0794b122520e 100644 --- a/drivers/mca/Makefile +++ b/drivers/mca/Makefile @@ -5,4 +5,3 @@ obj-y := mca-bus.o mca-device.o mca-driver.o obj-$(CONFIG_MCA_PROC_FS) += mca-proc.o obj-$(CONFIG_MCA_LEGACY) += mca-legacy.o -export-objs := mca-bus.o mca-legacy.o mca-proc.o mca-driver.o diff --git a/drivers/md/Makefile b/drivers/md/Makefile index a67bcaf83f7f..9593096cbe51 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -2,7 +2,6 @@ # Makefile for the kernel software RAID and LVM drivers. # -export-objs := md.o xor.o dm-table.o dm-target.o dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ dm-ioctl.o diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index 8bc7b71162c7..2dd9f2b555cc 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel DVB device drivers. # -export-objs := dvb_ksyms.o - dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ dvb_frontend.o dvb_i2c.o dvb_net.o dvb_ksyms.o diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 2b3721c5a58b..62263fa62991 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -2,11 +2,6 @@ # Makefile for the kernel character device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := miropcm20-rds-core.o - miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 56f11de54de2..5bb0b014f8e4 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -2,12 +2,6 @@ # Makefile for the video capture/playback device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := videodev.o v4l2-common.o v4l1-compat.o \ - bttv-if.o cpia.o video-buf.o - bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ bttv-risc.o bttv-vbi.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 79676fe6c37c..b9d3949f9857 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -247,7 +247,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { },{ .v4l2_id = V4L2_STD_PAL_N, .name = "PAL-N", - .Fsc 35468950, + .Fsc = 35468950, .swidth = 768, .sheight = 576, .totalwidth = 1135, diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 71b87992b921..52901b090d7a 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -241,12 +241,6 @@ static void attach_inform(struct saa7146 *saa, int id) } } -static void detach_inform(struct saa7146 *saa, int id) -{ - int i; - i = saa->nr; -} - static void I2CBusScan(struct saa7146 *saa) { int i; @@ -1323,9 +1317,12 @@ static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr) clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y)); } -static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +static int saa_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long argl) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; + void *arg = (void *)argl; + switch (cmd) { case VIDIOCGCAP: { @@ -1809,24 +1806,23 @@ static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg) return 0; } -static int saa_mmap(struct video_device *dev, const char *adr, - unsigned long size) +static int saa_mmap(struct file *file, struct vm_area_struct *vma) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr); return -EINVAL; } -static long saa_read(struct video_device *dev, char *buf, - unsigned long count, int nonblock) +static ssize_t saa_read(struct file *file, char *buf, + size_t count, loff_t *ppos) { return -EINVAL; } -static long saa_write(struct video_device *dev, const char *buf, - unsigned long count, int nonblock) +static ssize_t saa_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; unsigned long todo = count; int blocksize, split; unsigned long flags; @@ -1945,11 +1941,23 @@ static long saa_write(struct video_device *dev, const char *buf, return count; } -static int saa_open(struct video_device *dev, int flags) +static int saa_open(struct inode *inode, struct file *file) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = NULL; + unsigned int minor = minor(inode->i_rdev); + int i; + + for (i = 0; i < SAA7146_MAX; i++) { + if (saa7146s[i].video_dev.minor == minor) { + saa = &saa7146s[i]; + } + } + if (saa == NULL) { + return -ENODEV; + } + file->private_data = saa; - saa->video_dev.busy = 0; + //saa->video_dev.busy = 0; /* old hack to support multiple open */ saa->user++; if (saa->user > 1) return 0; /* device open already, don't reset */ @@ -1957,31 +1965,39 @@ static int saa_open(struct video_device *dev, int flags) return 0; } -static void saa_close(struct video_device *dev) +static int saa_release(struct inode *inode, struct file *file) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; saa->user--; - saa->video_dev.busy = 0; + //saa->video_dev.busy = 0; /* old hack to support multiple open */ if (saa->user > 0) /* still someone using device */ - return; + return 0; saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */ + return 0; } -/* template for video_device-structure */ -static struct video_device saa_template = +static struct file_operations saa_fops = { .owner = THIS_MODULE, - .name = "SAA7146A", - .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, - .hardware = VID_HARDWARE_SAA7146, .open = saa_open, - .close = saa_close, + .release = saa_release, + .ioctl = saa_ioctl, .read = saa_read, + .llseek = no_llseek, .write = saa_write, - .ioctl = saa_ioctl, .mmap = saa_mmap, }; +/* template for video_device-structure */ +static struct video_device saa_template = +{ + .name = "SAA7146A", + .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, + .hardware = VID_HARDWARE_SAA7146, + .fops = &saa_fops, + .minor = -1, +}; + static int configure_saa7146(struct pci_dev *dev, int num) { int result; diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index ec175cec26fc..4ebecaa377ad 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -46,8 +46,6 @@ EXTRA_CFLAGS += ${MPT_CFLAGS} #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC -export-objs := mptbase.o mptscsih.o mptlan.o mptctl.o isense.o - obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o obj-$(CONFIG_FUSION_ISENSE) += isense.o obj-$(CONFIG_FUSION_CTL) += mptctl.o diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile index 8abc1a975d19..a59efb09fed8 100644 --- a/drivers/message/i2o/Makefile +++ b/drivers/message/i2o/Makefile @@ -5,8 +5,6 @@ # In the future, some of these should be built conditionally. # -export-objs := i2o_core.o - obj-$(CONFIG_I2O_PCI) += i2o_pci.o obj-$(CONFIG_I2O) += i2o_core.o i2o_config.o obj-$(CONFIG_I2O_BLOCK) += i2o_block.o diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 711370fed5c6..99d84bed9b3c 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -4,8 +4,6 @@ # Based on: # $Id: Makefile,v 1.66 2002/04/23 13:52:14 mag Exp $ -export-objs := mtdcore.o mtdpart.o redboot.o cmdline.o afs.o mtdconcat.o - obj-y += chips/ maps/ devices/ nand/ # *** BIG UGLY NOTE *** diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile index f33a0191fe08..0ad996f50e59 100644 --- a/drivers/mtd/chips/Makefile +++ b/drivers/mtd/chips/Makefile @@ -3,8 +3,6 @@ # # $Id: Makefile,v 1.7 2001/10/05 06:53:51 dwmw2 Exp $ -export-objs := chipreg.o gen_probe.o - # *** BIG UGLY NOTE *** # # The removal of get_module_symbol() and replacement with diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index a9b817e1b7c8..acac6447e90b 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -3,8 +3,6 @@ # # $Id: Makefile,v 1.5 2001/09/19 22:39:59 dwmw2 Exp $ -export-objs := nand.o nand_ecc.o - nandobjs-y := nand.o nandobjs-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3a66d85f19ed..49d1b678ba27 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -212,6 +212,14 @@ config NET_ETHERNET kernel: saying N will just cause the configurator to skip all the questions about Ethernet network cards. If unsure, say N. +config MII + tristate "generic Media Independent Interface device support" + depends on NET_ETHERNET + help + Most ethernet controllers have MII transceiver either as an external + or internal device. It is safe to say Y or M here even if your + ethernet card lack MII. + config ARM_AM79C961A bool "ARM EBSA110 AM79C961A support" depends on NET_ETHERNET && ARM && ARCH_EBSA110 diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f6a0725f3925..fac88c2ed1af 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -2,12 +2,6 @@ # Makefile for the Linux network (ethercard) device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := 8390.o arlan.o aironet4500_core.o aironet4500_card.o \ - ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \ - net_init.o mii.o rcpci-objs := rcpci45.o rclanmtl.o ifeq ($(CONFIG_ISDN_PPP),y) @@ -63,6 +57,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o # end link order section # +obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_AIRONET4500) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o @@ -199,3 +194,6 @@ obj-$(CONFIG_NET_WIRELESS) += wireless/ obj-$(CONFIG_NET_TULIP) += tulip/ obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_IRDA) += irda/ + + +include $(TOPDIR)/drivers/usb/net/Makefile.mii diff --git a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile index a4a35d58bdfe..6cfc705f7c5c 100644 --- a/drivers/net/appletalk/Makefile +++ b/drivers/net/appletalk/Makefile @@ -2,8 +2,6 @@ # Makefile for drivers/net/appletalk # -export-objs := - obj-$(CONFIG_IPDDP) += ipddp.o obj-$(CONFIG_COPS) += cops.o obj-$(CONFIG_LTPC) += ltpc.o diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile index 2ddc8ad8d4df..e4dae223a344 100644 --- a/drivers/net/arcnet/Makefile +++ b/drivers/net/arcnet/Makefile @@ -1,8 +1,6 @@ # Makefile for linux/drivers/net/arcnet # -export-objs := arcnet.o com20020.o - obj-$(CONFIG_ARCNET) += arcnet.o obj-$(CONFIG_ARCNET_1201) += rfc1201.o obj-$(CONFIG_ARCNET_1051) += rfc1051.o diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile index 68fce8ce9daa..9def86704a91 100644 --- a/drivers/net/hamradio/Makefile +++ b/drivers/net/hamradio/Makefile @@ -10,8 +10,6 @@ # Christoph Hellwig <hch@infradead.org> # -export-objs = hdlcdrv.o - obj-$(CONFIG_DMASCC) += dmascc.o obj-$(CONFIG_SCC) += scc.o obj-$(CONFIG_MKISS) += mkiss.o diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 94e0b522cd81..4d31d2b3c95c 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs = irport.o sir_core.o - # Old SIR drivers (irtty is broken) obj-$(CONFIG_IRTTY_OLD) += irtty.o obj-$(CONFIG_IRPORT_SIR) += irport.o diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index a2b744f10623..888eb07e1050 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -91,6 +91,7 @@ #include <asm/irq.h> #include <asm/pdc.h> #include <asm/cache.h> +#include <asm/parisc-device.h> static char version[] __devinitdata = "82596.c $Revision: 1.29 $\n"; @@ -121,13 +122,13 @@ static char version[] __devinitdata = #define CHECK_WBACK(addr,len) \ - do { if (!dma_consistent) dma_cache_wback((unsigned long)addr,len); } while (0) + do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0) #define CHECK_INV(addr,len) \ - do { if (!dma_consistent) dma_cache_inv((unsigned long)addr,len); } while(0) + do { dma_cache_sync((void *)addr,len, DMA_FROM_DEVICE); } while(0) #define CHECK_WBACK_INV(addr,len) \ - do { if (!dma_consistent) dma_cache_wback_inv((unsigned long)addr,len); } while (0) + do { dma_cache_sync((void *)addr,len, DMA_BIDIRECTIONAL); } while (0) #define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ @@ -383,6 +384,7 @@ struct i596_private { int options; spinlock_t lock; dma_addr_t dma_addr; + struct device *dev; }; static char init_setup[] = @@ -402,10 +404,6 @@ static char init_setup[] = 0x00, 0x7f /* *multi IA */ }; -static struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for - pci_* functions under ccio. */ -static int dma_consistent = 1; /* Zero if pci_alloc_consistent() fails */ - static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -558,8 +556,8 @@ static inline void init_rx_bufs(struct net_device *dev) if (skb == NULL) panic("82596: alloc_skb() failed"); skb_reserve(skb, 2); - dma_addr = pci_map_single(fake_pci_dev, skb->tail,PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ, + DMA_FROM_DEVICE); skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); @@ -605,9 +603,9 @@ static inline void remove_rx_bufs(struct net_device *dev) for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { if (rbd->skb == NULL) break; - pci_unmap_single(fake_pci_dev, + dma_unmap_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ, DMA_FROM_DEVICE); dev_kfree_skb(rbd->skb); } } @@ -774,7 +772,7 @@ static inline int i596_rx(struct net_device *dev) struct sk_buff *newskb; dma_addr_t dma_addr; - pci_unmap_single(fake_pci_dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); /* Get fresh skbuff to replace filled one. */ newskb = dev_alloc_skb(PKT_BUF_SZ + 4); if (newskb == NULL) { @@ -788,7 +786,7 @@ static inline int i596_rx(struct net_device *dev) rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - dma_addr = pci_map_single(fake_pci_dev, newskb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE); rbd->v_data = newskb->tail; rbd->b_data = WSWAPchar(dma_addr); CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); @@ -805,7 +803,7 @@ memory_squeeze: skb->dev = dev; if (!rx_in_place) { /* 16 byte align the data fields */ - pci_dma_sync_single(fake_pci_dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_sync_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); skb_reserve(skb, 2); memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len); } @@ -886,7 +884,7 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private { struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; struct sk_buff *skb = tx_cmd->skb; - pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); @@ -1118,8 +1116,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) tbd->pad = 0; tbd->size = EOF | length; - tx_cmd->dma_addr = pci_map_single(fake_pci_dev, skb->data, skb->len, - PCI_DMA_TODEVICE); + tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len, + DMA_TO_DEVICE); tbd->data = WSWAPchar(tx_cmd->dma_addr); DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); @@ -1156,6 +1154,8 @@ static int __devinit i82596_probe(struct net_device *dev) { int i; struct i596_private *lp; + /* we're going to overwrite dev->priv, so pull the device out */ + struct device *gen_dev = dev->priv; char eth_addr[6]; dma_addr_t dma_addr; @@ -1198,17 +1198,11 @@ static int __devinit i82596_probe(struct net_device *dev) printk("82596.c: MAC of HP700 LAN read from EEPROM\n"); } - dev->mem_start = (unsigned long) pci_alloc_consistent(fake_pci_dev, - sizeof(struct i596_private), &dma_addr); + dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev, + sizeof(struct i596_private), &dma_addr, GFP_KERNEL); if (!dev->mem_start) { - printk("%s: Couldn't get consistent shared memory\n", dev->name); - dma_consistent = 0; - dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); - if (!dev->mem_start) { - printk("%s: Couldn't get shared memory\n", dev->name); - return -ENOMEM; - } - dma_addr = virt_to_bus(dev->mem_start); + printk("%s: Couldn't get shared memory\n", dev->name); + return -ENOMEM; } ether_setup(dev); @@ -1243,6 +1237,7 @@ static int __devinit i82596_probe(struct net_device *dev) lp->scb.rfd = I596_NULL; lp->lock = SPIN_LOCK_UNLOCKED; lp->dma_addr = dma_addr; + lp->dev = gen_dev; CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private)); @@ -1320,7 +1315,7 @@ static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++; } - pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq(skb); tx_cmd->cmd.command = 0; /* Mark free */ @@ -1530,8 +1525,6 @@ lan_init_chip(struct parisc_device *dev) return -ENODEV; } - fake_pci_dev = ccio_get_fake(dev); - if (!dev->irq) { printk(KERN_ERR __FILE__ ": IRQ not found for i82596 at 0x%lx\n", dev->hpa); return -ENODEV; @@ -1546,6 +1539,7 @@ lan_init_chip(struct parisc_device *dev) netdevice->base_addr = dev->hpa; netdevice->irq = dev->irq; netdevice->init = i82596_probe; + netdevice->priv = &dev->dev; retval = register_netdev(netdevice); if (retval) { @@ -1601,13 +1595,8 @@ static void __exit lasi_82596_exit(void) unregister_netdev(netdevice); lp = (struct i596_private *) netdevice->priv; - if (dma_consistent) - pci_free_consistent(fake_pci_dev, - sizeof(struct i596_private), - (void *)netdevice->mem_start, lp->dma_addr); - else - free_page(netdevice->mem_start); - + dma_free_noncoherent(lp->dev, sizeof(struct i596_private), + (void *)netdevice->mem_start, lp->dma_addr); netdevice->priv = NULL; } diff --git a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile index 80393af696ce..98404b743a85 100644 --- a/drivers/net/pcmcia/Makefile +++ b/drivers/net/pcmcia/Makefile @@ -2,9 +2,6 @@ # Makefile for the Linux PCMCIA network device drivers. # -# Things that need to export symbols -export-objs := ray_cs.o - # 16-bit client drivers obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o obj-$(CONFIG_PCMCIA_3C574) += 3c574_cs.o diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile index ff1765b8dc18..f764c538bc7f 100644 --- a/drivers/net/tokenring/Makefile +++ b/drivers/net/tokenring/Makefile @@ -2,8 +2,6 @@ # Makefile for drivers/net/tokenring # -export-objs := tms380tr.o - obj-$(CONFIG_IBMTR) += ibmtr.o obj-$(CONFIG_IBMOL) += olympic.o obj-$(CONFIG_IBMLS) += lanstreamer.o diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 998f810b2ba3..5eef9b7d7c75 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -5,9 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o \ - dlci.o - wanpipe-y := sdlamain.o sdla_ft1.o wanpipe-$(CONFIG_WANPIPE_X25) += sdla_x25.o wanpipe-$(CONFIG_WANPIPE_FR) += sdla_fr.o diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 8ff64e712a46..090523148210 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -2,9 +2,6 @@ # Makefile for the Linux Wireless network device drivers. # -# Things that need to export symbols -export-objs := airo.o orinoco.o hermes.o - # Obsolete cards obj-$(CONFIG_WAVELAN) += wavelan.o obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o diff --git a/drivers/nubus/Makefile b/drivers/nubus/Makefile index 65e553e6b18e..f5ef03cf9879 100644 --- a/drivers/nubus/Makefile +++ b/drivers/nubus/Makefile @@ -2,8 +2,6 @@ # Makefile for the nubus specific drivers. # -export-objs := nubus_syms.o - obj-y := nubus.o obj-$(CONFIG_MODULES) += nubus_syms.o diff --git a/drivers/parisc/Makefile b/drivers/parisc/Makefile index 09e248fd596b..2b9d768bb796 100644 --- a/drivers/parisc/Makefile +++ b/drivers/parisc/Makefile @@ -2,8 +2,6 @@ # Makefile for most of the non-PCI devices in PA-RISC machines # -export-objs := gsc.o superio.o - obj-y := obj-m := obj-n := diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 9c5af58ecab4..20505f6997a9 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1555,38 +1555,6 @@ static int ccio_probe(struct parisc_device *dev) return 0; } -struct pci_dev * ccio_get_fake(const struct parisc_device *dev) -{ - struct ioc *ioc; - - dev = find_pa_parent_type(dev, HPHW_IOA); - if(!dev) - return NULL; - - ioc = ccio_find_ioc(dev->hw_path); - if(!ioc) - return NULL; - - if(ioc->fake_pci_dev) - return ioc->fake_pci_dev; - - ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); - if(ioc->fake_pci_dev == NULL) { - printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); - return NULL; - } - memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev)); - - ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); - if(ioc->fake_pci_dev->dev.platform_data == NULL) { - printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); - return NULL; - } - - HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc; - return ioc->fake_pci_dev; -} - /* We *can't* support JAVA (T600). Venture there at your own risk. */ static struct parisc_device_id ccio_tbl[] = { { HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */ diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 41d2f167aa9a..a66bb850a312 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -974,8 +974,8 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, * * See Documentation/DMA-mapping.txt */ -static void * -sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle) +static void *sba_alloc_consistent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, int gfp) { void *ret; @@ -985,7 +985,7 @@ sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle) return 0; } - ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + ret = (void *) __get_free_pages(gfp, get_order(size)); if (ret) { memset(ret, 0, size); diff --git a/drivers/parport/Makefile b/drivers/parport/Makefile index bfd8516fcfb9..57a5fdedcfa9 100644 --- a/drivers/parport/Makefile +++ b/drivers/parport/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel Parallel port device drivers. # -export-objs := init.o parport_pc.o - parport-objs := share.o ieee1284.o ieee1284_ops.o init.o procfs.o ifeq ($(CONFIG_PARPORT_1284),y) diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 34fb645ff8fe..d00cfb4c862a 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -40,6 +40,7 @@ #include <linux/parport.h> #include <asm/pdc.h> +#include <asm/parisc-device.h> #include <asm/hardware.h> #include <asm/parport_gsc.h> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 5542f7e5dd15..68d448c736bb 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -2,9 +2,6 @@ # Makefile for the PCI bus specific drivers. # -export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ - probe.o proc.o search.o setup-bus.o - obj-y += access.o probe.o pci.o pool.o quirks.o \ names.o pci-driver.o search.o hotplug.o obj-$(CONFIG_PM) += power.o diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 700be62795bf..64145126b7c8 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel pcmcia subsystem (c/o David Hinds) # -export-objs := ds.o cs.o yenta.o sa1100_generic.o - obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o ifeq ($(CONFIG_CARDBUS),y) obj-$(CONFIG_PCMCIA) += yenta_socket.o diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile index de32e032755d..9d42052d9472 100644 --- a/drivers/pnp/Makefile +++ b/drivers/pnp/Makefile @@ -9,4 +9,3 @@ obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o $(pnp obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ -export-objs := core.o driver.o resource.o $(pnp-card-y) diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile index 1539195169db..cac18bbfb817 100644 --- a/drivers/pnp/isapnp/Makefile +++ b/drivers/pnp/isapnp/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel ISAPNP driver. # -export-objs := core.o compat.o - isapnp-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o compat.o $(isapnp-proc-y) diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile index 60a06c7831c3..8c6c3d61aba7 100644 --- a/drivers/pnp/pnpbios/Makefile +++ b/drivers/pnp/pnpbios/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel PNPBIOS driver. # -export-objs := core.o - pnpbios-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o $(pnpbios-proc-y) diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index 8aa452c422d2..9b4729c2cb8d 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile @@ -2,8 +2,6 @@ # S/390 block devices # -export-objs := dasd.o dasd_devmap.o dasd_ioctl.o dasd_erp.o - dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o dasd_diag_mod-objs := dasd_diag.o diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 8f79046e0a1a..7264cc6182c9 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -2,8 +2,6 @@ # S/390 character devices # -export-objs := sclp.o tape_core.o tape_devmap.o tape_std.o - tub3270-objs := tuball.o tubfs.o tubtty.o \ tubttyaid.o tubttybld.o tubttyscl.o \ tubttyrcl.o tubttysiz.o diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index d1483e186c46..c0ed46dbe0a4 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -3,15 +3,8 @@ # obj-y += airq.o blacklist.o chsc.o cio.o css.o requestirq.o -export-objs += airq.o css.o cio.o requestirq.o - ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o -export-objs += device.o device_ops.o - obj-$(CONFIG_CCWGROUP) += ccwgroup.o -export-objs += ccwgroup.o - obj-$(CONFIG_QDIO) += qdio.o -export-objs += qdio.o diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 692d42c758ba..fe513e2ee15d 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile @@ -2,8 +2,6 @@ # S/390 network devices # -export-objs := iucv.o fsm.o cu3088.o - ctc-objs := ctcmain.o ctctty.o obj-$(CONFIG_IUCV) += iucv.o fsm.o diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile index 52bafc65ff79..3a5ea1dc789a 100644 --- a/drivers/sbus/char/Makefile +++ b/drivers/sbus/char/Makefile @@ -7,8 +7,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := bbc_i2c.o - vfc-objs := vfc_dev.o vfc_i2c.o bbc-objs := bbc_i2c.o bbc_envctrl.o diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 1a3c4b5ada34..eb12ae5c4e88 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -18,8 +18,6 @@ CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM -export-objs := scsi_syms.o scsi_proc.o 53c700.o - subdir-$(CONFIG_PCMCIA) += pcmcia obj-$(CONFIG_SCSI) += scsi_mod.o diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index adf574bd313b..a397ed69b47a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -42,12 +42,6 @@ * POSSIBILITY OF SUCH DAMAGES. */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHD_MODVERSION_FILE - #include "aic79xx_osm.h" #include "aic79xx_inline.h" #include <scsi/scsicam.h> diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 28995d6edb90..5913588f86d2 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -50,9 +50,6 @@ #include <linux/pci.h> #include <linux/smp_lock.h> #include <linux/version.h> -#ifndef AHD_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include <linux/module.h> #include <asm/byteorder.h> #include <asm/io.h> diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 8ddc984c5ed3..a12ad53ec289 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -119,12 +119,6 @@ * */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHC_MODVERSION_FILE - #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" #include <scsi/scsicam.h> diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 82656585d4fb..4baa42a415b6 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -67,9 +67,6 @@ #include <linux/pci.h> #include <linux/smp_lock.h> #include <linux/version.h> -#ifndef AHC_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include <linux/module.h> #include <asm/byteorder.h> #include <asm/io.h> diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index d0f22c5b018d..a6eb8a9730fb 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -453,7 +453,7 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun) Scsi_Cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; - ptr && ((ptr->target != target) || (ptr->lun != lun)); + ptr && ((ptr->device->id != target) || (ptr->device->lun != lun)); prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble) ; if (ptr) { @@ -1447,7 +1447,7 @@ static void esp_release_dmabufs(struct esp *esp, Scsi_Cmnd *sp) static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->target]; + struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; sp->SCp.ptr = ep->saved_ptr; sp->SCp.buffer = ep->saved_buffer; @@ -1457,7 +1457,7 @@ static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp) static void esp_save_pointers(struct esp *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->target]; + struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; ep->saved_ptr = sp->SCp.ptr; ep->saved_buffer = sp->SCp.buffer; @@ -1559,8 +1559,8 @@ static void esp_exec_cmd(struct esp *esp) SDptr = SCptr->device; esp_dev = SDptr->hostdata; - lun = SCptr->lun; - target = SCptr->target; + lun = SCptr->device->lun; + target = SCptr->device->id; esp->snip = 0; esp->msgout_len = 0; @@ -1621,7 +1621,7 @@ do_sync_known: * disconnect. */ ESPMISC(("esp: Selecting device for first time. target=%d " - "lun=%d\n", target, SCptr->lun)); + "lun=%d\n", target, SCptr->device->lun)); if (!SDptr->borken && !esp_dev->disconnect) esp_dev->disconnect = 1; @@ -1731,7 +1731,7 @@ after_nego_msg_built: SDptr->removable == 0) || cdrom_hwbug_wkaround || SDptr->borken) { ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d " - "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); + "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun)); esp_dev->disconnect = 0; *cmdp++ = IDENTIFY(0, lun); } else { @@ -1822,10 +1822,10 @@ static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) SCpnt->SCp.phase = not_issued; /* We use the scratch area. */ - ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->target, SCpnt->lun)); - ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun)); + ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->device->lun)); + ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->device->lun)); - esp = (struct esp *) SCpnt->host->hostdata; + esp = (struct esp *) SCpnt->device->host->hostdata; esp_get_dmabufs(esp, SCpnt); esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */ @@ -1852,7 +1852,7 @@ static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) /* Only queuing supported in this ESP driver. */ static int esp_command(Scsi_Cmnd *SCpnt) { - struct esp *esp = (struct esp *) SCpnt->host->hostdata; + struct esp *esp = (struct esp *) SCpnt->device->host->hostdata; ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id)); return -1; @@ -1863,7 +1863,7 @@ static void esp_dump_cmd(Scsi_Cmnd *SCptr) { ESPLOG(("[tgt<%02x> lun<%02x> " "pphase<%s> cphase<%s>]", - SCptr->target, SCptr->lun, + SCptr->device->id, SCptr->device->lun, phase_string(SCptr->SCp.sent_command), phase_string(SCptr->SCp.phase))); } @@ -1917,7 +1917,7 @@ static void esp_dump_state(struct esp *esp) /* Abort a command. The host_lock is acquired by caller. */ static int esp_abort(Scsi_Cmnd *SCptr) { - struct esp *esp = (struct esp *) SCptr->host->hostdata; + struct esp *esp = (struct esp *) SCptr->device->host->hostdata; int don; ESPLOG(("esp%d: Aborting command\n", esp->esp_id)); @@ -2049,7 +2049,7 @@ static int esp_do_resetbus(struct esp *esp) */ static int esp_reset(Scsi_Cmnd *SCptr) { - struct esp *esp = (struct esp *) SCptr->host->hostdata; + struct esp *esp = (struct esp *) SCptr->device->host->hostdata; (void) esp_do_resetbus(esp); @@ -2474,13 +2474,13 @@ static inline void esp_connect(struct esp *esp, Scsi_Cmnd *sp) if (esp->prev_soff != esp_dev->sync_max_offset || esp->prev_stp != esp_dev->sync_min_period || (esp->erev > esp100a && - esp->prev_cfg3 != esp->config3[sp->target])) { + esp->prev_cfg3 != esp->config3[sp->device->id])) { esp->prev_soff = esp_dev->sync_max_offset; esp->prev_stp = esp_dev->sync_min_period; sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF); sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP); if (esp->erev > esp100a) { - esp->prev_cfg3 = esp->config3[sp->target]; + esp->prev_cfg3 = esp->config3[sp->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } } @@ -2736,7 +2736,7 @@ static int esp_do_data_finale(struct esp *esp) esp->esp_id, SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual)); ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, - SCptr->target)); + SCptr->device->id)); SCptr->device->borken = 1; esp_dev->sync = 0; bytes_sent = 0; @@ -2842,7 +2842,7 @@ static int esp_do_freebus(struct esp *esp) if (SCptr->SCp.Status != GOOD && SCptr->SCp.Status != CONDITION_GOOD && - ((1<<SCptr->target) & esp->targets_present) && + ((1<<SCptr->device->id) & esp->targets_present) && esp_dev->sync && esp_dev->sync_max_offset) { /* SCSI standard says that the synchronous capabilities @@ -2853,7 +2853,7 @@ static int esp_do_freebus(struct esp *esp) * state. */ ESPMISC(("esp: Status <%d> for target %d lun %d\n", - SCptr->SCp.Status, SCptr->target, SCptr->lun)); + SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun)); /* But don't do this when spinning up a disk at * boot time while we poll for completion as it @@ -2864,14 +2864,14 @@ static int esp_do_freebus(struct esp *esp) if (esp_should_clear_sync(SCptr) != 0) esp_dev->sync = 0; } - ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->lun)); + ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun)); esp_done(esp, ((SCptr->SCp.Status & 0xff) | ((SCptr->SCp.Message & 0xff)<<8) | (DID_OK << 16))); } else if (esp->prevmsgin == DISCONNECT) { /* Normal disconnect. */ esp_cmd(esp, ESP_CMD_ESEL); - ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun)); + ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun)); append_SC(&esp->disconnected_SC, SCptr); esp->current_SC = NULL; if (esp->issue_SC) @@ -2901,21 +2901,21 @@ static int esp_bad_reconnect(struct esp *esp) sp = esp->issue_SC; ESPLOG(("esp%d: issue_SC[", esp->esp_id)); while (sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); sp = (Scsi_Cmnd *) sp->host_scribble; } ESPLOG(("]\n")); sp = esp->current_SC; ESPLOG(("esp%d: current_SC[", esp->esp_id)); if (sp) - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); else ESPLOG(("<NULL>")); ESPLOG(("]\n")); sp = esp->disconnected_SC; ESPLOG(("esp%d: disconnected_SC[", esp->esp_id)); while (sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); sp = (Scsi_Cmnd *) sp->host_scribble; } ESPLOG(("]\n")); @@ -2959,7 +2959,7 @@ static int esp_do_reconnect(struct esp *esp) esp_cmd(esp, ESP_CMD_MOK); if (esp->erev == fashme) - sbus_writeb(((SCptr->target & 0xf) | + sbus_writeb(((SCptr->device->id & 0xf) | (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)), esp->eregs + ESP_BUSID); @@ -3246,7 +3246,7 @@ static int esp_select_complete(struct esp *esp) */ if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) { /* target speaks... */ - esp->targets_present |= (1<<SCptr->target); + esp->targets_present |= (1<<SCptr->device->id); /* What if the target ignores the sdtr? */ if (esp->snip) @@ -3275,7 +3275,7 @@ static int esp_select_complete(struct esp *esp) * XXX for synchronous transfers. */ ESPLOG(("esp%d: STEP_ASEL for tgt %d\n", - esp->esp_id, SCptr->target)); + esp->esp_id, SCptr->device->id)); case ESP_STEP_SID: /* Arbitration won, target selected, went @@ -3395,7 +3395,7 @@ static int esp_select_complete(struct esp *esp) if (esp->disconnected_SC) esp_cmd(esp, ESP_CMD_ESEL); - if (((1<<SCptr->target) & esp->targets_present) && + if (((1<<SCptr->device->id) & esp->targets_present) && esp->seqreg != 0 && (esp->cur_msgout[0] == EXTENDED_MESSAGE) && (SCptr->SCp.phase == in_slct_msg || @@ -3403,7 +3403,7 @@ static int esp_select_complete(struct esp *esp) /* shit */ esp->snip = 0; ESPLOG(("esp%d: Failed synchronous negotiation for target %d " - "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); + "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun)); esp_dev->sync_max_offset = 0; esp_dev->sync_min_period = 0; esp_dev->sync = 1; /* so we don't negotiate again */ @@ -3429,9 +3429,9 @@ static int esp_select_complete(struct esp *esp) * or whenever when we are scanning the bus for targets. * But first make sure that is really what is happening. */ - if (((1<<SCptr->target) & esp->targets_present)) { + if (((1<<SCptr->device->id) & esp->targets_present)) { ESPLOG(("esp%d: Warning, live target %d not responding to " - "selection.\n", esp->esp_id, SCptr->target)); + "selection.\n", esp->esp_id, SCptr->device->id)); /* This _CAN_ happen. The SCSI standard states that * the target is to _not_ respond to selection if @@ -3444,7 +3444,7 @@ static int esp_select_complete(struct esp *esp) /* Else, there really isn't anyone there. */ ESPMISC(("esp: selection failure, maybe nobody there?\n")); ESPMISC(("esp: target %d lun %d\n", - SCptr->target, SCptr->lun)); + SCptr->device->id, SCptr->device->lun)); esp_done(esp, (DID_BAD_TARGET << 16)); } return do_intr_end; @@ -3517,7 +3517,7 @@ static int check_singlebyte_msg(struct esp *esp) case NOP: ESPLOG(("esp%d: target %d sends a nop\n", esp->esp_id, - esp->current_SC->target)); + esp->current_SC->device->id)); return 0; case RESTORE_POINTERS: @@ -3600,7 +3600,7 @@ static void sync_report(struct esp *esp) int integer = hz / 1000000; int fraction = (hz - (integer * 1000000)) / 10000; if ((esp->erev == fashme) && - (esp->config3[esp->current_SC->target] & ESP_CONFIG3_EWIDE)) { + (esp->config3[esp->current_SC->device->id] & ESP_CONFIG3_EWIDE)) { type = "FAST-WIDE"; integer <<= 1; fraction <<= 1; @@ -3615,7 +3615,7 @@ static void sync_report(struct esp *esp) * sibling call optimization. -DaveM */ ESPLOG((KERN_INFO "esp%d: target %d ", - esp->esp_id, esp->current_SC->target)); + esp->esp_id, esp->current_SC->device->id)); ESPLOG(("[period %dns offset %d %d.%02dMHz ", (int) msg3 * 4, (int) msg4, integer, fraction)); @@ -3623,7 +3623,7 @@ static void sync_report(struct esp *esp) (((msg3 * 4) < 200) ? "-II" : ""))); } else { ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n", - esp->esp_id, esp->current_SC->target)); + esp->esp_id, esp->current_SC->device->id)); } } @@ -3707,11 +3707,11 @@ static int check_multibyte_msg(struct esp *esp) */ if (esp->erev == fashme) esp_dev->sync_max_offset &= ~esp->radelay; - esp->config3[SCptr->target] |= bit; + esp->config3[SCptr->device->id] |= bit; } else { - esp->config3[SCptr->target] &= ~bit; + esp->config3[SCptr->device->id] &= ~bit; } - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } esp->prev_soff = esp_dev->sync_max_offset; @@ -3721,7 +3721,7 @@ static int check_multibyte_msg(struct esp *esp) ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n", esp_dev->sync_max_offset, esp_dev->sync_min_period, - esp->config3[SCptr->target])); + esp->config3[SCptr->device->id])); esp->snip = 0; } else if (esp_dev->sync_max_offset) { @@ -3740,8 +3740,8 @@ static int check_multibyte_msg(struct esp *esp) bit = ESP_CONFIG3_FAST; else bit = ESP_CONFIG3_FSCSI; - esp->config3[SCptr->target] &= ~bit; - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->config3[SCptr->device->id] &= ~bit; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } } @@ -3778,7 +3778,7 @@ static int check_multibyte_msg(struct esp *esp) /* Things look good; let's see what we got. */ if (size == 16) { /* Set config 3 register for this target. */ - esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE; + esp->config3[SCptr->device->id] |= ESP_CONFIG3_EWIDE; } else { /* Just make sure it was one byte sized. */ if (size != 8) { @@ -3788,9 +3788,9 @@ static int check_multibyte_msg(struct esp *esp) goto finish; } /* Pure paranoia. */ - esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE); + esp->config3[SCptr->device->id] &= ~(ESP_CONFIG3_EWIDE); } - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); /* Regardless, next try for sync transfers. */ @@ -4258,7 +4258,7 @@ static void esp_handle(struct esp *esp) * a nexus is alive on the bus. */ ESPLOG(("esp%d: Forcing async and disabling disconnect for " - "target %d\n", esp->esp_id, SCptr->target)); + "target %d\n", esp->esp_id, SCptr->device->id)); SCptr->device->borken = 1; /* foo on you */ } diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c index f8d8fa5adfb6..287a58623856 100644 --- a/drivers/scsi/fcal.c +++ b/drivers/scsi/fcal.c @@ -292,11 +292,12 @@ static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmn if (SCpnt->cmnd[1] & 0xe0) return -EINVAL; /* FC-PLDA tells us... */ memset(addr, 0, 8); - f = (struct fcal *)SCpnt->host->hostdata; - if (!f->map[SCpnt->target]) return -EINVAL; + f = (struct fcal *)SCpnt->device->host->hostdata; + if (!f->map[SCpnt->device->id]) + return -EINVAL; /* Now, determine DID: It will be Native Identifier, so we zero upper 2 bytes of the 3 byte DID, lowest byte will be AL-PA */ - fcmd->did = target2alpa[SCpnt->target]; + fcmd->did = target2alpa[SCpnt->device->id]; FCALD(("trying DID %06x\n", fcmd->did)) return 0; } diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 59c003465dc1..13aba88e03d6 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -351,7 +351,7 @@ static void aha152x_release_cs(u_long arg) DEBUG(0, "aha152x_release_cs(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(driver_template.module) != 0) { DEBUG(1, "aha152x_cs: release postponed, " diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index fe0afc581202..5d99e11bf066 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -314,7 +314,7 @@ static void fdomain_release(u_long arg) DEBUG(0, "fdomain_release(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(&__this_module) != 0) { DEBUG(1, "fdomain_cs: release postponed, " diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 142622fcdb89..981e52266acf 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -330,7 +330,7 @@ static void qlogic_release(u_long arg) DEBUG(0, "qlogic_release(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(&__this_module) != 0) { DEBUG(0, "qlogic_cs: release postponed, device still open\n"); diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index 3c3452557f8b..24a7379d67d5 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -156,12 +156,12 @@ int __init pluto_detect(Scsi_Host_Template *tpnt) pluto->fc = fc; - SCpnt->host = host; SCpnt->cmnd[0] = INQUIRY; SCpnt->cmnd[4] = 255; /* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */ SCpnt->device = &dev; + dev.host = host; SCpnt->cmd_len = COMMAND_SIZE(INQUIRY); @@ -325,16 +325,18 @@ const char *pluto_info(struct Scsi_Host *host) */ static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd) { - PLND(("encode addr %d %d %d\n", SCpnt->channel, SCpnt->target, SCpnt->cmnd[1] & 0xe0)) + PLND(("encode addr %d %d %d\n", SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd[1] & 0xe0)) /* We don't support LUNs - neither does SSA :) */ - if (SCpnt->cmnd[1] & 0xe0) return -EINVAL; - if (!SCpnt->channel) { - if (SCpnt->target) return -EINVAL; + if (SCpnt->cmnd[1] & 0xe0) + return -EINVAL; + if (!SCpnt->device->channel) { + if (SCpnt->device->id) + return -EINVAL; memset (addr, 0, 4 * sizeof(u16)); } else { addr[0] = 1; - addr[1] = SCpnt->channel - 1; - addr[2] = SCpnt->target; + addr[1] = SCpnt->device->channel - 1; + addr[2] = SCpnt->device->id; addr[3] = 0; } /* We're Point-to-Point, so target it to the default DID */ diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 933b90ed639b..a9ca081ffd60 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1004,16 +1004,16 @@ static inline void cmd_frob(struct Command_Entry *cmd, Scsi_Cmnd *Cmnd, memset(cmd, 0, sizeof(struct Command_Entry)); cmd->hdr.entry_cnt = 1; cmd->hdr.entry_type = ENTRY_COMMAND; - cmd->target_id = Cmnd->target; - cmd->target_lun = Cmnd->lun; + cmd->target_id = Cmnd->device->id; + cmd->target_lun = Cmnd->device->lun; cmd->cdb_length = Cmnd->cmd_len; cmd->control_flags = 0; if (Cmnd->device->tagged_supported) { - if (qpti->cmd_count[Cmnd->target] == 0) - qpti->tag_ages[Cmnd->target] = jiffies; - if ((jiffies - qpti->tag_ages[Cmnd->target]) > (5*HZ)) { + if (qpti->cmd_count[Cmnd->device->id] == 0) + qpti->tag_ages[Cmnd->device->id] = jiffies; + if ((jiffies - qpti->tag_ages[Cmnd->device->id]) > (5*HZ)) { cmd->control_flags = CFLAG_ORDERED_TAG; - qpti->tag_ages[Cmnd->target] = jiffies; + qpti->tag_ages[Cmnd->device->id] = jiffies; } else cmd->control_flags = CFLAG_SIMPLE_TAG; } @@ -1097,7 +1097,7 @@ static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd, cmd->handle = in_ptr; qpti->cmd_slots[in_ptr] = Cmnd; - qpti->cmd_count[Cmnd->target]++; + qpti->cmd_count[Cmnd->device->id]++; sbus_writew(in_ptr, qpti->qregs + MBOX4); qpti->req_in_ptr = in_ptr; @@ -1118,8 +1118,8 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int */ static void ourdone(Scsi_Cmnd *Cmnd) { - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata; - int tgt = Cmnd->target; + struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; + int tgt = Cmnd->device->id; void (*done) (Scsi_Cmnd *); /* This grot added by DaveM, blame him for ugliness. @@ -1170,7 +1170,7 @@ static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)); static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) { - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata; + struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; unsigned long flags; /* @@ -1229,7 +1229,7 @@ static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, * and can rock on.. */ if (qpti == NULL) - Cmnd->host->hostt->queuecommand = qlogicpti_queuecommand; + Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand; spin_unlock_irqrestore(&qpti->lock, flags); @@ -1246,7 +1246,7 @@ static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, */ static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) { - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; struct Command_Entry *cmd; unsigned long flags; @@ -1431,7 +1431,7 @@ static Scsi_Cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) Cmnd->request_bufflen, scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); } - qpti->cmd_count[Cmnd->target]--; + qpti->cmd_count[Cmnd->device->id]--; sbus_writew(out_ptr, qpti->qregs + MBOX5); Cmnd->host_scribble = (unsigned char *) done_queue; done_queue = Cmnd; @@ -1468,7 +1468,7 @@ static void qpti_intr(int irq, void *dev_id, struct pt_regs *regs) static int qlogicpti_abort(Scsi_Cmnd *Cmnd) { u_short param[6]; - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; int return_status = SUCCESS; unsigned long flags; @@ -1476,7 +1476,7 @@ static int qlogicpti_abort(Scsi_Cmnd *Cmnd) int i; printk(KERN_WARNING "qlogicpti : Aborting cmd for tgt[%d] lun[%d]\n", - (int)Cmnd->target, (int)Cmnd->lun); + (int)Cmnd->device->id, (int)Cmnd->device->lun); spin_lock_irqsave(&qpti->lock, flags); @@ -1491,7 +1491,7 @@ static int qlogicpti_abort(Scsi_Cmnd *Cmnd) cmd_cookie = i; param[0] = MBOX_ABORT; - param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; + param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun; param[2] = cmd_cookie >> 16; param[3] = cmd_cookie & 0xffff; if (qlogicpti_mbox_command(qpti, param, 0) || @@ -1510,7 +1510,7 @@ static int qlogicpti_abort(Scsi_Cmnd *Cmnd) static int qlogicpti_reset(Scsi_Cmnd *Cmnd) { u_short param[6]; - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; int return_status = SUCCESS; unsigned long flags; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index bef0602ef98a..1624be1a83df 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1594,6 +1594,7 @@ void scsi_error_handler(void *data) */ sprintf(current->comm, "scsi_eh_%d", shost->host_no); + current->flags |= PF_IOTHREAD; shost->eh_wait = &sem; shost->ehandler = current; diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index a5bb58e9fd55..97482bed7f31 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -20,6 +20,7 @@ #include <linux/types.h> #include <asm/hardware.h> +#include <asm/parisc-device.h> #include <asm/io.h> #include <asm/serial.h> @@ -32,6 +33,7 @@ static void setup_parisc_serial(struct serial_struct *serial, serial->type = PORT_16550A; serial->line = line; + serial->iomap_base = address; serial->iomem_base = ioremap(address, 0x8); serial->irq = irq; @@ -91,11 +93,13 @@ static struct parisc_device_id serial_tbl[] = { { 0 } }; -/* Hack. Dino's serial port will get listed first on some machines. - * So we register this driver first which knows about Lasi's serial port. - * This needs to get fixed properly somehow. +/* Hack. Some machines have SERIAL_0 attached to Lasi and SERIAL_1 + * attached to Dino. Unfortunately, Dino appears before Lasi in the device + * tree. To ensure that ttyS0 == SERIAL_0, we register two drivers; one + * which only knows about Lasi and then a second which will find all the + * other serial ports. HPUX ignores this problem. */ -static struct parisc_device_id serial1_tbl[] = { +static struct parisc_device_id lasi_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ @@ -111,9 +115,9 @@ static struct parisc_device_id serial1_tbl[] = { MODULE_DEVICE_TABLE(parisc, serial_tbl); -static struct parisc_driver serial1_driver = { - .name = "Serial RS232", - .id_table = serial1_tbl, +static struct parisc_driver lasi_driver = { + .name = "Lasi RS232", + .id_table = lasi_tbl, .probe = serial_init_chip, }; @@ -125,7 +129,7 @@ static struct parisc_driver serial_driver = { int __init probe_serial_gsc(void) { - register_parisc_driver(&serial1_driver); + register_parisc_driver(&lasi_driver); register_parisc_driver(&serial_driver); return 0; } diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index b23d6ef441cd..b06bb73f3ee4 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -4,8 +4,6 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -export-objs := core.o 8250.o 8250_pci.o suncore.o - serial-8250-y := serial-8250-$(CONFIG_GSC) += 8250_gsc.o serial-8250-$(CONFIG_PCI) += 8250_pci.o diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 3ef15146632e..26d884a3189d 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -23,7 +23,9 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/console.h> +#include <linux/slab.h> #include <asm/io.h> +#include <asm/parisc-device.h> #ifdef CONFIG_MAGIC_SYSRQ #include <linux/sysrq.h> @@ -32,34 +34,35 @@ #include <linux/serial_core.h> -#define MUX_NR 1 - #define MUX_OFFSET 0x800 #define MUX_LINE_OFFSET 0x80 #define MUX_FIFO_SIZE 255 -#define MUX_MIN_FREE_SIZE 32 - -#define MUX_FIFO_DRAIN_DELAY 1 -#define MUX_POLL_DELAY (30 * HZ / 1000) +#define MUX_POLL_DELAY (30 * HZ / 1000) -#define IO_COMMAND_REG_OFFSET 0x30 -#define IO_STATUS_REG_OFFSET 0x34 #define IO_DATA_REG_OFFSET 0x3c #define IO_DCOUNT_REG_OFFSET 0x40 -#define IO_UCOUNT_REG_OFFSET 0x44 -#define IO_FIFOS_REG_OFFSET 0x48 #define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000) #define MUX_STATUS(status) ((status & 0xF000) == 0x8000) #define MUX_BREAK(status) ((status & 0xF000) == 0x2000) +#define UART_NR 8 +struct mux_card { + struct uart_port ports[UART_NR]; + struct uart_driver drv; + struct mux_card *next; +}; + +static struct mux_card mux_card_head = { + .next = NULL, +}; -static struct uart_port mux_ports[MUX_NR]; static struct timer_list mux_timer; #define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET) #define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET) +#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8 /** * mux_tx_empty - Check if the transmitter fifo is empty. @@ -205,8 +208,8 @@ static void mux_write(struct uart_port *port) static void mux_read(struct uart_port *port) { int data; - __u32 start_count = port->icount.rx; struct tty_struct *tty = port->info->tty; + __u32 start_count = port->icount.rx; while(1) { data = __raw_readl((unsigned long)port->membase @@ -294,7 +297,7 @@ static const char *mux_type(struct uart_port *port) } /** - * release_port - Release memory and IO regions. + * mux_release_port - Release memory and IO regions. * @port: Ptr to the uart_port. * * Release any memory and IO region resources currently in use by @@ -350,17 +353,26 @@ static int mux_verify_port(struct uart_port *port, struct serial_struct *ser) } /** - * mux_drv_poll - Mux poll function. + * mux_drv_poll - Mux poll function. * @unused: Unused variable * * This function periodically polls the Serial MUX to check for new data. */ static void mux_poll(unsigned long unused) { - struct uart_port *port = &mux_ports[0]; + int i; + struct mux_card *card = &mux_card_head; + + while(card) { + for(i = 0; i < UART_NR; ++i) { + if(!card->ports[i].info) + continue; - mux_read(port); - mux_write(port); + mux_read(&card->ports[i]); + mux_write(&card->ports[i]); + } + card = card->next; + } mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); } @@ -395,20 +407,6 @@ static struct uart_ops mux_pops = { .verify_port = mux_verify_port, }; -static struct uart_driver mux_reg = { - .owner = THIS_MODULE, - .driver_name = "ttyB", -#ifdef CONFIG_DEVFS_FS - .dev_name = "ttyB%d", -#else - .dev_name = "ttyB%d", -#endif - .major = MUX_MAJOR, - .minor = 0, - .nr = MUX_NR, - .cons = MUX_CONSOLE, -}; - /** * mux_probe - Determine if the Serial Mux should claim this device. * @dev: The parisc device. @@ -418,36 +416,77 @@ static struct uart_driver mux_reg = { */ static int __init mux_probe(struct parisc_device *dev) { - int i, ret; - struct uart_port *port = &mux_ports[0]; - - init_timer(&mux_timer); - mux_timer.function = mux_poll; - - printk(KERN_INFO "Serial mux driver Revision: 0.1\n"); - - ret = uart_register_driver(&mux_reg); - if (ret) - return ret; - - for (i = 0; i < MUX_NR; i++) { - port = &mux_ports[i]; - - port->iobase = 0; - port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET); - port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); - port->iotype = SERIAL_IO_MEM; - port->type = PORT_MUX; - port->irq = SERIAL_IRQ_NONE; - port->uartclk = 0; - port->fifosize = MUX_FIFO_SIZE; - port->ops = &mux_pops; - port->flags = UPF_BOOT_AUTOCONF; - port->line = 0; - - uart_add_one_port(&mux_reg, port); + int i, j, ret, ports, port_cnt = 0; + u8 iodc_data[8]; + unsigned long bytecnt; + struct uart_port *port; + struct mux_card *card = &mux_card_head; + + ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8); + if(ret != PDC_OK) { + printk(KERN_ERR "Serial mux: Unable to read IODC.\n"); + return 1; + } + + ports = GET_MUX_PORTS(iodc_data); + printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n", + ports); + + if(!card->drv.nr) { + init_timer(&mux_timer); + mux_timer.function = mux_poll; + } else { + port_cnt += UART_NR; + while(card->next) { + card = card->next; + port_cnt += UART_NR; + } } + for(i = 0; i < ports / UART_NR; ++i) { + if(card->drv.nr) { + card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL); + if(!card->next) { + printk(KERN_ERR "Serial mux: Unable to allocate memory.\n"); + return 1; + } + memset(card->next, '\0', sizeof(struct mux_card)); + card = card->next; + } + + card->drv.owner = THIS_MODULE; + card->drv.driver_name = "ttyB"; + card->drv.dev_name = "ttyB%d"; + card->drv.major = MUX_MAJOR; + card->drv.minor = port_cnt; + card->drv.nr = UART_NR; + card->drv.cons = MUX_CONSOLE; + + ret = uart_register_driver(&card->drv); + if(ret) { + printk(KERN_ERR "Serial mux: Unable to register driver.\n"); + return 1; + } + + for(j = 0; j < UART_NR; ++j) { + port = &card->ports[j]; + + port->iobase = 0; + port->mapbase = dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET); + port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); + port->iotype = SERIAL_IO_MEM; + port->type = PORT_MUX; + port->irq = SERIAL_IRQ_NONE; + port->uartclk = 0; + port->fifosize = MUX_FIFO_SIZE; + port->ops = &mux_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->line = j; + ret = uart_add_one_port(&card->drv, port); + BUG_ON(ret); + } + port_cnt += UART_NR; + } return 0; } @@ -459,9 +498,9 @@ static struct parisc_device_id mux_tbl[] = { MODULE_DEVICE_TABLE(parisc, mux_tbl); static struct parisc_driver mux_driver = { - .name = "Serial MUX driver", - .id_table = mux_tbl, - .probe = mux_probe, + .name = "Serial MUX", + .id_table = mux_tbl, + .probe = mux_probe, }; /** @@ -482,12 +521,13 @@ static int __init mux_init(void) static void __exit mux_exit(void) { int i; + struct mux_card *card = &mux_card_head; - for (i = 0; i < MUX_NR; i++) { - uart_remove_one_port(&mux_reg, &mux_ports[i]); + for (i = 0; i < UART_NR; i++) { + uart_remove_one_port(&card->drv, &card->ports[i]); } - uart_unregister_driver(&mux_reg); + uart_unregister_driver(&card->drv); } module_init(mux_init); diff --git a/drivers/sgi/char/Makefile b/drivers/sgi/char/Makefile index fe6f41b78136..6b11668b2bcf 100644 --- a/drivers/sgi/char/Makefile +++ b/drivers/sgi/char/Makefile @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -export-objs := newport.o shmiq.o sgicons.o usema.o rrm.o obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o obj-$(CONFIG_SGI_SERIAL) += sgiserial.o diff --git a/drivers/tc/Makefile b/drivers/tc/Makefile index 1c0622fe7c24..83b5bd75ce26 100644 --- a/drivers/tc/Makefile +++ b/drivers/tc/Makefile @@ -2,11 +2,6 @@ # Makefile for the linux kernel. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := tc.o - # Object file lists. obj-$(CONFIG_TC) += tc.o diff --git a/drivers/telephony/Makefile b/drivers/telephony/Makefile index ae8717c92f5f..1206615d69e4 100644 --- a/drivers/telephony/Makefile +++ b/drivers/telephony/Makefile @@ -2,8 +2,6 @@ # Makefile for drivers/telephony # -export-objs := phonedev.o ixj.o - obj-$(CONFIG_PHONE) += phonedev.o obj-$(CONFIG_PHONE_IXJ) += ixj.o obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0594f82b6191..d388c48e5756 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -257,7 +257,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) if (urb->status) dbg("nonzero read bulk status received: %d", urb->status); - if (!urb->status & !acm->throttle) { + if (!urb->status && !acm->throttle) { for (i = 0; i < urb->actual_length && !acm->throttle; i++) { /* if we insert more than TTY_FLIPBUF_SIZE characters, * we drop them. */ @@ -697,6 +697,7 @@ static void acm_disconnect(struct usb_interface *intf) static struct usb_device_id acm_ids[] = { { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) }, + { USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) }, { } }; diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index cfeb5c4ba6b5..cbbf426352bd 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -2,8 +2,6 @@ # Makefile for USB Core files and filesystem # -export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o - usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \ config.o file.o buffer.o driverfs.o diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 3d4c29b579b4..7fe1cf0dd283 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -68,7 +68,7 @@ static char *format_topo = /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ - "T: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; +"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; static char *format_string_manufacturer = /* S: Manufacturer=xxxx */ diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 940a5deeafcf..ef25a85a939a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -310,9 +310,9 @@ static int rh_string ( } else return 0; - data [0] = 2 + ascii2utf (buf, data + 2, len - 2); + data [0] = 2 * (strlen (buf) + 1); data [1] = 3; /* type == string */ - return data [0]; + return 2 + ascii2utf (buf, data + 2, len - 2); } @@ -1029,8 +1029,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) return status; } - /* lower level hcd code should use *_dma exclusively */ - if (!(urb->transfer_flags & URB_NO_DMA_MAP)) { + /* lower level hcd code should use *_dma exclusively, + * unless it uses pio or talks to another transport. + */ + if (!(urb->transfer_flags & URB_NO_DMA_MAP) + && hcd->controller->dma_mask) { if (usb_pipecontrol (urb->pipe)) urb->setup_dma = dma_map_single ( hcd->controller, diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 8e8f58fb33d6..5a0dd57af6e1 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -111,6 +111,13 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ */ }; +/* 2.4 does this a bit differently ... */ +static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd) +{ + return &hcd->self; +} + + struct hcd_dev { /* usb_device.hcpriv points to this */ struct list_head dev_list; /* on this hcd */ struct list_head urb_list; /* pending on this dev */ @@ -343,6 +350,13 @@ extern void usb_deregister_bus (struct usb_bus *); extern int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev); +/* for portability to 2.4, hcds should call this */ +static inline int hcd_register_root (struct usb_hcd *hcd) +{ + return usb_register_root_hub ( + hcd_to_bus (hcd)->root_hub, hcd->controller); +} + /*-------------------------------------------------------------------------*/ /* exported only within usbcore */ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 7b7689e38944..53d1f410dcf7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -206,7 +206,8 @@ static void sg_clean (struct usb_sg_request *io) kfree (io->urbs); io->urbs = 0; } - usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); + if (io->dev->dev.dma_mask != 0) + usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); io->dev = 0; } @@ -301,6 +302,7 @@ int usb_sg_init ( { int i; int urb_flags; + int dma; if (!io || !dev || !sg || usb_pipecontrol (pipe) @@ -314,8 +316,16 @@ int usb_sg_init ( io->sg = sg; io->nents = nents; + /* not all host controllers use DMA (like the mainstream pci ones); + * they can use PIO (sl811) or be software over another transport. + */ + dma = (dev->dev.dma_mask != 0); + if (dma) + io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); + else + io->entries = nents; + /* initialize all the urbs we'll use */ - io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); if (io->entries <= 0) return io->entries; @@ -347,8 +357,17 @@ int usb_sg_init ( io->urbs [i]->status = -EINPROGRESS; io->urbs [i]->actual_length = 0; - io->urbs [i]->transfer_dma = sg_dma_address (sg + i); - len = sg_dma_len (sg + i); + if (dma) { + /* hc may use _only_ transfer_dma */ + io->urbs [i]->transfer_dma = sg_dma_address (sg + i); + len = sg_dma_len (sg + i); + } else { + /* hc may use _only_ transfer_buffer */ + io->urbs [i]->transfer_buffer = + page_address (sg [i].page) + sg [i].offset; + len = sg [i].length; + } + if (length) { len = min_t (unsigned, len, length); length -= len; @@ -434,9 +453,7 @@ void usb_sg_wait (struct usb_sg_request *io) retval = 0; i--; // FIXME: should it usb_sg_cancel() on INTERRUPT? - // how about imposing a backoff? - set_current_state (TASK_UNINTERRUPTIBLE); - schedule (); + yield (); break; /* no error? continue immediately. diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index bd06a32f88d6..f1643fff1d7b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1224,7 +1224,8 @@ void usb_buffer_free ( * * Return value is either null (indicating no buffer could be mapped), or * the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the - * operation succeeds. + * operation succeeds. If the device is connected to this system through + * a non-DMA controller, this operation always succeeds. * * This call would normally be used for an urb which is reused, perhaps * as the target of a large periodic transfer, with usb_buffer_dmasync() @@ -1245,12 +1246,15 @@ struct urb *usb_buffer_map (struct urb *urb) || !(controller = bus->controller)) return 0; - urb->transfer_dma = dma_map_single (controller, + if (controller->dma_mask) { + urb->transfer_dma = dma_map_single (controller, urb->transfer_buffer, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); // FIXME generic api broken like pci, can't report errors // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; + } else + urb->transfer_dma = ~0; urb->transfer_flags |= URB_NO_DMA_MAP; return urb; } @@ -1271,7 +1275,8 @@ void usb_buffer_dmasync (struct urb *urb) || !(controller = bus->controller)) return; - dma_sync_single (controller, + if (controller->dma_mask) + dma_sync_single (controller, urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); @@ -1295,10 +1300,12 @@ void usb_buffer_unmap (struct urb *urb) || !(controller = bus->controller)) return; - dma_unmap_single (controller, + if (controller->dma_mask) + dma_unmap_single (controller, urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + urb->transfer_flags &= ~URB_NO_DMA_MAP; } /** @@ -1336,7 +1343,8 @@ int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe, if (!dev || usb_pipecontrol (pipe) || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return -1; // FIXME generic api broken like pci, can't report errors @@ -1362,7 +1370,8 @@ void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe, if (!dev || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return; dma_sync_sg (controller, sg, n_hw_ents, @@ -1386,7 +1395,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, if (!dev || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return; dma_unmap_sg (controller, sg, n_hw_ents, diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 5a5dbee4dd88..f27f582546aa 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -277,7 +277,26 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { } default: tmp = '?'; break; \ }; tmp; }) -static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) +static inline char token_mark (u32 token) +{ + token = le32_to_cpu (token); + if (token & QTD_STS_ACTIVE) + return '*'; + if (token & QTD_STS_HALT) + return '-'; + if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */ + || QTD_LENGTH (token) == 0) + return ' '; + /* tries to advance through hw_alt_next */ + return '/'; +} + +static void qh_lines ( + struct ehci_hcd *ehci, + struct ehci_qh *qh, + char **nextp, + unsigned *sizep +) { u32 scratch; u32 hw_curr; @@ -286,26 +305,49 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) unsigned temp; unsigned size = *sizep; char *next = *nextp; - + char mark; + + mark = token_mark (qh->hw_token); + if (mark == '/') { /* qh_alt_next controls qh advance? */ + if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next) + mark = '#'; /* blocked */ + else if (qh->hw_alt_next & cpu_to_le32 (0x01)) + mark = '.'; /* use hw_qtd_next */ + /* else alt_next points to some other qtd */ + } scratch = cpu_to_le32p (&qh->hw_info1); - hw_curr = cpu_to_le32p (&qh->hw_current); + hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0; temp = snprintf (next, size, - "qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)", + "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", qh, scratch & 0x007f, speed_char (scratch), (scratch >> 8) & 0x000f, scratch, cpu_to_le32p (&qh->hw_info2), - hw_curr, cpu_to_le32p (&qh->hw_token)); + cpu_to_le32p (&qh->hw_token), mark, + (cpu_to_le32 (0x8000000) & qh->hw_token) + ? "data0" : "data1", + (cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f); size -= temp; next += temp; + /* hc may be modifying the list as we read it ... */ list_for_each (entry, &qh->qtd_list) { td = list_entry (entry, struct ehci_qtd, qtd_list); scratch = cpu_to_le32p (&td->hw_token); + mark = ' '; + if (hw_curr == td->qtd_dma) + mark = '*'; + else if (qh->hw_qtd_next == td->qtd_dma) + mark = '+'; + else if (QTD_LENGTH (scratch)) { + if (td->hw_alt_next == ehci->async->hw_alt_next) + mark = '#'; + else if (td->hw_alt_next != EHCI_LIST_END) + mark = '/'; + } temp = snprintf (next, size, - "\n\t%std/%p %s len=%d %08x urb %p", - (hw_curr == td->qtd_dma) ? "*" : "", - td, ({ char *tmp; + "\n\t%p%c%s len=%d %08x urb %p", + td, mark, ({ char *tmp; switch ((scratch>>8)&0x03) { case 0: tmp = "out"; break; case 1: tmp = "in"; break; @@ -315,13 +357,27 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) (scratch >> 16) & 0x7fff, scratch, td->urb); + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; size -= temp; next += temp; + if (temp == size) + goto done; } temp = snprintf (next, size, "\n"); - *sizep = size - temp; - *nextp = next + temp; + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; + size -= temp; + next += temp; + +done: + *sizep = size; + *nextp = next; } static ssize_t @@ -344,14 +400,15 @@ show_async (struct device *dev, char *buf) * one QH per line, and TDs we know about */ spin_lock_irqsave (&ehci->lock, flags); - for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) - qh_lines (qh, &next, &size); - if (ehci->reclaim) { + for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh) + qh_lines (ehci, qh, &next, &size); + if (ehci->reclaim && size > 0) { temp = snprintf (next, size, "\nreclaim =\n"); size -= temp; next += temp; - qh_lines (ehci->reclaim, &next, &size); + for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim) + qh_lines (ehci, qh, &next, &size); } spin_unlock_irqrestore (&ehci->lock, flags); @@ -421,7 +478,7 @@ show_periodic (struct device *dev, char *buf) scratch & 0x007f, (scratch >> 8) & 0x000f, p.qh->usecs, p.qh->c_usecs, - scratch >> 16); + 0x7ff & (scratch >> 16)); /* FIXME TD info too */ @@ -490,7 +547,8 @@ show_registers (struct device *dev, char *buf) /* Capability Registers */ i = readw (&ehci->caps->hci_version); - temp = snprintf (next, size, "EHCI %x.%02x, hcd state %d\n", + temp = snprintf (next, size, + "EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n", i >> 8, i & 0x0ff, ehci->hcd.state); size -= temp; next += temp; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 02724f00fba6..6e4b5eebcf1a 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -94,7 +94,7 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2002-Nov-29" +#define DRIVER_VERSION "2003-Jan-22" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -110,10 +110,11 @@ static const char hcd_name [] = "ehci-hcd"; /* magic numbers that can affect system performance */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 0 /* nak throttle; see 4.9 */ +#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_TT 0 #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ #define EHCI_TUNE_MULT_TT 1 +#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ #define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ @@ -416,13 +417,26 @@ static int ehci_start (struct usb_hcd *hcd) ehci_info (ehci, "enabled 64bit PCI DMA\n"); } + /* help hc dma work well with cachelines */ + pci_set_mwi (ehci->hcd.pdev); + /* clear interrupt enables, set irq latency */ temp = readl (&ehci->regs->command) & 0xff; if (log2_irq_thresh < 0 || log2_irq_thresh > 6) log2_irq_thresh = 0; temp |= 1 << (16 + log2_irq_thresh); // if hc can park (ehci >= 0.96), default is 3 packets per async QH - // keeping default periodic framelist size + if (HCC_PGM_FRAMELISTLEN (hcc_params)) { + /* periodic schedule size can be smaller than default */ + temp &= ~(3 << 2); + temp |= (EHCI_TUNE_FLS << 2); + switch (EHCI_TUNE_FLS) { + case 0: ehci->periodic_size = 1024; break; + case 1: ehci->periodic_size = 512; break; + case 2: ehci->periodic_size = 256; break; + default: BUG (); + } + } temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE), // Philips, Intel, and maybe others need CMD_RUN before the // root hub will detect new devices (why?); NEC doesn't @@ -759,7 +773,6 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_qh *qh; unsigned long flags; - int maybe_irq = 1; spin_lock_irqsave (&ehci->lock, flags); switch (usb_pipetype (urb->pipe)) { @@ -769,23 +782,23 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - while (qh->qh_state == QH_STATE_LINKED + + /* if we need to use IAA and it's busy, defer */ + if (qh->qh_state == QH_STATE_LINKED && ehci->reclaim && HCD_IS_RUNNING (ehci->hcd.state) ) { - spin_unlock_irqrestore (&ehci->lock, flags); + struct ehci_qh *last; - if (maybe_irq) { - if (in_interrupt ()) - return -EAGAIN; - maybe_irq = 0; - } - /* let pending unlinks complete, so this can start */ - wait_ms (1); + for (last = ehci->reclaim; + last->reclaim; + last = last->reclaim) + continue; + qh->qh_state = QH_STATE_UNLINK_WAIT; + last->reclaim = qh; - spin_lock_irqsave (&ehci->lock, flags); - } - if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) + /* bypass IAA if the hc can't care */ + } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) end_unlink_async (ehci, NULL); /* something else might have unlinked the qh by now */ diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index beded1eb2269..8d3f74561499 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -75,8 +75,6 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags) qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); if (qtd != 0) { ehci_qtd_init (qtd, dma); - if (ehci->async) - qtd->hw_alt_next = ehci->async->hw_alt_next; } return qtd; } diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index fef1e3688b65..6969316681e0 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -43,7 +43,8 @@ /* fill a qtd, returning how much of the buffer we were able to queue up */ static int -qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) +qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, + int token, int maxpacket) { int i, count; u64 addr = buf; @@ -69,6 +70,10 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) else count = len; } + + /* short packets may only terminate transfers */ + if (count != len) + count -= (count % maxpacket); } qtd->hw_token = cpu_to_le32 ((count << 16) | token); qtd->length = count; @@ -85,7 +90,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) { qh->hw_current = 0; qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma); - qh->hw_alt_next = ehci->async->hw_alt_next; + qh->hw_alt_next = EHCI_LIST_END; /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ wmb (); @@ -96,7 +101,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) #define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) -static inline void qtd_copy_status ( +static void qtd_copy_status ( struct ehci_hcd *ehci, struct urb *urb, size_t length, @@ -224,12 +229,24 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) { struct ehci_qtd *last = 0, *end = qh->dummy; struct list_head *entry, *tmp; - int stopped = 0; + int stopped; unsigned count = 0; + int do_status = 0; + u8 state; if (unlikely (list_empty (&qh->qtd_list))) return count; + /* completions (or tasks on other cpus) must never clobber HALT + * till we've gone through and cleaned everything up, even when + * they add urbs to this qh's queue or mark them for unlinking. + * + * NOTE: unlinking expects to be done in queue order. + */ + state = qh->qh_state; + qh->qh_state = QH_STATE_COMPLETING; + stopped = (state == QH_STATE_IDLE); + /* remove de-activated QTDs from front of queue. * after faults (including short reads), cleanup this urb * then let the queue advance. @@ -261,7 +278,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) rmb (); token = le32_to_cpu (qtd->hw_token); stopped = stopped - || (qh->qh_state == QH_STATE_IDLE) || (HALT_BIT & qh->hw_token) != 0 || (ehci->hcd.state == USB_STATE_HALT); @@ -271,36 +287,53 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) /* magic dummy for short reads; won't advance */ if (IS_SHORT_READ (token) && !(token & QTD_STS_HALT) - && ehci->async->hw_alt_next - == qh->hw_alt_next) + && (qh->hw_alt_next & QTD_MASK) + == ehci->async->hw_alt_next) { + stopped = 1; goto halt; + } /* stop scanning when we reach qtds the hc is using */ } else if (likely (!stopped)) { - last = 0; break; } else { - /* ignore active qtds unless some previous qtd + /* ignore active urbs unless some previous qtd * for the urb faulted (including short read) or * its urb was canceled. we may patch qh or qtds. */ - if ((token & QTD_STS_ACTIVE) - && urb->status == -EINPROGRESS) { - last = 0; + if (likely (urb->status == -EINPROGRESS)) + continue; + + /* issue status after short control reads */ + if (unlikely (do_status != 0) + && QTD_PID (token) == 0 /* OUT */) { + do_status = 0; continue; } + + /* token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_le32 (qtd->qtd_dma) + == qh->hw_current) + token = le32_to_cpu (qh->hw_token); + + /* force halt for unlinked or blocked qh, so we'll + * patch the qh later and so that completions can't + * activate it while we "know" it's stopped. + */ if ((HALT_BIT & qh->hw_token) == 0) { halt: qh->hw_token |= HALT_BIT; wmb (); - stopped = 1; } } /* remove it from the queue */ spin_lock (&urb->lock); qtd_copy_status (ehci, urb, qtd->length, token); + do_status = (urb->status == -EREMOTEIO) + && usb_pipecontrol (urb->pipe); spin_unlock (&urb->lock); if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { @@ -319,6 +352,9 @@ halt: ehci_qtd_free (ehci, last); } + /* restore original state; caller must unlink or relink */ + qh->qh_state = state; + /* update qh after fault cleanup */ if (unlikely ((HALT_BIT & qh->hw_token) != 0)) { qh_update (ehci, qh, @@ -367,7 +403,7 @@ qh_urb_transaction ( struct ehci_qtd *qtd, *qtd_prev; dma_addr_t buf; int len, maxpacket; - int is_input, status_patch = 0; + int is_input; u32 token; /* @@ -388,7 +424,7 @@ qh_urb_transaction ( if (usb_pipecontrol (urb->pipe)) { /* SETUP pid */ qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest), - token | (2 /* "setup" */ << 8)); + token | (2 /* "setup" */ << 8), 8); /* ... and always at least one more pid */ token ^= QTD_TOGGLE; @@ -399,10 +435,6 @@ qh_urb_transaction ( qtd->urb = urb; qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); list_add_tail (&qtd->qtd_list, head); - - if (len > 0 && is_input - && !(urb->transfer_flags & URB_SHORT_NOT_OK)) - status_patch = 1; } /* @@ -413,6 +445,7 @@ qh_urb_transaction ( else buf = 0; + // FIXME this 'buf' check break some zlps... if (!buf || is_input) token |= (1 /* "in" */ << 8); /* else it's already initted to "out" pid (0 << 8) */ @@ -427,9 +460,11 @@ qh_urb_transaction ( for (;;) { int this_qtd_len; - this_qtd_len = qtd_fill (qtd, buf, len, token); + this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket); len -= this_qtd_len; buf += this_qtd_len; + if (is_input) + qtd->hw_alt_next = ehci->async->hw_alt_next; /* qh makes control packets use qtd toggle; maybe switch it */ if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) @@ -447,6 +482,13 @@ qh_urb_transaction ( list_add_tail (&qtd->qtd_list, head); } + /* unless the bulk/interrupt caller wants a chance to clean + * up after short reads, hc should advance qh past this urb + */ + if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 + || usb_pipecontrol (urb->pipe))) + qtd->hw_alt_next = EHCI_LIST_END; + /* * control requests may need a terminating data "status" ack; * bulk ones may need a terminating short packet (zero length). @@ -473,23 +515,10 @@ qh_urb_transaction ( list_add_tail (&qtd->qtd_list, head); /* never any data in such packets */ - qtd_fill (qtd, 0, 0, token); + qtd_fill (qtd, 0, 0, token, 0); } } - /* if we're permitting a short control read, we want the hardware to - * just continue after short data and send the status ack. it can do - * that on the last data packet (typically the only one). for other - * packets, software fixup is needed (in qh_completions). - */ - if (status_patch) { - struct ehci_qtd *prev; - - prev = list_entry (qtd->qtd_list.prev, - struct ehci_qtd, qtd_list); - prev->hw_alt_next = QTD_NEXT (qtd->qtd_dma); - } - /* by default, enable interrupt on urb completion */ if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT))) qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC); @@ -611,7 +640,8 @@ qh_make ( case USB_SPEED_FULL: /* EPS 0 means "full" */ - info1 |= (EHCI_TUNE_RL_TT << 28); + if (type != PIPE_INTERRUPT) + info1 |= (EHCI_TUNE_RL_TT << 28); if (type == PIPE_CONTROL) { info1 |= (1 << 27); /* for TT */ info1 |= 1 << 14; /* toggle from qtd */ @@ -628,12 +658,13 @@ qh_make ( case USB_SPEED_HIGH: /* no TT involved */ info1 |= (2 << 12); /* EPS "high" */ - info1 |= (EHCI_TUNE_RL_HS << 28); if (type == PIPE_CONTROL) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 64 << 16; /* usb2 fixed maxpacket */ info1 |= 1 << 14; /* toggle from qtd */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else if (type == PIPE_BULK) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 512 << 16; /* usb2 fixed maxpacket */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else { /* PIPE_INTERRUPT */ @@ -769,8 +800,7 @@ static struct ehci_qh *qh_append_tds ( && !usb_pipecontrol (urb->pipe)) { /* "never happens": drivers do stall cleanup right */ if (qh->qh_state != QH_STATE_IDLE - && (cpu_to_le32 (QTD_STS_HALT) - & qh->hw_token) == 0) + && qh->qh_state != QH_STATE_COMPLETING) ehci_warn (ehci, "clear toggle dev%d " "ep%d%s: not idle\n", usb_pipedevice (urb->pipe), @@ -809,7 +839,6 @@ static struct ehci_qh *qh_append_tds ( __list_splice (qtd_list, qh->qtd_list.prev); ehci_qtd_init (qtd, qtd->qtd_dma); - qtd->hw_alt_next = ehci->async->hw_alt_next; qh->dummy = qtd; /* hc must see the new dummy at list end */ @@ -877,9 +906,12 @@ submit_async ( /* the async qh for the qtds being reclaimed are now unlinked from the HC */ +static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh); + static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh = ehci->reclaim; + struct ehci_qh *next; del_timer (&ehci->watchdog); @@ -890,6 +922,10 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) ehci->reclaim = 0; ehci->reclaim_ready = 0; + /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ + next = qh->reclaim; + qh->reclaim = 0; + qh_completions (ehci, qh, regs); if (!list_empty (&qh->qtd_list) @@ -909,6 +945,9 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) jiffies + EHCI_ASYNC_JIFFIES); } } + + if (next) + start_unlink_async (ehci, next); } /* makes sure the async qh will become idle */ @@ -921,7 +960,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) #ifdef DEBUG if (ehci->reclaim - || qh->qh_state != QH_STATE_LINKED + || (qh->qh_state != QH_STATE_LINKED + && qh->qh_state != QH_STATE_UNLINK_WAIT) #ifdef CONFIG_SMP // this macro lies except on SMP compiles || !spin_is_locked (&ehci->lock) @@ -953,6 +993,9 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) wmb (); if (unlikely (ehci->hcd.state == USB_STATE_HALT)) { + /* if (unlikely (qh->reclaim != 0)) + * this will recurse, probably not much + */ end_unlink_async (ehci, NULL); return; } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 7b49ddf0648a..baf6bb611676 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -236,12 +236,12 @@ struct ehci_qtd { /* the rest is HCD-private */ dma_addr_t qtd_dma; /* qtd address */ struct list_head qtd_list; /* sw qtd list */ - - /* dma same in urb's qtds, except 1st control qtd (setup buffer) */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ } __attribute__ ((aligned (32))); +#define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */ + /*-------------------------------------------------------------------------*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ @@ -305,6 +305,7 @@ struct ehci_qh { union ehci_shadow qh_next; /* ptr to qh; or periodic */ struct list_head qtd_list; /* sw qtd list */ struct ehci_qtd *dummy; + struct ehci_qh *reclaim; /* next to reclaim */ atomic_t refcount; unsigned stamp; @@ -313,6 +314,8 @@ struct ehci_qh { #define QH_STATE_LINKED 1 /* HC sees this */ #define QH_STATE_UNLINK 2 /* HC may still see this */ #define QH_STATE_IDLE 3 /* HC doesn't see this */ +#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ +#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ /* periodic schedule info */ u8 usecs; /* intr bandwidth */ @@ -426,16 +429,6 @@ static inline int hcd_register_root (struct usb_hcd *hcd) #else /* LINUX_VERSION_CODE */ -// hcd_to_bus() eventually moves to hcd.h on 2.5 too -static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd) - { return &hcd->self; } -// ... as does hcd_register_root() -static inline int hcd_register_root (struct usb_hcd *hcd) -{ - return usb_register_root_hub ( - hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev); -} - #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags) #ifndef DEBUG diff --git a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c index d8b8039b8b0d..5d4cf5c02971 100644 --- a/drivers/usb/host/hc_simple.c +++ b/drivers/usb/host/hc_simple.c @@ -219,7 +219,7 @@ static int hci_unlink_urb (struct urb * urb) if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) { /* URB active? */ - if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) { + if (urb->transfer_flags & URB_ASYNC_UNLINK) { /* asynchronous with callback */ /* relink the urb to the del list */ list_move (&urb->urb_list, &hci->del_list); @@ -388,7 +388,6 @@ static void qu_urb_timeout (unsigned long lurb) struct urb *urb = (struct urb *) lurb; DBGFUNC ("enter qu_urb_timeout\n"); - urb->transfer_flags |= URB_TIMEOUT_KILLED; hci_unlink_urb (urb); } #endif diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 0a3971713f28..b048949f6cc7 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -203,28 +203,28 @@ static int ohci_urb_enqueue ( return -ENOMEM; memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); - spin_lock_irqsave (&ohci->lock, flags); - - /* don't submit to a dead HC */ - if (ohci->disabled || ohci->sleeping) { - retval = -ENODEV; - goto fail; - } - /* fill the private part of the URB */ urb_priv->length = size; urb_priv->ed = ed; - /* allocate the TDs (updating hash chains) */ + /* allocate the TDs (deferring hash chain updates) */ for (i = 0; i < size; i++) { - urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC); + urb_priv->td [i] = td_alloc (ohci, mem_flags); if (!urb_priv->td [i]) { urb_priv->length = i; - retval = -ENOMEM; - goto fail; + urb_free_priv (ohci, urb_priv); + return -ENOMEM; } } + spin_lock_irqsave (&ohci->lock, flags); + + /* don't submit to a dead HC */ + if (ohci->disabled || ohci->sleeping) { + retval = -ENODEV; + goto fail; + } + /* schedule the ed if needed */ if (ed->state == ED_IDLE) { retval = ed_schedule (ohci, ed); diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index b09df67e59bd..ced91da1a1c7 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -97,17 +97,11 @@ td_alloc (struct ohci_hcd *hc, int mem_flags) td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); if (td) { - int hash; - /* in case hc fetches it, make it look dead */ memset (td, 0, sizeof *td); td->hwNextTD = cpu_to_le32 (dma); td->td_dma = dma; - - /* hash it for later reverse mapping */ - hash = TD_HASH_FUNC (dma); - td->td_hash = hc->td_hash [hash]; - hc->td_hash [hash] = td; + /* hashed in td_fill */ } return td; } diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 402e245161cb..6edf40780ac3 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -463,13 +463,14 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ static void -td_fill (unsigned int info, +td_fill (struct ohci_hcd *ohci, u32 info, dma_addr_t data, int len, struct urb *urb, int index) { struct td *td, *td_pt; struct urb_priv *urb_priv = urb->hcpriv; int is_iso = info & TD_ISO; + int hash; // ASSERT (index < urb_priv->length); @@ -516,11 +517,16 @@ td_fill (unsigned int info, td->hwBE = 0; td->hwNextTD = cpu_to_le32 (td_pt->td_dma); - /* HC might read the TD right after we link it ... */ - wmb (); - /* append to queue */ list_add_tail (&td->td_list, &td->ed->td_list); + + /* hash it for later reverse mapping */ + hash = TD_HASH_FUNC (td->td_dma); + td->td_hash = ohci->td_hash [hash]; + ohci->td_hash [hash] = td; + + /* HC might read the TD (or cachelines) right away ... */ + wmb (); td->ed->hwTailP = td->hwNextTD; } @@ -578,7 +584,7 @@ static void td_submit_urb ( : TD_T_TOGGLE | TD_CC | TD_DP_IN; /* TDs _could_ transfer up to 8K each */ while (data_len > 4096) { - td_fill (info, data, 4096, urb, cnt); + td_fill (ohci, info, data, 4096, urb, cnt); data += 4096; data_len -= 4096; cnt++; @@ -586,11 +592,11 @@ static void td_submit_urb ( /* maybe avoid ED halt on final TD short read */ if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) info |= TD_R; - td_fill (info, data, data_len, urb, cnt); + td_fill (ohci, info, data, data_len, urb, cnt); cnt++; if ((urb->transfer_flags & URB_ZERO_PACKET) && cnt < urb_priv->length) { - td_fill (info, 0, 0, urb, cnt); + td_fill (ohci, info, 0, 0, urb, cnt); cnt++; } /* maybe kickstart bulk list */ @@ -605,17 +611,17 @@ static void td_submit_urb ( */ case PIPE_CONTROL: info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (info, urb->setup_dma, 8, urb, cnt++); + td_fill (ohci, info, urb->setup_dma, 8, urb, cnt++); if (data_len > 0) { info = TD_CC | TD_R | TD_T_DATA1; info |= is_out ? TD_DP_OUT : TD_DP_IN; /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (info, data, data_len, urb, cnt++); + td_fill (ohci, info, data, data_len, urb, cnt++); } info = is_out ? TD_CC | TD_DP_IN | TD_T_DATA1 : TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (info, data, 0, urb, cnt++); + td_fill (ohci, info, data, 0, urb, cnt++); /* maybe kickstart control list */ wmb (); writel (OHCI_CLF, &ohci->regs->cmdstatus); @@ -634,7 +640,7 @@ static void td_submit_urb ( // a 2^16 iso range, vs other HCs max of 2^10) frame += cnt * urb->interval; frame &= 0xffff; - td_fill (TD_CC | TD_ISO | frame, + td_fill (ohci, TD_CC | TD_ISO | frame, data + urb->iso_frame_desc [cnt].offset, urb->iso_frame_desc [cnt].length, urb, cnt); } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index b3a8d06d6c19..c3c0a7505765 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -1747,7 +1747,6 @@ static void stall_callback(unsigned long ptr) tmp = tmp->next; - u->transfer_flags |= URB_TIMEOUT_KILLED; uhci_urb_dequeue(hcd, u); } diff --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index ffe02faa4a0e..9590371e8203 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -274,7 +274,7 @@ hpusbscsi_scsi_detect (struct SHT *sht) static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); usb_complete_t usb_callback; int res; @@ -349,7 +349,7 @@ out: static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); printk(KERN_DEBUG"SCSI reset requested.\n"); //usb_reset_device(hpusbscsi->dev); @@ -361,7 +361,7 @@ static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb) static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); printk(KERN_DEBUG"Requested is canceled.\n"); usb_unlink_urb(hpusbscsi->dataurb); diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index ddd98e4c6cf5..ad7e24b05fb4 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -398,7 +398,7 @@ static int mts_scsi_release(struct Scsi_Host *psh) static int mts_scsi_abort (Scsi_Cmnd *srb) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); MTS_DEBUG_GOT_HERE(); @@ -409,7 +409,7 @@ static int mts_scsi_abort (Scsi_Cmnd *srb) static int mts_scsi_host_reset (Scsi_Cmnd *srb) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); @@ -692,7 +692,7 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) static int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int err = 0; int res; diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index 2f4faf65d067..50b62d9f17d8 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -1,13 +1,16 @@ /* -*- linux-c -*- */ /* - * Driver for USB Scanners (linux-2.5.54) + * Driver for USB Scanners (linux-2.5.60) * * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson + * Copyright (C) 2002, 2003 Henning Meier-Geinitz * * Portions may be copyright Brad Keryan and Michael Gee. * - * Brian Beattie <beattie@beattie-home.net> + * Previously maintained by Brian Beattie + * + * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -300,8 +303,6 @@ * Frank Zago <fzago@greshamstorage.com> and * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. * - * 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net> - * * 0.4.8 5/30/2002 * - Added Mustek BearPaw 2400 TA. Thanks to Sergey * Vlasov <vsu@mivlgu.murom.ru>. @@ -332,12 +333,18 @@ * <oliver@neukum.name>. * * 0.4.10 01/07/2003 - * - Added vendor/product ids for Visioneer scanners. + * - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek + * and Visioneer scanners. Thanks to William Lam <wklam@triad.rr.com>, + * Till Kamppeter <till.kamppeter@gmx.net> and others for all the ids. + * - Cleaned up list of vendor/product ids. * - Print information about user-supplied ids only once at startup instead * of everytime any USB device is plugged in. * - Removed PV8630 ioctls. Use the standard ioctls instead. * - Made endpoint detection more generic. Basically, only one bulk-in * endpoint is required, everything else is optional. + * - New maintainer: Henning Meier-Geinitz. + * - Print ids and device number when a device was detected. + * - Don't print errors when the device is busy. * * TODO * - Performance @@ -360,7 +367,7 @@ * - All the developers that are working on USB SANE backends or other * applications to use USB scanners. * - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie - * to be the new USB Scanner maintainer. + * and Henning Meier-Geinitz to be the new USB Scanner maintainer. * * Performance: * @@ -369,6 +376,14 @@ * 24 Bit Color ~ 70 secs - 3.6 Mbit/sec * 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */ +/* + * For documentation, see Documentation/usb/scanner.txt. + * Website: http://www.meier-geinitz.de/kernel/ + * Please contact the maintainer if your scanner is not detected by this + * driver automatically. + */ + + #include <asm/byteorder.h> /* @@ -461,7 +476,7 @@ open_scanner(struct inode * inode, struct file * file) } if (scn->isopen) { - err("open_scanner(%d): Scanner device is already open", scn_minor); + dbg("open_scanner(%d): Scanner device is already open", scn_minor); err = -EBUSY; goto out_error; } @@ -1047,6 +1062,9 @@ probe_scanner(struct usb_interface *intf, if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); + info ("USB scanner device (0x%04x/0x%04x) now attached to %s", + dev->descriptor.idVendor, dev->descriptor.idProduct, name); + up(&scn_mutex); usb_set_intfdata(intf, scn); diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h index 6defdf138a90..04ba5c7386ce 100644 --- a/drivers/usb/image/scanner.h +++ b/drivers/usb/image/scanner.h @@ -1,9 +1,10 @@ /* - * Driver for USB Scanners (linux-2.5.54) + * Driver for USB Scanners (linux-2.5.60) * * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson + * Previously maintained by Brian Beattie * - * Brian Beattie <beattie@beattie-home.net> + * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,11 +20,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net> - * - * */ +/* + * For documentation, see Documentation/usb/scanner.txt. + * Website: http://www.meier-geinitz.de/kernel/ + * Please contact the maintainer if your scanner is not detected by this + * driver automatically. + */ + + #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -45,7 +51,7 @@ static __s32 vendor=-1, product=-1, read_timeout=0; -MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net"); +MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de"); MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION); MODULE_LICENSE("GPL"); @@ -65,79 +71,90 @@ MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds"); static struct usb_device_id scanner_device_ids [] = { /* Acer (now Benq) */ - { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/ - { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */ - { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */ - { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x1a2a) }, /* Another 620U */ + { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */ + { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */ + { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/ { USB_DEVICE(0x04a5, 0x207e) }, /* 640BU */ + { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */ + { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ - { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */ - { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */ { USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */ + { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */ /* Agfa */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */ - { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */ + { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ + { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ + { USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */ + { USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/ { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ - { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ - { USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/ - { USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/ - { USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/ { USB_DEVICE(0x06bd, 0x20fd) }, /* SnapScan e52*/ + { USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/ + /* Artec */ + { USB_DEVICE(0x05d8, 0x4001) }, /* Ultima 2000 */ + { USB_DEVICE(0x05d8, 0x4002) }, /* Ultima 2000 (GT6801 based) */ /* Benq: see Acer */ /* Canon */ - { USB_DEVICE(0x04a9, 0x2201) }, /* FB320U */ - { USB_DEVICE(0x04a9, 0x2205) }, /* FB1210U */ + { USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */ { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ + { USB_DEVICE(0x04a9, 0x2205) }, /* CanoScan FB1210U */ { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ - { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ + { USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */ + { USB_DEVICE(0x04a9, 0x220c) }, /* CanoScan D1250U2 */ { USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */ { USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */ { USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */ /* Colorado -- See Primax/Colorado below */ + /* Compaq */ + { USB_DEVICE(0x049f, 0x0021) }, /* S200 */ /* Epson -- See Seiko/Epson below */ /* Genius */ - { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ + { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage Vivid Pro */ { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ - { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage-HR6 V2 */ - { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage-HR6A */ - { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage-Vivid3x */ - { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage-HR7 */ - { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage-HR7LE */ - { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage-HR6X */ + { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage HR6 V2 */ + { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage HR6A */ + { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage Vivid3x */ + { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage HR7 */ + { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */ + { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */ /* Hewlett Packard */ - { USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */ - { USB_DEVICE(0x03f0, 0x0605) }, /* 2200C */ - { USB_DEVICE(0x03f0, 0x0901) }, /* 2300C */ - { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ - { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ - { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */ - { USB_DEVICE(0x03f0, 0x0105) }, /* 4200C */ - { USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */ - { USB_DEVICE(0x03f0, 0x0705) }, /* 4400C */ + { USB_DEVICE(0x03f0, 0x0101) }, /* ScanJet 4100C */ { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */ - { USB_DEVICE(0x03f0, 0x0401) }, /* 5200C */ - // { USB_DEVICE(0x03f0, 0x0701) }, /* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */ - { USB_DEVICE(0x03f0, 0x0201) }, /* 6200C */ - { USB_DEVICE(0x03f0, 0x0601) }, /* 6300C */ + { USB_DEVICE(0x03f0, 0x0105) }, /* ScanJet 4200C */ + { USB_DEVICE(0x03f0, 0x0201) }, /* ScanJet 6200C */ + { USB_DEVICE(0x03f0, 0x0205) }, /* ScanJet 3300C */ + { USB_DEVICE(0x03f0, 0x0305) }, /* ScanJet 4300C */ + { USB_DEVICE(0x03f0, 0x0401) }, /* ScanJet 5200C */ + { USB_DEVICE(0x03f0, 0x0405) }, /* ScanJet 3400C */ + { USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */ + { USB_DEVICE(0x03f0, 0x0601) }, /* ScanJet 6300C */ + { USB_DEVICE(0x03f0, 0x0605) }, /* ScanJet 2200C */ + // { USB_DEVICE(0x03f0, 0x0701) }, /* ScanJet 5300C - NOT SUPPORTED - use hpusbscsi driver */ + { USB_DEVICE(0x03f0, 0x0705) }, /* ScanJet 4400C */ + // { USB_DEVICE(0x03f0, 0x0801) }, /* ScanJet 7400C - NOT SUPPORTED - use hpusbscsi driver */ + { USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */ + { USB_DEVICE(0x03f0, 0x1305) }, /* Scanjet 4570c */ + { USB_DEVICE(0x03f0, 0x2005) }, /* ScanJet 3570c */ + { USB_DEVICE(0x03f0, 0x2205) }, /* ScanJet 3500c */ /* iVina */ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ /* Lexmark */ { USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */ - /* Lifetec */ - { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ /* Memorex */ { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ - /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */ + /* Microtek */ + { USB_DEVICE(0x05da, 0x30ce) }, /* ScanMaker 3800 */ + /* The following SCSI-over-USB Microtek devices are supported by the + microtek driver: Enable SCSI and USB Microtek in kernel config */ // { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */ // { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */ // { USB_DEVICE(0x05da, 0x00a0) }, /* Phantom 336CX - C3 #2 */ @@ -146,58 +163,59 @@ static struct usb_device_id scanner_device_ids [] = { // { USB_DEVICE(0x05da, 0x80a3) }, /* ScanMaker V6USL #2 */ // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */ /* Minolta */ - // { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */ - // { USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */ { USB_DEVICE(0x0686, 0x400d) }, /* Scan Dual III */ + /* The following SCSI-over-USB Minolta devices are supported by the + hpusbscsi driver: Enable SCSI and USB hpusbscsi in kernel config */ + // { USB_DEVICE(0x0638, 0x026a) }, /* Minolta Dimage Scan Dual II */ + // { USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */ /* Mustek */ + { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 (National Semiconductor LM9831) */ + { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 (National Semiconductor LM9832) */ { USB_DEVICE(0x055f, 0x0001) }, /* ScanExpress 1200 CU */ - { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */ { USB_DEVICE(0x055f, 0x0002) }, /* ScanExpress 600 CU */ - { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */ { USB_DEVICE(0x055f, 0x0003) }, /* ScanExpress 1200 USB */ { USB_DEVICE(0x055f, 0x0006) }, /* ScanExpress 1200 UB */ { USB_DEVICE(0x055f, 0x0007) }, /* ScanExpress 1200 USB Plus */ - { USB_DEVICE(0x055f, 0x0210) }, /* ScanExpress A3 USB */ - { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */ { USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */ + { USB_DEVICE(0x055f, 0x0210) }, /* ScanExpress A3 USB */ { USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */ - { USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus */ { USB_DEVICE(0x055f, 0x0219) }, /* BearPaw 2400 TA Plus */ { USB_DEVICE(0x055f, 0x021c) }, /* BearPaw 1200 CU Plus */ { USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */ { USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */ { USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */ + { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */ { USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */ + // { USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus (see Artec) */ /* Nikon */ { USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */ /* Plustek */ - { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */ - { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */ - { USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */ - { USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */ + { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */ { USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ - { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ { USB_DEVICE(0x0461, 0x0301) }, /* G2E-300 #1 */ - { USB_DEVICE(0x0461, 0x0381) }, /* ReadyScan 636i */ { USB_DEVICE(0x0461, 0x0302) }, /* G2-300 #2 */ - { USB_DEVICE(0x0461, 0x0382) }, /* G2-600 #2 */ { USB_DEVICE(0x0461, 0x0303) }, /* G2E-300 #2 */ - { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ { USB_DEVICE(0x0461, 0x0340) }, /* Colorado USB 9600 */ - // { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 - undetected endpoint */ { USB_DEVICE(0x0461, 0x0341) }, /* Colorado 600u */ + { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 */ { USB_DEVICE(0x0461, 0x0361) }, /* Colorado 1200u */ + { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ + { USB_DEVICE(0x0461, 0x0381) }, /* ReadyScan 636i */ + { USB_DEVICE(0x0461, 0x0382) }, /* G2-600 #2 */ + { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ /* Relisis */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ /* Seiko/Epson Corp. */ @@ -221,17 +239,18 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */ { USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */ { USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */ + { USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */ { USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */ /* Umax */ { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */ { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */ { USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ - { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ + { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ /* Visioneer */ - { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0211) }, /* OneTouch 7600 USB */ + { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0231) }, /* 6100 USB */ { USB_DEVICE(0x04a7, 0x0311) }, /* 6200 EPP/USB */ { USB_DEVICE(0x04a7, 0x0321) }, /* OneTouch 8100 EPP/USB */ diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 2da265ac3202..dc77e786b596 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1324,6 +1324,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_MGE_UPS 0xffff #define USB_DEVICE_ID_MGE_UPS1 0x0001 +#define USB_VENDOR_ID_ONTRAK 0x0a07 +#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1359,6 +1362,12 @@ struct hid_blacklist { { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, { 0, 0 } }; diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile index 674d47aa8393..e297d6e4f601 100644 --- a/drivers/usb/media/Makefile +++ b/drivers/usb/media/Makefile @@ -2,8 +2,6 @@ # Makefile for USB Media drivers # -export-objs := ov511.o pwc-uncompress.o usbvideo.o - pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o obj-$(CONFIG_USB_DABUSB) += dabusb.o diff --git a/drivers/usb/misc/atmsar.c b/drivers/usb/misc/atmsar.c index 79ccb77c46b5..5f6a7f033361 100644 --- a/drivers/usb/misc/atmsar.c +++ b/drivers/usb/misc/atmsar.c @@ -381,6 +381,83 @@ void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc) ** ***********************/ +/* encapsulate in an AAL5 frame, which is then split into ATM cells */ +unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length) +{ + unsigned int num_cells = (pdu_length + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD; + unsigned int num_pdu_cells = pdu_length / ATM_CELL_PAYLOAD + 1; + unsigned int aal5_length = num_cells * ATM_CELL_PAYLOAD; + unsigned int zero_padding = aal5_length - pdu_length - ATM_AAL5_TRAILER; + unsigned int final_length = num_cells * ATM_CELL_SIZE; + unsigned char aal5_trailer [ATM_AAL5_TRAILER]; + unsigned char cell_header [ATM_CELL_HEADER]; + u32 crc; + int i; + + PDEBUG ("atmsar_encode entered\n"); + + PDEBUG ("pdu_length %d, num_cells %d, num_pdu_cells %d, aal5_length %d, zero_padding %d, final_length %d\n", pdu_length, num_cells, num_pdu_cells, aal5_length, zero_padding, final_length); + + PDEBUG ("source 0x=%p, target 0x%p\n", source, target); + + aal5_trailer [0] = 0; /* UU = 0 */ + aal5_trailer [1] = 0; /* CPI = 0 */ + aal5_trailer [2] = pdu_length >> 8; + aal5_trailer [3] = pdu_length; + + crc = crc32 (~0, source, pdu_length); + for (i = 0; i < zero_padding; i++) + crc = CRC32 (0, crc); + crc = crc32 (crc, aal5_trailer, 4); + crc = ~crc; + + aal5_trailer [4] = crc >> 24; + aal5_trailer [5] = crc >> 16; + aal5_trailer [6] = crc >> 8; + aal5_trailer [7] = crc; + + cell_header [0] = ctx->atmHeader >> 24; + cell_header [1] = ctx->atmHeader >> 16; + cell_header [2] = ctx->atmHeader >> 8; + cell_header [3] = ctx->atmHeader; + cell_header [4] = 0xec; + + for (i = 1; i < num_pdu_cells; i++) { + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + memcpy (target, source, ATM_CELL_PAYLOAD); + target += ATM_CELL_PAYLOAD; + source += ATM_CELL_PAYLOAD; + PDEBUG ("source 0x=%p, target 0x%p\n", source, target); + } + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + memcpy (target, source, pdu_length % ATM_CELL_PAYLOAD); + target += pdu_length % ATM_CELL_PAYLOAD; + if (num_pdu_cells < num_cells) { + memset (target, 0, zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD); + target += zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD; + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + zero_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER; + } + memset (target, 0, zero_padding); + target += zero_padding; + memcpy (target, aal5_trailer, ATM_AAL5_TRAILER); + + /* set pti bit in last cell */ + *(target + ATM_AAL5_TRAILER + 3 - ATM_CELL_SIZE) |= 0x2; + + /* update stats */ + if (ctx->stats) + atomic_inc (&ctx->stats->tx); + + if (ctx->stats && (ctx->type <= ATMSAR_TYPE_AAL1)) + atomic_add (num_cells, &(ctx->stats->tx)); + + return final_length; +} + struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb) { int number_of_cells = (skb->len) / 48; @@ -624,9 +701,8 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b } else { /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */ if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) == - NULL) { - skb_trim (skb, 0); - } + NULL) + return NULL; } } diff --git a/drivers/usb/misc/atmsar.h b/drivers/usb/misc/atmsar.h index d15342b671c1..63836a0464c1 100644 --- a/drivers/usb/misc/atmsar.h +++ b/drivers/usb/misc/atmsar.h @@ -33,6 +33,7 @@ #define ATMSAR_USE_53BYTE_CELL 0x1L #define ATMSAR_SET_PTI 0x2L +#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) /* types */ #define ATMSAR_TYPE_AAL0 ATM_AAL0 @@ -89,4 +90,6 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size); +unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length); + #endif /* _ATMSAR_H_ */ diff --git a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c index c0eabddaa128..3a82d5934388 100644 --- a/drivers/usb/misc/speedtouch.c +++ b/drivers/usb/misc/speedtouch.c @@ -46,6 +46,7 @@ * */ +#include <asm/semaphore.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -58,7 +59,6 @@ #include <linux/usb.h> #include <linux/smp_lock.h> #include <linux/interrupt.h> - #include <linux/atm.h> #include <linux/atmdev.h> #include "atmsar.h" @@ -106,20 +106,21 @@ #define UDSL_ENDPOINT_DATA_OUT 0x07 #define UDSL_ENDPOINT_DATA_IN 0x87 +#define hex2int(c) ( (c >= '0')&&(c <= '9') ? (c - '0') : ((c & 0xf)+9) ) + /* usb_device_id struct */ -static struct usb_device_id udsl_usb_ids[] = { - {USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)}, - {} /* list terminator */ +static struct usb_device_id udsl_usb_ids [] = { + { USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) }, + { } /* Terminating entry */ }; -/* not exporting this prevents the depmod from generating the map that causes the modules to be isnserted as driver. - * we do not want this, we want the script run. -MODULE_DEVICE_TABLE ( usb, udsl_usb_ids); -*/ +MODULE_DEVICE_TABLE (usb, udsl_usb_ids); + /* context declarations */ -struct udsl_data_ctx { +struct udsl_receiver { + struct list_head list; struct sk_buff *skb; struct urb *urb; struct udsl_instance_data *instance; @@ -137,25 +138,32 @@ struct udsl_usb_send_data_context { */ struct udsl_instance_data { - struct tasklet_struct recvqueue_tasklet; + struct semaphore serialize; /* usb device part */ struct usb_device *usb_dev; - struct udsl_data_ctx *rcvbufs; struct sk_buff_head sndqueue; - struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS]; - int data_started; + struct udsl_usb_send_data_context send_ctx [UDSL_NUMBER_SND_URBS]; + int firmware_loaded; /* atm device part */ struct atm_dev *atm_dev; - struct sk_buff_head recvqueue; struct atmsar_vcc_data *atmsar_vcc_list; -}; -static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; + /* receiving */ + struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS]; + + spinlock_t spare_receivers_lock; + struct list_head spare_receivers; + + spinlock_t completed_receivers_lock; + struct list_head completed_receivers; + + struct tasklet_struct receive_tasklet; +}; -static DECLARE_MUTEX(udsl_usb_ioctl_lock); +static const char udsl_driver_name [] = "Alcatel SpeedTouch USB"; #ifdef DEBUG_PACKET static int udsl_print_packet (const unsigned char *data, int len); @@ -169,8 +177,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci); static void udsl_atm_close (struct atm_vcc *vcc); static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb); -static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page); -static void udsl_atm_processqueue (unsigned long data); +static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page); static struct atmdev_ops udsl_atm_devops = { .open = udsl_atm_open, @@ -203,6 +210,170 @@ static struct usb_driver udsl_usb_driver = { .id_table = udsl_usb_ids, }; + +/************** +** receive ** +**************/ + +static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs) +{ + struct udsl_instance_data *instance; + struct udsl_receiver *rcv; + unsigned long flags; + + PDEBUG ("udsl_complete_receive entered\n"); + + if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) { + PDEBUG ("udsl_complete_receive: bad urb!\n"); + return; + } + + /* may not be in_interrupt() */ + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + list_add_tail (&rcv->list, &instance->completed_receivers); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + PDEBUG ("udsl_complete_receive: scheduling tasklet\n"); + tasklet_schedule (&instance->receive_tasklet); +} + +static void udsl_process_receive (unsigned long data) +{ + struct udsl_instance_data *instance = (struct udsl_instance_data *) data; + struct udsl_receiver *rcv; + unsigned long flags; + unsigned char *data_start; + struct sk_buff *skb; + struct urb *urb; + struct atmsar_vcc_data *atmsar_vcc = NULL; + struct sk_buff *new = NULL, *tmp = NULL; + + PDEBUG ("udsl_process_receive entered\n"); + + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + while (!list_empty (&instance->completed_receivers)) { + rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list); + list_del (&rcv->list); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + + urb = rcv->urb; + PDEBUG ("udsl_process_receive: got packet %p with length %d and status %d\n", urb, urb->actual_length, urb->status); + + switch (urb->status) { + case 0: + PDEBUG ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p\n", rcv, urb, rcv->skb); + + /* update the skb structure */ + skb = rcv->skb; + skb_trim (skb, 0); + skb_put (skb, urb->actual_length); + data_start = skb->data; + + PDEBUG ("skb->len = %d\n", skb->len); + PACKETDEBUG (skb->data, skb->len); + + while ((new = + atmsar_decode_rawcell (instance->atmsar_vcc_list, skb, + &atmsar_vcc)) != NULL) { + PDEBUG ("(after cell processing)skb->len = %d\n", new->len); + + switch (atmsar_vcc->type) { + case ATMSAR_TYPE_AAL5: + tmp = new; + new = atmsar_decode_aal5 (atmsar_vcc, new); + + /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */ + if (new) { + PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len); + if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) { + PACKETDEBUG (new->data, new->len); + atmsar_vcc->vcc->push (atmsar_vcc->vcc, new); + } else { + PDEBUG + ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n", + atomic_read (&atmsar_vcc->vcc->rx_inuse), + atmsar_vcc->vcc->sk->rcvbuf, new->truesize); + dev_kfree_skb (new); + } + } else { + PDEBUG ("atmsar_decode_aal5 returned NULL!\n"); + dev_kfree_skb (tmp); + } + break; + default: + /* not supported. we delete the skb. */ + printk (KERN_INFO + "SpeedTouch USB: illegal vcc type. Dropping packet.\n"); + dev_kfree_skb (new); + break; + } + } + + /* restore skb */ + skb_push (skb, skb->data - data_start); + + usb_fill_bulk_urb (urb, + instance->usb_dev, + usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), + (unsigned char *) rcv->skb->data, + UDSL_RECEIVE_BUFFER_SIZE, + udsl_complete_receive, + rcv); + if (!usb_submit_urb (urb, GFP_ATOMIC)) + break; + PDEBUG ("udsl_process_receive: submission failed\n"); + /* fall through */ + default: /* error or urb unlinked */ + PDEBUG ("udsl_process_receive: adding to spare_receivers\n"); + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_add (&rcv->list, &instance->spare_receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + break; + } /* switch */ + + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + } /* while */ + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + PDEBUG ("udsl_process_receive successful\n"); +} + +static void udsl_fire_receivers (struct udsl_instance_data *instance) +{ + struct list_head receivers, *pos, *n; + unsigned long flags; + + INIT_LIST_HEAD (&receivers); + + down (&instance->serialize); + + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_splice_init (&instance->spare_receivers, &receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + + list_for_each_safe (pos, n, &receivers) { + struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list); + + PDEBUG ("udsl_fire_receivers: firing urb %p\n", rcv->urb); + + usb_fill_bulk_urb (rcv->urb, + instance->usb_dev, + usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), + (unsigned char *) rcv->skb->data, + UDSL_RECEIVE_BUFFER_SIZE, + udsl_complete_receive, + rcv); + + if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) { + PDEBUG ("udsl_fire_receivers: submit failed!\n"); + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_move (pos, &instance->spare_receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + } + } + + up (&instance->serialize); +} + + /************ ** ATM ** ************/ @@ -213,27 +384,9 @@ static struct usb_driver udsl_usb_driver = { * ****************************************************************************/ -static struct atm_dev *udsl_atm_startdevice (struct udsl_instance_data *instance, struct atmdev_ops *devops) -{ - MOD_INC_USE_COUNT; - instance->atm_dev = atm_dev_register (udsl_driver_name, devops, -1, 0); - instance->atm_dev->dev_data = instance; - instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX; - instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX; - instance->atm_dev->signal = ATM_PHY_SIG_LOST; - - skb_queue_head_init (&instance->recvqueue); - - /* tmp init atm device, set to 128kbit */ - instance->atm_dev->link_rate = 128 * 1000 / 424; - - return instance->atm_dev; -} - static void udsl_atm_stopdevice (struct udsl_instance_data *instance) { struct atm_vcc *walk; - struct sk_buff *skb; struct atm_dev *atm_dev; if (!instance->atm_dev) @@ -241,10 +394,6 @@ static void udsl_atm_stopdevice (struct udsl_instance_data *instance) atm_dev = instance->atm_dev; - /* clean queue */ - while ((skb = skb_dequeue (&instance->recvqueue))) - dev_kfree_skb (skb); - atm_dev->signal = ATM_PHY_SIG_LOST; walk = atm_dev->vccs; shutdown_atm_dev (atm_dev); @@ -253,16 +402,8 @@ static void udsl_atm_stopdevice (struct udsl_instance_data *instance) wake_up (&walk->sleep); instance->atm_dev = NULL; - MOD_DEC_USE_COUNT; } -static void udsl_atm_set_mac (struct udsl_instance_data *instance, const char mac[6]) -{ - if (!instance->atm_dev) - return; - - memcpy (instance->atm_dev->esi, mac, 6); -} /*************************************************************************** * @@ -281,11 +422,16 @@ static struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size return NULL; } -static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page) +static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page) { struct udsl_instance_data *instance = atm_dev->dev_data; int left = *pos; + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; + } + if (!left--) return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", instance->usb_dev->bus->bus_name, instance->usb_dev->devpath, @@ -311,6 +457,7 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page return 0; } + /*************************************************************************** * * ATM DATA functions @@ -325,8 +472,13 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) PDEBUG ("udsl_atm_send called\n"); - if (!dev_data) + if (!dev_data || !instance) { + PDEBUG ("NULL data!\n"); return -EINVAL; + } + + if (!instance->firmware_loaded) + return -EAGAIN; switch (vcc->qos.aal) { case ATM_AAL5: @@ -350,67 +502,13 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) break; default: return -EINVAL; - }; + } PDEBUG ("udsl_atm_send unsuccessfull\n"); return 0; nomem: vcc->pop (vcc, skb); return -ENOMEM; -}; - - -static void udsl_atm_processqueue (unsigned long data) -{ - struct udsl_instance_data *instance = (struct udsl_instance_data *) data; - struct atmsar_vcc_data *atmsar_vcc = NULL; - struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL; - - PDEBUG ("udsl_atm_processqueue entered\n"); - - while ((skb = skb_dequeue (&instance->recvqueue))) { - PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len); - PACKETDEBUG (skb->data, skb->len); - - while ((new = - atmsar_decode_rawcell (instance->atmsar_vcc_list, skb, - &atmsar_vcc)) != NULL) { - PDEBUG ("(after cell processing)skb->len = %d\n", new->len); - switch (atmsar_vcc->type) { - case ATMSAR_TYPE_AAL5: - tmp = new; - new = atmsar_decode_aal5 (atmsar_vcc, new); - - /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */ - if (new) { - PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len); - if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) { - PACKETDEBUG (new->data, new->len); - atmsar_vcc->vcc->push (atmsar_vcc->vcc, new); - } else { - PDEBUG - ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n", - atomic_read (&atmsar_vcc->vcc->rx_inuse), - atmsar_vcc->vcc->sk->rcvbuf, new->truesize); - dev_kfree_skb (new); - } - } else { - PDEBUG ("atmsar_decode_aal5 returned NULL!\n"); - dev_kfree_skb (tmp); - } - break; - default: - /* not supported. we delete the skb. */ - printk (KERN_INFO - "SpeedTouch USB: illegal vcc type. Dropping packet.\n"); - dev_kfree_skb (new); - break; - } - }; - dev_kfree_skb (skb); - }; - - PDEBUG ("udsl_atm_processqueue successfull\n"); } @@ -419,6 +517,7 @@ static void udsl_atm_processqueue (unsigned long data) * SAR driver entries * ****************************************************************************/ + static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) { struct udsl_atm_dev_data *dev_data; @@ -426,6 +525,11 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) PDEBUG ("udsl_atm_open called\n"); + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; + } + /* at the moment only AAL5 support */ if (vcc->qos.aal != ATM_AAL5) return -EINVAL; @@ -453,6 +557,9 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) dev_data->atmsar_vcc->mtu = UDSL_MAX_AAL5_MRU; + if (instance->firmware_loaded) + udsl_fire_receivers (instance); + PDEBUG ("udsl_atm_open successfull\n"); return 0; } @@ -464,6 +571,11 @@ static void udsl_atm_close (struct atm_vcc *vcc) PDEBUG ("udsl_atm_close called\n"); + if (!dev_data || !instance) { + PDEBUG ("NULL data!\n"); + return; + } + /* freeing resources */ /* cancel all sends on this vcc */ udsl_usb_cancelsends (instance, vcc); @@ -482,7 +594,7 @@ static void udsl_atm_close (struct atm_vcc *vcc) PDEBUG ("udsl_atm_close successfull\n"); return; -}; +} static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg) { @@ -492,7 +604,7 @@ static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg) default: return -ENOIOCTLCMD; } -}; +} /************ @@ -566,9 +678,6 @@ static int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_v PDEBUG ("udsl_usb_send_data entered, sending packet %p with length %d\n", skb, skb->len); - if (!instance->data_started) - return -EAGAIN; - PACKETDEBUG (skb->data, skb->len); spin_lock_irqsave (&instance->sndqueue.lock, flags); @@ -592,7 +701,7 @@ static int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_v spin_unlock_irqrestore (&instance->sndqueue.lock, flags); PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb); return 0; - }; + } /* init context */ urb = instance->send_ctx[i].urb; @@ -620,285 +729,264 @@ static int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_v return err; } -/********* receive *******/ -static void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) -{ - struct udsl_data_ctx *ctx; - struct udsl_instance_data *instance; - if (!urb) - return; +/*************************************************************************** +* +* usb driver entries +* +****************************************************************************/ - PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb, - urb->actual_length, urb->status); +static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data) +{ + struct udsl_instance_data *instance = usb_get_intfdata (intf); - ctx = urb->context; - if (!ctx || !ctx->skb) - return; + PDEBUG ("udsl_usb_ioctl entered\n"); - instance = ctx->instance; - - switch (urb->status) { - case 0: - PDEBUG ("udsl_usb_data_receive: processing urb with ctx %p, urb %p (%p), skb %p\n", - ctx, ctx ? ctx->urb : NULL, urb, ctx ? ctx->skb : NULL); - /* update the skb structure */ - skb_put (ctx->skb, urb->actual_length); - - /* queue the skb for processing and wake the SAR */ - skb_queue_tail (&instance->recvqueue, ctx->skb); - tasklet_schedule (&instance->recvqueue_tasklet); - /* get a new skb */ - ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); - if (!ctx->skb) { - PDEBUG ("No skb, loosing urb.\n"); - usb_free_urb (ctx->urb); - ctx->urb = NULL; - return; - } - break; - case -ENOENT: /* buffer was unlinked */ - case -EILSEQ: /* unplug or timeout */ - case -ETIMEDOUT: /* unplug or timeout */ - /* - * we don't do anything here and we don't resubmit - */ - return; + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; } - usb_fill_bulk_urb (urb, - instance->usb_dev, - usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), - (unsigned char *) ctx->skb->data, - UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx); - usb_submit_urb (urb, GFP_ATOMIC); - return; -}; + switch (code) { + case UDSL_IOCTL_START: + instance->atm_dev->signal = ATM_PHY_SIG_FOUND; + down (&instance->serialize); /* vs self */ + if (!instance->firmware_loaded) { + usb_set_interface (instance->usb_dev, 1, 2); + instance->firmware_loaded = 1; + } + up (&instance->serialize); + udsl_fire_receivers (instance); + return 0; + case UDSL_IOCTL_STOP: + instance->atm_dev->signal = ATM_PHY_SIG_LOST; + return 0; + default: + return -ENOTTY; + } +} -static int udsl_usb_data_init (struct udsl_instance_data *instance) +static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { - int i, succes; + struct usb_device *dev = interface_to_usbdev(intf); + int ifnum = intf->altsetting->desc.bInterfaceNumber; + struct udsl_instance_data *instance; + unsigned char mac_str [13]; + unsigned char mac [6]; + int i, err; - if (instance->data_started) - return 1; + PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n", + dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); - /* set alternate setting 1 on interface 1 */ - usb_set_interface (instance->usb_dev, 1, 2); + if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || + (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) || + (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1)) + return -ENODEV; - PDEBUG ("max packet size on endpoint %d is %d\n", UDSL_ENDPOINT_DATA_OUT, - usb_maxpacket (instance->usb_dev, - usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0)); + PDEBUG ("Device Accepted\n"); - instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL); - if (!instance->rcvbufs) - return -ENOMEM; + /* instance init */ + if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) { + PDEBUG ("No memory for Instance data!\n"); + err = -ENOMEM; + goto fail_instance; + } - memset (instance->rcvbufs, 0, sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS); + memset (instance, 0, sizeof (struct udsl_instance_data)); - skb_queue_head_init (&instance->sndqueue); + init_MUTEX (&instance->serialize); - for (i = 0, succes = 0; i < UDSL_NUMBER_RCV_URBS; i++) { - struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]); + instance->usb_dev = dev; - ctx->urb = NULL; - ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); - if (!ctx->skb) - continue; + spin_lock_init (&instance->spare_receivers_lock); + INIT_LIST_HEAD (&instance->spare_receivers); - ctx->urb = usb_alloc_urb (0, GFP_KERNEL); - if (!ctx->urb) { - kfree_skb (ctx->skb); - ctx->skb = NULL; - break; - }; + spin_lock_init (&instance->completed_receivers_lock); + INIT_LIST_HEAD (&instance->completed_receivers); - usb_fill_bulk_urb (ctx->urb, - instance->usb_dev, - usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), - (unsigned char *) ctx->skb->data, - UDSL_RECEIVE_BUFFER_SIZE, - udsl_usb_data_receive, ctx); + tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance); + skb_queue_head_init (&instance->sndqueue); - ctx->instance = instance; + /* receive urb init */ + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - PDEBUG ("udsl_usb_data_init: usb with skb->truesize = %d (Asked for %d)\n", - ctx->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE); + if (!(rcv->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE))) { + PDEBUG ("No memory for skb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } - if (usb_submit_urb (ctx->urb, GFP_KERNEL) < 0) - PDEBUG ("udsl_usb_data_init: Submit failed, loosing urb.\n"); - else - succes++; - } + if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) { + PDEBUG ("No memory for receive urb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } - PDEBUG ("udsl_usb_data_init %d urb%s queued for receive\n", succes, - (succes != 1) ? "s" : ""); + rcv->instance = instance; - for (i = 0, succes = 0; i < UDSL_NUMBER_SND_URBS; i++) { - instance->send_ctx[i].urb = usb_alloc_urb (0, GFP_KERNEL); - PDEBUG ("udsl_usb_data_init: send urb allocted address %p\n", - instance->send_ctx[i].urb); - if (instance->send_ctx[i].urb) - succes++; + list_add (&rcv->list, &instance->spare_receivers); + + PDEBUG ("skb->truesize = %d (asked for %d)\n", rcv->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE); } - PDEBUG ("udsl_usb_data_init %d urb%s queued for send\n", succes, (succes != 1) ? "s" : ""); + for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { + struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]); - instance->data_started = 1; - instance->atm_dev->signal = ATM_PHY_SIG_FOUND; + if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) { + PDEBUG ("No memory for send urb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } - return 0; -} + snd->instance = instance; + } -static int udsl_usb_data_exit (struct udsl_instance_data *instance) -{ - int i; + /* atm init */ + if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) { + PDEBUG ("failed to register ATM device!\n"); + err = -ENOMEM; + goto fail_atm; + } - if (!instance->data_started) - return 0; + instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX; + instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX; + instance->atm_dev->signal = ATM_PHY_SIG_LOST; - if (!instance->rcvbufs) - return 0; + /* tmp init atm device, set to 128kbit */ + instance->atm_dev->link_rate = 128 * 1000 / 424; - /* destroy urbs */ - for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { - struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]); + /* set MAC address, it is stored in the serial number */ + usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13); + for (i = 0; i < 6; i++) + mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1])); - if ((!ctx->urb) || (!ctx->skb)) - continue; + PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - usb_unlink_urb (ctx->urb); + memcpy (instance->atm_dev->esi, mac, 6); - usb_free_urb (ctx->urb); - kfree_skb (ctx->skb); - ctx->skb = NULL; - } + wmb (); - tasklet_kill (&instance->recvqueue_tasklet); + instance->atm_dev->dev_data = instance; + usb_set_intfdata (intf, instance); + + return 0; + +fail_atm: +fail_urbs: for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { - struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]); + struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]); - usb_unlink_urb (ctx->urb); + if (snd->urb) + usb_free_urb (snd->urb); + } - if (ctx->skb) - ctx->vcc->pop (ctx->vcc, ctx->skb); - ctx->skb = NULL; + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - usb_free_urb (ctx->urb); + if (rcv->skb) + kfree_skb (rcv->skb); + if (rcv->urb) + usb_free_urb (rcv->urb); } + kfree (instance); +fail_instance: + return err; +} - /* free receive contexts */ - kfree (instance->rcvbufs); - instance->rcvbufs = NULL; +static void udsl_usb_disconnect (struct usb_interface *intf) +{ + struct udsl_instance_data *instance = usb_get_intfdata (intf); + struct list_head *pos; + unsigned long flags; + unsigned int count = 0; + int i; - instance->data_started = 0; - instance->atm_dev->signal = ATM_PHY_SIG_LOST; + PDEBUG ("disconnecting\n"); - return 0; -}; + usb_set_intfdata (intf, NULL); + if (!instance) { + PDEBUG ("NULL instance!\n"); + return; + } -/*************************************************************************** -* -* usb driver entries -* -****************************************************************************/ -#define hex2int(c) ( (c >= '0')&&(c <= '9') ? (c - '0') : ((c & 0xf)+9) ) + tasklet_disable (&instance->receive_tasklet); + down (&instance->serialize); /* vs udsl_fire_receivers */ + /* no need to take the spinlock - receive_tasklet is not running */ + list_for_each (pos, &instance->spare_receivers) + if (++count > UDSL_NUMBER_RCV_URBS) + panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); + INIT_LIST_HEAD (&instance->spare_receivers); + up (&instance->serialize); -static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data) -{ - struct udsl_instance_data *instance = usb_get_intfdata (intf); - int retval; + PDEBUG ("udsl_usb_disconnect: flushed %u spare receivers\n", count); - down(&udsl_usb_ioctl_lock); - switch (code) { - case UDSL_IOCTL_START: - retval = udsl_usb_data_init (instance); - break; - case UDSL_IOCTL_STOP: - retval = udsl_usb_data_exit (instance); - break; - default: - retval = -ENOTTY; - break; - } - up(&udsl_usb_ioctl_lock); - return retval; -} + count = UDSL_NUMBER_RCV_URBS - count; -static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->desc.bInterfaceNumber; - int i; - unsigned char mac[6]; - unsigned char mac_str[13]; - struct udsl_instance_data *instance = NULL; + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) + usb_unlink_urb (instance->all_receivers[i].urb); - PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n", - dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); + /* wait for completion handlers to finish */ + do { + unsigned int completed = 0; - if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || - (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) || - (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1)) - return -ENODEV; + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + list_for_each (pos, &instance->completed_receivers) + if (++completed > count) + panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); - MOD_INC_USE_COUNT; + PDEBUG ("udsl_usb_disconnect: found %u completed receivers\n", completed); - PDEBUG ("Device Accepted\n"); + if (completed == count) + break; - /* device init */ - instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL); - if (!instance) { - PDEBUG ("No memory for Instance data!\n"); - return -ENOMEM; - } + /* not all urbs completed */ + yield (); + } while (1); - /* initialize structure */ - memset (instance, 0, sizeof (struct udsl_instance_data)); - instance->usb_dev = dev; - instance->rcvbufs = NULL; - tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance); + PDEBUG ("udsl_usb_disconnect: flushing %u completed receivers\n", count); + /* no need to take the spinlock - no completion handlers running */ + INIT_LIST_HEAD (&instance->completed_receivers); - udsl_atm_startdevice (instance, &udsl_atm_devops); + tasklet_enable (&instance->receive_tasklet); + tasklet_kill (&instance->receive_tasklet); - /* set MAC address, it is stored in the serial number */ - usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13); - for (i = 0; i < 6; i++) - mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1])); + PDEBUG ("udsl_usb_disconnect: freeing receivers\n"); + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], - mac[5]); - udsl_atm_set_mac (instance, mac); + usb_free_urb (rcv->urb); + kfree_skb (rcv->skb); + } - usb_set_intfdata (intf, instance); - return 0; -} + for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { + struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]); -static void udsl_usb_disconnect (struct usb_interface *intf) -{ - struct udsl_instance_data *instance = usb_get_intfdata (intf); + usb_unlink_urb (ctx->urb); - PDEBUG ("disconnecting\n"); + if (ctx->skb) + ctx->vcc->pop (ctx->vcc, ctx->skb); + ctx->skb = NULL; - usb_set_intfdata (intf, NULL); - if (instance) { - /* unlinking receive buffers */ - udsl_usb_data_exit (instance); + usb_free_urb (ctx->urb); - /* removing atm device */ - if (instance->atm_dev) - udsl_atm_stopdevice (instance); + } - kfree (instance); - MOD_DEC_USE_COUNT; - } + /* removing atm device */ + if (instance->atm_dev) + udsl_atm_stopdevice (instance); + + kfree (instance); } + /*************************************************************************** * * Driver Init @@ -907,18 +995,25 @@ static void udsl_usb_disconnect (struct usb_interface *intf) static int __init udsl_usb_init (void) { - PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n"); + PDEBUG ("udsl_usb_init: driver version " DRIVER_VERSION "\n"); return usb_register (&udsl_usb_driver); } static void __exit udsl_usb_cleanup (void) { + PDEBUG ("udsl_usb_cleanup\n"); + usb_deregister (&udsl_usb_driver); } -module_init(udsl_usb_init); -module_exit(udsl_usb_cleanup); +module_init (udsl_usb_init); +module_exit (udsl_usb_cleanup); + +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_LICENSE ("GPL"); + #ifdef DEBUG_PACKET /******************************************************************************* @@ -929,7 +1024,7 @@ module_exit(udsl_usb_cleanup); static int udsl_print_packet (const unsigned char *data, int len) { - unsigned char buffer[256]; + unsigned char buffer [256]; int i = 0, j = 0; for (i = 0; i < len;) { @@ -941,10 +1036,6 @@ static int udsl_print_packet (const unsigned char *data, int len) PDEBUG ("%s\n", buffer); } return i; -}; +} #endif /* PACKETDEBUG */ - -MODULE_AUTHOR (DRIVER_AUTHOR); -MODULE_DESCRIPTION (DRIVER_DESC); -MODULE_LICENSE ("GPL"); diff --git a/drivers/usb/net/Makefile.mii b/drivers/usb/net/Makefile.mii new file mode 100644 index 000000000000..5fa1204701a2 --- /dev/null +++ b/drivers/usb/net/Makefile.mii @@ -0,0 +1,5 @@ +# +# Makefile for USB Network drivers which require generic MII code. +# + +obj-$(CONFIG_USB_PEGASUS) += mii.o diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 7ac4907de3a8..73b899e52fb5 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -30,7 +30,4 @@ obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o -# Objects that export symbols. -export-objs := usb-serial.o ezusb.o - usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0d24afa9864b..caedb621689b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -135,6 +135,7 @@ static struct usb_device_id id_table_sio [] = { static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; @@ -143,6 +144,7 @@ static struct usb_device_id id_table_8U232AM [] = { static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 369c4c066cf6..b03067d36920 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -17,11 +17,14 @@ * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the * FTDI_SIO implementation. * + * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais + * from Rudolf Gugler */ #define FTDI_VID 0x0403 /* Vendor Id */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d5dc7d80a578..ec9da1f5926d 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -106,6 +106,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_AXIM_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) }, @@ -126,6 +127,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) }, { USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) }, { USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) }, { USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) }, { } /* Terminating entry */ diff --git a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h index f3302b337ee0..8a6482642168 100644 --- a/drivers/usb/serial/ipaq.h +++ b/drivers/usb/serial/ipaq.h @@ -30,6 +30,9 @@ #define COMPAQ_IPAQ_ID 0x0003 #define COMPAQ_0032_ID 0x0032 +#define DELL_VENDOR_ID 0x413c +#define DELL_AXIM_ID 0x4001 + #define HP_VENDOR_ID 0x03f0 #define HP_JORNADA_548_ID 0x1016 #define HP_JORNADA_568_ID 0x1116 @@ -63,6 +66,7 @@ #define TOSHIBA_VENDOR_ID 0x0930 #define TOSHIBA_PRODUCT_ID 0x0700 +#define TOSHIBA_E740_ID 0x0706 #define HTC_VENDOR_ID 0x0bb4 #define HTC_PRODUCT_ID 0x00ce diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 9543766f207c..9c92bd5cbc8e 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -74,6 +74,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, + { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 6566b2b85573..addcac2684fa 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -28,3 +28,6 @@ #define RATOC_VENDOR_ID 0x0584 #define RATOC_PRODUCT_ID 0xb000 + +#define TRIPP_VENDOR_ID 0x2478 +#define TRIPP_PRODUCT_ID 0x2008 diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h index 5515583ddce3..2f03462b6ad3 100644 --- a/drivers/usb/storage/datafab.h +++ b/drivers/usb/storage/datafab.h @@ -27,14 +27,14 @@ extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us); struct datafab_info { - unsigned long sectors; // total sector count - unsigned long ssize; // sector size in bytes - char lun; // used for dual-slot readers - - // the following aren't used yet + unsigned long sectors; // total sector count + unsigned long ssize; // sector size in bytes + char lun; // used for dual-slot readers + + // the following aren't used yet unsigned char sense_key; - unsigned long sense_asc; // additional sense code - unsigned long sense_ascq; // additional sense code qualifier + unsigned long sense_asc; // additional sense code + unsigned long sense_ascq; // additional sense code qualifier }; #endif diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 2f3bbba3fd7b..8c723e012997 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -45,42 +45,42 @@ static void pdump (void *, int); #define DRQ_STAT 0x08 struct freecom_udata { - u8 buffer[64]; /* Common command block. */ + u8 buffer[64]; /* Common command block. */ }; typedef struct freecom_udata *freecom_udata_t; /* All of the outgoing packets are 64 bytes long. */ struct freecom_cb_wrap { - u8 Type; /* Command type. */ - u8 Timeout; /* Timeout in seconds. */ - u8 Atapi[12]; /* An ATAPI packet. */ - u8 Filler[50]; /* Padding Data. */ + u8 Type; /* Command type. */ + u8 Timeout; /* Timeout in seconds. */ + u8 Atapi[12]; /* An ATAPI packet. */ + u8 Filler[50]; /* Padding Data. */ }; struct freecom_xfer_wrap { - u8 Type; /* Command type. */ - u8 Timeout; /* Timeout in seconds. */ - u32 Count; /* Number of bytes to transfer. */ - u8 Pad[58]; + u8 Type; /* Command type. */ + u8 Timeout; /* Timeout in seconds. */ + u32 Count; /* Number of bytes to transfer. */ + u8 Pad[58]; } __attribute__ ((packed)); struct freecom_ide_out { - u8 Type; /* Type + IDE register. */ - u8 Pad; - u16 Value; /* Value to write. */ - u8 Pad2[60]; + u8 Type; /* Type + IDE register. */ + u8 Pad; + u16 Value; /* Value to write. */ + u8 Pad2[60]; }; struct freecom_ide_in { - u8 Type; /* Type | IDE register. */ - u8 Pad[63]; + u8 Type; /* Type | IDE register. */ + u8 Pad[63]; }; struct freecom_status { - u8 Status; - u8 Reason; - u16 Count; - u8 Pad[60]; + u8 Status; + u8 Reason; + u16 Count; + u8 Pad[60]; }; /* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide @@ -110,32 +110,32 @@ struct freecom_status { static int freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, - unsigned int ipipe, unsigned int opipe, int count) + unsigned int ipipe, unsigned int opipe, int count) { - freecom_udata_t extra = (freecom_udata_t) us->extra; - struct freecom_xfer_wrap *fxfr = - (struct freecom_xfer_wrap *) extra->buffer; - int result; - - fxfr->Type = FCM_PACKET_INPUT | 0x00; - fxfr->Timeout = 0; /* Short timeout for debugging. */ - fxfr->Count = cpu_to_le32 (count); - memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - - US_DEBUGP("Read data Freecom! (c=%d)\n", count); - - /* Issue the transfer command. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, - FCM_PACKET_LENGTH, NULL); - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom readdata transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* Now transfer all of our blocks. */ + freecom_udata_t extra = (freecom_udata_t) us->extra; + struct freecom_xfer_wrap *fxfr = + (struct freecom_xfer_wrap *) extra->buffer; + int result; + + fxfr->Type = FCM_PACKET_INPUT | 0x00; + fxfr->Timeout = 0; /* Short timeout for debugging. */ + fxfr->Count = cpu_to_le32 (count); + memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); + + US_DEBUGP("Read data Freecom! (c=%d)\n", count); + + /* Issue the transfer command. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("Freecom readdata transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* Now transfer all of our blocks. */ US_DEBUGP("Start of read\n"); result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count); - US_DEBUGP("freecom_readdata done!\n"); + US_DEBUGP("freecom_readdata done!\n"); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; @@ -144,33 +144,33 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, static int freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, - int unsigned ipipe, unsigned int opipe, int count) + int unsigned ipipe, unsigned int opipe, int count) { - freecom_udata_t extra = (freecom_udata_t) us->extra; - struct freecom_xfer_wrap *fxfr = - (struct freecom_xfer_wrap *) extra->buffer; - int result; - - fxfr->Type = FCM_PACKET_OUTPUT | 0x00; - fxfr->Timeout = 0; /* Short timeout for debugging. */ - fxfr->Count = cpu_to_le32 (count); - memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - - US_DEBUGP("Write data Freecom! (c=%d)\n", count); - - /* Issue the transfer command. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, - FCM_PACKET_LENGTH, NULL); - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom writedata transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* Now transfer all of our blocks. */ + freecom_udata_t extra = (freecom_udata_t) us->extra; + struct freecom_xfer_wrap *fxfr = + (struct freecom_xfer_wrap *) extra->buffer; + int result; + + fxfr->Type = FCM_PACKET_OUTPUT | 0x00; + fxfr->Timeout = 0; /* Short timeout for debugging. */ + fxfr->Count = cpu_to_le32 (count); + memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); + + US_DEBUGP("Write data Freecom! (c=%d)\n", count); + + /* Issue the transfer command. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("Freecom writedata transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* Now transfer all of our blocks. */ US_DEBUGP("Start of write\n"); result = usb_stor_bulk_transfer_srb(us, opipe, srb, count); - US_DEBUGP("freecom_writedata done!\n"); + US_DEBUGP("freecom_writedata done!\n"); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_GOOD; @@ -182,54 +182,54 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, */ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) { - struct freecom_cb_wrap *fcb; - struct freecom_status *fst; - unsigned int ipipe, opipe; /* We need both pipes. */ - int result; + struct freecom_cb_wrap *fcb; + struct freecom_status *fst; + unsigned int ipipe, opipe; /* We need both pipes. */ + int result; unsigned int partial; - int length; - freecom_udata_t extra; + int length; + freecom_udata_t extra; - extra = (freecom_udata_t) us->extra; + extra = (freecom_udata_t) us->extra; - fcb = (struct freecom_cb_wrap *) extra->buffer; - fst = (struct freecom_status *) extra->buffer; + fcb = (struct freecom_cb_wrap *) extra->buffer; + fst = (struct freecom_status *) extra->buffer; - US_DEBUGP("Freecom TRANSPORT STARTED\n"); + US_DEBUGP("Freecom TRANSPORT STARTED\n"); - /* Get handles for both transports. */ - opipe = us->send_bulk_pipe; - ipipe = us->recv_bulk_pipe; + /* Get handles for both transports. */ + opipe = us->send_bulk_pipe; + ipipe = us->recv_bulk_pipe; - /* The ATAPI Command always goes out first. */ - fcb->Type = FCM_PACKET_ATAPI | 0x00; - fcb->Timeout = 0; - memcpy (fcb->Atapi, srb->cmnd, 12); - memset (fcb->Filler, 0, sizeof (fcb->Filler)); + /* The ATAPI Command always goes out first. */ + fcb->Type = FCM_PACKET_ATAPI | 0x00; + fcb->Timeout = 0; + memcpy (fcb->Atapi, srb->cmnd, 12); + memset (fcb->Filler, 0, sizeof (fcb->Filler)); - US_DEBUG(pdump (srb->cmnd, 12)); + US_DEBUG(pdump (srb->cmnd, 12)); - /* Send it out. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fcb, - FCM_PACKET_LENGTH, NULL); + /* Send it out. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); - /* The Freecom device will only fail if there is something wrong in - * USB land. It returns the status in its own registers, which - * come back in the bulk pipe. */ - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } + /* The Freecom device will only fail if there is something wrong in + * USB land. It returns the status in its own registers, which + * come back in the bulk pipe. */ + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("freecom transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } - /* There are times we can optimize out this status read, but it - * doesn't hurt us to always do it now. */ - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); - US_DEBUGP("foo Status result %d %u\n", result, partial); + /* There are times we can optimize out this status read, but it + * doesn't hurt us to always do it now. */ + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); + US_DEBUGP("foo Status result %d %u\n", result, partial); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUG(pdump ((void *) fst, partial)); + US_DEBUG(pdump ((void *) fst, partial)); /* The firmware will time-out commands after 20 seconds. Some commands * can legitimately take longer than this, so we use a different @@ -249,7 +249,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) memset (fcb->Atapi, 0, sizeof(fcb->Atapi)); memset (fcb->Filler, 0, sizeof (fcb->Filler)); - /* Send it out. */ + /* Send it out. */ result = usb_stor_bulk_transfer_buf (us, opipe, fcb, FCM_PACKET_LENGTH, NULL); @@ -263,31 +263,31 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) } /* get the data */ - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); US_DEBUGP("bar Status result %d %u\n", result, partial); if (result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; + return USB_STOR_TRANSPORT_ERROR; US_DEBUG(pdump ((void *) fst, partial)); } - if (partial != 4) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & 1) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - - /* The device might not have as much data available as we - * requested. If you ask for more than the device has, this reads - * and such will hang. */ - US_DEBUGP("Device indicates that it has %d bytes available\n", - le16_to_cpu (fst->Count)); - US_DEBUGP("SCSI requested %d\n", srb->request_bufflen); - - /* Find the length we desire to read. */ + if (partial != 4) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & 1) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + + /* The device might not have as much data available as we + * requested. If you ask for more than the device has, this reads + * and such will hang. */ + US_DEBUGP("Device indicates that it has %d bytes available\n", + le16_to_cpu (fst->Count)); + US_DEBUGP("SCSI requested %d\n", srb->request_bufflen); + + /* Find the length we desire to read. */ switch (srb->cmnd[0]) { case INQUIRY: case REQUEST_SENSE: /* 16 or 18 bytes? spec says 18, lots of devices only have 16 */ @@ -305,97 +305,97 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUGP("Truncating request to match buffer length: %d\n", length); } - /* What we do now depends on what direction the data is supposed to - * move in. */ - - switch (us->srb->sc_data_direction) { - case SCSI_DATA_READ: - /* Make sure that the status indicates that the device - * wants data as well. */ - if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { - US_DEBUGP("SCSI wants data, drive doesn't have any\n"); - return USB_STOR_TRANSPORT_FAILED; - } - result = freecom_readdata (srb, us, ipipe, opipe, length); - if (result != USB_STOR_TRANSPORT_GOOD) - return result; - - US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); + /* What we do now depends on what direction the data is supposed to + * move in. */ + + switch (us->srb->sc_data_direction) { + case SCSI_DATA_READ: + /* Make sure that the status indicates that the device + * wants data as well. */ + if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { + US_DEBUGP("SCSI wants data, drive doesn't have any\n"); + return USB_STOR_TRANSPORT_FAILED; + } + result = freecom_readdata (srb, us, ipipe, opipe, length); + if (result != USB_STOR_TRANSPORT_GOOD) + return result; + + US_DEBUGP("FCM: Waiting for status\n"); + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); US_DEBUG(pdump ((void *) fst, partial)); - if (partial != 4 || result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & ERR_STAT) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - if ((fst->Reason & 3) != 3) { - US_DEBUGP("Drive seems still hungry\n"); - return USB_STOR_TRANSPORT_FAILED; - } - US_DEBUGP("Transfer happy\n"); - break; - - case SCSI_DATA_WRITE: - /* Make sure the status indicates that the device wants to - * send us data. */ - /* !!IMPLEMENT!! */ - result = freecom_writedata (srb, us, ipipe, opipe, length); - if (result != USB_STOR_TRANSPORT_GOOD) - return result; - - US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); - - if (partial != 4 || result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & ERR_STAT) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - if ((fst->Reason & 3) != 3) { - US_DEBUGP("Drive seems still hungry\n"); - return USB_STOR_TRANSPORT_FAILED; - } - - US_DEBUGP("Transfer happy\n"); - break; - - - case SCSI_DATA_NONE: - /* Easy, do nothing. */ - break; - - default: - US_DEBUGP ("freecom unimplemented direction: %d\n", - us->srb->sc_data_direction); - // Return fail, SCSI seems to handle this better. - return USB_STOR_TRANSPORT_FAILED; - break; - } - - return USB_STOR_TRANSPORT_GOOD; + if (partial != 4 || result > USB_STOR_XFER_SHORT) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & ERR_STAT) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + if ((fst->Reason & 3) != 3) { + US_DEBUGP("Drive seems still hungry\n"); + return USB_STOR_TRANSPORT_FAILED; + } + US_DEBUGP("Transfer happy\n"); + break; + + case SCSI_DATA_WRITE: + /* Make sure the status indicates that the device wants to + * send us data. */ + /* !!IMPLEMENT!! */ + result = freecom_writedata (srb, us, ipipe, opipe, length); + if (result != USB_STOR_TRANSPORT_GOOD) + return result; + + US_DEBUGP("FCM: Waiting for status\n"); + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); + + if (partial != 4 || result > USB_STOR_XFER_SHORT) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & ERR_STAT) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + if ((fst->Reason & 3) != 3) { + US_DEBUGP("Drive seems still hungry\n"); + return USB_STOR_TRANSPORT_FAILED; + } + + US_DEBUGP("Transfer happy\n"); + break; + + + case SCSI_DATA_NONE: + /* Easy, do nothing. */ + break; + + default: + US_DEBUGP ("freecom unimplemented direction: %d\n", + us->srb->sc_data_direction); + // Return fail, SCSI seems to handle this better. + return USB_STOR_TRANSPORT_FAILED; + break; + } + + return USB_STOR_TRANSPORT_GOOD; } int freecom_init (struct us_data *us) { - int result; + int result; char buffer[33]; - /* Allocate a buffer for us. The upper usb transport code will - * free this for us when cleaning up. */ - if (us->extra == NULL) { - us->extra = kmalloc (sizeof (struct freecom_udata), - GFP_KERNEL); - if (us->extra == NULL) { - US_DEBUGP("Out of memory\n"); - return USB_STOR_TRANSPORT_ERROR; - } - } + /* Allocate a buffer for us. The upper usb transport code will + * free this for us when cleaning up. */ + if (us->extra == NULL) { + us->extra = kmalloc (sizeof (struct freecom_udata), + GFP_KERNEL); + if (us->extra == NULL) { + US_DEBUGP("Out of memory\n"); + return USB_STOR_TRANSPORT_ERROR; + } + } result = usb_control_msg(us->pusb_dev, us->recv_ctrl_pipe, 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ); @@ -424,15 +424,15 @@ freecom_init (struct us_data *us) /* wait 3 seconds */ mdelay(3 * 1000); - return USB_STOR_TRANSPORT_GOOD; + return USB_STOR_TRANSPORT_GOOD; } int usb_stor_freecom_reset(struct us_data *us) { - printk (KERN_CRIT "freecom reset called\n"); + printk (KERN_CRIT "freecom reset called\n"); - /* We don't really have this feature. */ - return FAILED; + /* We don't really have this feature. */ + return FAILED; } #ifdef CONFIG_USB_STORAGE_DEBUG diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index a2ea1d931558..9a88b60c9bd5 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -34,11 +34,11 @@ * 2002-10-19: Removed the specialized transfer routines. * (Alan Stern <stern@rowland.harvard.edu>) * 2001-02-24: Removed lots of duplicate code and simplified the structure. - * (bjorn@haxx.se) + * (bjorn@haxx.se) * 2002-01-16: Fixed endianness bug so it works on the ppc arch. - * (Luc Saillard <luc@saillard.org>) + * (Luc Saillard <luc@saillard.org>) * 2002-01-17: All bitfields removed. - * (bjorn@haxx.se) + * (bjorn@haxx.se) */ @@ -59,14 +59,14 @@ /* Timeout defines (in Seconds) */ -#define ISD200_ENUM_BSY_TIMEOUT 35 +#define ISD200_ENUM_BSY_TIMEOUT 35 #define ISD200_ENUM_DETECT_TIMEOUT 30 -#define ISD200_DEFAULT_TIMEOUT 30 +#define ISD200_DEFAULT_TIMEOUT 30 /* device flags */ -#define DF_ATA_DEVICE 0x0001 -#define DF_MEDIA_STATUS_ENABLED 0x0002 -#define DF_REMOVABLE_MEDIA 0x0004 +#define DF_ATA_DEVICE 0x0001 +#define DF_MEDIA_STATUS_ENABLED 0x0002 +#define DF_REMOVABLE_MEDIA 0x0004 /* capability bit definitions */ #define CAPABILITY_DMA 0x01 @@ -82,46 +82,46 @@ #define ATA_ADDRESS_DEVHEAD_SLAVE 0x10 /* Action Select bits */ -#define ACTION_SELECT_0 0x01 -#define ACTION_SELECT_1 0x02 -#define ACTION_SELECT_2 0x04 -#define ACTION_SELECT_3 0x08 -#define ACTION_SELECT_4 0x10 -#define ACTION_SELECT_5 0x20 -#define ACTION_SELECT_6 0x40 -#define ACTION_SELECT_7 0x80 +#define ACTION_SELECT_0 0x01 +#define ACTION_SELECT_1 0x02 +#define ACTION_SELECT_2 0x04 +#define ACTION_SELECT_3 0x08 +#define ACTION_SELECT_4 0x10 +#define ACTION_SELECT_5 0x20 +#define ACTION_SELECT_6 0x40 +#define ACTION_SELECT_7 0x80 /* Register Select bits */ -#define REG_ALTERNATE_STATUS 0x01 -#define REG_DEVICE_CONTROL 0x01 -#define REG_ERROR 0x02 -#define REG_FEATURES 0x02 -#define REG_SECTOR_COUNT 0x04 -#define REG_SECTOR_NUMBER 0x08 -#define REG_CYLINDER_LOW 0x10 -#define REG_CYLINDER_HIGH 0x20 -#define REG_DEVICE_HEAD 0x40 -#define REG_STATUS 0x80 -#define REG_COMMAND 0x80 +#define REG_ALTERNATE_STATUS 0x01 +#define REG_DEVICE_CONTROL 0x01 +#define REG_ERROR 0x02 +#define REG_FEATURES 0x02 +#define REG_SECTOR_COUNT 0x04 +#define REG_SECTOR_NUMBER 0x08 +#define REG_CYLINDER_LOW 0x10 +#define REG_CYLINDER_HIGH 0x20 +#define REG_DEVICE_HEAD 0x40 +#define REG_STATUS 0x80 +#define REG_COMMAND 0x80 /* ATA error definitions not in <linux/hdreg.h> */ -#define ATA_ERROR_MEDIA_CHANGE 0x20 +#define ATA_ERROR_MEDIA_CHANGE 0x20 /* ATA command definitions not in <linux/hdreg.h> */ -#define ATA_COMMAND_GET_MEDIA_STATUS 0xDA -#define ATA_COMMAND_MEDIA_EJECT 0xED +#define ATA_COMMAND_GET_MEDIA_STATUS 0xDA +#define ATA_COMMAND_MEDIA_EJECT 0xED /* ATA drive control definitions */ -#define ATA_DC_DISABLE_INTERRUPTS 0x02 -#define ATA_DC_RESET_CONTROLLER 0x04 -#define ATA_DC_REENABLE_CONTROLLER 0x00 +#define ATA_DC_DISABLE_INTERRUPTS 0x02 +#define ATA_DC_RESET_CONTROLLER 0x04 +#define ATA_DC_REENABLE_CONTROLLER 0x00 /* * General purpose return codes */ -#define ISD200_ERROR -1 -#define ISD200_GOOD 0 +#define ISD200_ERROR -1 +#define ISD200_GOOD 0 /* * Transport return codes @@ -162,7 +162,7 @@ union ata_cdb { unsigned char WriteData1F7; unsigned char Reserved[3]; } generic; - + struct { unsigned char SignatureByte0; unsigned char SignatureByte1; @@ -180,7 +180,7 @@ union ata_cdb { unsigned char Reserved[3]; } read; - struct { + struct { unsigned char SignatureByte0; unsigned char SignatureByte1; unsigned char ActionSelect; @@ -211,8 +211,8 @@ union ata_cdb { /* * DeviceType field */ -#define DIRECT_ACCESS_DEVICE 0x00 /* disks */ -#define DEVICE_REMOVABLE 0x80 +#define DIRECT_ACCESS_DEVICE 0x00 /* disks */ +#define DEVICE_REMOVABLE 0x80 struct inquiry_data { unsigned char DeviceType; @@ -240,9 +240,9 @@ struct inquiry_data { * ISD200 CONFIG data struct */ -#define ATACFG_TIMING 0x0f +#define ATACFG_TIMING 0x0f #define ATACFG_ATAPI_RESET 0x10 -#define ATACFG_MASTER 0x20 +#define ATACFG_MASTER 0x20 #define ATACFG_BLOCKSIZE 0xa0 #define ATACFGE_LAST_LUN 0x07 @@ -255,12 +255,12 @@ struct inquiry_data { #define CFG_CAPABILITY_SRST 0x01 struct isd200_config { - unsigned char EventNotification; - unsigned char ExternalClock; - unsigned char ATAInitTimeout; + unsigned char EventNotification; + unsigned char ExternalClock; + unsigned char ATAInitTimeout; unsigned char ATAConfig; - unsigned char ATAMajorCommand; - unsigned char ATAMinorCommand; + unsigned char ATAMajorCommand; + unsigned char ATAMinorCommand; unsigned char ATAExtraConfig; unsigned char Capability; }__attribute__ ((packed)); @@ -309,7 +309,7 @@ struct read_block_limits { * Sense Data Format */ -#define SENSE_ERRCODE 0x7f +#define SENSE_ERRCODE 0x7f #define SENSE_ERRCODE_VALID 0x80 #define SENSE_FLAG_SENSE_KEY 0x0f #define SENSE_FLAG_BAD_LENGTH 0x20 @@ -319,13 +319,13 @@ struct sense_data { unsigned char ErrorCode; unsigned char SegmentNumber; unsigned char Flags; - unsigned char Information[4]; - unsigned char AdditionalSenseLength; - unsigned char CommandSpecificInformation[4]; - unsigned char AdditionalSenseCode; - unsigned char AdditionalSenseCodeQualifier; - unsigned char FieldReplaceableUnitCode; - unsigned char SenseKeySpecific[3]; + unsigned char Information[4]; + unsigned char AdditionalSenseLength; + unsigned char CommandSpecificInformation[4]; + unsigned char AdditionalSenseCode; + unsigned char AdditionalSenseCodeQualifier; + unsigned char FieldReplaceableUnitCode; + unsigned char SenseKeySpecific[3]; } __attribute__ ((packed)); /* @@ -340,18 +340,18 @@ struct sense_data { /************************************************************************** * isd200_build_sense - * + * * Builds an artificial sense buffer to report the results of a * failed command. - * + * * RETURNS: * void - */ + */ void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb) { - struct isd200_info *info = (struct isd200_info *)us->extra; - struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; - unsigned char error = info->ATARegs[IDE_ERROR_OFFSET]; + struct isd200_info *info = (struct isd200_info *)us->extra; + struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; + unsigned char error = info->ATARegs[IDE_ERROR_OFFSET]; if(error & ATA_ERROR_MEDIA_CHANGE) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; @@ -359,31 +359,31 @@ void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb) buf->Flags = UNIT_ATTENTION; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & MCR_ERR) { + } else if(error & MCR_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = UNIT_ATTENTION; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & TRK0_ERR) { + } else if(error & TRK0_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = NOT_READY; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & ECC_ERR) { + } else if(error & ECC_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = DATA_PROTECT; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else { + } else { buf->ErrorCode = 0; buf->AdditionalSenseLength = 0; buf->Flags = 0; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } + } } @@ -430,8 +430,8 @@ static int isd200_action( struct us_data *us, int action, case ACTION_ENUM: US_DEBUGP(" isd200_action(ENUM,0x%02x)\n",value); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4| - ACTION_SELECT_5; + ACTION_SELECT_3|ACTION_SELECT_4| + ACTION_SELECT_5; ata.generic.RegisterSelect = REG_DEVICE_HEAD; ata.write.DeviceHeadByte = value; srb.sc_data_direction = SCSI_DATA_NONE; @@ -440,7 +440,7 @@ static int isd200_action( struct us_data *us, int action, case ACTION_RESET: US_DEBUGP(" isd200_action(RESET)\n"); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4; + ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER; srb.sc_data_direction = SCSI_DATA_NONE; @@ -449,7 +449,7 @@ static int isd200_action( struct us_data *us, int action, case ACTION_REENABLE: US_DEBUGP(" isd200_action(REENABLE)\n"); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4; + ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER; srb.sc_data_direction = SCSI_DATA_NONE; @@ -493,12 +493,12 @@ static int isd200_action( struct us_data *us, int action, /************************************************************************** * isd200_read_regs - * + * * Read ATA Registers * * RETURNS: * ISD status code - */ + */ int isd200_read_regs( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -512,10 +512,10 @@ int isd200_read_regs( struct us_data *us ) if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error reading ATA registers\n"); retStatus = ISD200_ERROR; - } else { + } else { US_DEBUGP(" Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", info->ATARegs[IDE_ERROR_OFFSET]); - } + } return retStatus; } @@ -649,12 +649,12 @@ static void isd200_log_config( struct isd200_info* info ) /************************************************************************** * isd200_write_config - * + * * Write the ISD200 Configuraton data * * RETURNS: * ISD status code - */ + */ int isd200_write_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -669,21 +669,21 @@ int isd200_write_config( struct us_data *us ) /* let's send the command via the control pipe */ result = usb_stor_ctrl_transfer( - us, - us->send_ctrl_pipe, - 0x01, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x0000, - 0x0002, - (void *) &info->ConfigData, - sizeof(info->ConfigData)); + us, + us->send_ctrl_pipe, + 0x01, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + 0x0000, + 0x0002, + (void *) &info->ConfigData, + sizeof(info->ConfigData)); if (result >= 0) { US_DEBUGP(" ISD200 Config Data was written successfully\n"); - } else { + } else { US_DEBUGP(" Request to write ISD200 Config Data failed!\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_write_config %08X\n", retStatus); return retStatus; @@ -692,12 +692,12 @@ int isd200_write_config( struct us_data *us ) /************************************************************************** * isd200_read_config - * + * * Reads the ISD200 Configuraton data * * RETURNS: * ISD status code - */ + */ int isd200_read_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -707,17 +707,17 @@ int isd200_read_config( struct us_data *us ) US_DEBUGP("Entering isd200_read_config\n"); /* read the configuration information from ISD200. Use this to */ - /* determine what the special ATA CDB bytes are. */ + /* determine what the special ATA CDB bytes are. */ result = usb_stor_ctrl_transfer( - us, - us->recv_ctrl_pipe, - 0x02, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0000, - 0x0002, - (void *) &info->ConfigData, - sizeof(info->ConfigData)); + us, + us->recv_ctrl_pipe, + 0x02, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x0000, + 0x0002, + (void *) &info->ConfigData, + sizeof(info->ConfigData)); if (result >= 0) { @@ -725,10 +725,10 @@ int isd200_read_config( struct us_data *us ) #ifdef CONFIG_USB_STORAGE_DEBUG isd200_log_config(info); #endif - } else { + } else { US_DEBUGP(" Request to get ISD200 Config Data failed!\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_read_config %08X\n", retStatus); return retStatus; @@ -737,12 +737,12 @@ int isd200_read_config( struct us_data *us ) /************************************************************************** * isd200_atapi_soft_reset - * + * * Perform an Atapi Soft Reset on the device * * RETURNS: * NT status code - */ + */ int isd200_atapi_soft_reset( struct us_data *us ) { int retStatus = ISD200_GOOD; @@ -754,7 +754,7 @@ int isd200_atapi_soft_reset( struct us_data *us ) if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing Atapi Soft Reset\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_atapi_soft_reset %08X\n", retStatus); return retStatus; @@ -763,12 +763,12 @@ int isd200_atapi_soft_reset( struct us_data *us ) /************************************************************************** * isd200_srst - * + * * Perform an SRST on the device * * RETURNS: * ISD status code - */ + */ int isd200_srst( struct us_data *us ) { int retStatus = ISD200_GOOD; @@ -782,7 +782,7 @@ int isd200_srst( struct us_data *us ) if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing SRST\n"); retStatus = ISD200_ERROR; - } else { + } else { /* delay 10ms to give the drive a chance to see it */ wait_ms(10); @@ -794,7 +794,7 @@ int isd200_srst( struct us_data *us ) /* delay 50ms to give the drive a chance to recover after SRST */ wait_ms(50); } - } + } US_DEBUGP("Leaving isd200_srst %08X\n", retStatus); return retStatus; @@ -803,13 +803,13 @@ int isd200_srst( struct us_data *us ) /************************************************************************** * isd200_try_enum - * + * * Helper function for isd200_manual_enum(). Does ENUM and READ_STATUS * and tries to analyze the status registers * * RETURNS: * ISD status code - */ + */ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, int detect ) { @@ -908,13 +908,13 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, /************************************************************************** * isd200_manual_enum - * + * * Determines if the drive attached is an ATA or ATAPI and if it is a * master or slave. * * RETURNS: * ISD status code - */ + */ int isd200_manual_enum(struct us_data *us) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -1078,15 +1078,15 @@ int isd200_get_inquiry_data( struct us_data *us ) us->proto_handler = usb_stor_transparent_scsi_command; US_DEBUGP("Protocol changed to: %s\n", us->protocol_name); - - /* Free driver structure */ + + /* Free driver structure */ if (us->extra != NULL) { kfree(us->extra); us->extra = NULL; us->extra_destructor = NULL; } } - } + } US_DEBUGP("Leaving isd200_get_inquiry_data %08X\n", retStatus); @@ -1096,12 +1096,12 @@ int isd200_get_inquiry_data( struct us_data *us ) /************************************************************************** * isd200_data_copy - * + * * Copy data into the srb request buffer. Use scatter gather if required. * * RETURNS: * void - */ + */ void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length) { unsigned int len = length; @@ -1150,13 +1150,13 @@ void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length) /************************************************************************** * isd200_scsi_to_ata - * + * * Translate SCSI commands to ATA commands. * * RETURNS: * TRUE if the command needs to be sent to the transport layer * FALSE otherwise - */ + */ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, union ata_cdb * ataCdb) { @@ -1321,7 +1321,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, if (info->DeviceFlags & DF_REMOVABLE_MEDIA) { US_DEBUGP(" srb->cmnd[4] = 0x%X\n", srb->cmnd[4]); - + ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; ataCdb->generic.TransferBlockSize = 1; @@ -1378,12 +1378,12 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, /************************************************************************** * isd200_init_info - * + * * Allocates (if necessary) and initializes the driver structure. * * RETURNS: * ISD status code - */ + */ int isd200_init_info(struct us_data *us) { int retStatus = ISD200_GOOD; @@ -1394,11 +1394,11 @@ int isd200_init_info(struct us_data *us) US_DEBUGP("ERROR - kmalloc failure\n"); retStatus = ISD200_ERROR; } - } + } if (retStatus == ISD200_GOOD) { memset(us->extra, 0, sizeof(struct isd200_info)); - } + } return(retStatus); } @@ -1415,14 +1415,14 @@ int isd200_Initialization(struct us_data *us) if (isd200_init_info(us) == ISD200_ERROR) { US_DEBUGP("ERROR Initializing ISD200 Info struct\n"); - } else { + } else { /* Get device specific data */ if (isd200_get_inquiry_data(us) != ISD200_GOOD) US_DEBUGP("ISD200 Initialization Failure\n"); else US_DEBUGP("ISD200 Initialization complete\n"); - } + } return 0; } diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 4153a6c7144b..32b29498c77b 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h @@ -53,7 +53,7 @@ #define US_SC_UFI 0x04 /* Floppy */ #define US_SC_8070 0x05 /* Removable media */ #define US_SC_SCSI 0x06 /* Transparent */ -#define US_SC_ISD200 0x07 /* ISD200 ATA */ +#define US_SC_ISD200 0x07 /* ISD200 ATA */ #define US_SC_MIN US_SC_RBC #define US_SC_MAX US_SC_ISD200 diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index f587f53295c0..f30d8c162db9 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -50,23 +50,25 @@ #include "transport.h" #include <linux/slab.h> +#include <linux/module.h> /*********************************************************************** * Host functions ***********************************************************************/ -static const char* host_info(struct Scsi_Host *host) +static const char* usb_storage_info(struct Scsi_Host *host) { return "SCSI emulation for USB Mass Storage devices"; } +#if 0 /* detect a virtual adapter (always works) * Synchronization: 2.4: with the io_request_lock * 2.5: no locks. * fortunately we don't care. * */ -static int detect(struct SHT *sht) +static int usb_storage_detect(struct SHT *sht) { struct us_data *us; char local_name[32]; @@ -109,7 +111,7 @@ static int detect(struct SHT *sht) * the driver and we're doing each virtual host in turn, not in parallel * Synchronization: BKL, no spinlock. */ -static int release(struct Scsi_Host *psh) +static int usb_storage_release(struct Scsi_Host *psh) { struct us_data *us = (struct us_data *)psh->hostdata[0]; @@ -132,18 +134,11 @@ static int release(struct Scsi_Host *psh) /* we always have a successful release */ return 0; } - -/* run command */ -static int command( Scsi_Cmnd *srb ) -{ - US_DEBUGP("Bad use of us_command\n"); - - return DID_BAD_TARGET << 16; -} +#endif /* queue a command */ /* This is always called with scsi_lock(srb->host) held */ -static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) +static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; @@ -168,7 +163,7 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) /* Command abort */ /* This is always called with scsi_lock(srb->host) held */ -static int command_abort( Scsi_Cmnd *srb ) +static int usb_storage_command_abort( Scsi_Cmnd *srb ) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; @@ -187,7 +182,7 @@ static int command_abort( Scsi_Cmnd *srb ) /* This invokes the transport reset mechanism to reset the state of the * device */ /* This is always called with scsi_lock(srb->host) held */ -static int device_reset( Scsi_Cmnd *srb ) +static int usb_storage_device_reset( Scsi_Cmnd *srb ) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; int result; @@ -202,11 +197,10 @@ static int device_reset( Scsi_Cmnd *srb ) /* lock the device pointers */ down(&(us->dev_semaphore)); - /* if the device was removed, then we're already reset */ - if (!(us->flags & US_FL_DEV_ATTACHED)) - result = SUCCESS; - else - result = us->transport_reset(us); + /* do the reset */ + result = us->transport_reset(us); + + /* unlock */ up(&(us->dev_semaphore)); /* lock access to the state and clear it */ @@ -219,31 +213,26 @@ static int device_reset( Scsi_Cmnd *srb ) * disconnect/reconnect for all drivers which have claimed * interfaces, including ourself. */ /* This is always called with scsi_lock(srb->host) held */ -static int bus_reset( Scsi_Cmnd *srb ) + +/* FIXME: This needs to be re-examined in the face of the new + * hotplug system -- this will implicitly cause a detach/reattach of + * usb-storage, which is not what we want now. + * + * Can we just skip over usb-storage in the while loop? + */ +static int usb_storage_bus_reset( Scsi_Cmnd *srb ) { - struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; + struct us_data *us; int i; int result; - struct usb_device *pusb_dev_save; /* we use the usb_reset_device() function to handle this for us */ US_DEBUGP("bus_reset() called\n"); - scsi_unlock(srb->device->host); - - /* if the device has been removed, this worked */ - down(&us->dev_semaphore); - if (!(us->flags & US_FL_DEV_ATTACHED)) { - US_DEBUGP("-- device removed already\n"); - up(&us->dev_semaphore); - scsi_lock(srb->device->host); - return SUCCESS; - } - pusb_dev_save = us->pusb_dev; - up(&us->dev_semaphore); + us = (struct us_data *)srb->device->host->hostdata[0]; /* attempt to reset the port */ - result = usb_reset_device(pusb_dev_save); + result = usb_reset_device(us->pusb_dev); US_DEBUGP("usb_reset_device returns %d\n", result); if (result < 0) { scsi_lock(srb->device->host); @@ -253,9 +242,9 @@ static int bus_reset( Scsi_Cmnd *srb ) /* FIXME: This needs to lock out driver probing while it's working * or we can have race conditions */ /* This functionality really should be provided by the khubd thread */ - for (i = 0; i < pusb_dev_save->actconfig->desc.bNumInterfaces; i++) { + for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = - &pusb_dev_save->actconfig->interface[i]; + &us->pusb_dev->actconfig->interface[i]; /* if this is an unclaimed interface, skip it */ if (!intf->driver) { @@ -274,14 +263,6 @@ static int bus_reset( Scsi_Cmnd *srb ) return SUCCESS; } -/* FIXME: This doesn't do anything right now */ -static int host_reset( Scsi_Cmnd *srb ) -{ - printk(KERN_CRIT "usb-storage: host_reset() requested but not implemented\n" ); - bus_reset(srb); - return FAILED; -} - /*********************************************************************** * /proc/scsi/ functions ***********************************************************************/ @@ -291,29 +272,23 @@ static int host_reset( Scsi_Cmnd *srb ) #define SPRINTF(args...) \ do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) -static int proc_info (char *buffer, char **start, off_t offset, int length, - int hostno, int inout) +static int usb_storage_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout) { struct us_data *us; char *pos = buffer; + struct Scsi_Host *hostptr; /* if someone is sending us data, just throw it away */ if (inout) return length; - /* lock the data structures */ - down(&us_list_semaphore); - - /* find our data from hostno */ - us = us_list; - while (us) { - if (us->host_no == hostno) - break; - us = us->next; + /* find our data from the given hostno */ + hostptr = scsi_host_hn_get(hostno); + if (!hostptr) { /* if we couldn't find it, we return an error */ + return -ESRCH; } - - /* release our lock on the data structures */ - up(&us_list_semaphore); + us = (struct us_data*)hostptr->hostdata[0]; /* if we couldn't find it, we return an error */ if (!us) { @@ -332,10 +307,8 @@ static int proc_info (char *buffer, char **start, off_t offset, int length, SPRINTF(" Protocol: %s\n", us->protocol_name); SPRINTF(" Transport: %s\n", us->transport_name); - /* show the GUID of the device */ - SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); - SPRINTF(" Attached: %s\n", (us->flags & US_FL_DEV_ATTACHED ? - "Yes" : "No")); + /* release the reference count on this host */ + scsi_host_put(hostptr); /* * Calculate start of next buffer, and return value. @@ -351,33 +324,69 @@ static int proc_info (char *buffer, char **start, off_t offset, int length, } /* - * this defines our 'host' + * this defines our host template, with which we'll allocate hosts */ -Scsi_Host_Template usb_stor_host_template = { - .name = "usb-storage", - .proc_info = proc_info, - .info = host_info, - - .detect = detect, - .release = release, - .command = command, - .queuecommand = queuecommand, - - .eh_abort_handler = command_abort, - .eh_device_reset_handler =device_reset, - .eh_bus_reset_handler = bus_reset, - .eh_host_reset_handler =host_reset, - - .can_queue = 1, - .this_id = -1, - - .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, - .present = 0, - .unchecked_isa_dma = FALSE, - .use_clustering = TRUE, - .emulated = TRUE +struct SHT usb_stor_host_template = { + /* basic userland interface stuff */ + .name = "usb-storage", + .proc_name = "usb-storage", + .proc_info = usb_storage_proc_info, + .proc_dir = NULL, + .info = usb_storage_info, + .ioctl = NULL, + + /* old-style detect and release */ + .detect = NULL, + .release = NULL, + + /* command interface -- queued only */ + .command = NULL, + .queuecommand = usb_storage_queuecommand, + + /* error and abort handlers */ + .eh_abort_handler = usb_storage_command_abort, + .eh_device_reset_handler = usb_storage_device_reset, + .eh_bus_reset_handler = usb_storage_bus_reset, + .eh_host_reset_handler = NULL, + .eh_strategy_handler = NULL, + + /* queue commands only, only one command per LUN */ + .can_queue = 1, + .cmd_per_lun = 1, + + /* unknown initiator id */ + .this_id = -1, + + /* no limit on commands */ + .max_sectors = 0, + + /* pre- and post- device scan functions */ + .slave_alloc = NULL, + .slave_configure = NULL, + .slave_destroy = NULL, + + /* lots of sg segments can be handled */ + .sg_tablesize = SG_ALL, + + /* use 32-bit address space for DMA */ + .unchecked_isa_dma = FALSE, + .highmem_io = FALSE, + + /* merge commands... this seems to help performance, but + * periodically someone should test to see which setting is more + * optimal. + */ + .use_clustering = TRUE, + + /* emulated HBA */ + .emulated = TRUE, + + /* sorry, no BIOS to help us */ + .bios_param = NULL, + + /* module management */ + .module = THIS_MODULE }; /* For a device that is "Not Ready" */ diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h index efe2ba42644c..35f4cb7e4bfc 100644 --- a/drivers/usb/storage/scsiglue.h +++ b/drivers/usb/storage/scsiglue.h @@ -47,7 +47,7 @@ extern unsigned char usb_stor_sense_notready[18]; extern unsigned char usb_stor_sense_invalidCDB[18]; -extern Scsi_Host_Template usb_stor_host_template; +extern struct SHT usb_stor_host_template; extern int usb_stor_scsiSense10to6(Scsi_Cmnd*); extern int usb_stor_scsiSense6to10(Scsi_Cmnd*); diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 0c9fe0ed3a7a..799c4134751e 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -55,8 +55,7 @@ #define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ #endif #ifdef CONFIG_USB_STORAGE_SDDR09 -#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for - SDDR-09 */ +#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ #endif #ifdef CONFIG_USB_STORAGE_SDDR55 #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ @@ -64,15 +63,15 @@ #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ #ifdef CONFIG_USB_STORAGE_FREECOM -#define US_PR_FREECOM 0xf1 /* Freecom */ +#define US_PR_FREECOM 0xf1 /* Freecom */ #endif #ifdef CONFIG_USB_STORAGE_DATAFAB -#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ +#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ #endif #ifdef CONFIG_USB_STORAGE_JUMPSHOT -#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ +#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ #endif /* @@ -118,10 +117,10 @@ struct bulk_cs_wrap { * usb_stor_bulk_transfer_xxx() return codes, in order of severity */ -#define USB_STOR_XFER_GOOD 0 /* good transfer */ -#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ -#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ -#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ +#define USB_STOR_XFER_GOOD 0 /* good transfer */ +#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ +#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ +#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ /* * Transport return codes diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 81b2d316f6f8..96f175e965a2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -264,7 +264,7 @@ UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999, /* Submitted by Nathan Babb <nathan@lexi.com> */ UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, - "Sony", + "Sony", "PEG Mass Storage", US_SC_8070, US_PR_CBI, NULL, US_FL_FIX_INQUIRY ), @@ -546,10 +546,10 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, - "Feiya", - "5-in-1 Card Reader", - US_SC_SCSI, US_PR_BULK, NULL, - US_FL_FIX_CAPACITY ), + "Feiya", + "5-in-1 Card Reader", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_CAPACITY ), UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001, "Minds@Work", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index dc93ad389a56..aa4af2b0a948 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -93,16 +93,6 @@ MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); MODULE_LICENSE("GPL"); -/* - * Per device data - */ - -static int my_host_number; - -/* The list of structures and the protective lock for them */ -struct us_data *us_list; -struct semaphore us_list_semaphore; - static int storage_probe(struct usb_interface *iface, const struct usb_device_id *id); @@ -319,7 +309,7 @@ static int usb_stor_control_thread(void * __us) spin_unlock_irq(¤t->sig->siglock); /* set our name for identification purposes */ - sprintf(current->comm, "usb-storage-%d", us->host_number); + sprintf(current->comm, "usb-storage"); unlock_kernel(); @@ -395,35 +385,6 @@ static int usb_stor_control_thread(void * __us) us->srb->result = CHECK_CONDITION << 1; } - /* our device has gone - pretend not ready */ - else if (!(us->flags & US_FL_DEV_ATTACHED)) { - US_DEBUGP("Request is for removed device\n"); - /* For REQUEST_SENSE, it's the data. But - * for anything else, it should look like - * we auto-sensed for it. - */ - if (us->srb->cmnd[0] == REQUEST_SENSE) { - memcpy(us->srb->request_buffer, - usb_stor_sense_notready, - sizeof(usb_stor_sense_notready)); - us->srb->result = GOOD << 1; - } else if(us->srb->cmnd[0] == INQUIRY) { - /* INQUIRY should always work, per spec... */ - unsigned char data_ptr[36] = { - 0x20, 0x80, 0x02, 0x02, - 0x1F, 0x00, 0x00, 0x00}; - US_DEBUGP("Faking INQUIRY command for disconnected device\n"); - fill_inquiry_response(us, data_ptr, 36); - us->srb->result = GOOD << 1; - } else { - /* not ready */ - memcpy(us->srb->sense_buffer, - usb_stor_sense_notready, - sizeof(usb_stor_sense_notready)); - us->srb->result = CHECK_CONDITION << 1; - } - } /* !(us->flags & US_FL_DEV_ATTACHED) */ - /* Handle those devices which need us to fake * their inquiry data */ else if ((us->srb->cmnd[0] == INQUIRY) && @@ -547,7 +508,6 @@ static void usb_stor_deallocate_urbs(struct us_data *ss) } /* mark the device as gone */ - ss->flags &= ~ US_FL_DEV_ATTACHED; usb_put_dev(ss->pusb_dev); ss->pusb_dev = NULL; } @@ -563,12 +523,10 @@ static int storage_probe(struct usb_interface *intf, char mf[USB_STOR_STRING_LEN]; /* manufacturer */ char prod[USB_STOR_STRING_LEN]; /* product */ char serial[USB_STOR_STRING_LEN]; /* serial number */ - GUID(guid); /* Global Unique Identifier */ unsigned int flags; struct us_unusual_dev *unusual_dev; struct us_data *ss = NULL; int result; - int new_device = 0; /* these are temporary copies -- we test on these, then put them * in the us-data structure @@ -676,8 +634,7 @@ static int storage_probe(struct usb_interface *intf, /* At this point, we've decided to try to use the device */ usb_get_dev(dev); - /* clear the GUID and fetch the strings */ - GUID_CLEAR(guid); + /* fetch the strings */ if (dev->descriptor.iManufacturer) usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf)); @@ -688,346 +645,277 @@ static int storage_probe(struct usb_interface *intf, usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - /* Create a GUID for this device */ - if (dev->descriptor.iSerialNumber && serial[0]) { - /* If we have a serial number, and it's a non-NULL string */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, serial); - } else { - /* We don't have a serial number, so we use 0 */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, "0"); + /* New device -- allocate memory and initialize */ + if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), + GFP_KERNEL)) == NULL) { + printk(KERN_WARNING USB_STORAGE "Out of memory\n"); + usb_put_dev(dev); + return -ENOMEM; } - - /* - * Now check if we have seen this GUID before - * We're looking for a device with a matching GUID that isn't - * already on the system - */ - ss = us_list; - while ((ss != NULL) && - ((ss->flags & US_FL_DEV_ATTACHED) || - !GUID_EQUAL(guid, ss->guid))) - ss = ss->next; - - if (ss != NULL) { - /* Existing device -- re-connect */ - US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", - GUID_ARGS(guid)); - - /* lock the device pointers */ - down(&(ss->dev_semaphore)); - - /* establish the connection to the new device upon reconnect */ - ss->ifnum = ifnum; - ss->pusb_dev = dev; - ss->flags |= US_FL_DEV_ATTACHED; - - /* copy over the endpoint data */ - ss->ep_in = ep_in->bEndpointAddress & + memset(ss, 0, sizeof(struct us_data)); + + /* Initialize the mutexes only when the struct is new */ + init_completion(&(ss->notify)); + init_MUTEX_LOCKED(&(ss->dev_semaphore)); + + /* copy over the subclass and protocol data */ + ss->subclass = subclass; + ss->protocol = protocol; + ss->flags = flags; + ss->unusual_dev = unusual_dev; + + /* copy over the endpoint data */ + ss->ep_in = ep_in->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + ss->ep_out = ep_out->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + if (ep_int) { + ss->ep_int = ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - ss->ep_out = ep_out->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - if (ep_int) { - ss->ep_int = ep_int->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_bInterval = ep_int->bInterval; - } + ss->ep_bInterval = ep_int->bInterval; + } + else + ss->ep_int = ss->ep_bInterval = 0; + + /* establish the connection to the new device */ + ss->ifnum = ifnum; + ss->pusb_dev = dev; + + /* copy over the identifiying strings */ + strncpy(ss->vendor, mf, USB_STOR_STRING_LEN); + strncpy(ss->product, prod, USB_STOR_STRING_LEN); + strncpy(ss->serial, serial, USB_STOR_STRING_LEN); + if (strlen(ss->vendor) == 0) { + if (unusual_dev->vendorName) + strncpy(ss->vendor, unusual_dev->vendorName, + USB_STOR_STRING_LEN); else - ss->ep_int = ss->ep_bInterval = 0; - - /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ - if (usb_stor_allocate_urbs(ss)) - goto BadDevice; - - /* Re-Initialize the device if it needs it */ - if (unusual_dev && unusual_dev->initFunction) - (unusual_dev->initFunction)(ss); - - /* unlock the device pointers */ - up(&(ss->dev_semaphore)); - - } else { - /* New device -- allocate memory and initialize */ - US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); - - if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), - GFP_KERNEL)) == NULL) { - printk(KERN_WARNING USB_STORAGE "Out of memory\n"); - usb_put_dev(dev); - return -ENOMEM; - } - memset(ss, 0, sizeof(struct us_data)); - new_device = 1; - - /* Initialize the mutexes only when the struct is new */ - init_completion(&(ss->notify)); - init_MUTEX_LOCKED(&(ss->dev_semaphore)); - - /* copy over the subclass and protocol data */ - ss->subclass = subclass; - ss->protocol = protocol; - ss->flags = flags | US_FL_DEV_ATTACHED; - ss->unusual_dev = unusual_dev; - - /* copy over the endpoint data */ - ss->ep_in = ep_in->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_out = ep_out->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - if (ep_int) { - ss->ep_int = ep_int->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_bInterval = ep_int->bInterval; - } + strncpy(ss->vendor, "Unknown", + USB_STOR_STRING_LEN); + } + if (strlen(ss->product) == 0) { + if (unusual_dev->productName) + strncpy(ss->product, unusual_dev->productName, + USB_STOR_STRING_LEN); else - ss->ep_int = ss->ep_bInterval = 0; - - /* establish the connection to the new device */ - ss->ifnum = ifnum; - ss->pusb_dev = dev; - - /* copy over the identifiying strings */ - strncpy(ss->vendor, mf, USB_STOR_STRING_LEN); - strncpy(ss->product, prod, USB_STOR_STRING_LEN); - strncpy(ss->serial, serial, USB_STOR_STRING_LEN); - if (strlen(ss->vendor) == 0) { - if (unusual_dev->vendorName) - strncpy(ss->vendor, unusual_dev->vendorName, - USB_STOR_STRING_LEN); - else - strncpy(ss->vendor, "Unknown", - USB_STOR_STRING_LEN); - } - if (strlen(ss->product) == 0) { - if (unusual_dev->productName) - strncpy(ss->product, unusual_dev->productName, - USB_STOR_STRING_LEN); - else - strncpy(ss->product, "Unknown", - USB_STOR_STRING_LEN); - } - if (strlen(ss->serial) == 0) - strncpy(ss->serial, "None", USB_STOR_STRING_LEN); - - /* copy the GUID we created before */ - memcpy(ss->guid, guid, sizeof(guid)); - - /* - * Set the handler pointers based on the protocol - * Again, this data is persistant across reattachments - */ - switch (ss->protocol) { - case US_PR_CB: - ss->transport_name = "Control/Bulk"; - ss->transport = usb_stor_CB_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 7; - break; - - case US_PR_CBI: - ss->transport_name = "Control/Bulk/Interrupt"; - ss->transport = usb_stor_CBI_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 7; - break; + strncpy(ss->product, "Unknown", + USB_STOR_STRING_LEN); + } + if (strlen(ss->serial) == 0) + strncpy(ss->serial, "None", USB_STOR_STRING_LEN); - case US_PR_BULK: - ss->transport_name = "Bulk"; - ss->transport = usb_stor_Bulk_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = usb_stor_Bulk_max_lun(ss); - break; + /* + * Set the handler pointers based on the protocol + * Again, this data is persistant across reattachments + */ + switch (ss->protocol) { + case US_PR_CB: + ss->transport_name = "Control/Bulk"; + ss->transport = usb_stor_CB_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 7; + break; + + case US_PR_CBI: + ss->transport_name = "Control/Bulk/Interrupt"; + ss->transport = usb_stor_CBI_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 7; + break; + + case US_PR_BULK: + ss->transport_name = "Bulk"; + ss->transport = usb_stor_Bulk_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = usb_stor_Bulk_max_lun(ss); + break; #ifdef CONFIG_USB_STORAGE_HP8200e - case US_PR_SCM_ATAPI: - ss->transport_name = "SCM/ATAPI"; - ss->transport = hp8200e_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 1; - break; + case US_PR_SCM_ATAPI: + ss->transport_name = "SCM/ATAPI"; + ss->transport = hp8200e_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_SDDR09 - case US_PR_EUSB_SDDR09: - ss->transport_name = "EUSB/SDDR09"; - ss->transport = sddr09_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 0; - break; + case US_PR_EUSB_SDDR09: + ss->transport_name = "EUSB/SDDR09"; + ss->transport = sddr09_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_SDDR55 - case US_PR_SDDR55: - ss->transport_name = "SDDR55"; - ss->transport = sddr55_transport; - ss->transport_reset = sddr55_reset; - ss->max_lun = 0; - break; + case US_PR_SDDR55: + ss->transport_name = "SDDR55"; + ss->transport = sddr55_transport; + ss->transport_reset = sddr55_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_DPCM - case US_PR_DPCM_USB: - ss->transport_name = "Control/Bulk-EUSB/SDDR09"; - ss->transport = dpcm_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 1; - break; + case US_PR_DPCM_USB: + ss->transport_name = "Control/Bulk-EUSB/SDDR09"; + ss->transport = dpcm_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_FREECOM - case US_PR_FREECOM: - ss->transport_name = "Freecom"; - ss->transport = freecom_transport; - ss->transport_reset = usb_stor_freecom_reset; - ss->max_lun = 0; - break; + case US_PR_FREECOM: + ss->transport_name = "Freecom"; + ss->transport = freecom_transport; + ss->transport_reset = usb_stor_freecom_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_DATAFAB - case US_PR_DATAFAB: - ss->transport_name = "Datafab Bulk-Only"; - ss->transport = datafab_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = 1; - break; + case US_PR_DATAFAB: + ss->transport_name = "Datafab Bulk-Only"; + ss->transport = datafab_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_JUMPSHOT - case US_PR_JUMPSHOT: - ss->transport_name = "Lexar Jumpshot Control/Bulk"; - ss->transport = jumpshot_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = 1; - break; + case US_PR_JUMPSHOT: + ss->transport_name = "Lexar Jumpshot Control/Bulk"; + ss->transport = jumpshot_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = 1; + break; #endif - default: - /* ss->transport_name = "Unknown"; */ - goto BadDevice; - } - US_DEBUGP("Transport: %s\n", ss->transport_name); - - /* fix for single-lun devices */ - if (ss->flags & US_FL_SINGLE_LUN) - ss->max_lun = 0; - - switch (ss->subclass) { - case US_SC_RBC: - ss->protocol_name = "Reduced Block Commands (RBC)"; - ss->proto_handler = usb_stor_transparent_scsi_command; - break; + default: + /* ss->transport_name = "Unknown"; */ + goto BadDevice; + } + US_DEBUGP("Transport: %s\n", ss->transport_name); + + /* fix for single-lun devices */ + if (ss->flags & US_FL_SINGLE_LUN) + ss->max_lun = 0; + + switch (ss->subclass) { + case US_SC_RBC: + ss->protocol_name = "Reduced Block Commands (RBC)"; + ss->proto_handler = usb_stor_transparent_scsi_command; + break; + + case US_SC_8020: + ss->protocol_name = "8020i"; + ss->proto_handler = usb_stor_ATAPI_command; + ss->max_lun = 0; + break; + + case US_SC_QIC: + ss->protocol_name = "QIC-157"; + ss->proto_handler = usb_stor_qic157_command; + ss->max_lun = 0; + break; + + case US_SC_8070: + ss->protocol_name = "8070i"; + ss->proto_handler = usb_stor_ATAPI_command; + ss->max_lun = 0; + break; + + case US_SC_SCSI: + ss->protocol_name = "Transparent SCSI"; + ss->proto_handler = usb_stor_transparent_scsi_command; + break; + + case US_SC_UFI: + ss->protocol_name = "Uniform Floppy Interface (UFI)"; + ss->proto_handler = usb_stor_ufi_command; + break; - case US_SC_8020: - ss->protocol_name = "8020i"; - ss->proto_handler = usb_stor_ATAPI_command; - ss->max_lun = 0; - break; +#ifdef CONFIG_USB_STORAGE_ISD200 + case US_SC_ISD200: + ss->protocol_name = "ISD200 ATA/ATAPI"; + ss->proto_handler = isd200_ata_command; + break; +#endif - case US_SC_QIC: - ss->protocol_name = "QIC-157"; - ss->proto_handler = usb_stor_qic157_command; - ss->max_lun = 0; - break; + default: + /* ss->protocol_name = "Unknown"; */ + goto BadDevice; + } + US_DEBUGP("Protocol: %s\n", ss->protocol_name); - case US_SC_8070: - ss->protocol_name = "8070i"; - ss->proto_handler = usb_stor_ATAPI_command; - ss->max_lun = 0; - break; + /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ + if (usb_stor_allocate_urbs(ss)) + goto BadDevice; - case US_SC_SCSI: - ss->protocol_name = "Transparent SCSI"; - ss->proto_handler = usb_stor_transparent_scsi_command; - break; + /* + * Since this is a new device, we need to generate a scsi + * host definition, and register with the higher SCSI layers + */ - case US_SC_UFI: - ss->protocol_name = "Uniform Floppy Interface (UFI)"; - ss->proto_handler = usb_stor_ufi_command; - break; + /* Just before we start our control thread, initialize + * the device if it needs initialization */ + if (unusual_dev && unusual_dev->initFunction) + unusual_dev->initFunction(ss); + + /* start up our control thread */ + atomic_set(&ss->sm_state, US_STATE_IDLE); + ss->pid = kernel_thread(usb_stor_control_thread, ss, + CLONE_VM); + if (ss->pid < 0) { + printk(KERN_WARNING USB_STORAGE + "Unable to start control thread\n"); + goto BadDevice; + } -#ifdef CONFIG_USB_STORAGE_ISD200 - case US_SC_ISD200: - ss->protocol_name = "ISD200 ATA/ATAPI"; - ss->proto_handler = isd200_ata_command; - break; -#endif + /* wait for the thread to start */ + wait_for_completion(&(ss->notify)); - default: - /* ss->protocol_name = "Unknown"; */ - goto BadDevice; - } - US_DEBUGP("Protocol: %s\n", ss->protocol_name); + /* unlock the device pointers */ + up(&(ss->dev_semaphore)); - /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ - if (usb_stor_allocate_urbs(ss)) - goto BadDevice; + /* now register */ + ss->host = scsi_register(&usb_stor_host_template, sizeof(ss)); + if (!ss->host) { + printk(KERN_WARNING USB_STORAGE + "Unable to register the scsi host\n"); - /* - * Since this is a new device, we need to generate a scsi - * host definition, and register with the higher SCSI layers - */ + /* tell the control thread to exit */ + ss->srb = NULL; + up(&ss->sema); + wait_for_completion(&ss->notify); - /* Initialize the host template based on the default one */ - memcpy(&(ss->htmplt), &usb_stor_host_template, - sizeof(usb_stor_host_template)); + /* re-lock the device pointers */ + down(&ss->dev_semaphore); + goto BadDevice; + } - /* Grab the next host number */ - ss->host_number = my_host_number++; + /* set the hostdata to prepare for scanning */ + ss->host->hostdata[0] = (unsigned long)ss; - /* We abuse this pointer so we can pass the ss pointer to - * the host controller thread in us_detect. But how else are - * we to do it? - */ - (struct us_data *)ss->htmplt.proc_dir = ss; - - /* Just before we start our control thread, initialize - * the device if it needs initialization */ - if (unusual_dev && unusual_dev->initFunction) - unusual_dev->initFunction(ss); - - /* start up our control thread */ - atomic_set(&ss->sm_state, US_STATE_IDLE); - ss->pid = kernel_thread(usb_stor_control_thread, ss, - CLONE_VM); - if (ss->pid < 0) { - printk(KERN_WARNING USB_STORAGE - "Unable to start control thread\n"); - goto BadDevice; - } + /* associate this host with our interface */ + scsi_set_device(ss->host, &intf->dev); - /* wait for the thread to start */ - wait_for_completion(&(ss->notify)); + /* now add the host */ + result = scsi_add_host(ss->host, NULL); + if (result) { + printk(KERN_WARNING USB_STORAGE + "Unable to add the scsi host\n"); - /* unlock the device pointers */ - up(&(ss->dev_semaphore)); - - /* now register - our detect function will be called */ - ss->htmplt.module = THIS_MODULE; - result = scsi_register_host(&(ss->htmplt)); - if (result) { - printk(KERN_WARNING USB_STORAGE - "Unable to register the scsi host\n"); - - /* tell the control thread to exit */ - ss->srb = NULL; - up(&ss->sema); - wait_for_completion(&ss->notify); - - /* re-lock the device pointers */ - down(&ss->dev_semaphore); - goto BadDevice; - } + /* tell the control thread to exit */ + ss->srb = NULL; + up(&ss->sema); + wait_for_completion(&ss->notify); - /* lock access to the data structures */ - down(&us_list_semaphore); - - /* put us in the list */ - ss->next = us_list; - us_list = ss; - - /* release the data structure lock */ - up(&us_list_semaphore); + /* re-lock the device pointers */ + down(&ss->dev_semaphore); + goto BadDevice; } printk(KERN_DEBUG @@ -1041,33 +929,96 @@ static int storage_probe(struct usb_interface *intf, /* we come here if there are any problems */ /* ss->dev_semaphore must be locked */ - BadDevice: +BadDevice: US_DEBUGP("storage_probe() failed\n"); usb_stor_deallocate_urbs(ss); up(&ss->dev_semaphore); - if (new_device) - kfree(ss); + kfree(ss); return -EIO; } /* Handle a disconnect event from the USB core */ static void storage_disconnect(struct usb_interface *intf) { - struct us_data *ss = usb_get_intfdata(intf); + struct us_data *ss; + struct scsi_device *sdev; US_DEBUGP("storage_disconnect() called\n"); + ss = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - /* this is the odd case -- we disconnected but weren't using it */ - if (!ss) { - US_DEBUGP("-- device was not in use\n"); - return; - } + /* serious error -- we're attempting to disconnect an interface but + * cannot locate the local data structure + */ + BUG_ON(ss == NULL); + + /* set devices offline -- need host lock for this */ + scsi_lock(ss->host); + list_for_each_entry(sdev, &ss->host->my_devices, siblings) + sdev->online = 0; + scsi_unlock(ss->host); + /* lock device access -- no need to unlock, as we're going away */ down(&(ss->dev_semaphore)); + + /* Complete all pending commands with * cmd->result = DID_ERROR << 16. + * Since we only queue one command at a time, this is pretty easy. */ + if (ss->srb) { + ss->srb->result = DID_ERROR << 16; + ss->srb->scsi_done(ss->srb); + } + + /* TODO: somehow, wait for the device to + * be 'idle' (tasklet completion) */ + + /* remove the pointer to the data structure we were using */ + (struct us_data*)ss->host->hostdata[0] = NULL; + + /* begin SCSI host removal sequence */ + if(scsi_remove_host(ss->host)) { + US_DEBUGP("-- SCSI refused to unregister\n"); + BUG(); + return; + }; + + /* finish SCSI host removal sequence */ + scsi_unregister(ss->host); + + /* Kill the control threads + * + * Enqueue the command, wake up the thread, and wait for + * notification that it has exited. + */ + US_DEBUGP("-- sending exit command to thread\n"); + BUG_ON(atomic_read(&ss->sm_state) != US_STATE_IDLE); + ss->srb = NULL; + up(&(ss->sema)); + wait_for_completion(&(ss->notify)); + + /* free allocated urbs */ usb_stor_deallocate_urbs(ss); + + /* If there's extra data in the us_data structure then + * free that first */ + if (ss->extra) { + /* call the destructor routine, if it exists */ + if (ss->extra_destructor) { + US_DEBUGP("-- calling extra_destructor()\n"); + ss->extra_destructor(ss->extra); + } + + /* destroy the extra data */ + US_DEBUGP("-- freeing the data structure\n"); + kfree(ss->extra); + } + + /* up the semaphore so auto-code-checkers won't complain about + * the down/up imbalance */ up(&(ss->dev_semaphore)); + + /* free the structure itself */ + kfree (ss); } /*********************************************************************** @@ -1078,11 +1029,6 @@ int __init usb_stor_init(void) { printk(KERN_INFO "Initializing USB Mass Storage driver...\n"); - /* initialize internal global data elements */ - us_list = NULL; - init_MUTEX(&us_list_semaphore); - my_host_number = 0; - /* register the driver, return -1 if error */ if (usb_register(&usb_storage_driver) < 0) return -1; @@ -1094,16 +1040,16 @@ int __init usb_stor_init(void) void __exit usb_stor_exit(void) { - struct us_data *next; - US_DEBUGP("usb_stor_exit() called\n"); /* Deregister the driver - * This eliminates races with probes and disconnects + * This will cause disconnect() to be called for each + * attached unit */ US_DEBUGP("-- calling usb_deregister()\n"); usb_deregister(&usb_storage_driver) ; +#if 0 /* While there are still virtual hosts, unregister them * Note that it's important to do this completely before removing * the structures because of possible races with the /proc @@ -1111,7 +1057,7 @@ void __exit usb_stor_exit(void) */ for (next = us_list; next; next = next->next) { US_DEBUGP("-- calling scsi_unregister_host()\n"); - scsi_unregister_host(&(next->htmplt)); + scsi_unregister_host(&usb_stor_host_template); } /* While there are still structures, free them. Note that we are @@ -1137,11 +1083,12 @@ void __exit usb_stor_exit(void) } /* free the structure itself */ - kfree (us_list); + kfree (us_list); /* advance the list pointer */ us_list = next; } +#endif } module_init(usb_stor_init); diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 3e79030a4e2f..8c8712bf3e38 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -52,33 +52,6 @@ #include "scsi.h" #include "hosts.h" -/* - * GUID definitions - */ - -#define GUID(x) __u32 x[3] -#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) -#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0; -#define GUID_NONE(x) (!x[0] && !x[1] && !x[2]) -#define GUID_FORMAT "%08x%08x%08x" -#define GUID_ARGS(x) x[0], x[1], x[2] - -static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial) -{ - pg[0] = (vendor << 16) | product; - pg[1] = pg[2] = 0; - while (*serial) { - pg[1] <<= 4; - pg[1] |= pg[2] >> 28; - pg[2] <<= 4; - if (*serial >= 'a') - *serial -= 'a' - 'A'; - pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0' - : *serial - 'A' + 10; - serial++; - } -} - struct us_data; /* @@ -104,7 +77,6 @@ struct us_unusual_dev { #define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */ #define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ -#define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */ #define US_FLIDX_CAN_CANCEL 18 /* 0x00040000 okay to cancel current_urb? */ #define US_FLIDX_CANCEL_SG 19 /* 0x00080000 okay to cancel current_sg? */ @@ -124,12 +96,9 @@ typedef void (*extra_data_destructor)(void *); /* extra data destructor */ /* we allocate one of these for every device that we remember */ struct us_data { - struct us_data *next; /* next device */ - /* The device we're working with * It's important to note: * (o) you must hold dev_semaphore to change pusb_dev - * (o) DEV_ATTACHED in flags should change whenever pusb_dev does */ struct semaphore dev_semaphore; /* protect pusb_dev */ struct usb_device *pusb_dev; /* this usb_device */ @@ -163,11 +132,7 @@ struct us_data { proto_cmnd proto_handler; /* protocol handler */ /* SCSI interfaces */ - GUID(guid); /* unique dev id */ struct Scsi_Host *host; /* our dummy host data */ - Scsi_Host_Template htmplt; /* own host template */ - int host_number; /* to find us */ - int host_no; /* allocated by scsi */ Scsi_Cmnd *srb; /* current srb */ /* thread information */ @@ -192,10 +157,6 @@ struct us_data { extra_data_destructor extra_destructor;/* extra data destructor */ }; -/* The list of structures and the protective lock for them */ -extern struct us_data *us_list; -extern struct semaphore us_list_semaphore; - /* The structure which defines our driver */ extern struct usb_driver usb_storage_driver; diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 6be5d0698a5e..c7a80836286c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -2,12 +2,6 @@ # 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net> # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \ - cfbcopyarea.o cfbimgblt.o cyber2000fb.o vgastate.o - # Each configuration option enables a list of files. obj-$(CONFIG_VT) += console/ diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index 4d05b169ccbb..1d1d33a9eea3 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -2,11 +2,6 @@ # 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net> # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := fbcon.o fonts.o - # Font handling font-objs := fonts.o diff --git a/drivers/video/matrox/Makefile b/drivers/video/matrox/Makefile index f35e9b543532..72c117da1666 100644 --- a/drivers/video/matrox/Makefile +++ b/drivers/video/matrox/Makefile @@ -2,11 +2,6 @@ # 5 Aug 1999, James Simmons, <mailto:jsimmons@edgeglobal.com> # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o matroxfb_g450.o - # Each configuration option enables a list of files. my-obj-$(CONFIG_FB_MATROX_G100) += g450_pll.o diff --git a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile index 0867e56e3dda..aaed8c2b4a64 100644 --- a/drivers/video/sis/Makefile +++ b/drivers/video/sis/Makefile @@ -2,8 +2,6 @@ # Makefile for the SiS framebuffer device driver # -export-objs := sis_main.o - obj-$(CONFIG_FB_SIS) += sisfb.o sisfb-objs := sis_main.o sis_accel.o init.o init301.o diff --git a/drivers/zorro/Makefile b/drivers/zorro/Makefile index 95135165b893..82a5817eed2d 100644 --- a/drivers/zorro/Makefile +++ b/drivers/zorro/Makefile @@ -2,8 +2,6 @@ # Makefile for the Zorro bus specific drivers. # -export-objs := zorro.o - obj-$(CONFIG_ZORRO) += zorro.o names.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/fs/Makefile b/fs/Makefile index e2b76bcd9f87..0462ed4d42db 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -5,9 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ - fcntl.o read_write.o dcookies.o mbcache.o posix_acl.o xattr_acl.o - obj-y := open.o read_write.o file_table.o buffer.o \ bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \ namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 03924a4c62fe..0d214c4a54fd 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -236,7 +236,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, return; p += len; } - __put_user(NULL, argv); + __put_user(0, argv); current->mm->arg_end = current->mm->env_start = p; while (envc-- > 0) { size_t len; @@ -246,7 +246,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, return; p += len; } - __put_user(NULL, envp); + __put_user(0, envp); current->mm->env_end = p; /* Put the elf_info on the stack in the right place. */ @@ -362,8 +362,6 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, } } - /* Now use mmap to map the library into memory. */ - /* * Now fill out the bss section. First pad the last page up * to the page boundary, and then perform a mmap to make sure @@ -536,6 +534,25 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) ibcs2_interpreter = 1; + /* + * The early SET_PERSONALITY here is so that the lookup + * for the interpreter happens in the namespace of the + * to-be-execed image. SET_PERSONALITY can select an + * alternate root. + * + * However, SET_PERSONALITY is NOT allowed to switch + * this task into the new images's memory mapping + * policy - that is, TASK_SIZE must still evaluate to + * that which is appropriate to the execing application. + * This is because exit_mmap() needs to have TASK_SIZE + * evaluate to the size of the old image. + * + * So if (say) a 64-bit application is execing a 32-bit + * application it is the architecture's responsibility + * to defer changing the value of TASK_SIZE until the + * switch really is going to happen - do this in + * flush_thread(). - akpm + */ SET_PERSONALITY(elf_ex, ibcs2_interpreter); interpreter = open_exec(elf_interpreter); diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index 1f1165436d91..3c9e596596ea 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c @@ -56,7 +56,7 @@ static int som_core_dump(long signr, struct pt_regs * regs); static struct linux_binfmt som_format = { .module = THIS_MODULE, .load_binary = load_som_binary, - .load_library = load_som_library, + .load_shlib = load_som_library, .core_dump = som_core_dump, .min_coredump = SOM_PAGESIZE }; diff --git a/fs/devfs/Makefile b/fs/devfs/Makefile index 3c9422e366b0..6dd8d1245e2c 100644 --- a/fs/devfs/Makefile +++ b/fs/devfs/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux devfs-filesystem routines. # -export-objs := base.o util.o - obj-$(CONFIG_DEVFS_FS) += devfs.o devfs-objs := base.o util.o diff --git a/fs/eventpoll.c b/fs/eventpoll.c index d52fcf73766d..ff4282e71288 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1543,7 +1543,7 @@ static int __init eventpoll_init(void) /* Allocates slab cache used to allocate "struct epitem" items */ error = -ENOMEM; - epi_cache = kmem_cache_create("eventpoll epi", + epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), 0, SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL); @@ -1552,7 +1552,7 @@ static int __init eventpoll_init(void) /* Allocates slab cache used to allocate "struct eppoll_entry" */ error = -ENOMEM; - pwq_cache = kmem_cache_create("eventpoll pwq", + pwq_cache = kmem_cache_create("eventpoll_pwq", sizeof(struct eppoll_entry), 0, EPI_SLAB_DEBUG, NULL, NULL); diff --git a/fs/exportfs/Makefile b/fs/exportfs/Makefile index 10829757c20e..d7c5d4ddb34b 100644 --- a/fs/exportfs/Makefile +++ b/fs/exportfs/Makefile @@ -1,8 +1,6 @@ # # Makefile for the filesystem export support routines. -export-objs := expfs.o - obj-$(CONFIG_EXPORTFS) += exportfs.o exportfs-objs := expfs.o diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile index 06c549a1357d..5b498c3e4fbd 100644 --- a/fs/ext2/Makefile +++ b/fs/ext2/Makefile @@ -7,8 +7,6 @@ obj-$(CONFIG_EXT2_FS) += ext2.o ext2-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o -export-objs += xattr.o - ifeq ($(CONFIG_EXT2_FS_XATTR),y) ext2-objs += xattr.o xattr_user.o endif diff --git a/fs/ext3/Makefile b/fs/ext3/Makefile index dcf1f806f4e5..3a59440df6da 100644 --- a/fs/ext3/Makefile +++ b/fs/ext3/Makefile @@ -7,8 +7,6 @@ obj-$(CONFIG_EXT3_FS) += ext3.o ext3-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o hash.o -export-objs += xattr.o - ifeq ($(CONFIG_EXT3_FS_XATTR),y) ext3-objs += xattr.o xattr_user.o endif diff --git a/fs/fat/Makefile b/fs/fat/Makefile index 04743747f4d9..e083e68edeee 100644 --- a/fs/fat/Makefile +++ b/fs/fat/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux fat filesystem support. # -export-objs := fatfs_syms.o - obj-$(CONFIG_FAT_FS) += fat.o fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index a7eda58424bf..d3db0faa9abe 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -123,12 +123,12 @@ static void write_inode(struct inode *inode, int sync) * Called under inode_lock. */ static void -__sync_single_inode(struct inode *inode, int wait, - struct writeback_control *wbc) +__sync_single_inode(struct inode *inode, struct writeback_control *wbc) { unsigned dirty; struct address_space *mapping = inode->i_mapping; struct super_block *sb = inode->i_sb; + int wait = wbc->sync_mode == WB_SYNC_ALL; BUG_ON(inode->i_state & I_LOCK); @@ -182,14 +182,17 @@ __sync_single_inode(struct inode *inode, int wait, * Write out an inode's dirty pages. Called under inode_lock. */ static void -__writeback_single_inode(struct inode *inode, int sync, +__writeback_single_inode(struct inode *inode, struct writeback_control *wbc) { - if (current_is_pdflush() && (inode->i_state & I_LOCK)) { + if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { list_move(&inode->i_list, &inode->i_sb->s_dirty); return; } + /* + * It's a data-integrity sync. We must wait. + */ while (inode->i_state & I_LOCK) { __iget(inode); spin_unlock(&inode_lock); @@ -197,7 +200,7 @@ __writeback_single_inode(struct inode *inode, int sync, iput(inode); spin_lock(&inode_lock); } - __sync_single_inode(inode, sync, wbc); + __sync_single_inode(inode, wbc); } /* @@ -243,7 +246,6 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) struct inode, i_list); struct address_space *mapping = inode->i_mapping; struct backing_dev_info *bdi = mapping->backing_dev_info; - int really_sync; if (bdi->memory_backed) break; @@ -276,10 +278,9 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (current_is_pdflush() && !writeback_acquire(bdi)) break; - really_sync = (wbc->sync_mode == WB_SYNC_ALL); BUG_ON(inode->i_state & I_FREEING); __iget(inode); - __writeback_single_inode(inode, really_sync, wbc); + __writeback_single_inode(inode, wbc); if (wbc->sync_mode == WB_SYNC_HOLD) { mapping->dirtied_when = jiffies|1; list_move(&inode->i_list, &sb->s_dirty); @@ -452,10 +453,11 @@ void write_inode_now(struct inode *inode, int sync) { struct writeback_control wbc = { .nr_to_write = LONG_MAX, + .sync_mode = WB_SYNC_ALL, }; spin_lock(&inode_lock); - __writeback_single_inode(inode, sync, &wbc); + __writeback_single_inode(inode, &wbc); spin_unlock(&inode_lock); if (sync) wait_on_inode(inode); diff --git a/fs/inode.c b/fs/inode.c index 257f33f98e05..4179e6a45075 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -16,6 +16,7 @@ #include <linux/backing-dev.h> #include <linux/wait.h> #include <linux/hash.h> +#include <linux/swap.h> #include <linux/security.h> /* @@ -392,6 +393,7 @@ static void prune_icache(int nr_to_scan) LIST_HEAD(freeable); int nr_pruned = 0; int nr_scanned; + unsigned long reap = 0; spin_lock(&inode_lock); for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) { @@ -410,7 +412,7 @@ static void prune_icache(int nr_to_scan) __iget(inode); spin_unlock(&inode_lock); if (remove_inode_buffers(inode)) - invalidate_inode_pages(&inode->i_data); + reap += invalidate_inode_pages(&inode->i_data); iput(inode); spin_lock(&inode_lock); @@ -428,6 +430,10 @@ static void prune_icache(int nr_to_scan) inodes_stat.nr_unused -= nr_pruned; spin_unlock(&inode_lock); dispose_list(&freeable); + if (current_is_kswapd) + mod_page_state(kswapd_inodesteal, reap); + else + mod_page_state(pginodesteal, reap); } /* diff --git a/fs/jbd/Makefile b/fs/jbd/Makefile index c60ad6490cdf..54aca4868a36 100644 --- a/fs/jbd/Makefile +++ b/fs/jbd/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux journaling routines. # -export-objs := journal.o - obj-$(CONFIG_JBD) += jbd.o jbd-objs := transaction.o commit.o recovery.o checkpoint.o revoke.o journal.o diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index ee234724e7a5..303ab9ce478a 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -85,7 +85,7 @@ int jfs_commit_inode(struct inode *inode, int wait) tid_t tid; static int noisy = 5; - jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode)); + jfs_info("In jfs_commit_inode, inode = 0x%p", inode); /* * Don't commit if inode has been committed since last being @@ -100,9 +100,9 @@ int jfs_commit_inode(struct inode *inode, int wait) * partitions and may think inode is dirty */ if (!special_file(inode->i_mode) && noisy) { - jERROR(1, ("jfs_commit_inode(0x%p) called on " - "read-only volume\n", inode)); - jERROR(1, ("Is remount racy?\n")); + jfs_err("jfs_commit_inode(0x%p) called on " + "read-only volume", inode); + jfs_err("Is remount racy?"); noisy--; } return 0; @@ -128,13 +128,13 @@ void jfs_write_inode(struct inode *inode, int wait) return; if (jfs_commit_inode(inode, wait)) { - jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n")); + jfs_err("jfs_write_inode: jfs_commit_inode failed!"); } } void jfs_delete_inode(struct inode *inode) { - jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode)); + jfs_info("In jfs_delete_inode, inode = 0x%p", inode); if (test_cflag(COMMIT_Freewmap, inode)) freeZeroLink(inode); @@ -153,9 +153,8 @@ void jfs_dirty_inode(struct inode *inode) /* kernel allows writes to devices on read-only * partitions and may try to mark inode dirty */ - jERROR(1, ("jfs_dirty_inode called on " - "read-only volume\n")); - jERROR(1, ("Is remount racy?\n")); + jfs_err("jfs_dirty_inode called on read-only volume"); + jfs_err("Is remount racy?"); noisy--; } return; @@ -302,7 +301,7 @@ static int jfs_readpages(struct file *file, struct address_space *mapping, static int jfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { - return block_prepare_write(page, from, to, jfs_get_block); + return nobh_prepare_write(page, from, to, jfs_get_block); } static sector_t jfs_bmap(struct address_space *mapping, sector_t block) @@ -327,7 +326,7 @@ struct address_space_operations jfs_aops = { .writepages = jfs_writepages, .sync_page = block_sync_page, .prepare_write = jfs_prepare_write, - .commit_write = generic_commit_write, + .commit_write = nobh_commit_write, .bmap = jfs_bmap, .direct_IO = jfs_direct_IO, }; @@ -378,9 +377,9 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length) void jfs_truncate(struct inode *ip) { - jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size)); + jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size); - block_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block); + nobh_truncate_page(ip->i_mapping, ip->i_size); IWRITE_LOCK(ip); jfs_truncate_nolock(ip, ip->i_size); diff --git a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h index 8409c569d02a..5d1f39148231 100644 --- a/fs/jfs/jfs_btree.h +++ b/fs/jfs/jfs_btree.h @@ -71,19 +71,16 @@ struct btpage { MP = (struct metapage *)&JFS_IP(IP)->bxflag;\ P = (TYPE *)&JFS_IP(IP)->ROOT;\ RC = 0;\ - jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\ }\ else\ {\ - jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\ - (int)BN));\ MP = read_metapage((IP), BN, SIZE, 1);\ if (MP) {\ RC = 0;\ P = (MP)->data;\ } else {\ P = NULL;\ - jERROR(1,("bread failed!\n"));\ + jfs_err("bread failed!");\ RC = EIO;\ }\ }\ diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h index 70dd476c9e93..0524a747fbf7 100644 --- a/fs/jfs/jfs_debug.h +++ b/fs/jfs/jfs_debug.h @@ -41,13 +41,13 @@ /* kgdb stuff */ #define assert(p) KERNEL_ASSERT(#p, p) #else -#define assert(p) {\ -if (!(p))\ - {\ - printk("assert(%s)\n",#p);\ - BUG();\ - }\ -} +#define assert(p) do { \ + if (!(p)) { \ + printk(KERN_CRIT "BUG at %s:%d assert(%s)\n", \ + __FILE__, __LINE__, #p); \ + BUG(); \ + } \ +} while (0) #endif /* @@ -57,33 +57,53 @@ if (!(p))\ #ifdef CONFIG_JFS_DEBUG #define ASSERT(p) assert(p) +/* printk verbosity */ +#define JFS_LOGLEVEL_ERR 1 +#define JFS_LOGLEVEL_WARN 2 +#define JFS_LOGLEVEL_DEBUG 3 +#define JFS_LOGLEVEL_INFO 4 + +extern int jfsloglevel; + /* dump memory contents */ extern void dump_mem(char *label, void *data, int length); -extern int jfsloglevel; /* information message: e.g., configuration, major event */ -#define jFYI(button, prspec) \ - do { if (button && jfsloglevel > 1) printk prspec; } while (0) +#define jfs_info(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_INFO) \ + printk(KERN_INFO fmt "\n", ## arg); \ +} while (0) -/* error event message: e.g., i/o error */ -extern int jfsERROR; -#define jERROR(button, prspec) \ - do { if (button && jfsloglevel > 0) { printk prspec; } } while (0) +/* debug message: ad hoc */ +#define jfs_debug(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_DEBUG) \ + printk(KERN_DEBUG fmt "\n", ## arg); \ +} while (0) + +/* warn message: */ +#define jfs_warn(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_WARN) \ + printk(KERN_WARNING fmt "\n", ## arg); \ +} while (0) -/* debug event message: */ -#define jEVENT(button,prspec) \ - do { if (button) printk prspec; } while (0) +/* error event message: e.g., i/o error */ +#define jfs_err(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_ERR) \ + printk(KERN_ERR "%s:%d " fmt "\n", \ + __FILE__, __LINE__, ## arg); \ +} while (0) /* * debug OFF * --------- */ #else /* CONFIG_JFS_DEBUG */ -#define dump_mem(label,data,length) -#define ASSERT(p) -#define jEVENT(button,prspec) -#define jERROR(button,prspec) -#define jFYI(button,prspec) +#define dump_mem(label,data,length) do {} while (0) +#define ASSERT(p) do {} while (0) +#define jfs_info(fmt, arg...) do {} while (0) +#define jfs_debug(fmt, arg...) do {} while (0) +#define jfs_warn(fmt, arg...) do {} while (0) +#define jfs_err(fmt, arg...) do {} while (0) #endif /* CONFIG_JFS_DEBUG */ /* diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 0e903c9fb8bc..0d3a45444f15 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -314,7 +314,7 @@ int dbSync(struct inode *ipbmap) BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage, PSIZE, 0); if (mp == NULL) { - jERROR(1,("dbSync: read_metapage failed!\n")); + jfs_err("dbSync: read_metapage failed!"); return (EIO); } /* copy the in-memory version of the bmap to the on-disk version */ @@ -1444,10 +1444,10 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) /* assert(!(rc == ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */ if ((rc == ENOSPC) && (bmp->db_agfree[agno] == bmp->db_agsize)) { - jERROR(1, - ("dbAllocAG: removed assert, but still need to debug here\nblkno = 0x%Lx, nblocks = 0x%Lx\n", + jfs_err("dbAllocAG: removed assert, but still need to " + "debug here\nblkno = 0x%Lx, nblocks = 0x%Lx", (unsigned long long) blkno, - (unsigned long long) nblocks)); + (unsigned long long) nblocks); } return (rc); } @@ -1829,8 +1829,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) * to indicate that we have leaked blocks. */ fsDirty(); /* !!! */ - jERROR(1, - ("dbAllocCtl: I/O Error: Block Leakage.\n")); + jfs_err("dbAllocCtl: I/O Error: Block Leakage."); continue; } dp = (struct dmap *) mp->data; @@ -1843,7 +1842,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) */ release_metapage(mp); fsDirty(); /* !!! */ - jERROR(1, ("dbAllocCtl: Block Leakage.\n")); + jfs_err("dbAllocCtl: Block Leakage."); continue; } @@ -3276,9 +3275,8 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) newsize = blkno + nblocks; - jEVENT(0, ("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld\n", - (long long) blkno, (long long) nblocks, - (long long) newsize)); + jfs_info("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld", + (long long) blkno, (long long) nblocks, (long long) newsize); /* * initialize bmap control page. diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 5cd767ad3dc1..89aab0bc5b46 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -130,7 +130,7 @@ struct dtsplit { if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\ ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\ {\ - jERROR(1,("DT_GETPAGE: dtree page corrupt\n"));\ + jfs_err("DT_GETPAGE: dtree page corrupt");\ BT_PUTPAGE(MP);\ updateSuper((IP)->i_sb, FM_DIRTY);\ MP = NULL;\ @@ -222,6 +222,25 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno) } /* + * get_index_page() + * + * Same as get_index_page(), but get's a new page without reading + */ +static struct metapage *get_index_page(struct inode *inode, s64 blkno) +{ + int rc; + s64 xaddr; + int xflag; + s32 xlen; + + rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); + if (rc || (xlen == 0)) + return NULL; + + return get_metapage(inode, xaddr, PSIZE, 1); +} + +/* * find_index() * * Returns dtree page containing directory table entry for specified @@ -241,15 +260,14 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index, if (index < 2) { if (maxWarnings) { - jERROR(1, ("find_entry called with index = %d\n", - index)); + jfs_warn("find_entry called with index = %d", index); maxWarnings--; } return 0; } if (index >= jfs_ip->next_index) { - jFYI(1, ("find_entry called with index >= next_index\n")); + jfs_warn("find_entry called with index >= next_index"); return 0; } @@ -274,8 +292,7 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index, *mp = read_index_page(ip, blkno); } if (*mp == 0) { - jERROR(1, - ("free_index: error reading directory table\n")); + jfs_err("free_index: error reading directory table"); return 0; } @@ -336,8 +353,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) ASSERT(DO_INDEX(ip)); if (jfs_ip->next_index < 2) { - jERROR(1, ("next_index = %d. Please fix this!\n", - jfs_ip->next_index)); + jfs_warn("add_index: next_index = %d. Resetting!", + jfs_ip->next_index); jfs_ip->next_index = 2; } @@ -386,14 +403,14 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) if ((rc = xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0))) { - jFYI(1, ("add_index: xtInsert failed!\n")); + jfs_warn("add_index: xtInsert failed!"); return -1; } ip->i_size = PSIZE; ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); - if ((mp = read_index_page(ip, 0)) == 0) { - jERROR(1, ("add_index: get_metapage failed!\n")); + if ((mp = get_index_page(ip, 0)) == 0) { + jfs_err("add_index: get_metapage failed!"); xtTruncate(tid, ip, 0, COMMIT_PWMAP); return -1; } @@ -428,14 +445,14 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) if ((rc = xtInsert(tid, ip, 0, blkno, sbi->nbperpage, &xaddr, 0))) { - jFYI(1, ("add_index: xtInsert failed!\n")); + jfs_warn("add_index: xtInsert failed!"); jfs_ip->next_index--; return -1; } ip->i_size += PSIZE; ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); - if ((mp = read_index_page(ip, blkno))) + if ((mp = get_index_page(ip, blkno))) memset(mp->data, 0, PSIZE); /* Just looks better */ else xtTruncate(tid, ip, offset, COMMIT_PWMAP); @@ -443,7 +460,7 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) mp = read_index_page(ip, blkno); if (mp == 0) { - jERROR(1, ("add_index: get/read_metapage failed!\n")); + jfs_err("add_index: get/read_metapage failed!"); return -1; } @@ -751,7 +768,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, /* Something's corrupted, mark filesytem dirty so * chkdsk will fix it. */ - jERROR(1, ("stack overrun in dtSearch!\n")); + jfs_err("stack overrun in dtSearch!"); updateSuper(sb, FM_DIRTY); rc = EIO; goto out; @@ -1162,7 +1179,7 @@ static int dtSplitUp(tid_t tid, break; default: - jERROR(2, ("dtSplitUp(): UFO!\n")); + jfs_err("dtSplitUp(): UFO!"); break; } @@ -1313,8 +1330,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, if (rmp == NULL) return EIO; - jEVENT(0, - ("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); BT_MARK_DIRTY(rmp, ip); /* @@ -1420,9 +1436,8 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, * acquire a transaction lock on the next page */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header of previous right sibling page */ @@ -1564,7 +1579,6 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd)); - jEVENT(0, ("dtSplitPage: ip:0x%p sp:0x%p rp:0x%p\n", ip, sp, rp)); return 0; } @@ -1665,8 +1679,7 @@ static int dtExtendPage(tid_t tid, */ sp->header.self = *pxd; - jEVENT(0, - ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); + jfs_info("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p", ip, smp, sp); BT_MARK_DIRTY(smp, ip); /* @@ -1804,10 +1817,6 @@ static int dtExtendPage(tid_t tid, ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ? lengthDXD(&JFS_IP(ip)->acl) : 0)); - jEVENT(0, - ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); - - DT_PUTPAGE(pmp); return 0; } @@ -2401,9 +2410,9 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, oxaddr = addressPXD(opxd); xlen = lengthPXD(opxd); - jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n", + jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d", (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, - xlen)); + xlen); /* * 1. get the internal parent dtpage covering @@ -2415,7 +2424,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, /* retrieve search result */ DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); - jEVENT(0, ("dtRelocate: parent router entry validated.\n")); + jfs_info("dtRelocate: parent router entry validated."); /* * 2. relocate the target dtpage @@ -2521,7 +2530,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, #endif /* _STILL_TO_PORT */ /* unpin the relocated page */ DT_PUTPAGE(mp); - jEVENT(0, ("dtRelocate: target dtpage relocated.\n")); + jfs_info("dtRelocate: target dtpage relocated."); /* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec @@ -2549,7 +2558,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, * acquire tlck for the parent entry covering the target dtpage; * write LOG_REDOPAGE to apply after image only; */ - jEVENT(0, ("dtRelocate: update parent router entry.\n")); + jfs_info("dtRelocate: update parent router entry."); tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); dtlck = (struct dt_lock *) & tlck->lock; lv = & dtlck->lv[dtlck->index]; @@ -2708,9 +2717,8 @@ static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p) * action: update prev pointer; */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header */ @@ -2738,9 +2746,8 @@ static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p) * action: update next pointer; */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header */ @@ -3012,8 +3019,8 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } if (dirtab_slot.flag == DIR_INDEX_FREE) { if (loop_count++ > JFS_IP(ip)->next_index) { - jERROR(1, ("jfs_readdir detected " - "infinite loop!\n")); + jfs_err("jfs_readdir detected " + "infinite loop!"); filp->f_pos = DIREND; return 0; } @@ -3032,7 +3039,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) return 0; } if (p->header.flag & BT_INTERNAL) { - jERROR(1,("jfs_readdir: bad index table\n")); + jfs_err("jfs_readdir: bad index table"); DT_PUTPAGE(mp); filp->f_pos = -1; return 0; @@ -3097,8 +3104,8 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) PARENT(ip), DT_DIR)) return 0; } else { - jERROR(1, - ("jfs_readdir called with invalid offset!\n")); + jfs_err("jfs_readdir called with " + "invalid offset!"); } dtoffset->pn = 1; dtoffset->index = 0; @@ -3111,9 +3118,8 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) { - jERROR(1, - ("jfs_readdir: unexpected rc = %d from dtReadNext\n", - rc)); + jfs_err("jfs_readdir: unexpected rc = %d " + "from dtReadNext", rc); filp->f_pos = DIREND; return 0; } @@ -3130,7 +3136,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) dirent_buf = __get_free_page(GFP_KERNEL); if (dirent_buf == 0) { DT_PUTPAGE(mp); - jERROR(1, ("jfs_readdir: __get_free_page failed!\n")); + jfs_warn("jfs_readdir: __get_free_page failed!"); filp->f_pos = DIREND; return -ENOMEM; } @@ -3202,9 +3208,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) d_namleft -= len; /* Sanity Check */ if (d_namleft == 0) { - jERROR(1,("JFS:Dtree error: " - "ino = %ld, bn=%Ld, index = %d\n", - (long)ip->i_ino, (long long)bn, i)); + jfs_err("JFS:Dtree error: ino = " + "%ld, bn=%Ld, index = %d", + (long)ip->i_ino,(long long)bn, + i); updateSuper(ip->i_sb, FM_DIRTY); goto skip_one; } diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 08153bfb9313..598ee5e5fa2f 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -137,7 +137,7 @@ int diMount(struct inode *ipimap) /* allocate the in-memory inode map control structure. */ imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL); if (imap == NULL) { - jERROR(1, ("diMount: kmalloc returned NULL!\n")); + jfs_err("diMount: kmalloc returned NULL!"); return (ENOMEM); } @@ -253,7 +253,7 @@ int diSync(struct inode *ipimap) IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage, PSIZE, 0); if (mp == NULL) { - jERROR(1,("diSync: get_metapage failed!\n")); + jfs_err("diSync: get_metapage failed!"); return EIO; } @@ -339,7 +339,7 @@ int diRead(struct inode *ip) uint pageno; int rel_inode; - jFYI(1, ("diRead: ino = %ld\n", ip->i_ino)); + jfs_info("diRead: ino = %ld", ip->i_ino); ipimap = sbi->ipimap; JFS_IP(ip)->ipimap = ipimap; @@ -353,7 +353,7 @@ int diRead(struct inode *ip) rc = diIAGRead(imap, iagno, &mp); IREAD_UNLOCK(ipimap); if (rc) { - jERROR(1, ("diRead: diIAGRead returned %d\n", rc)); + jfs_err("diRead: diIAGRead returned %d", rc); return (rc); } @@ -400,7 +400,7 @@ int diRead(struct inode *ip) /* read the page of disk inode */ mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1); if (mp == 0) { - jERROR(1, ("diRead: read_metapage failed\n")); + jfs_err("diRead: read_metapage failed"); return EIO; } @@ -409,7 +409,7 @@ int diRead(struct inode *ip) dp += rel_inode; if (ip->i_ino != le32_to_cpu(dp->di_number)) { - jERROR(1, ("diRead: i_ino != di_number\n")); + jfs_err("diRead: i_ino != di_number"); updateSuper(ip->i_sb, FM_DIRTY); rc = EIO; } else if (le32_to_cpu(dp->di_nlink) == 0) @@ -460,8 +460,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) ip = new_inode(sb); if (ip == NULL) { - jERROR(1, - ("diReadSpecial: new_inode returned NULL!\n")); + jfs_err("diReadSpecial: new_inode returned NULL!"); return ip; } @@ -480,9 +479,6 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) address += inum >> 3; /* 8 inodes per 4K page */ /* read the page of fixed disk inode (AIT) in raw mode */ - jEVENT(0, - ("Reading aggregate inode %d from block %d\n", (uint) inum, - address)); mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); if (mp == NULL) { ip->i_sb = NULL; @@ -553,13 +549,10 @@ void diWriteSpecial(struct inode *ip, int secondary) address += inum >> 3; /* 8 inodes per 4K page */ /* read the page of fixed disk inode (AIT) in raw mode */ - jEVENT(0, - ("Reading aggregate inode %d from block %d\n", (uint) inum, - address)); mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); if (mp == NULL) { - jERROR(1, - ("diWriteSpecial: failed to read aggregate inode extent!\n")); + jfs_err("diWriteSpecial: failed to read aggregate inode " + "extent!"); return; } @@ -586,7 +579,7 @@ void diWriteSpecial(struct inode *ip, int secondary) void diFreeSpecial(struct inode *ip) { if (ip == NULL) { - jERROR(1, ("diFreeSpecial called with NULL ip!\n")); + jfs_err("diFreeSpecial called with NULL ip!"); return; } filemap_fdatawrite(ip->i_mapping); @@ -794,7 +787,7 @@ int diWrite(tid_t tid, struct inode *ip) lv->length << L2DTSLOTSIZE); } } else { - jERROR(1, ("diWrite: UFO tlock\n")); + jfs_err("diWrite: UFO tlock"); } inlineData: @@ -926,8 +919,8 @@ int diFree(struct inode *ip) */ //assert(iagno < imap->im_nextiag); if (iagno >= imap->im_nextiag) { - jERROR(1, ("diFree: inum = %d, iagno = %d, nextiag = %d\n", - (uint) inum, iagno, imap->im_nextiag)); + jfs_err("diFree: inum = %d, iagno = %d, nextiag = %d", + (uint) inum, iagno, imap->im_nextiag); dump_mem("imap", imap, 32); updateSuper(ip->i_sb, FM_DIRTY); return EIO; @@ -974,7 +967,7 @@ int diFree(struct inode *ip) bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask; if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) { - jERROR(1,("diFree: numfree > numinos\n")); + jfs_err("diFree: numfree > numinos"); release_metapage(mp); IREAD_UNLOCK(ipimap); AG_UNLOCK(imap, agno); @@ -1684,7 +1677,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) numinos = imap->im_agctl[agno].numinos; if (numfree > numinos) { - jERROR(1,("diAllocAG: numfree > numinos\n")); + jfs_err("diAllocAG: numfree > numinos"); updateSuper(ip->i_sb, FM_DIRTY); return EIO; } @@ -1835,9 +1828,8 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) */ //assert(iagp->nfreeinos); if (!iagp->nfreeinos) { - jERROR(1, - ("diAllocIno: nfreeinos = 0, but iag on freelist\n")); - jERROR(1, (" agno = %d, iagno = %d\n", agno, iagno)); + jfs_err("diAllocIno: nfreeinos = 0, but iag on freelist"); + jfs_err(" agno = %d, iagno = %d", agno, iagno); dump_mem("iag", iagp, 64); updateSuper(ip->i_sb, FM_DIRTY); return EIO; @@ -2764,18 +2756,14 @@ diUpdatePMap(struct inode *ipimap, * the inode will be freed from working map at the release * of last reference release; */ -// assert(le32_to_cpu(iagp->wmap[extno]) & mask); if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) { - jERROR(1, - ("diUpdatePMap: inode %ld not marked as allocated in wmap!\n", - inum)); + jfs_err("diUpdatePMap: inode %ld not marked as " + "allocated in wmap!", inum); updateSuper(ipimap->i_sb, FM_DIRTY); } -// assert(le32_to_cpu(iagp->pmap[extno]) & mask); if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) { - jERROR(1, - ("diUpdatePMap: inode %ld not marked as allocated in pmap!\n", - inum)); + jfs_err("diUpdatePMap: inode %ld not marked as " + "allocated in pmap!", inum); updateSuper(ipimap->i_sb, FM_DIRTY); } /* update the bitmap for the extent of the freed inode */ @@ -2851,9 +2839,9 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) int numinos, xnuminos = 0, xnumfree = 0; s64 agstart; - jEVENT(0, ("diExtendFS: nextiag:%d numinos:%d numfree:%d\n", + jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d", imap->im_nextiag, atomic_read(&imap->im_numinos), - atomic_read(&imap->im_numfree))); + atomic_read(&imap->im_numfree)); /* * reconstruct imap diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 5f1c908da5e7..cdadd1e099cb 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -38,7 +38,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) inode = new_inode(sb); if (!inode) { - jERROR(1, ("ialloc: new_inode returned NULL!\n")); + jfs_warn("ialloc: new_inode returned NULL!"); return inode; } @@ -46,7 +46,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { - jERROR(1, ("ialloc: diAlloc returned %d!\n", rc)); + jfs_warn("ialloc: diAlloc returned %d!", rc); make_bad_inode(inode); iput(inode); return NULL; @@ -87,7 +87,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) jfs_inode->atltail = 0; jfs_inode->xtlid = 0; - jFYI(1, ("ialloc returns inode = 0x%p\n", inode)); + jfs_info("ialloc returns inode = 0x%p\n", inode); return inode; } diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index bc5720ac2510..e3d931ff7ca2 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -222,8 +222,8 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, int diffp, difft; struct metapage *mp = NULL; - jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n", - log, tblk, lrd, tlck)); + jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", + log, tblk, lrd, tlck); LOG_LOCK(log); @@ -390,7 +390,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } #endif /* _JFS_WIP */ else { - jERROR(2, ("lmWriteRecord: UFO tlck:0x%p\n", tlck)); + jfs_err("lmWriteRecord: UFO tlck:0x%p", tlck); return 0; /* Probably should trap */ } l2linesize = linelock->l2linesize; @@ -449,9 +449,8 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, lvd->offset = cpu_to_le16(lv->offset); lvd->length = cpu_to_le16(lv->length); dstoffset += 4; - jFYI(1, - ("lmWriteRecord: lv offset:%d length:%d\n", - lv->offset, lv->length)); + jfs_info("lmWriteRecord: lv offset:%d length:%d", + lv->offset, lv->length); } if ((i = linelock->next)) { @@ -492,9 +491,8 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, if (lrd->type & cpu_to_le16(LOG_COMMIT)) { tblk->clsn = lsn; - jFYI(1, - ("wr: tclsn:0x%x, beor:0x%x\n", tblk->clsn, - bp->l_eor)); + jfs_info("wr: tclsn:0x%x, beor:0x%x", tblk->clsn, + bp->l_eor); INCREMENT(lmStat.commit); /* # of commit */ @@ -526,10 +524,8 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, LOGGC_UNLOCK(log); } - jFYI(1, - ("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x\n", - le16_to_cpu(lrd->type), log->bp, log->page, - dstoffset)); + jfs_info("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x", + le16_to_cpu(lrd->type), log->bp, log->page, dstoffset); /* page not full ? */ if (dstoffset < LOGPSIZE - LOGPTLRSIZE) @@ -569,8 +565,6 @@ static int lmNextPage(struct jfs_log * log) struct lbuf *nextbp; struct tblock *tblk; - jFYI(1, ("lmNextPage\n")); - /* get current log page number and log sequence page number */ pn = log->page; bp = log->bp; @@ -646,7 +640,6 @@ static int lmNextPage(struct jfs_log * log) lp->h.page = lp->t.page = cpu_to_le32(lspn + 1); lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE); - jFYI(1, ("lmNextPage done\n")); return 0; } @@ -680,8 +673,7 @@ int lmGroupCommit(struct jfs_log * log, struct tblock * tblk) LOGGC_UNLOCK(log); return rc; } - jFYI(1, ("lmGroup Commit: tblk = 0x%p, gcrtc = %d\n", tblk, - log->gcrtc)); + jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc); if (tblk->xflag & COMMIT_LAZY) { /* @@ -783,9 +775,6 @@ static void lmGCwrite(struct jfs_log * log, int cant_write) tblk->flag |= tblkGC_FREE; bp->l_ceor = bp->l_eor; lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); - jEVENT(0, - ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, - bp->l_ceor)); lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC, cant_write); INCREMENT(lmStat.full_page); @@ -794,9 +783,6 @@ static void lmGCwrite(struct jfs_log * log, int cant_write) else { bp->l_ceor = tblk->eor; /* ? bp->l_ceor = bp->l_eor; */ lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); - jEVENT(0, - ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, - bp->l_ceor)); lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write); INCREMENT(lmStat.partial_page); } @@ -845,9 +831,8 @@ void lmPostGC(struct lbuf * bp) tblk->flag &= ~tblkGC_QUEUE; tblk->cqnext = 0; - jEVENT(0, - ("lmPostGC: tblk = 0x%p, flag = 0x%x\n", tblk, - tblk->flag)); + jfs_info("lmPostGC: tblk = 0x%p, flag = 0x%x", tblk, + tblk->flag); if (!(tblk->xflag & COMMIT_FORCE)) /* @@ -877,7 +862,7 @@ void lmPostGC(struct lbuf * bp) lp = (struct logpage *) bp->l_ldata; bp->l_ceor = bp->l_eor; lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); - jEVENT(0, ("lmPostGC: calling lbmWrite\n")); + jfs_info("lmPostGC: calling lbmWrite"); lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 1); } @@ -1008,8 +993,7 @@ int lmLogSync(struct jfs_log * log, int nosyncwait) delta = LOGSYNC_DELTA(logsize); more = min(free / 2, delta); if (more < 2 * LOGPSIZE) { - jEVENT(1, - ("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n\n")); + jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n"); /* * log wrapping * @@ -1048,8 +1032,8 @@ int lmLogSync(struct jfs_log * log, int nosyncwait) */ if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { set_bit(log_SYNCBARRIER, &log->flag); - jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn, - log->syncpt)); + jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, + log->syncpt); /* * We may have to initiate group commit */ @@ -1148,7 +1132,6 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) goto shutdown; out: - jFYI(1, ("lmLogOpen: exit(0)\n")); *logptr = log; return 0; @@ -1167,7 +1150,7 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) free: /* free log descriptor */ kfree(log); - jFYI(1, ("lmLogOpen: exit(%d)\n", rc)); + jfs_warn("lmLogOpen: exit(%d)", rc); return rc; } @@ -1200,7 +1183,7 @@ int lmLogInit(struct jfs_log * log) struct logpage *lp; int lsn; - jFYI(1, ("lmLogInit: log:0x%p\n", log)); + jfs_info("lmLogInit: log:0x%p", log); /* * log inode is overlaid on generic inode where @@ -1224,14 +1207,14 @@ int lmLogInit(struct jfs_log * log) logsuper = (struct logsuper *) bpsuper->l_ldata; if (logsuper->magic != cpu_to_le32(LOGMAGIC)) { - jERROR(1, ("*** Log Format Error ! ***\n")); + jfs_warn("*** Log Format Error ! ***"); rc = EINVAL; goto errout20; } /* logredo() should have been run successfully. */ if (logsuper->state != cpu_to_le32(LOGREDONE)) { - jERROR(1, ("*** Log Is Dirty ! ***\n")); + jfs_warn("*** Log Is Dirty ! ***"); rc = EINVAL; goto errout20; } @@ -1242,19 +1225,17 @@ int lmLogInit(struct jfs_log * log) rc = EINVAL; goto errout20; } - jFYI(0, - ("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x\n", - log, (unsigned long long) log->base, log->size)); + jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x", + log, (unsigned long long) log->base, log->size); } else { if (memcmp(logsuper->uuid, log->uuid, 16)) { - jERROR(1,("wrong uuid on JFS log device\n")); + jfs_warn("wrong uuid on JFS log device"); goto errout20; } log->size = le32_to_cpu(logsuper->size); log->l2bsize = le32_to_cpu(logsuper->l2bsize); - jFYI(0, - ("lmLogInit: external log:0x%p base:0x%Lx size:0x%x\n", - log, (unsigned long long) log->base, log->size)); + jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x", + log, (unsigned long long) log->base, log->size); } log->page = le32_to_cpu(logsuper->end) / LOGPSIZE; @@ -1269,9 +1250,9 @@ int lmLogInit(struct jfs_log * log) lp = (struct logpage *) bp->l_ldata; - jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n", + jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d", le32_to_cpu(logsuper->end), log->page, log->eor, - le16_to_cpu(lp->h.eor))); + le16_to_cpu(lp->h.eor)); // ASSERT(log->eor == lp->h.eor); @@ -1319,8 +1300,8 @@ int lmLogInit(struct jfs_log * log) log->sync = log->syncpt; log->nextsync = LOGSYNC_DELTA(log->logsize); - jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n", - log->lsn, log->syncpt, log->sync)); + jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x", + log->lsn, log->syncpt, log->sync); LOGSYNC_LOCK_INIT(log); @@ -1345,7 +1326,6 @@ int lmLogInit(struct jfs_log * log) if ((rc = lbmIOWait(bpsuper, lbmFREE))) goto errout30; - jFYI(1, ("lmLogInit: exit(%d)\n", rc)); return 0; /* @@ -1360,7 +1340,7 @@ int lmLogInit(struct jfs_log * log) errout10: /* unwind lbmLogInit() */ lbmLogShutdown(log); - jFYI(1, ("lmLogInit: exit(%d)\n", rc)); + jfs_warn("lmLogInit: exit(%d)", rc); return rc; } @@ -1383,7 +1363,7 @@ int lmLogClose(struct super_block *sb, struct jfs_log * log) struct block_device *bdev = log->bdev; int rc; - jFYI(1, ("lmLogClose: log:0x%p\n", log)); + jfs_info("lmLogClose: log:0x%p", log); if (!test_bit(log_INLINELOG, &log->flag)) goto externalLog; @@ -1405,7 +1385,7 @@ int lmLogClose(struct super_block *sb, struct jfs_log * log) blkdev_put(bdev, BDEV_FS); out: - jFYI(0, ("lmLogClose: exit(%d)\n", rc)); + jfs_info("lmLogClose: exit(%d)", rc); return rc; } @@ -1420,7 +1400,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait) { int i; - jFYI(1, ("jfs_flush_journal: log:0x%p wait=%d\n", log, wait)); + jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait); /* * This ensures that we will keep writing to the journal as long @@ -1485,7 +1465,7 @@ int lmLogShutdown(struct jfs_log * log) struct lbuf *bp; struct logpage *lp; - jFYI(1, ("lmLogShutdown: log:0x%p\n", log)); + jfs_info("lmLogShutdown: log:0x%p", log); jfs_flush_journal(log, 1); @@ -1525,8 +1505,8 @@ int lmLogShutdown(struct jfs_log * log) lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); rc = lbmIOWait(bpsuper, lbmFREE); - jFYI(1, ("lmLogShutdown: lsn:0x%x page:%d eor:%d\n", - lsn, log->page, log->eor)); + jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d", + lsn, log->page, log->eor); out: /* @@ -1535,7 +1515,7 @@ int lmLogShutdown(struct jfs_log * log) lbmLogShutdown(log); if (rc) { - jFYI(1, ("lmLogShutdown: exit(%d)\n", rc)); + jfs_warn("lmLogShutdown: exit(%d)", rc); } return rc; } @@ -1576,7 +1556,7 @@ static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate) break; } if (i == MAX_ACTIVE) { - jERROR(1,("Too many file systems sharing journal!\n")); + jfs_warn("Too many file systems sharing journal!"); lbmFree(bpsuper); return EMFILE; /* Is there a better rc? */ } @@ -1587,7 +1567,7 @@ static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate) break; } if (i == MAX_ACTIVE) { - jERROR(1,("Somebody stomped on the journal!\n")); + jfs_warn("Somebody stomped on the journal!"); lbmFree(bpsuper); return EIO; } @@ -1636,7 +1616,7 @@ static int lbmLogInit(struct jfs_log * log) int i; struct lbuf *lbuf; - jFYI(1, ("lbmLogInit: log:0x%p\n", log)); + jfs_info("lbmLogInit: log:0x%p", log); /* initialize current buffer cursor */ log->bp = NULL; @@ -1690,7 +1670,7 @@ static void lbmLogShutdown(struct jfs_log * log) { struct lbuf *lbuf; - jFYI(1, ("lbmLogShutdown: log:0x%p\n", log)); + jfs_info("lbmLogShutdown: log:0x%p", log); lbuf = log->lbuf_free; while (lbuf) { @@ -1804,7 +1784,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) * allocate a log buffer */ *bpp = bp = lbmAllocate(log, pn); - jFYI(1, ("lbmRead: bp:0x%p pn:0x%x\n", bp, pn)); + jfs_info("lbmRead: bp:0x%p pn:0x%x", bp, pn); bp->l_flag |= lbmREAD; @@ -1852,8 +1832,7 @@ static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, struct lbuf *tail; unsigned long flags; - jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n", - bp, flag, bp->l_pn)); + jfs_info("lbmWrite: bp:0x%p flag:0x%x pn:0x%x", bp, flag, bp->l_pn); /* map the logical block address to physical block address */ bp->l_blkno = @@ -1917,8 +1896,8 @@ static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, */ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag) { - jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n", - bp, flag, bp->l_pn)); + jfs_info("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x", + bp, flag, bp->l_pn); /* * initialize buffer for device driver @@ -1950,7 +1929,7 @@ static void lbmStartIO(struct lbuf * bp) struct bio *bio; struct jfs_log *log = bp->l_log; - jFYI(1, ("lbmStartIO\n")); + jfs_info("lbmStartIO\n"); bio = bio_alloc(GFP_NOFS, 1); bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); @@ -1970,8 +1949,6 @@ static void lbmStartIO(struct lbuf * bp) INCREMENT(lmStat.submitted); blk_run_queues(); - - jFYI(1, ("lbmStartIO done\n")); } @@ -1983,9 +1960,7 @@ static int lbmIOWait(struct lbuf * bp, int flag) unsigned long flags; int rc = 0; - jFYI(1, - ("lbmIOWait1: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, - flag)); + jfs_info("lbmIOWait1: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag); LCACHE_LOCK(flags); /* disable+lock */ @@ -1998,9 +1973,7 @@ static int lbmIOWait(struct lbuf * bp, int flag) LCACHE_UNLOCK(flags); /* unlock+enable */ - jFYI(1, - ("lbmIOWait2: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, - flag)); + jfs_info("lbmIOWait2: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag); return rc; } @@ -2022,7 +1995,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) /* * get back jfs buffer bound to the i/o buffer */ - jEVENT(0, ("lbmIODone: bp:0x%p flag:0x%x\n", bp, bp->l_flag)); + jfs_info("lbmIODone: bp:0x%p flag:0x%x", bp, bp->l_flag); LCACHE_LOCK(flags); /* disable+lock */ @@ -2031,7 +2004,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { bp->l_flag |= lbmERROR; - jERROR(1, ("lbmIODone: I/O error in JFS log\n")); + jfs_err("lbmIODone: I/O error in JFS log"); } bio_put(bio); @@ -2159,8 +2132,6 @@ int jfsIOWait(void *arg) { struct lbuf *bp; - jFYI(1, ("jfsIOWait is here!\n")); - lock_kernel(); daemonize(); @@ -2199,7 +2170,7 @@ int jfsIOWait(void *arg) } } while (!jfs_stop_threads); - jFYI(1,("jfsIOWait being killed!\n")); + jfs_info("jfsIOWait being killed!"); complete(&jfsIOwait); return 0; } @@ -2231,8 +2202,8 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) int npages = 0; struct lbuf *bp; - jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n", - (long long)logAddress, logSize)); + jfs_info("lmLogFormat: logAddress:%Ld logSize:%d", + (long long)logAddress, logSize); /* allocate a log buffer */ bp = lbmAllocate(log, 1); diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index ac29204cf772..2aa570746e64 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -229,8 +229,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, unsigned long page_index; unsigned long page_offset; - jFYI(1, ("__get_metapage: inode = 0x%p, lblock = 0x%lx\n", - inode, lblock)); + jfs_info("__get_metapage: inode = 0x%p, lblock = 0x%lx", inode, lblock); if (absolute) mapping = inode->i_sb->s_bdev->bd_inode->i_mapping; @@ -249,7 +248,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, clear_bit(META_discard, &mp->flag); } mp->count++; - jFYI(1, ("__get_metapage: found 0x%p, in hash\n", mp)); + jfs_info("__get_metapage: found 0x%p, in hash", mp); assert(mp->logical_size == size); lock_metapage(mp); spin_unlock(&meta_lock); @@ -261,7 +260,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, l2bsize; if ((page_offset + size) > PAGE_CACHE_SIZE) { spin_unlock(&meta_lock); - jERROR(1, ("MetaData crosses page boundary!!\n")); + jfs_err("MetaData crosses page boundary!!"); return NULL; } @@ -320,30 +319,28 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, spin_unlock(&meta_lock); if (new) { - jFYI(1, - ("__get_metapage: Calling grab_cache_page\n")); + jfs_info("__get_metapage: Calling grab_cache_page"); mp->page = grab_cache_page(mapping, page_index); if (!mp->page) { - jERROR(1, ("grab_cache_page failed!\n")); + jfs_err("grab_cache_page failed!"); goto freeit; } else { INCREMENT(mpStat.pagealloc); unlock_page(mp->page); } } else { - jFYI(1, - ("__get_metapage: Calling read_cache_page\n")); + jfs_info("__get_metapage: Calling read_cache_page"); mp->page = read_cache_page(mapping, lblock, (filler_t *)mapping->a_ops->readpage, NULL); if (IS_ERR(mp->page)) { - jERROR(1, ("read_cache_page failed!\n")); + jfs_err("read_cache_page failed!"); goto freeit; } else INCREMENT(mpStat.pagealloc); } mp->data = kmap(mp->page) + page_offset; } - jFYI(1, ("__get_metapage: returning = 0x%p\n", mp)); + jfs_info("__get_metapage: returning = 0x%p", mp); return mp; freeit: @@ -378,7 +375,7 @@ static void __write_metapage(struct metapage * mp) unsigned long page_offset; int rc; - jFYI(1, ("__write_metapage: mp = 0x%p\n", mp)); + jfs_info("__write_metapage: mp = 0x%p", mp); if (test_bit(META_discard, &mp->flag)) { /* @@ -397,7 +394,7 @@ static void __write_metapage(struct metapage * mp) page_offset + mp->logical_size); if (rc) { - jERROR(1, ("prepare_write return %d!\n", rc)); + jfs_err("prepare_write return %d!", rc); ClearPageUptodate(mp->page); unlock_page(mp->page); clear_bit(META_dirty, &mp->flag); @@ -407,13 +404,13 @@ static void __write_metapage(struct metapage * mp) page_offset + mp->logical_size); if (rc) { - jERROR(1, ("commit_write returned %d\n", rc)); + jfs_err("commit_write returned %d", rc); } unlock_page(mp->page); clear_bit(META_dirty, &mp->flag); - jFYI(1, ("__write_metapage done\n")); + jfs_info("__write_metapage done"); } static inline void sync_metapage(struct metapage *mp) @@ -435,9 +432,7 @@ void release_metapage(struct metapage * mp) { struct jfs_log *log; - jFYI(1, - ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp, - mp->flag)); + jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag); spin_lock(&meta_lock); if (test_bit(META_forced, &mp->flag)) { @@ -491,7 +486,6 @@ void release_metapage(struct metapage * mp) free_metapage(mp); } - jFYI(1, ("release_metapage: done\n")); } void __invalidate_metapages(struct inode *ip, s64 addr, int len) diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 7859b2f22d28..c477cdb3ff82 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -87,8 +87,6 @@ int jfs_mount(struct super_block *sb) struct inode *ipimap = NULL; struct inode *ipbmap = NULL; - jFYI(1, ("\nMount JFS\n")); - /* * read/validate superblock * (initialize mount inode from the superblock) @@ -99,21 +97,19 @@ int jfs_mount(struct super_block *sb) ipaimap = diReadSpecial(sb, AGGREGATE_I, 0); if (ipaimap == NULL) { - jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n")); + jfs_err("jfs_mount: Faild to read AGGREGATE_I"); rc = EIO; goto errout20; } sbi->ipaimap = ipaimap; - jFYI(1, ("jfs_mount: ipaimap:0x%p\n", ipaimap)); + jfs_info("jfs_mount: ipaimap:0x%p", ipaimap); /* * initialize aggregate inode allocation map */ if ((rc = diMount(ipaimap))) { - jERROR(1, - ("jfs_mount: diMount(ipaimap) failed w/rc = %d\n", - rc)); + jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc); goto errout21; } @@ -126,7 +122,7 @@ int jfs_mount(struct super_block *sb) goto errout22; } - jFYI(1, ("jfs_mount: ipbmap:0x%p\n", ipbmap)); + jfs_info("jfs_mount: ipbmap:0x%p", ipbmap); sbi->ipbmap = ipbmap; @@ -134,7 +130,7 @@ int jfs_mount(struct super_block *sb) * initialize aggregate block allocation map */ if ((rc = dbMount(ipbmap))) { - jERROR(1, ("jfs_mount: dbMount failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: dbMount failed w/rc = %d", rc); goto errout22; } @@ -152,22 +148,20 @@ int jfs_mount(struct super_block *sb) if ((sbi->mntflag & JFS_BAD_SAIT) == 0) { ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1); if (ipaimap2 == 0) { - jERROR(1, - ("jfs_mount: Faild to read AGGREGATE_I\n")); + jfs_err("jfs_mount: Faild to read AGGREGATE_I"); rc = EIO; goto errout35; } sbi->ipaimap2 = ipaimap2; - jFYI(1, ("jfs_mount: ipaimap2:0x%p\n", ipaimap2)); + jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2); /* * initialize secondary aggregate inode allocation map */ if ((rc = diMount(ipaimap2))) { - jERROR(1, - ("jfs_mount: diMount(ipaimap2) failed, rc = %d\n", - rc)); + jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d", + rc); goto errout35; } } else @@ -182,23 +176,22 @@ int jfs_mount(struct super_block *sb) */ ipimap = diReadSpecial(sb, FILESYSTEM_I, 0); if (ipimap == NULL) { - jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n")); + jfs_err("jfs_mount: Failed to read FILESYSTEM_I"); /* open fileset secondary inode allocation map */ rc = EIO; goto errout40; } - jFYI(1, ("jfs_mount: ipimap:0x%p\n", ipimap)); + jfs_info("jfs_mount: ipimap:0x%p", ipimap); /* map further access of per fileset inodes by the fileset inode */ sbi->ipimap = ipimap; /* initialize fileset inode allocation map */ if ((rc = diMount(ipimap))) { - jERROR(1, ("jfs_mount: diMount failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: diMount failed w/rc = %d", rc); goto errout41; } - jFYI(1, ("Mount JFS Complete.\n")); goto out; /* @@ -234,9 +227,9 @@ int jfs_mount(struct super_block *sb) out: - if (rc) { - jERROR(1, ("Mount JFS Failure: %d\n", rc)); - } + if (rc) + jfs_err("Mount JFS Failure: %d", rc); + return rc; } @@ -265,13 +258,13 @@ int jfs_mount_rw(struct super_block *sb, int remount) truncate_inode_pages(sbi->ipbmap->i_mapping, 0); diUnmount(sbi->ipimap, 1); if ((rc = diMount(sbi->ipimap))) { - jERROR(1,("jfs_mount_rw: diMount failed!\n")); + jfs_err("jfs_mount_rw: diMount failed!"); return rc; } dbUnmount(sbi->ipbmap, 1); if ((rc = dbMount(sbi->ipbmap))) { - jERROR(1,("jfs_mount_rw: dbMount failed!\n")); + jfs_err("jfs_mount_rw: dbMount failed!"); return rc; } } @@ -288,8 +281,7 @@ int jfs_mount_rw(struct super_block *sb, int remount) * update file system superblock; */ if ((rc = updateSuper(sb, FM_MOUNT))) { - jERROR(1, - ("jfs_mount: updateSuper failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc); lmLogClose(sb, log); JFS_SBI(sb)->log = 0; return rc; @@ -343,15 +335,15 @@ static int chkSuper(struct super_block *sb) bsize = le32_to_cpu(j_sb->s_bsize); #ifdef _JFS_4K if (bsize != PSIZE) { - jERROR(1, ("Currently only 4K block size supported!\n")); + jfs_err("Currently only 4K block size supported!"); rc = EINVAL; goto out; } #endif /* _JFS_4K */ - jFYI(1, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", + jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx", le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), - (unsigned long long) le64_to_cpu(j_sb->s_size))); + (unsigned long long) le64_to_cpu(j_sb->s_size)); /* validate the descriptors for Secondary AIM and AIT */ if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) != @@ -375,15 +367,11 @@ static int chkSuper(struct super_block *sb) if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) != cpu_to_le32(JFS_GROUPCOMMIT)) j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT); - jFYI(0, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", - le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), - (unsigned long long) le64_to_cpu(j_sb->s_size))); /* validate fs state */ if (j_sb->s_state != cpu_to_le32(FM_CLEAN) && !(sb->s_flags & MS_RDONLY)) { - jERROR(1, - ("jfs_mount: Mount Failure: File System Dirty.\n")); + jfs_err("jfs_mount: Mount Failure: File System Dirty."); rc = EINVAL; goto out; } diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 3a9fef349e74..58df2f7c38cd 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -214,7 +214,7 @@ static lid_t txLockAlloc(void) TxAnchor.freelock = TxLock[lid].next; HIGHWATERMARK(stattx.maxlid, lid); if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TxAnchor.TlocksLow == 0)) { - jEVENT(0,("txLockAlloc TlocksLow\n")); + jfs_info("txLockAlloc TlocksLow"); TxAnchor.TlocksLow = 1; wake_up(&jfs_sync_thread_wait); } @@ -228,7 +228,7 @@ static void txLockFree(lid_t lid) TxAnchor.freelock = lid; TxAnchor.tlocksInUse--; if (TxAnchor.TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) { - jEVENT(0,("txLockFree TlocksLow no more\n")); + jfs_info("txLockFree TlocksLow no more"); TxAnchor.TlocksLow = 0; TXN_WAKEUP(&TxAnchor.lowlockwait); } @@ -336,7 +336,7 @@ tid_t txBegin(struct super_block *sb, int flag) struct tblock *tblk; struct jfs_log *log; - jFYI(1, ("txBegin: flag = 0x%x\n", flag)); + jfs_info("txBegin: flag = 0x%x", flag); log = JFS_SBI(sb)->log; TXN_LOCK(); @@ -372,7 +372,7 @@ tid_t txBegin(struct super_block *sb, int flag) * allocate transaction id/block */ if ((t = TxAnchor.freetid) == 0) { - jFYI(1, ("txBegin: waiting for free tid\n")); + jfs_info("txBegin: waiting for free tid"); INCREMENT(TxStat.txBegin_freetid); TXN_SLEEP(&TxAnchor.freewait); goto retry; @@ -382,7 +382,7 @@ tid_t txBegin(struct super_block *sb, int flag) if ((tblk->next == 0) && (current != jfsCommitTask)) { /* Save one tblk for jfsCommit thread */ - jFYI(1, ("txBegin: waiting for free tid\n")); + jfs_info("txBegin: waiting for free tid"); INCREMENT(TxStat.txBegin_freetid); TXN_SLEEP(&TxAnchor.freewait); goto retry; @@ -413,7 +413,7 @@ tid_t txBegin(struct super_block *sb, int flag) TXN_UNLOCK(); - jFYI(1, ("txBegin: returning tid = %d\n", t)); + jfs_info("txBegin: returning tid = %d", t); return t; } @@ -476,7 +476,7 @@ void txEnd(tid_t tid) struct tblock *tblk = tid_to_tblock(tid); struct jfs_log *log; - jFYI(1, ("txEnd: tid = %d\n", tid)); + jfs_info("txEnd: tid = %d", tid); TXN_LOCK(); /* @@ -496,9 +496,7 @@ void txEnd(tid_t tid) * routine. */ if (tblk->flag & tblkGC_LAZY) { - jFYI(1, - ("txEnd called w/lazy tid: %d, tblk = 0x%p\n", - tid, tblk)); + jfs_info("txEnd called w/lazy tid: %d, tblk = 0x%p", tid, tblk); TXN_UNLOCK(); spin_lock_irq(&log->gclock); // LOGGC_LOCK @@ -507,7 +505,7 @@ void txEnd(tid_t tid) return; } - jFYI(1, ("txEnd: tid: %d, tblk = 0x%p\n", tid, tblk)); + jfs_info("txEnd: tid: %d, tblk = 0x%p", tid, tblk); assert(tblk->next == 0); @@ -529,7 +527,7 @@ void txEnd(tid_t tid) /* forward log syncpt */ /* lmSync(log); */ - jFYI(1, (" log barrier off: 0x%x\n", log->lsn)); + jfs_info(" log barrier off: 0x%x", log->lsn); /* enable new transactions start */ clear_bit(log_SYNCBARRIER, &log->flag); @@ -544,7 +542,6 @@ void txEnd(tid_t tid) TXN_WAKEUP(&TxAnchor.freewait); TXN_UNLOCK(); - jFYI(1, ("txEnd: exitting\n")); } @@ -589,8 +586,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, if (lid == 0) goto allocateLock; - jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%d\n", - tid, ip, mp, lid)); + jfs_info("txLock: tid:%d ip:0x%p mp:0x%p lid:%d", tid, ip, mp, lid); /* is page locked by the requester transaction ? */ tlck = lid_to_tlock(lid); @@ -676,9 +672,8 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, mark_metapage_dirty(mp); atomic_inc(&mp->nohomeok); - jFYI(1, - ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p\n", - mp, atomic_read(&mp->nohomeok), tid, tlck)); + jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", + mp, atomic_read(&mp->nohomeok), tid, tlck); /* if anonymous transaction, and buffer is on the group * commit synclist, mark inode to show this. This will @@ -774,7 +769,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, break; default: - jERROR(1, ("UFO tlock:0x%p\n", tlck)); + jfs_err("UFO tlock:0x%p", tlck); } /* @@ -794,7 +789,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, /* Only locks on ipimap or ipaimap should reach here */ /* assert(jfs_ip->fileset == AGGREGATE_I); */ if (jfs_ip->fileset != AGGREGATE_I) { - jERROR(1, ("txLock: trying to lock locked page!\n")); + jfs_err("txLock: trying to lock locked page!"); dump_mem("ip", ip, sizeof(struct inode)); dump_mem("mp", mp, sizeof(struct metapage)); dump_mem("Locker's tblk", tid_to_tblock(tid), @@ -805,10 +800,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, INCREMENT(stattx.waitlock); /* statistics */ release_metapage(mp); - jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %d\n", - tid, xtid, lid)); + jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", + tid, xtid, lid); TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); - jEVENT(0, ("txLock: awakened tid = %d, lid = %d\n", tid, lid)); + jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); return NULL; } @@ -869,7 +864,7 @@ static void txUnlock(struct tblock * tblk) struct jfs_log *log; int difft, diffp; - jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk)); + jfs_info("txUnlock: tblk = 0x%p", tblk); log = JFS_SBI(tblk->sb)->log; /* @@ -879,7 +874,7 @@ static void txUnlock(struct tblock * tblk) tlck = lid_to_tlock(lid); next = tlck->next; - jFYI(1, ("unlocking lid = %d, tlck = 0x%p\n", lid, tlck)); + jfs_info("unlocking lid = %d, tlck = 0x%p", lid, tlck); /* unbind page from tlock */ if ((mp = tlck->mp) != NULL && @@ -1113,7 +1108,7 @@ int txCommit(tid_t tid, /* transaction identifier */ ino_t top; struct super_block *sb; - jFYI(1, ("txCommit, tid = %d, flag = %d\n", tid, flag)); + jfs_info("txCommit, tid = %d, flag = %d", tid, flag); /* is read-only file system ? */ if (isReadOnly(iplist[0])) { rc = EROFS; @@ -1312,7 +1307,7 @@ int txCommit(tid_t tid, /* transaction identifier */ rc = rc1; TheEnd: - jFYI(1, ("txCommit: tid = %d, returning %d\n", tid, rc)); + jfs_info("txCommit: tid = %d, returning %d", tid, rc); return rc; } @@ -1376,7 +1371,7 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd) break; default: - jERROR(1, ("UFO tlock:0x%p\n", tlck)); + jfs_err("UFO tlock:0x%p", tlck); } if (tlck->mp) release_metapage(tlck->mp); @@ -1462,9 +1457,8 @@ int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, /* mark page as homeward bound */ tlck->flag |= tlckWRITEPAGE; - } else { - jERROR(2, ("diLog: UFO type tlck:0x%p\n", tlck)); - } + } else + jfs_err("diLog: UFO type tlck:0x%p", tlck); #ifdef _JFS_WIP /* * alloc/free external EA extent @@ -1754,9 +1748,8 @@ void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, xadlock->xdlist = &p->xad[lwm]; tblk->xflag &= ~COMMIT_LAZY; } - jFYI(1, - ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%d\n", - tlck->ip, mp, tlck, lwm, xadlock->count)); + jfs_info("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d " + "count:%d", tlck->ip, mp, tlck, lwm, xadlock->count); maplock->index = 1; @@ -1848,9 +1841,8 @@ void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, xadlock->xdlist = &p->xad[XTENTRYSTART]; tblk->xflag &= ~COMMIT_LAZY; } - jFYI(1, - ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2\n", - tlck->ip, mp, xadlock->count)); + jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2", + tlck->ip, mp, xadlock->count); maplock->index = 1; @@ -1978,9 +1970,9 @@ void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, xadlock->count = next - lwm; xadlock->xdlist = &p->xad[lwm]; - jFYI(1, - ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%d\n", - tlck->ip, mp, xadlock->count, lwm, next)); + jfs_info("xtLog: alloc ip:0x%p mp:0x%p count:%d " + "lwm:%d next:%d", + tlck->ip, mp, xadlock->count, lwm, next); maplock->index++; xadlock++; } @@ -2002,9 +1994,8 @@ void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, pxdlock->count = 1; pxdlock->pxd = tpxd; - jFYI(1, - ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%d\n", - ip, mp, pxdlock->count, hwm)); + jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d " + "hwm:%d", ip, mp, pxdlock->count, hwm); maplock->index++; xadlock++; } @@ -2022,9 +2013,9 @@ void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, xadlock->count = hwm - next + 1; xadlock->xdlist = &p->xad[next]; - jFYI(1, - ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%d\n", - tlck->ip, mp, xadlock->count, next, hwm)); + jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d " + "next:%d hwm:%d", + tlck->ip, mp, xadlock->count, next, hwm); maplock->index++; } @@ -2111,9 +2102,9 @@ void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, lrd->log.updatemap.pxd = pxdlock->pxd; lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); - jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%x\n", + jfs_info("mapLog: xaddr:0x%lx xlen:0x%x", (ulong) addressPXD(&pxdlock->pxd), - lengthPXD(&pxdlock->pxd))); + lengthPXD(&pxdlock->pxd)); } /* update bmap */ @@ -2429,9 +2420,8 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); xad->flag &= ~(XAD_NEW | XAD_EXTENDED); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } else if (maplock->flag & mlckALLOCPXD) { @@ -2439,9 +2429,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", (ulong) xaddr, - xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2451,9 +2439,8 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, xlen = lengthPXD(pxd); dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2479,9 +2466,8 @@ void txFreeMap(struct inode *ip, pxd_t *pxd; int n; - jFYI(1, - ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x\n", - tblk, maplock, maptype)); + jfs_info("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x", + tblk, maplock, maptype); /* * free from persistent map; @@ -2496,9 +2482,9 @@ void txFreeMap(struct inode *ip, xlen = lengthXAD(xad); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx " + "xlen:%d", + (ulong) xaddr, xlen); } } } else if (maplock->flag & mlckFREEPXD) { @@ -2507,9 +2493,8 @@ void txFreeMap(struct inode *ip, xlen = lengthPXD(&pxdlock->pxd); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2519,9 +2504,8 @@ void txFreeMap(struct inode *ip, xlen = lengthPXD(pxd); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2538,18 +2522,16 @@ void txFreeMap(struct inode *ip, xlen = lengthXAD(xad); dbFree(ip, xaddr, (s64) xlen); xad->flag = 0; - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } else if (maplock->flag & mlckFREEPXD) { pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); dbFree(ip, xaddr, (s64) xlen); - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckFREEPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2558,9 +2540,8 @@ void txFreeMap(struct inode *ip, xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); dbFree(ip, xaddr, (s64) xlen); - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2625,7 +2606,7 @@ void txAbort(tid_t tid, int dirty) struct metapage *mp; struct tblock *tblk = tid_to_tblock(tid); - jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty)); + jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty); /* * free tlocks of the transaction @@ -2688,7 +2669,7 @@ void txAbortCommit(struct commit * cd, int exval) struct metapage *mp; assert(exval == EIO || exval == ENOMEM); - jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd)); + jfs_warn("txAbortCommit: cd:0x%p", cd); /* * free tlocks of the transaction @@ -2743,12 +2724,11 @@ void txLazyCommit(struct tblock * tblk) ((tblk->flag & tblkGC_UNLOCKED) == 0)) { /* We must have gotten ahead of the user thread */ - jFYI(1, - ("jfs_lazycommit: tblk 0x%p not unlocked\n", tblk)); + jfs_info("jfs_lazycommit: tblk 0x%p not unlocked", tblk); schedule(); } - jFYI(1, ("txLazyCommit: processing tblk 0x%p\n", tblk)); + jfs_info("txLazyCommit: processing tblk 0x%p", tblk); txUpdateMap(tblk); @@ -2775,7 +2755,7 @@ void txLazyCommit(struct tblock * tblk) } else spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK - jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk)); + jfs_info("txLazyCommit: done: tblk = 0x%p", tblk); } /* @@ -2861,9 +2841,9 @@ restart: } while (!jfs_stop_threads); if (TxAnchor.unlock_queue) - jERROR(1, ("jfs_lazycommit being killed with pending transactions!\n")); + jfs_err("jfs_lazycommit being killed w/pending transactions!"); else - jFYI(1, ("jfs_lazycommit being killed\n")); + jfs_info("jfs_lazycommit being killed\n"); complete(&jfsIOwait); return 0; } @@ -3077,7 +3057,7 @@ int jfs_sync(void *arg) } } while (!jfs_stop_threads); - jFYI(1, ("jfs_sync being killed\n")); + jfs_info("jfs_sync being killed"); complete(&jfsIOwait); return 0; } diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c index a81ef8c832bb..b40511e4cf18 100644 --- a/fs/jfs/jfs_umount.c +++ b/fs/jfs/jfs_umount.c @@ -58,7 +58,7 @@ int jfs_umount(struct super_block *sb) struct jfs_log *log; int rc = 0; - jFYI(1, ("\n UnMount JFS: sb:0x%p\n", sb)); + jfs_info("UnMount JFS: sb:0x%p", sb); /* * update superblock and close log @@ -74,7 +74,6 @@ int jfs_umount(struct super_block *sb) /* * close fileset inode allocation map (aka fileset inode) */ - jEVENT(0, ("jfs_umount: close ipimap:0x%p\n", ipimap)); diUnmount(ipimap, 0); diFreeSpecial(ipimap); @@ -85,7 +84,6 @@ int jfs_umount(struct super_block *sb) */ ipaimap2 = sbi->ipaimap2; if (ipaimap2) { - jEVENT(0, ("jfs_umount: close ipaimap2:0x%p\n", ipaimap2)); diUnmount(ipaimap2, 0); diFreeSpecial(ipaimap2); sbi->ipaimap2 = NULL; @@ -95,7 +93,6 @@ int jfs_umount(struct super_block *sb) * close aggregate inode allocation map */ ipaimap = sbi->ipaimap; - jEVENT(0, ("jfs_umount: close ipaimap:0x%p\n", ipaimap)); diUnmount(ipaimap, 0); diFreeSpecial(ipaimap); sbi->ipaimap = NULL; @@ -103,7 +100,6 @@ int jfs_umount(struct super_block *sb) /* * close aggregate block allocation map */ - jEVENT(0, ("jfs_umount: close ipbmap:%p\n", ipbmap)); dbUnmount(ipbmap, 0); diFreeSpecial(ipbmap); @@ -134,7 +130,7 @@ int jfs_umount(struct super_block *sb) */ rc = lmLogClose(sb, log); } - jFYI(0, (" UnMount JFS Complete: %d\n", rc)); + jfs_info("UnMount JFS Complete: rc = %d", rc); return rc; } diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c index fdf48758a533..8a0ee0a0d845 100644 --- a/fs/jfs/jfs_unicode.c +++ b/fs/jfs/jfs_unicode.c @@ -47,7 +47,6 @@ int jfs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ } } to[outlen] = 0; - jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to)); return outlen; } @@ -63,22 +62,17 @@ int jfs_strtoUCS(wchar_t * to, int charlen; int i; - jEVENT(0, ("jfs_strtoUCS - '%s'\n", from)); - for (i = 0; len && *from; i++, from += charlen, len -= charlen) { charlen = codepage->char2uni(from, len, &to[i]); if (charlen < 1) { - jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n", - charlen)); - jERROR(1, ("charset = %s, char = 0x%x\n", - codepage->charset, (unsigned char) *from)); + jfs_err("jfs_strtoUCS: char2uni returned %d.", charlen); + jfs_err("charset = %s, char = 0x%x", + codepage->charset, (unsigned char) *from); to[i] = 0x003f; /* a question mark */ charlen = 1; } } - jEVENT(0, (" returning %d\n", i)); - to[i] = 0; return i; } diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index 46d6795634d4..359867a1eb61 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -69,7 +69,7 @@ (le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\ (le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\ {\ - jERROR(1,("XT_GETPAGE: xtree page corrupt\n"));\ + jfs_err("XT_GETPAGE: xtree page corrupt");\ BT_PUTPAGE(MP);\ updateSuper((IP)->i_sb, FM_DIRTY);\ MP = NULL;\ @@ -169,9 +169,8 @@ int xtLookup(struct inode *ip, s64 lstart, size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> JFS_SBI(ip->i_sb)->l2bsize; if (lstart >= size) { - jERROR(1, - ("xtLookup: lstart (0x%lx) >= size (0x%lx)\n", - (ulong) lstart, (ulong) size)); + jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)", + (ulong) lstart, (ulong) size); return 0; } } @@ -181,7 +180,7 @@ int xtLookup(struct inode *ip, s64 lstart, */ //search: if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { - jERROR(1, ("xtLookup: xtSearch returned %d\n", rc)); + jfs_err("xtLookup: xtSearch returned %d", rc); return rc; } @@ -198,10 +197,8 @@ int xtLookup(struct inode *ip, s64 lstart, * lstart is a page start address, * i.e., lstart cannot start in a hole; */ - if (cmp) { - jFYI(1, ("xtLookup: cmp = %d\n", cmp)); + if (cmp) goto out; - } /* * lxd covered by xad @@ -212,10 +209,6 @@ int xtLookup(struct inode *ip, s64 lstart, xend = xoff + xlen; xaddr = addressXAD(xad); - jEVENT(0, - ("index = %d, xoff = 0x%lx, xlen = 0x%x, xaddr = 0x%lx\n", - index, (ulong) xoff, xlen, (ulong) xaddr)); - /* initialize new pxd */ *pflag = xad->flag; *paddr = xaddr + (lstart - xoff); @@ -802,8 +795,7 @@ int xtInsert(tid_t tid, /* transaction id */ struct tlock *tlck; struct xtlock *xtlck; - jFYI(1, - ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); /* * search for the entry location at which to insert: @@ -1248,8 +1240,7 @@ xtSplitPage(tid_t tid, struct inode *ip, if (rmp == NULL) return EIO; - jEVENT(0, - ("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); BT_MARK_DIRTY(rmp, ip); /* @@ -1324,7 +1315,7 @@ xtSplitPage(tid_t tid, struct inode *ip, ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); return 0; } @@ -1440,7 +1431,7 @@ xtSplitPage(tid_t tid, struct inode *ip, ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); return rc; } @@ -1496,7 +1487,7 @@ xtSplitRoot(tid_t tid, if (rmp == NULL) return EIO; - jEVENT(0, ("xtSplitRoot: ip:0x%p rmp:0x%p\n", ip, rmp)); + jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp); /* * acquire a transaction lock on the new right page; @@ -1581,7 +1572,7 @@ xtSplitRoot(tid_t tid, ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitRoot: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp); return 0; } @@ -1615,8 +1606,7 @@ int xtExtend(tid_t tid, /* transaction id */ struct xtlock *xtlck = 0; int rootsplit = 0; - jFYI(1, - ("xtExtend: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); /* there must exist extent to be extended */ if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) @@ -1628,9 +1618,6 @@ int xtExtend(tid_t tid, /* transaction id */ /* extension must be contiguous */ xad = &p->xad[index]; - jFYI(0, ("xtExtend: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", - (ulong) offsetXAD(xad), lengthXAD(xad), - (ulong) addressXAD(xad))); assert((offsetXAD(xad) + lengthXAD(xad)) == xoff); /* @@ -1893,10 +1880,6 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", PXDlength(&pxdlock->pxd, rlen); pxdlock->index = 1; } - jEVENT(0, - ("xtTailgate: free extent xaddr:0x%lx xlen:0x%x\n", - (ulong) addressPXD(&pxdlock->pxd), - lengthPXD(&pxdlock->pxd))); } else /* free from WMAP */ dbFree(ip, addressXAD(xad) + llen, (s64) rlen); @@ -2408,9 +2391,8 @@ int xtAppend(tid_t tid, /* transaction id */ xaddr = *xaddrp; xlen = *xlenp; - jEVENT(0, - ("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx\n", - (ulong) xoff, maxblocks, xlen, (ulong) xaddr)); + jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx", + (ulong) xoff, maxblocks, xlen, (ulong) xaddr); /* * search for the entry location at which to insert: @@ -2747,9 +2729,8 @@ xtDeleteUp(tid_t tid, struct inode *ip, p->header.nextindex = cpu_to_le16(le16_to_cpu(p->header.nextindex) - 1); - jEVENT(0, - ("xtDeleteUp(entry): 0x%lx[%d]\n", - (ulong) parent->bn, index)); + jfs_info("xtDeleteUp(entry): 0x%lx[%d]", + (ulong) parent->bn, index); } /* unpin the parent page */ @@ -2809,10 +2790,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ if (offset >= ip->i_size) return ESTALE; /* stale extent */ - jEVENT(0, - ("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx\n", - xtype, (ulong) xoff, xlen, (ulong) oxaddr, - (ulong) nxaddr)); + jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx", + xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr); /* * 1. get and validate the parent xtpage/xad entry @@ -2855,7 +2834,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ */ xad = &pp->xad[index]; } - jEVENT(0, ("xtRelocate: parent xad entry validated.\n")); + jfs_info("xtRelocate: parent xad entry validated."); /* * 2. relocate the extent @@ -2926,7 +2905,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ /* get back parent page */ rc = xtSearch(ip, xoff, &cmp, &btstack, 0); XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); - jEVENT(0, ("xtRelocate: target data extent relocated.\n")); + jfs_info("xtRelocate: target data extent relocated."); } else { /* (xtype == XTPAGE) */ /* @@ -3026,7 +3005,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ /* unpin the target page to new homeward bound */ XT_PUTPAGE(mp); - jEVENT(0, ("xtRelocate: target xtpage relocated.\n")); + jfs_info("xtRelocate: target xtpage relocated."); } /* @@ -3067,7 +3046,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ * update which will write LOG_REDOPAGE and update bmap for * allocation of XAD_NEW destination extent; */ - jEVENT(0, ("xtRelocate: update parent xad entry.\n")); + jfs_info("xtRelocate: update parent xad entry."); BT_MARK_DIRTY(pmp, ip); tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW); xtlck = (struct xtlock *) & tlck->lock; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9c9eab010a04..736fd5dc6c04 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -70,7 +70,7 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode) struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); /* * search parent directory for entry/freespace @@ -96,7 +96,7 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode) down(&JFS_IP(ip)->commit_sem); if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { - jERROR(1, ("jfs_create: dtSearch returned %d\n", rc)); + jfs_err("jfs_create: dtSearch returned %d", rc); goto out3; } @@ -118,7 +118,7 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode) */ ino = ip->i_ino; if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_create: dtInsert returned %d\n", rc)); + jfs_err("jfs_create: dtInsert returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks Filesystem dirty */ else @@ -159,7 +159,7 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode) out1: - jFYI(1, ("jfs_create: rc:%d\n", -rc)); + jfs_info("jfs_create: rc:%d", -rc); return -rc; } @@ -190,7 +190,7 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name); /* link count overflow on parent directory ? */ if (dip->i_nlink == JFS_LINK_MAX) { @@ -222,7 +222,7 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) down(&JFS_IP(ip)->commit_sem); if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { - jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc)); + jfs_err("jfs_mkdir: dtSearch returned %d", rc); goto out3; } @@ -244,7 +244,7 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) */ ino = ip->i_ino; if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc)); + jfs_err("jfs_mkdir: dtInsert returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks Filesystem dirty */ @@ -289,7 +289,7 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) out1: - jFYI(1, ("jfs_mkdir: rc:%d\n", -rc)); + jfs_info("jfs_mkdir: rc:%d", -rc); return -rc; } @@ -322,7 +322,7 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry) struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); /* directory must be empty to be removed */ if (!dtEmpty(ip)) { @@ -351,7 +351,7 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry) */ ino = ip->i_ino; if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { - jERROR(1, ("jfs_rmdir: dtDelete returned %d\n", rc)); + jfs_err("jfs_rmdir: dtDelete returned %d", rc); if (rc == EIO) txAbort(tid, 1); txEnd(tid); @@ -411,7 +411,7 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry) free_UCSname(&dname); out: - jFYI(1, ("jfs_rmdir: rc:%d\n", rc)); + jfs_info("jfs_rmdir: rc:%d", rc); return -rc; } @@ -447,7 +447,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry) s64 new_size = 0; int commit_flag; - jFYI(1, ("jfs_unlink: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) goto out; @@ -467,7 +467,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry) */ ino = ip->i_ino; if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { - jERROR(1, ("jfs_unlink: dtDelete returned %d\n", rc)); + jfs_err("jfs_unlink: dtDelete returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks FS Dirty */ txEnd(tid); @@ -560,7 +560,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry) out1: free_UCSname(&dname); out: - jFYI(1, ("jfs_unlink: rc:%d\n", -rc)); + jfs_info("jfs_unlink: rc:%d", -rc); return -rc; } @@ -593,7 +593,7 @@ s64 commitZeroLink(tid_t tid, struct inode *ip) int filetype; struct tblock *tblk; - jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip)); + jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip); filetype = ip->i_mode & S_IFMT; switch (filetype) { @@ -661,7 +661,7 @@ int freeZeroLink(struct inode *ip) int rc = 0; int type; - jFYI(1, ("freeZeroLink: ip = 0x%p\n", ip)); + jfs_info("freeZeroLink: ip = 0x%p", ip); /* return if not reg or symbolic link or if size is * already ok. @@ -767,9 +767,8 @@ int jfs_link(struct dentry *old_dentry, struct btstack btstack; struct inode *iplist[2]; - jFYI(1, - ("jfs_link: %s %s\n", old_dentry->d_name.name, - dentry->d_name.name)); + jfs_info("jfs_link: %s %s", old_dentry->d_name.name, + dentry->d_name.name); tid = txBegin(ip->i_sb, 0); @@ -814,7 +813,7 @@ int jfs_link(struct dentry *old_dentry, up(&JFS_IP(dir)->commit_sem); up(&JFS_IP(ip)->commit_sem); - jFYI(1, ("jfs_link: rc:%d\n", rc)); + jfs_info("jfs_link: rc:%d", rc); return -rc; } @@ -855,7 +854,7 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name) struct inode *iplist[2]; - jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name)); + jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name); ssize = strlen(name) + 1; @@ -898,7 +897,7 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name) if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc)); + jfs_err("jfs_symlink: dtInsert returned %d", rc); /* discard ne inode */ goto out3; @@ -933,15 +932,14 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name) if (ssize > sizeof (JFS_IP(ip)->i_inline)) JFS_IP(ip)->mode2 &= ~INLINEEA; - jFYI(1, - ("jfs_symlink: fast symlink added ssize:%d name:%s \n", - ssize, name)); + jfs_info("jfs_symlink: fast symlink added ssize:%d name:%s ", + ssize, name); } /* * write source path name in a single extent */ else { - jFYI(1, ("jfs_symlink: allocate extent ip:0x%p\n", ip)); + jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); ip->i_op = &page_symlink_inode_operations; ip->i_mapping->a_ops = &jfs_aops; @@ -1033,7 +1031,7 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name) #endif out1: - jFYI(1, ("jfs_symlink: rc:%d\n", -rc)); + jfs_info("jfs_symlink: rc:%d", -rc); return -rc; } @@ -1064,9 +1062,8 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, int commit_flag; - jFYI(1, - ("jfs_rename: %s %s\n", old_dentry->d_name.name, - new_dentry->d_name.name)); + jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, + new_dentry->d_name.name); old_ip = old_dentry->d_inode; new_ip = new_dentry->d_inode; @@ -1168,18 +1165,16 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_CREATE); if (rc) { - jERROR(1, - ("jfs_rename didn't expect dtSearch to fail w/rc = %d\n", - rc)); + jfs_err("jfs_rename didn't expect dtSearch to fail " + "w/rc = %d", rc); goto out4; } ino = old_ip->i_ino; rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack); if (rc) { - jERROR(1, - ("jfs_rename: dtInsert failed w/rc = %d\n", - rc)); + jfs_err("jfs_rename: dtInsert failed w/rc = %d", + rc); goto out4; } if (S_ISDIR(old_ip->i_mode)) @@ -1192,9 +1187,8 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ino = old_ip->i_ino; rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE); if (rc) { - jERROR(1, - ("jfs_rename did not expect dtDelete to return rc = %d\n", - rc)); + jfs_err("jfs_rename did not expect dtDelete to return rc = %d", + rc); txAbort(tid, 1); /* Marks Filesystem dirty */ goto out4; } @@ -1297,7 +1291,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, clear_cflag(COMMIT_Stale, old_dir); } - jFYI(1, ("jfs_rename: returning %d\n", rc)); + jfs_info("jfs_rename: returning %d", rc); return -rc; } @@ -1318,7 +1312,7 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) tid_t tid; struct tblock *tblk; - jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name)); + jfs_info("jfs_mknod: %s", dentry->d_name.name); if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) goto out; @@ -1378,7 +1372,7 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) #endif out: - jFYI(1, ("jfs_mknod: returning %d\n", rc)); + jfs_info("jfs_mknod: returning %d", rc); return -rc; } @@ -1392,7 +1386,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry) int len = dentry->d_name.len; int rc; - jFYI(1, ("jfs_lookup: name = %s\n", name)); + jfs_info("jfs_lookup: name = %s", name); if ((name[0] == '.') && (len == 1)) @@ -1409,17 +1403,14 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry) d_add(dentry, NULL); return ERR_PTR(0); } else if (rc) { - jERROR(1, - ("jfs_lookup: dtSearch returned %d\n", rc)); + jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(-rc); } } ip = jfs_iget(dip->i_sb, inum); if (ip == NULL) { - jERROR(1, - ("jfs_lookup: iget failed on inum %d\n", - (uint) inum)); + jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum); return ERR_PTR(-EACCES); } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index fcc1ad80ceba..166df3331657 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -50,7 +50,7 @@ static pid_t jfsSyncThread; DECLARE_COMPLETION(jfsIOwait); #ifdef CONFIG_JFS_DEBUG -int jfsloglevel = 1; +int jfsloglevel = JFS_LOGLEVEL_WARN; MODULE_PARM(jfsloglevel, "i"); MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)"); #endif @@ -120,7 +120,7 @@ static int jfs_statfs(struct super_block *sb, struct statfs *buf) s64 maxinodes; struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap; - jFYI(1, ("In jfs_statfs\n")); + jfs_info("In jfs_statfs"); buf->f_type = JFS_SUPER_MAGIC; buf->f_bsize = sbi->bsize; buf->f_blocks = sbi->bmap->db_mapsize; @@ -151,11 +151,10 @@ static void jfs_put_super(struct super_block *sb) struct jfs_sb_info *sbi = JFS_SBI(sb); int rc; - jFYI(1, ("In jfs_put_super\n")); + jfs_info("In jfs_put_super"); rc = jfs_umount(sb); - if (rc) { - jERROR(1, ("jfs_umount failed with return code %d\n", rc)); - } + if (rc) + jfs_err("jfs_umount failed with return code %d", rc); unload_nls(sbi->nls_tab); sbi->nls_tab = NULL; @@ -259,7 +258,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) int rc; s64 newLVSize = 0; - jFYI(1, ("In jfs_read_super: s_flags=0x%lx\n", sb->s_flags)); + jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags); sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL); if (!sbi) @@ -291,8 +290,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) rc = jfs_mount(sb); if (rc) { if (!silent) { - jERROR(1, - ("jfs_mount failed w/return code = %d\n", rc)); + jfs_err("jfs_mount failed w/return code = %d", rc); } goto out_kfree; } @@ -302,9 +300,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) rc = jfs_mount_rw(sb, 0); if (rc) { if (!silent) { - jERROR(1, - ("jfs_mount_rw failed w/return code = %d\n", - rc)); + jfs_err("jfs_mount_rw failed, return code = %d", + rc); } goto out_no_rw; } @@ -335,14 +332,14 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) return 0; out_no_root: - jEVENT(1, ("jfs_read_super: get root inode failed\n")); + jfs_err("jfs_read_super: get root inode failed"); if (inode) iput(inode); out_no_rw: rc = jfs_umount(sb); if (rc) { - jERROR(1, ("jfs_umount failed with return code %d\n", rc)); + jfs_err("jfs_umount failed with return code %d", rc); } out_kfree: if (sbi->nls_tab) @@ -370,8 +367,7 @@ static void jfs_unlockfs(struct super_block *sb) if (!(sb->s_flags & MS_RDONLY)) { if ((rc = lmLogInit(log))) - jERROR(1, - ("jfs_unlock failed with return code %d\n", rc)); + jfs_err("jfs_unlock failed with return code %d", rc); else txResume(sb); } @@ -458,7 +454,7 @@ static int __init init_jfs_fs(void) */ rc = metapage_init(); if (rc) { - jERROR(1, ("metapage_init failed w/rc = %d\n", rc)); + jfs_err("metapage_init failed w/rc = %d", rc); goto free_slab; } @@ -467,7 +463,7 @@ static int __init init_jfs_fs(void) */ rc = txInit(); if (rc) { - jERROR(1, ("txInit failed w/rc = %d\n", rc)); + jfs_err("txInit failed w/rc = %d", rc); goto free_metapage; } @@ -477,8 +473,7 @@ static int __init init_jfs_fs(void) jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsIOthread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", jfsIOthread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread); goto end_txmngr; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -486,9 +481,7 @@ static int __init init_jfs_fs(void) jfsCommitThread = kernel_thread(jfs_lazycommit, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsCommitThread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", - jfsCommitThread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread); goto kill_iotask; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -496,8 +489,7 @@ static int __init init_jfs_fs(void) jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsSyncThread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", jfsSyncThread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread); goto kill_committask; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -527,7 +519,7 @@ free_slab: static void __exit exit_jfs_fs(void) { - jFYI(1, ("exit_jfs_fs called\n")); + jfs_info("exit_jfs_fs called"); jfs_stop_threads = 1; txExit(); diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile index 659350828a62..571af5b8f9ff 100644 --- a/fs/lockd/Makefile +++ b/fs/lockd/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux lock manager stuff # -export-objs := lockd_syms.o - obj-$(CONFIG_LOCKD) += lockd.o lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ diff --git a/fs/msdos/Makefile b/fs/msdos/Makefile index 40b155bae88d..df6f2004e7c9 100644 --- a/fs/msdos/Makefile +++ b/fs/msdos/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux msdos filesystem routines. # -export-objs := msdosfs_syms.o - obj-$(CONFIG_MSDOS_FS) += msdos.o msdos-objs := namei.o msdosfs_syms.o diff --git a/fs/namei.c b/fs/namei.c index 2dbd2642362c..5a7f617cad66 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1659,12 +1659,19 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) return error; } +/* + * Make sure that the actual truncation of the file will occur outside its + * directory's i_sem. Truncate can take a long time if there is a lot of + * writeout happening, and we don't want to prevent access to the directory + * while waiting on the I/O. + */ asmlinkage long sys_unlink(const char * pathname) { int error = 0; char * name; struct dentry *dentry; struct nameidata nd; + struct inode *inode = NULL; name = getname(pathname); if(IS_ERR(name)) @@ -1683,6 +1690,9 @@ asmlinkage long sys_unlink(const char * pathname) /* Why not before? Because we want correct error value */ if (nd.last.name[nd.last.len]) goto slashes; + inode = dentry->d_inode; + if (inode) + inode = igrab(inode); error = vfs_unlink(nd.dentry->d_inode, dentry); exit2: dput(dentry); @@ -1693,6 +1703,8 @@ exit1: exit: putname(name); + if (inode) + iput(inode); /* truncate the inode here */ return error; slashes: diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 8f1155367aa8..8cf8dc082280 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -390,11 +390,6 @@ nfs_readpages(struct file *filp, struct address_space *mapping, is_sync ? readpage_sync_filler : readpage_async_filler, &desc); - while (!list_empty(pages)) { - struct page *page = list_entry(pages->prev, struct page, list); - list_del(&page->list); - page_cache_release(page); - } if (!list_empty(&head)) { int err = nfs_pagein_list(&head, server->rpages); if (!ret) diff --git a/fs/nls/Makefile b/fs/nls/Makefile index bd5a13e07540..d32c68912583 100644 --- a/fs/nls/Makefile +++ b/fs/nls/Makefile @@ -2,8 +2,6 @@ # Makefile for native language support # -export-objs := nls_base.o - obj-$(CONFIG_NLS) += nls_base.o obj-$(CONFIG_NLS_CODEPAGE_437) += nls_cp437.o diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index 4162876cdf78..53f28233808b 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -export-objs := msdos.o - obj-y := check.o obj-$(CONFIG_ACORN_PARTITION) += acorn.o diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 17547aad9f56..7131ac9aa1c0 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux proc filesystem routines. # -export-objs := root.o - obj-$(CONFIG_PROC_FS) += proc.o proc-objs := inode.o root.o base.o generic.o array.o \ diff --git a/fs/proc/array.c b/fs/proc/array.c index 29b41941d83e..e135ac5a1080 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -301,7 +301,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ppid = task->pid ? task->real_parent->pid : 0; read_unlock(&tasklist_lock); res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ -%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ +%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n", task->pid, task->comm, @@ -324,7 +324,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer) nice, 0UL /* removed */, jiffies_to_clock_t(task->it_real_value), - jiffies_to_clock_t(task->start_time), + (unsigned long long) jiffies_64_to_clock_t(task->start_time), vsize, mm ? mm->rss : 0, /* you might want to shift this left 3 */ task->rlim[RLIMIT_RSS].rlim_cur, diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index ba036340fcd1..0b426bc1d760 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -41,11 +41,13 @@ #include <linux/profile.h> #include <linux/blkdev.h> #include <linux/hugetlb.h> +#include <linux/jiffies.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/io.h> #include <asm/pgalloc.h> #include <asm/tlb.h> +#include <asm/div64.h> #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -98,34 +100,35 @@ static int loadavg_read_proc(char *page, char **start, off_t off, static int uptime_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long uptime; - unsigned long idle; + u64 uptime; + unsigned long uptime_remainder; int len; - uptime = jiffies; - idle = init_task.utime + init_task.stime; - - /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but - that would overflow about every five days at HZ == 100. - Therefore the identity a = (a / b) * b + a % b is used so that it is - calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100. - The part in front of the '+' always evaluates as 0 (mod 100). All divisions - in the above formulas are truncating. For HZ being a power of 10, the - calculations simplify to the version in the #else part (if the printf - format is adapted to the same number of digits as zeroes in HZ. - */ + uptime = get_jiffies_64(); + uptime_remainder = (unsigned long) do_div(uptime, HZ); + #if HZ!=100 - len = sprintf(page,"%lu.%02lu %lu.%02lu\n", - uptime / HZ, - (((uptime % HZ) * 100) / HZ) % 100, - idle / HZ, - (((idle % HZ) * 100) / HZ) % 100); + { + u64 idle = init_task.utime + init_task.stime; + unsigned long idle_remainder; + + idle_remainder = (unsigned long) do_div(idle, HZ); + len = sprintf(page,"%lu.%02lu %lu.%02lu\n", + (unsigned long) uptime, + (uptime_remainder * 100) / HZ, + (unsigned long) idle, + (idle_remainder * 100) / HZ); + } #else - len = sprintf(page,"%lu.%02lu %lu.%02lu\n", - uptime / HZ, - uptime % HZ, - idle / HZ, - idle % HZ); + { + unsigned long idle = init_task.utime + init_task.stime; + + len = sprintf(page,"%lu.%02lu %lu.%02lu\n", + (unsigned long) uptime, + uptime_remainder, + idle / HZ, + idle % HZ); + } #endif return proc_calc_metrics(page, start, off, count, eof, len); } @@ -317,7 +320,7 @@ static int kstat_read_proc(char *page, char **start, off_t off, { int i, len; extern unsigned long total_forks; - unsigned long jif = jiffies; + u64 jif = get_jiffies_64(); unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0; for (i = 0 ; i < NR_CPUS; i++) { @@ -358,6 +361,7 @@ static int kstat_read_proc(char *page, char **start, off_t off, len += sprintf(page + len, " %u", kstat_irqs(i)); #endif + do_div(jif, HZ); len += sprintf(page + len, "\nctxt %lu\n" "btime %lu\n" @@ -365,7 +369,7 @@ static int kstat_read_proc(char *page, char **start, off_t off, "procs_running %lu\n" "procs_blocked %lu\n", nr_context_switches(), - xtime.tv_sec - jif / HZ, + xtime.tv_sec - (unsigned long) jif, total_forks, nr_running(), nr_iowait()); diff --git a/fs/read_write.c b/fs/read_write.c index d91e4ea4ec95..04904f7fa206 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -531,6 +531,10 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (retval) goto fput_in; + retval = security_file_permission (in_file, MAY_READ); + if (retval) + goto fput_in; + /* * Get output file, and verify that it is ok.. */ @@ -548,6 +552,10 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (retval) goto fput_out; + retval = security_file_permission (out_file, MAY_WRITE); + if (retval) + goto fput_out; + if (!ppos) ppos = &in_file->f_pos; diff --git a/fs/seq_file.c b/fs/seq_file.c index b95d78e796ef..ac5ab8beba9e 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <asm/uaccess.h> +#include <asm/page.h> /** * seq_open - initialize sequential file diff --git a/fs/sysfs/Makefile b/fs/sysfs/Makefile index 66cee07697be..c355b8ecfe15 100644 --- a/fs/sysfs/Makefile +++ b/fs/sysfs/Makefile @@ -2,6 +2,4 @@ # Makefile for the sysfs virtual filesystem # -export-objs := inode.o - obj-y := inode.o diff --git a/fs/vfat/Makefile b/fs/vfat/Makefile index 7452712582ce..392f0a43fdaa 100644 --- a/fs/vfat/Makefile +++ b/fs/vfat/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux vfat-filesystem routines. # -export-objs := vfatfs_syms.o - obj-$(CONFIG_VFAT_FS) += vfat.o vfat-objs := namei.o vfatfs_syms.o diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index cce9733536f1..93afc0a65581 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -45,9 +45,6 @@ ifeq ($(CONFIG_PAGEBUF_DEBUG),y) EXTRA_CFLAGS += -DPAGEBUF_TRACE endif -export-objs := pagebuf/page_buf.o support/ktrace.o \ - linux/xfs_globals.o - obj-$(CONFIG_XFS_FS) += xfs.o diff --git a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c index 905dfcf757a6..4c60a8799fcb 100644 --- a/fs/xfs/pagebuf/page_buf.c +++ b/fs/xfs/pagebuf/page_buf.c @@ -1299,7 +1299,6 @@ pagebuf_iorequest( /* start real I/O */ int status = 0; int i, map_i, total_nr_pages, nr_pages; struct bio *bio; - struct bio_vec *bvec; int offset = pb->pb_offset; int size = pb->pb_count_desired; sector_t sector = pb->pb_bn; @@ -1335,13 +1334,8 @@ pagebuf_iorequest( /* start real I/O */ bio->bi_sector = sector - (offset >> BBSHIFT); bio->bi_end_io = bio_end_io_pagebuf; bio->bi_private = pb; - bio->bi_vcnt++; - bio->bi_size = PAGE_CACHE_SIZE; - bvec = bio->bi_io_vec; - bvec->bv_page = pb->pb_pages[0]; - bvec->bv_len = PAGE_CACHE_SIZE; - bvec->bv_offset = 0; + bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0); atomic_inc(&pb->pb_io_remaining); submit_bio(READ, bio); @@ -1389,9 +1383,7 @@ next_chunk: bio->bi_end_io = bio_end_io_pagebuf; bio->bi_private = pb; - bvec = bio->bi_io_vec; - - for (; size && nr_pages; nr_pages--, bvec++, map_i++) { + for (; size && nr_pages; nr_pages--, map_i++) { int nbytes = PAGE_CACHE_SIZE - offset; if (nbytes > size) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index b0677c73957d..b5acad2dcb36 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -379,7 +379,8 @@ xfs_buf_item_pin( */ void xfs_buf_item_unpin( - xfs_buf_log_item_t *bip) + xfs_buf_log_item_t *bip, + int stale) { xfs_mount_t *mp; xfs_buf_t *bp; @@ -396,7 +397,8 @@ xfs_buf_item_unpin( freed = atomic_dec_and_test(&bip->bli_refcount); mp = bip->bli_item.li_mountp; xfs_bunpin(bp); - if (freed && (bip->bli_flags & XFS_BLI_STALE)) { + if (freed && stale) { + ASSERT(bip->bli_flags & XFS_BLI_STALE); ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); ASSERT(XFS_BUF_ISSTALE(bp)); @@ -418,7 +420,6 @@ xfs_buf_item_unpin( ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL); xfs_buf_relse(bp); } - } /* @@ -435,6 +436,7 @@ xfs_buf_item_unpin_remove( { xfs_buf_t *bp; xfs_log_item_desc_t *lidp; + int stale = 0; bp = bip->bli_buf; /* @@ -454,6 +456,7 @@ xfs_buf_item_unpin_remove( * will be able to bump up the refcount. */ lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) bip); + stale = lidp->lid_flags & XFS_LID_BUF_STALE; xfs_trans_free_item(tp, lidp); /* * Since the transaction no longer refers to the buffer, @@ -462,7 +465,7 @@ xfs_buf_item_unpin_remove( XFS_BUF_SET_FSPRIVATE2(bp, NULL); } - xfs_buf_item_unpin(bip); + xfs_buf_item_unpin(bip, stale); return; } @@ -686,7 +689,7 @@ struct xfs_item_ops xfs_buf_item_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_buf_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_buf_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *)) xfs_buf_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock, diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index bd8d7de4faab..2d5c619543a2 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -93,9 +93,11 @@ xfs_qm_dquot_logitem_pin( * anyone in xfs_dqwait_unpin() if the count goes to 0. The * dquot must have been previously pinned with a call to xfs_dqpin(). */ +/* ARGSUSED */ STATIC void xfs_qm_dquot_logitem_unpin( - xfs_dq_logitem_t *logitem) + xfs_dq_logitem_t *logitem, + int stale) { unsigned long s; xfs_dquot_t *dqp; @@ -116,7 +118,7 @@ xfs_qm_dquot_logitem_unpin_remove( xfs_dq_logitem_t *logitem, xfs_trans_t *tp) { - xfs_qm_dquot_logitem_unpin(logitem); + xfs_qm_dquot_logitem_unpin(logitem, 0); } /* @@ -396,7 +398,8 @@ struct xfs_item_ops xfs_dquot_item_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_dquot_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int)) + xfs_qm_dquot_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_qm_dquot_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*)) @@ -492,7 +495,7 @@ xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf) */ /*ARGSUSED*/ STATIC void -xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf) +xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale) { return; } @@ -613,7 +616,8 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t* ,int)) + xfs_qm_qoff_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) xfs_qm_qoff_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, @@ -635,7 +639,8 @@ struct xfs_item_ops xfs_qm_qoff_logitem_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int)) + xfs_qm_qoff_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) xfs_qm_qoff_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 051244882029..3ec3cbf89b03 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -105,7 +105,7 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efip) */ /*ARGSUSED*/ STATIC void -xfs_efi_item_unpin(xfs_efi_log_item_t *efip) +xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) { int nexts; int size; @@ -280,7 +280,7 @@ struct xfs_item_ops xfs_efi_item_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efi_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_efi_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efi_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efi_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *)) xfs_efi_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock, @@ -474,7 +474,7 @@ xfs_efd_item_pin(xfs_efd_log_item_t *efdp) */ /*ARGSUSED*/ STATIC void -xfs_efd_item_unpin(xfs_efd_log_item_t *efdp) +xfs_efd_item_unpin(xfs_efd_log_item_t *efdp, int stale) { return; } @@ -607,7 +607,7 @@ struct xfs_item_ops xfs_efd_item_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efd_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_efd_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efd_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efd_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_efd_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock, diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index a005d9c23d38..15be5aa6f41d 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -534,9 +534,11 @@ xfs_inode_item_pin( * item which was previously pinned with a call to xfs_inode_item_pin(). * Just call xfs_iunpin() on the inode to do this. */ +/* ARGSUSED */ STATIC void xfs_inode_item_unpin( - xfs_inode_log_item_t *iip) + xfs_inode_log_item_t *iip, + int stale) { xfs_iunpin(iip->ili_inode); } @@ -880,7 +882,7 @@ struct xfs_item_ops xfs_inode_item_ops = { .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_inode_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_inode_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_inode_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_inode_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_inode_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock, diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index e75cd88d476f..a30359bcbbba 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -45,7 +45,7 @@ /* Local miscellaneous function prototypes */ STATIC int xlog_bdstrat_cb(struct xfs_buf *); STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket, - xfs_lsn_t *); + xlog_in_core_t **, xfs_lsn_t *); STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, dev_t log_dev, xfs_daddr_t blk_offset, @@ -55,7 +55,9 @@ STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_unalloc_log(xlog_t *log); STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[], int nentries, xfs_log_ticket_t tic, - xfs_lsn_t *start_lsn, uint flags); + xfs_lsn_t *start_lsn, + xlog_in_core_t **commit_iclog, + uint flags); /* local state machine functions */ STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); @@ -70,10 +72,6 @@ STATIC int xlog_state_get_iclog_space(xlog_t *log, xlog_ticket_t *ticket, int *continued_write, int *logoffsetp); -STATIC int xlog_state_lsn_is_synced(xlog_t *log, - xfs_lsn_t lsn, - xfs_log_callback_t *cb, - int *abortflg); STATIC void xlog_state_put_ticket(xlog_t *log, xlog_ticket_t *tic); STATIC int xlog_state_release_iclog(xlog_t *log, @@ -254,6 +252,7 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state) xfs_lsn_t xfs_log_done(xfs_mount_t *mp, xfs_log_ticket_t xtic, + void **iclog, uint flags) { xlog_t *log = mp->m_log; @@ -271,7 +270,8 @@ xfs_log_done(xfs_mount_t *mp, * If we get an error, just continue and give back the log ticket. */ (((ticket->t_flags & XLOG_TIC_INITED) == 0) && - (xlog_commit_record(mp, ticket, &lsn)))) { + (xlog_commit_record(mp, ticket, + (xlog_in_core_t **)iclog, &lsn)))) { lsn = (xfs_lsn_t) -1; if (ticket->t_flags & XLOG_TIC_PERM_RESERV) { flags |= XFS_LOG_REL_PERM_RESERV; @@ -354,21 +354,39 @@ xfs_log_force(xfs_mount_t *mp, * been synced to disk, we add the callback to the callback list of the * in-core log. */ -void +int xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ - xfs_lsn_t lsn, /* lsn looking for */ + void *iclog_hndl, /* iclog to hang callback off */ xfs_log_callback_t *cb) { xlog_t *log = mp->m_log; - int abortflg; + xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; + int abortflg, spl; #if defined(DEBUG) || defined(XLOG_NOLOG) if (! xlog_debug && xlog_devt == log->l_dev) - return; + return 0; #endif cb->cb_next = 0; - if (xlog_state_lsn_is_synced(log, lsn, cb, &abortflg)) + spl = LOG_LOCK(log); + abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); + if (!abortflg) { + ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) || + (iclog->ic_state == XLOG_STATE_WANT_SYNC)); + cb->cb_next = 0; + *(iclog->ic_callback_tail) = cb; + iclog->ic_callback_tail = &(cb->cb_next); + } + LOG_UNLOCK(log, spl); + if (!abortflg) { + if (xlog_state_release_iclog(log, iclog)) { + xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); + return EIO; + } + } else { cb->cb_func(cb->cb_arg, abortflg); + } + return 0; } /* xfs_log_notify */ @@ -611,7 +629,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) /* remove inited flag */ ((xlog_ticket_t *)tic)->t_flags = 0; error = xlog_write(mp, reg, 1, tic, &lsn, - XLOG_UNMOUNT_TRANS); + NULL, XLOG_UNMOUNT_TRANS); /* * At this point, we're umounting anyway, * so there's no point in transitioning log state @@ -717,7 +735,7 @@ xfs_log_write(xfs_mount_t * mp, if (XLOG_FORCED_SHUTDOWN(log)) return XFS_ERROR(EIO); - if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, 0))) { + if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); } return (error); @@ -1259,6 +1277,7 @@ xlog_alloc_log(xfs_mount_t *mp, STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket, + xlog_in_core_t **iclog, xfs_lsn_t *commitlsnp) { int error; @@ -1267,8 +1286,9 @@ xlog_commit_record(xfs_mount_t *mp, reg[0].i_addr = 0; reg[0].i_len = 0; + ASSERT_ALWAYS(iclog); if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, - XLOG_COMMIT_TRANS))) { + iclog, XLOG_COMMIT_TRANS))) { xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); } return (error); @@ -1614,6 +1634,7 @@ xlog_write(xfs_mount_t * mp, int nentries, xfs_log_ticket_t tic, xfs_lsn_t *start_lsn, + xlog_in_core_t **commit_iclog, uint flags) { xlog_t *log = mp->m_log; @@ -1776,7 +1797,10 @@ xlog_write(xfs_mount_t * mp, if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) { xlog_state_want_sync(log, iclog); - if ((error = xlog_state_release_iclog(log, iclog))) + if (commit_iclog) { + ASSERT(flags & XLOG_COMMIT_TRANS); + *commit_iclog = iclog; + } else if ((error = xlog_state_release_iclog(log, iclog))) return (error); if (index == nentries) return 0; /* we are done */ @@ -1788,6 +1812,11 @@ xlog_write(xfs_mount_t * mp, } /* for (index = 0; index < nentries; ) */ ASSERT(len == 0); + if (commit_iclog) { + ASSERT(flags & XLOG_COMMIT_TRANS); + *commit_iclog = iclog; + return 0; + } return (xlog_state_release_iclog(log, iclog)); } /* xlog_write */ @@ -2060,6 +2089,12 @@ xlog_state_do_callback( if (!(iclog->ic_state & XLOG_STATE_IOERROR)) iclog->ic_state = XLOG_STATE_DIRTY; + /* + * Transition from DIRTY to ACTIVE if applicable. + * NOP if STATE_IOERROR. + */ + xlog_state_clean_log(log); + /* wake up threads waiting in xfs_log_force() */ sv_broadcast(&iclog->ic_forcesema); @@ -2098,12 +2133,6 @@ xlog_state_do_callback( } #endif - /* - * Transition from DIRTY to ACTIVE if applicable. NOP if - * STATE_IOERROR. - */ - xlog_state_clean_log(log); - if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { flushcnt = log->l_flushcnt; log->l_flushcnt = 0; @@ -2655,52 +2684,6 @@ xlog_ungrant_log_space(xlog_t *log, /* - * If the lsn is not found or the iclog with the lsn is in the callback - * state, we need to call the function directly. This is done outside - * this function's scope. Otherwise, we insert the callback at the end - * of the iclog's callback list. - */ -int -xlog_state_lsn_is_synced(xlog_t *log, - xfs_lsn_t lsn, - xfs_log_callback_t *cb, - int *abortflg) -{ - xlog_in_core_t *iclog; - SPLDECL(s); - int lsn_is_synced = 1; - - *abortflg = 0; - s = LOG_LOCK(log); - - iclog = log->l_iclog; - do { - if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) { - iclog = iclog->ic_next; - continue; - } else { - if (iclog->ic_state & XLOG_STATE_DIRTY) /* call it*/ - break; - - if (iclog->ic_state & XLOG_STATE_IOERROR) { - *abortflg = XFS_LI_ABORTED; - break; - } - /* insert callback onto end of list */ - cb->cb_next = 0; - *(iclog->ic_callback_tail) = cb; - iclog->ic_callback_tail = &(cb->cb_next); - lsn_is_synced = 0; - break; - } - } while (iclog != log->l_iclog); - - LOG_UNLOCK(log, s); - return lsn_is_synced; -} /* xlog_state_lsn_is_synced */ - - -/* * Atomically put back used ticket. */ void diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index fec59717ab2e..68a3ea4fe730 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -148,6 +148,7 @@ typedef struct xfs_log_callback { struct xfs_mount; xfs_lsn_t xfs_log_done(struct xfs_mount *mp, xfs_log_ticket_t ticket, + void **iclog, uint flags); int xfs_log_force(struct xfs_mount *mp, xfs_lsn_t lsn, @@ -160,8 +161,8 @@ int xfs_log_mount(struct xfs_mount *mp, int xfs_log_mount_finish(struct xfs_mount *mp, int); void xfs_log_move_tail(struct xfs_mount *mp, xfs_lsn_t tail_lsn); -void xfs_log_notify(struct xfs_mount *mp, - xfs_lsn_t lsn, +int xfs_log_notify(struct xfs_mount *mp, + void *iclog, xfs_log_callback_t *callback_entry); int xfs_log_reserve(struct xfs_mount *mp, int length, diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 6e8dd532c1dc..355e283f8ab6 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -285,7 +285,7 @@ undo_log: } else { log_flags = 0; } - xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags); + xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags); tp->t_ticket = NULL; tp->t_log_res = 0; tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES; @@ -669,6 +669,7 @@ xfs_trans_commit( #if defined(XLOG_NOLOG) || defined(DEBUG) static xfs_lsn_t trans_lsn = 1; #endif + void *commit_iclog; int shutdown; commit_lsn = -1; @@ -706,7 +707,8 @@ shut_us_down: xfs_trans_unreserve_and_mod_dquots(tp); } if (tp->t_ticket) { - commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags); + commit_lsn = xfs_log_done(mp, tp->t_ticket, + NULL, log_flags); if (commit_lsn == -1 && !shutdown) shutdown = XFS_ERROR(EIO); } @@ -773,7 +775,7 @@ shut_us_down: #if defined(XLOG_NOLOG) || defined(DEBUG) if (xlog_debug) { commit_lsn = xfs_log_done(mp, tp->t_ticket, - log_flags); + &commit_iclog, log_flags); } else { commit_lsn = 0; tp->t_lsn = trans_lsn++; @@ -785,7 +787,7 @@ shut_us_down: * any time. However, all the items associated with the transaction * are still locked and pinned in memory. */ - commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags); + commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); #endif tp->t_commit_lsn = commit_lsn; @@ -845,21 +847,28 @@ shut_us_down: if (xlog_debug) { tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; tp->t_logcb.cb_arg = tp; - xfs_log_notify(mp, commit_lsn, &(tp->t_logcb)); + error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); } else { xfs_trans_committed(tp, 0); } #else tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; tp->t_logcb.cb_arg = tp; - xfs_log_notify(mp, commit_lsn, &(tp->t_logcb)); + + /* We need to pass the iclog buffer which was used for the + * transaction commit record into this function, attach + * the callback to it, and then release it. This will guarantee + * that we do callbacks on the transaction in the correct order. + */ + error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); #endif /* * If the transaction needs to be synchronous, then force the * log out now and wait for it. */ if (sync) { - error = xfs_log_force(mp, commit_lsn, + if (!error) + error = xfs_log_force(mp, commit_lsn, XFS_LOG_FORCE | XFS_LOG_SYNC); XFS_STATS_INC(xfsstats.xs_trans_sync); } else { @@ -1070,7 +1079,7 @@ xfs_trans_cancel( } else { log_flags = 0; } - xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags); + xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags); } xfs_trans_free_items(tp, flags); xfs_trans_free_busy(tp); @@ -1262,8 +1271,11 @@ xfs_trans_chunk_committed( /* * Now that we've repositioned the item in the AIL, - * unpin it so it can be flushed. + * unpin it so it can be flushed. Pass information + * about buffer stale state down from the log item + * flags, if anyone else stales the buffer we do not + * want to pay any attention to it. */ - IOP_UNPIN(lip); + IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE); } } diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index b02ac92c56a2..ed091cb1ce99 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -170,7 +170,7 @@ typedef struct xfs_item_ops { uint (*iop_size)(xfs_log_item_t *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); void (*iop_pin)(xfs_log_item_t *); - void (*iop_unpin)(xfs_log_item_t *); + void (*iop_unpin)(xfs_log_item_t *, int); void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); uint (*iop_trylock)(xfs_log_item_t *); void (*iop_unlock)(xfs_log_item_t *); @@ -184,7 +184,7 @@ typedef struct xfs_item_ops { #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) -#define IOP_UNPIN(ip) (*(ip)->li_ops->iop_unpin)(ip) +#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) #define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) #define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) @@ -222,6 +222,7 @@ typedef struct xfs_log_item_desc { #define XFS_LID_DIRTY 0x1 #define XFS_LID_PINNED 0x2 #define XFS_LID_SYNC_UNLOCK 0x4 +#define XFS_LID_BUF_STALE 0x8 /* * This structure is used to maintain a chunk list of log_item_desc diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index adcc0b050e5b..0be1285cbc42 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -796,6 +796,7 @@ xfs_trans_log_buf(xfs_trans_t *tp, tp->t_flags |= XFS_TRANS_DIRTY; lidp->lid_flags |= XFS_LID_DIRTY; + lidp->lid_flags &= ~XFS_LID_BUF_STALE; bip->bli_flags |= XFS_BLI_LOGGED; xfs_buf_item_log(bip, first, last); xfs_buf_item_trace("BLOG", bip); @@ -882,7 +883,7 @@ xfs_trans_binval( bip->bli_format.blf_flags |= XFS_BLI_CANCEL; memset((char *)(bip->bli_format.blf_data_map), 0, (bip->bli_format.blf_map_size * sizeof(uint))); - lidp->lid_flags |= XFS_LID_DIRTY; + lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE; tp->t_flags |= XFS_TRANS_DIRTY; xfs_buftrace("XFS_BINVAL", bp); xfs_buf_item_trace("BINVAL", bip); diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index f86e0f65def0..8073c0ce988f 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -873,7 +873,6 @@ xfs_syncsub( boolean_t mount_locked; boolean_t vnode_refed; int preempt; - int do_mmap_flush; xfs_dinode_t *dip; xfs_buf_log_item_t *bip; xfs_iptr_t *ipointer; @@ -944,8 +943,6 @@ xfs_syncsub( fflag = XFS_B_DELWRI; if (flags & SYNC_WAIT) fflag = 0; /* synchronous overrides all */ - do_mmap_flush = (flags & (SYNC_DELWRI|SYNC_BDFLUSH)) != - (SYNC_DELWRI|SYNC_BDFLUSH); base_lock_flags = XFS_ILOCK_SHARED; if (flags & (SYNC_DELWRI | SYNC_CLOSE)) { @@ -1177,12 +1174,8 @@ xfs_syncsub( * across calls to the buffer cache. */ xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (do_mmap_flush) { - VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, - fflag, FI_NONE, error); - } else { - filemap_fdatawrite(LINVFS_GET_IP(vp)->i_mapping); - } + VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, + fflag, FI_NONE, error); xfs_ilock(ip, XFS_ILOCK_SHARED); } diff --git a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c index 63ff6caa24b8..b3bffa3fd768 100644 --- a/fs/xfs/xfsidbg.c +++ b/fs/xfs/xfsidbg.c @@ -5248,6 +5248,7 @@ xfsidbg_xtp(xfs_trans_t *tp) "dirty", /* 0x1 */ "pinned", /* 0x2 */ "sync unlock", /* 0x4 */ + "buf stale", /* 0x8 */ 0 }; diff --git a/include/asm-alpha/core_irongate.h b/include/asm-alpha/core_irongate.h index 4a4e6fa4c0e8..9b9a49feb51b 100644 --- a/include/asm-alpha/core_irongate.h +++ b/include/asm-alpha/core_irongate.h @@ -50,13 +50,14 @@ typedef struct { igcsr32 bacsr10; /* 0x40 - base address chip selects */ igcsr32 bacsr32; /* 0x44 - base address chip selects */ - igcsr32 bacsr54; /* 0x48 - base address chip selects */ + igcsr32 bacsr54_eccms761; /* 0x48 - 751: base addr. chip selects + 761: ECC, mode/status */ igcsr32 rsrvd2[1]; /* 0x4C-0x4F reserved */ igcsr32 drammap; /* 0x50 - address mapping control */ igcsr32 dramtm; /* 0x54 - timing, driver strength */ - igcsr32 dramms; /* 0x58 - ECC, mode/status */ + igcsr32 dramms; /* 0x58 - DRAM mode/status */ igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */ @@ -73,7 +74,10 @@ typedef struct { igcsr32 pciarb; /* 0x84 - PCI arbitration control */ igcsr32 pcicfg; /* 0x88 - PCI config status */ - igcsr32 rsrvd6[5]; /* 0x8C-0x9F reserved */ + igcsr32 rsrvd6[4]; /* 0x8C-0x9B reserved */ + + igcsr32 pci_mem; /* 0x9C - PCI top of memory, + 761 only */ /* AGP (bus 1) control registers */ igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */ @@ -102,6 +106,7 @@ typedef struct { } Irongate1; +extern igcsr32 *IronECC; /* * Memory spaces: diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h index 9513f35aa8a1..033597e3e0ab 100644 --- a/include/asm-alpha/elf.h +++ b/include/asm-alpha/elf.h @@ -52,53 +52,25 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_PLAT_INIT(_r) _r->r0 = 0 -/* Use the same format as the OSF/1 procfs interface. The register - layout is sane. However, since dump_thread() creates the funky - layout that ECOFF coredumps want, we need to undo that layout here. - Eventually, it would be nice if the ECOFF core-dump had to do the - translation, then ELF_CORE_COPY_REGS() would become trivial and - faster. */ - -#define ELF_CORE_COPY_REGS(_dest,_regs) \ -{ \ - extern void dump_thread(struct pt_regs *, struct user *); \ - struct user _dump; \ - \ - dump_thread(_regs, &_dump); \ - _dest[ 0] = _dump.regs[EF_V0]; \ - _dest[ 1] = _dump.regs[EF_T0]; \ - _dest[ 2] = _dump.regs[EF_T1]; \ - _dest[ 3] = _dump.regs[EF_T2]; \ - _dest[ 4] = _dump.regs[EF_T3]; \ - _dest[ 5] = _dump.regs[EF_T4]; \ - _dest[ 6] = _dump.regs[EF_T5]; \ - _dest[ 7] = _dump.regs[EF_T6]; \ - _dest[ 8] = _dump.regs[EF_T7]; \ - _dest[ 9] = _dump.regs[EF_S0]; \ - _dest[10] = _dump.regs[EF_S1]; \ - _dest[11] = _dump.regs[EF_S2]; \ - _dest[12] = _dump.regs[EF_S3]; \ - _dest[13] = _dump.regs[EF_S4]; \ - _dest[14] = _dump.regs[EF_S5]; \ - _dest[15] = _dump.regs[EF_S6]; \ - _dest[16] = _dump.regs[EF_A0]; \ - _dest[17] = _dump.regs[EF_A1]; \ - _dest[18] = _dump.regs[EF_A2]; \ - _dest[19] = _dump.regs[EF_A3]; \ - _dest[20] = _dump.regs[EF_A4]; \ - _dest[21] = _dump.regs[EF_A5]; \ - _dest[22] = _dump.regs[EF_T8]; \ - _dest[23] = _dump.regs[EF_T9]; \ - _dest[24] = _dump.regs[EF_T10]; \ - _dest[25] = _dump.regs[EF_T11]; \ - _dest[26] = _dump.regs[EF_RA]; \ - _dest[27] = _dump.regs[EF_T12]; \ - _dest[28] = _dump.regs[EF_AT]; \ - _dest[29] = _dump.regs[EF_GP]; \ - _dest[30] = _dump.regs[EF_SP]; \ - _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \ - _dest[32] = _dump.regs[EF_PS]; \ -} +/* The registers are layed out in pt_regs for PAL and syscall + convenience. Re-order them for the linear elf_gregset_t. */ + +extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, + struct thread_info *ti); +#define ELF_CORE_COPY_REGS(DEST, REGS) \ + dump_elf_thread(DEST, REGS, current_thread_info()); + +/* Similar, but for a thread other than current. */ + +extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task); +#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \ + dump_elf_task(*(DEST), TASK) + +/* Similar, but for the FP registers. */ + +extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task); +#define ELF_CORE_COPY_FPREGS(TASK, DEST) \ + dump_elf_task_fp(*(DEST), TASK) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This is trivial on Alpha, diff --git a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h index 10061ab1c9ad..e7e1f7c8d148 100644 --- a/include/asm-alpha/kmap_types.h +++ b/include/asm-alpha/kmap_types.h @@ -23,8 +23,8 @@ D(7) KM_PTE0, D(8) KM_PTE1, D(9) KM_IRQ0, D(10) KM_IRQ1, -D(11) KM_CRYPTO_USER, -D(12) KM_CRYPTO_SOFTIRQ, +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, D(13) KM_TYPE_NR }; diff --git a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h index 074daa9353ae..742b68802fd0 100644 --- a/include/asm-alpha/topology.h +++ b/include/asm-alpha/topology.h @@ -6,7 +6,7 @@ #include <asm/machvec.h> #ifdef CONFIG_NUMA -static inline int __cpu_to_node(int cpu) +static inline int cpu_to_node(int cpu) { int node; @@ -23,13 +23,13 @@ static inline int __cpu_to_node(int cpu) return node; } -static inline int __node_to_cpu_mask(int node) +static inline int node_to_cpumask(int node) { unsigned long node_cpu_mask = 0; int cpu; for(cpu = 0; cpu < NR_CPUS; cpu++) { - if (cpu_online(cpu) && (__cpu_to_node(cpu) == node)) + if (cpu_online(cpu) && (cpu_to_node(cpu) == node)) node_cpu_mask |= 1UL << cpu; } @@ -40,8 +40,11 @@ static inline int __node_to_cpu_mask(int node) return node_cpu_mask; } -# define __node_to_memblk(node) (node) -# define __memblk_to_node(memblk) (memblk) +# define node_to_memblk(node) (node) +# define memblk_to_node(memblk) (memblk) + +/* Cross-node load balancing interval. */ +# define NODE_BALANCE_RATE 10 #else /* CONFIG_NUMA */ # include <asm-generic/topology.h> diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h index 990654bc86ec..955763b04857 100644 --- a/include/asm-generic/topology.h +++ b/include/asm-generic/topology.h @@ -29,23 +29,23 @@ /* Other architectures wishing to use this simple topology API should fill in the below functions as appropriate in their own <asm/topology.h> file. */ -#ifndef __cpu_to_node -#define __cpu_to_node(cpu) (0) +#ifndef cpu_to_node +#define cpu_to_node(cpu) (0) #endif -#ifndef __memblk_to_node -#define __memblk_to_node(memblk) (0) +#ifndef memblk_to_node +#define memblk_to_node(memblk) (0) #endif -#ifndef __parent_node -#define __parent_node(node) (0) +#ifndef parent_node +#define parent_node(node) (0) #endif -#ifndef __node_to_first_cpu -#define __node_to_first_cpu(node) (0) +#ifndef node_to_cpumask +#define node_to_cpumask(node) (cpu_online_map) #endif -#ifndef __node_to_cpu_mask -#define __node_to_cpu_mask(node) (cpu_online_map) +#ifndef node_to_first_cpu +#define node_to_first_cpu(node) (0) #endif -#ifndef __node_to_memblk -#define __node_to_memblk(node) (0) +#ifndef node_to_memblk +#define node_to_memblk(node) (0) #endif /* Cross-node load balancing interval. */ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 7563b5730aaa..0f09f5b73a69 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -20,10 +20,24 @@ } \ \ /* Kernel symbol table: GPL-only symbols */ \ - __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) { \ - __start___gpl_ksymtab = .; \ - *(__gpl_ksymtab) \ - __stop___gpl_ksymtab = .; \ + __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ + __start___ksymtab_gpl = .; \ + *(__ksymtab_gpl) \ + __stop___ksymtab_gpl = .; \ + } \ + \ + /* Kernel symbol table: Normal symbols */ \ + __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ + __start___kcrctab = .; \ + *(__kcrctab) \ + __stop___kcrctab = .; \ + } \ + \ + /* Kernel symbol table: GPL-only symbols */ \ + __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ + __start___kcrctab_gpl = .; \ + *(__kcrctab_gpl) \ + __stop___kcrctab_gpl = .; \ } \ \ /* Kernel symbol table: strings */ \ diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h index 47aa0c17c49a..485c1d8a8db5 100644 --- a/include/asm-i386/apicdef.h +++ b/include/asm-i386/apicdef.h @@ -115,7 +115,7 @@ #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) -#ifdef CONFIG_X86_NUMA +#ifdef CONFIG_NUMA #define MAX_IO_APICS 32 #else #define MAX_IO_APICS 8 diff --git a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h index 50b1d4439a44..b2b79ebda49b 100644 --- a/include/asm-i386/cpu.h +++ b/include/asm-i386/cpu.h @@ -17,7 +17,7 @@ static inline int arch_register_cpu(int num){ struct node *parent = NULL; #ifdef CONFIG_NUMA - parent = &node_devices[__cpu_to_node(num)].node; + parent = &node_devices[cpu_to_node(num)].node; #endif /* CONFIG_NUMA */ return register_cpu(&cpu_devices[num].cpu, num, parent); diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h index 9ee55b1dea1f..dda910c4f1ba 100644 --- a/include/asm-i386/kmap_types.h +++ b/include/asm-i386/kmap_types.h @@ -22,8 +22,8 @@ D(8) KM_PTE1, D(9) KM_PTE2, D(10) KM_IRQ0, D(11) KM_IRQ1, -D(12) KM_CRYPTO_USER, -D(13) KM_CRYPTO_SOFTIRQ, +D(12) KM_SOFTIRQ0, +D(13) KM_SOFTIRQ1, D(14) KM_TYPE_NR }; diff --git a/include/asm-i386/memblk.h b/include/asm-i386/memblk.h index a3a23052a93a..bd8187e358bb 100644 --- a/include/asm-i386/memblk.h +++ b/include/asm-i386/memblk.h @@ -14,7 +14,7 @@ struct i386_memblk { extern struct i386_memblk memblk_devices[MAX_NR_MEMBLKS]; static inline int arch_register_memblk(int num){ - int p_node = __memblk_to_node(num); + int p_node = memblk_to_node(num); return register_memblk(&memblk_devices[num].memblk, num, &node_devices[p_node].node); diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h index 6d9f3cf88d66..eae3564e686f 100644 --- a/include/asm-i386/mmzone.h +++ b/include/asm-i386/mmzone.h @@ -57,25 +57,47 @@ extern struct pglist_data *node_data[]; #define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map) #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) -#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ - NODE_DATA(nid)->node_size) +#define node_end_pfn(nid) \ +({ \ + pg_data_t *__pgdat = NODE_DATA(nid); \ + __pgdat->node_start_pfn + __pgdat->node_size; \ +}) -#define local_mapnr(kvaddr) \ - ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) ) +#define local_mapnr(kvaddr) \ +({ \ + unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \ + (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \ +}) -#define kern_addr_valid(kaddr) test_bit(local_mapnr(kaddr), \ - NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap) +#define kern_addr_valid(kaddr) \ +({ \ + unsigned long __kaddr = (unsigned long)(kaddr); \ + pg_data_t *__pgdat = NODE_DATA(kvaddr_to_nid(__kaddr)); \ + test_bit(local_mapnr(__kaddr), __pgdat->valid_addr_bitmap); \ +}) -#define pfn_to_page(pfn) (node_mem_map(pfn_to_nid(pfn)) + node_localnr(pfn, pfn_to_nid(pfn))) -#define page_to_pfn(page) ((page - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn) +#define pfn_to_page(pfn) \ +({ \ + unsigned long __pfn = pfn; \ + int __node = pfn_to_nid(__pfn); \ + &node_mem_map(__node)[node_localnr(__pfn,__node)]; \ +}) + +#define page_to_pfn(pg) \ +({ \ + struct page *__page = pg; \ + struct zone *__zone = page_zone(__page); \ + (unsigned long)(__page - __zone->zone_mem_map) \ + + __zone->zone_start_pfn; \ +}) #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) /* * pfn_valid should be made as fast as possible, and the current definition * is valid for machines that are NUMA, but still contiguous, which is what * is currently supported. A more generalised, but slower definition would * be something like this - mbligh: - * ( pfn_to_pgdat(pfn) && (pfn < node_end_pfn(pfn_to_nid(pfn))) ) + * ( pfn_to_pgdat(pfn) && ((pfn) < node_end_pfn(pfn_to_nid(pfn))) ) */ -#define pfn_valid(pfn) (pfn < num_physpages) +#define pfn_valid(pfn) ((pfn) < num_physpages) #endif /* CONFIG_DISCONTIGMEM */ #endif /* _ASM_MMZONE_H_ */ diff --git a/include/asm-i386/node.h b/include/asm-i386/node.h index 26836eb7be10..104f10b2bbf7 100644 --- a/include/asm-i386/node.h +++ b/include/asm-i386/node.h @@ -13,7 +13,7 @@ struct i386_node { extern struct i386_node node_devices[MAX_NUMNODES]; static inline int arch_register_node(int num){ - int p_node = __parent_node(num); + int p_node = parent_node(num); struct node *parent = NULL; if (p_node != num) diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h index a44e266934f6..640ca76d0ad2 100644 --- a/include/asm-i386/pgalloc.h +++ b/include/asm-i386/pgalloc.h @@ -20,11 +20,11 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *p * Allocate and free page tables. */ -extern pgd_t *pgd_alloc(struct mm_struct *); -extern void pgd_free(pgd_t *pgd); +pgd_t *pgd_alloc(struct mm_struct *); +void pgd_free(pgd_t *pgd); -extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); -extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); +pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +struct page *pte_alloc_one(struct mm_struct *, unsigned long); static inline void pte_free_kernel(pte_t *pte) { diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 0751ebf5d340..f06b393c7071 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -115,6 +115,4 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot)); } -extern struct kmem_cache_s *pae_pgd_cachep; - #endif /* _I386_PGTABLE_3LEVEL_H */ diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 0213fa88c792..c1c55b2d9682 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -41,22 +41,13 @@ extern unsigned long empty_zero_page[1024]; #ifndef __ASSEMBLY__ #if CONFIG_X86_PAE # include <asm/pgtable-3level.h> - -/* - * Need to initialise the X86 PAE caches - */ -extern void pgtable_cache_init(void); - #else # include <asm/pgtable-2level.h> +#endif -/* - * No page table caches to initialise - */ -#define pgtable_cache_init() do { } while (0) +void pgtable_cache_init(void); #endif -#endif #define __beep() asm("movb $0x3,%al; outb %al,$0x61") diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index 53d8a01ef8a7..be697216b1e3 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h @@ -34,32 +34,32 @@ extern volatile unsigned long node_2_cpu_mask[]; extern volatile int cpu_2_node[]; /* Returns the number of the node containing CPU 'cpu' */ -static inline int __cpu_to_node(int cpu) +static inline int cpu_to_node(int cpu) { return cpu_2_node[cpu]; } /* Returns the number of the node containing MemBlk 'memblk' */ -#define __memblk_to_node(memblk) (memblk) +#define memblk_to_node(memblk) (memblk) /* Returns the number of the node containing Node 'node'. This architecture is flat, so it is a pretty simple function! */ -#define __parent_node(node) (node) +#define parent_node(node) (node) /* Returns a bitmask of CPUs on Node 'node'. */ -static inline unsigned long __node_to_cpu_mask(int node) +static inline unsigned long node_to_cpumask(int node) { return node_2_cpu_mask[node]; } /* Returns the number of the first CPU on Node 'node'. */ -static inline int __node_to_first_cpu(int node) +static inline int node_to_first_cpu(int node) { - return __ffs(__node_to_cpu_mask(node)); + return __ffs(node_to_cpumask(node)); } /* Returns the number of the first MemBlk on Node 'node' */ -#define __node_to_memblk(node) (node) +#define node_to_memblk(node) (node) /* Cross-node load balancing interval. */ #define NODE_BALANCE_RATE 100 diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index fb5a97ec22f5..d21b3a8a4f4e 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -255,6 +255,8 @@ #define __NR_io_getevents 247 #define __NR_io_submit 248 #define __NR_io_cancel 249 +#define __NR_fadvise64 250 + #define __NR_exit_group 252 #define __NR_lookup_dcookie 253 #define __NR_epoll_create 254 diff --git a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h index 77187f614170..d54e19055e6c 100644 --- a/include/asm-ia64/kmap_types.h +++ b/include/asm-ia64/kmap_types.h @@ -21,8 +21,8 @@ D(7) KM_PTE0, D(8) KM_PTE1, D(9) KM_IRQ0, D(10) KM_IRQ1, -D(11) KM_CRYPTO_USER, -D(12) KM_CRYPTO_SOFTIRQ, +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, D(13) KM_TYPE_NR }; diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 22a5aaca8d21..b154e116980e 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h @@ -21,25 +21,25 @@ /* * Returns the number of the node containing CPU 'cpu' */ -#define __cpu_to_node(cpu) (int)(cpu_to_node_map[cpu]) +#define cpu_to_node(cpu) (int)(cpu_to_node_map[cpu]) /* * Returns a bitmask of CPUs on Node 'node'. */ -#define __node_to_cpu_mask(node) (node_to_cpu_mask[node]) +#define node_to_cpumask(node) (node_to_cpumask[node]) #else -#define __cpu_to_node(cpu) (0) -#define __node_to_cpu_mask(node) (phys_cpu_present_map) +#define cpu_to_node(cpu) (0) +#define node_to_cpumask(node) (phys_cpu_present_map) #endif /* * Returns the number of the node containing MemBlk 'memblk' */ #ifdef CONFIG_ACPI_NUMA -#define __memblk_to_node(memblk) (node_memblk[memblk].nid) +#define memblk_to_node(memblk) (node_memblk[memblk].nid) #else -#define __memblk_to_node(memblk) (memblk) +#define memblk_to_node(memblk) (memblk) #endif /* @@ -47,18 +47,18 @@ * Not implemented here. Multi-level hierarchies detected with * the help of node_distance(). */ -#define __parent_node(nid) (nid) +#define parent_node(nid) (nid) /* * Returns the number of the first CPU on Node 'node'. */ -#define __node_to_first_cpu(node) (__ffs(__node_to_cpu_mask(node))) +#define node_to_first_cpu(node) (__ffs(node_to_cpumask(node))) /* * Returns the number of the first MemBlk on Node 'node' * Should be fixed when IA64 discontigmem goes in. */ -#define __node_to_memblk(node) (node) +#define node_to_memblk(node) (node) /* Cross-node load balancing interval. */ #define NODE_BALANCE_RATE 10 diff --git a/include/asm-mips64/topology.h b/include/asm-mips64/topology.h index fe5988686b1d..04b0168e8736 100644 --- a/include/asm-mips64/topology.h +++ b/include/asm-mips64/topology.h @@ -3,6 +3,6 @@ #include <asm/mmzone.h> -#define __cpu_to_node(cpu) (cputocnode(cpu)) +#define cpu_to_node(cpu) (cputocnode(cpu)) #endif /* _ASM_MIPS64_TOPOLOGY_H */ diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index 99e163032f14..c2eed7aa218b 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h @@ -257,7 +257,14 @@ static __inline__ int ffs(int x) * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ - +#define hweight64(x) \ +({ \ + unsigned long __x = (x); \ + unsigned int __w; \ + __w = generic_hweight32((unsigned int) __x); \ + __w += generic_hweight32((unsigned int) (__x>>32)); \ + __w; \ +}) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index 6b146922ea10..4cbe08f1b22e 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h @@ -72,4 +72,24 @@ struct compat_flock { compat_pid_t l_pid; }; +struct compat_statfs { + s32 f_type; + s32 f_bsize; + s32 f_blocks; + s32 f_bfree; + s32 f_bavail; + s32 f_files; + s32 f_ffree; + __kernel_fsid_t f_fsid; + s32 f_namelen; + s32 f_spare[6]; +}; + +typedef u32 compat_old_sigset_t; /* at least 32 bits */ + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW BITS_PER_LONG + +typedef u32 compat_sigset_word; + #endif /* _ASM_PARISC_COMPAT_H */ diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index 2428762027b3..a4c2bf437b61 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -203,7 +203,6 @@ parisc_walk_tree(struct device *dev) struct parisc_device; struct ioc; void * ccio_get_iommu(const struct parisc_device *dev); -struct pci_dev * ccio_get_fake(const struct parisc_device *dev); int ccio_request_resource(const struct parisc_device *dev, struct resource *res); int ccio_allocate_resource(const struct parisc_device *dev, @@ -213,7 +212,6 @@ int ccio_allocate_resource(const struct parisc_device *dev, void *alignf_data); #else /* !CONFIG_IOMMU_CCIO */ #define ccio_get_iommu(dev) NULL -#define ccio_get_fake(dev) NULL #define ccio_request_resource(dev, res) request_resource(&iomem_resource, res) #define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \ allocate_resource(&iomem_resource, res, size, min, max, \ diff --git a/include/asm-parisc/module.h b/include/asm-parisc/module.h index f6c2466621f4..acf6770cd5d3 100644 --- a/include/asm-parisc/module.h +++ b/include/asm-parisc/module.h @@ -7,10 +7,14 @@ #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define Elf_Ehdr Elf64_Ehdr +#define Elf_Addr Elf64_Addr +#define Elf_Rela Elf64_Rela #else #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +#define Elf_Addr Elf32_Addr +#define Elf_Rela Elf32_Rela #endif #define module_map(x) vmalloc(x) @@ -20,6 +24,10 @@ struct mod_arch_specific { + unsigned long got_offset; + unsigned long fdesc_offset, fdesc_count; + unsigned long stub_offset; + unsigned long stub_count; }; #endif /* _ASM_PARISC_MODULE_H */ diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h index b43525324dc1..cda89e45e05f 100644 --- a/include/asm-parisc/smp.h +++ b/include/asm-parisc/smp.h @@ -12,6 +12,7 @@ #define PDC_OS_BOOT_RENDEZVOUS_HI 0x28 #ifndef ASSEMBLY +#include <linux/bitops.h> #include <linux/threads.h> /* for NR_CPUS */ typedef unsigned long address_t; @@ -53,7 +54,7 @@ extern unsigned long cpu_present_mask; #define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) #define cpu_possible(cpu) (cpu_present_mask & (1<<(cpu))) - + extern inline unsigned int num_online_cpus(void) { return hweight32(cpu_online_map); diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h index 1a4813527e74..5ffc886ddabb 100644 --- a/include/asm-ppc/kmap_types.h +++ b/include/asm-ppc/kmap_types.h @@ -14,8 +14,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h index f8422429758a..fd1574648223 100644 --- a/include/asm-ppc64/kmap_types.h +++ b/include/asm-ppc64/kmap_types.h @@ -14,8 +14,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h index c3b4266c2ebf..ecc6cab2895e 100644 --- a/include/asm-ppc64/topology.h +++ b/include/asm-ppc64/topology.h @@ -5,7 +5,7 @@ #ifdef CONFIG_NUMA -static inline int __cpu_to_node(int cpu) +static inline int cpu_to_node(int cpu) { int node; @@ -19,7 +19,7 @@ static inline int __cpu_to_node(int cpu) return node; } -static inline int __node_to_first_cpu(int node) +static inline int node_to_first_cpu(int node) { int cpu; @@ -31,7 +31,7 @@ static inline int __node_to_first_cpu(int node) return -1; } -static inline unsigned long __node_to_cpu_mask(int node) +static inline unsigned long node_to_cpumask(int node) { int cpu; unsigned long mask = 0UL; @@ -51,12 +51,7 @@ static inline unsigned long __node_to_cpu_mask(int node) #else /* !CONFIG_NUMA */ -#define __cpu_to_node(cpu) (0) -#define __memblk_to_node(memblk) (0) -#define __parent_node(nid) (0) -#define __node_to_first_cpu(node) (0) -#define __node_to_cpu_mask(node) (cpu_online_map) -#define __node_to_memblk(node) (0) +#include <asm-generic/topology.h> #endif /* CONFIG_NUMA */ diff --git a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h index f8422429758a..fd1574648223 100644 --- a/include/asm-s390/kmap_types.h +++ b/include/asm-s390/kmap_types.h @@ -14,8 +14,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h index e3994705a3eb..04dd4468abaa 100644 --- a/include/asm-sparc/delay.h +++ b/include/asm-sparc/delay.h @@ -21,5 +21,6 @@ extern __inline__ void __delay(unsigned long loops) /* This is too messy with inline asm on the Sparc. */ extern void udelay(unsigned long usecs); +extern void ndelay(unsigned long usecs); #endif /* defined(__SPARC_DELAY_H) */ diff --git a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h index 05eeec6d17f3..e215f7104974 100644 --- a/include/asm-sparc/kmap_types.h +++ b/include/asm-sparc/kmap_types.h @@ -13,8 +13,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h index 90bf4b469138..4157717dd736 100644 --- a/include/asm-sparc64/delay.h +++ b/include/asm-sparc64/delay.h @@ -45,6 +45,19 @@ static __inline__ void __udelay(unsigned long usecs, unsigned long lps) __delay(usecs * HZ); } +extern __inline__ void __ndelay(unsigned long usecs, unsigned long lps) +{ + usecs *= 0x0000000000000005UL; /* 2**32 / 10000 */ + + __asm__ __volatile__( +" mulx %1, %2, %0\n" +" srlx %0, 32, %0\n" + : "=r" (usecs) + : "r" (usecs), "r" (lps)); + + __delay(usecs * HZ); +} + #ifdef CONFIG_SMP #define __udelay_val cpu_data[smp_processor_id()].udelay_val #else @@ -52,6 +65,7 @@ static __inline__ void __udelay(unsigned long usecs, unsigned long lps) #endif #define udelay(usecs) __udelay((usecs),__udelay_val) +#define ndelay(usecs) __ndelay((usecs),__udelay_val) #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h index 26c28fb7c8b7..34c1d3d9a3b0 100644 --- a/include/asm-sparc64/kmap_types.h +++ b/include/asm-sparc64/kmap_types.h @@ -17,8 +17,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-x86_64/kmap_types.h b/include/asm-x86_64/kmap_types.h index e87ef2e0f74d..7486338c6cea 100644 --- a/include/asm-x86_64/kmap_types.h +++ b/include/asm-x86_64/kmap_types.h @@ -11,8 +11,8 @@ enum km_type { KM_BIO_DST_IRQ, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 90171e65e989..c599ea36233b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -292,7 +292,7 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn; #define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) extern int init_emergency_isa_pool(void); -inline void blk_queue_bounce(request_queue_t *q, struct bio **bio); +extern void blk_queue_bounce(request_queue_t *q, struct bio **bio); #define rq_for_each_bio(bio, rq) \ if ((rq->bio)) \ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 5c29e2b58011..5178882ec4d1 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -131,9 +131,13 @@ struct cipher_tfm { int (*cit_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); int (*cit_encrypt)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); int (*cit_decrypt)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); void (*cit_xor_block)(u8 *dst, const u8 *src); }; @@ -274,19 +278,21 @@ static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, } static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_encrypt(tfm, sg, nsg); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); } static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_decrypt(tfm, sg, nsg); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); } static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, diff --git a/include/linux/elf.h b/include/linux/elf.h index bef237b527bd..1330ef61c75c 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -519,6 +519,174 @@ typedef struct { #define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */ +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + typedef struct elf32_rel { Elf32_Addr r_offset; diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h new file mode 100644 index 000000000000..6fc656dfb93d --- /dev/null +++ b/include/linux/fadvise.h @@ -0,0 +1,11 @@ +#ifndef FADVISE_H_INCLUDED +#define FADVISE_H_INCLUDED + +#define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +#define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ + +#endif /* FADVISE_H_INCLUDED */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 76b32526394f..9a17c9819ae9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1102,7 +1102,9 @@ extern int full_check_disk_change(struct block_device *); extern int __check_disk_change(dev_t); extern int invalidate_inodes(struct super_block *); extern int invalidate_device(kdev_t, int); -extern void invalidate_inode_pages(struct address_space *mapping); +unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end); +unsigned long invalidate_inode_pages(struct address_space *mapping); extern void invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 54bf03eaf3e7..c9fb5039e753 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -14,20 +14,17 @@ /* Action modifiers - doesn't change the zoning */ #define __GFP_WAIT 0x10 /* Can wait and reschedule? */ #define __GFP_HIGH 0x20 /* Should access emergency pools? */ -#define __GFP_IO 0x40 /* Can start low memory physical IO? */ -#define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */ -#define __GFP_FS 0x100 /* Can call down to low-level FS? */ -#define __GFP_COLD 0x200 /* Cache-cold page required */ -#define __GFP_NOWARN 0x400 /* Suppress page allocation failure warning */ - -#define GFP_NOHIGHIO ( __GFP_WAIT | __GFP_IO) -#define GFP_NOIO ( __GFP_WAIT) -#define GFP_NOFS ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO) +#define __GFP_IO 0x40 /* Can start physical IO? */ +#define __GFP_FS 0x80 /* Can call down to low-level FS? */ +#define __GFP_COLD 0x100 /* Cache-cold page required */ +#define __GFP_NOWARN 0x200 /* Suppress page allocation failure warning */ + #define GFP_ATOMIC (__GFP_HIGH) -#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) -#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM) -#define GFP_KERNEL ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) -#define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) +#define GFP_NOIO (__GFP_WAIT) +#define GFP_NOFS (__GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM) /* Flag - indicates that the buffer will be suitable for DMA. Ignored on some platforms, used as appropriate on others */ diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 3bf94e2205bd..325d91ba012a 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -18,7 +18,6 @@ void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); void huge_page_release(struct page *); -void hugetlb_release_key(struct hugetlb_key *); int hugetlb_report_meminfo(char *); int is_hugepage_mem_enough(size_t); diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 7367127511b3..c81b51bab1e3 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -2,15 +2,35 @@ #define _LINUX_JIFFIES_H #include <linux/types.h> +#include <linux/spinlock.h> +#include <asm/system.h> #include <asm/param.h> /* for HZ */ /* * The 64-bit value is not volatile - you MUST NOT read it - * without holding read_lock_irq(&xtime_lock) + * without holding read_lock_irq(&xtime_lock). + * get_jiffies_64() will do this for you as appropriate. */ extern u64 jiffies_64; extern unsigned long volatile jiffies; +static inline u64 get_jiffies_64(void) +{ +#if BITS_PER_LONG < 64 + extern rwlock_t xtime_lock; + unsigned long flags; + u64 tmp; + + read_lock_irqsave(&xtime_lock, flags); + tmp = jiffies_64; + read_unlock_irqrestore(&xtime_lock, flags); + return tmp; +#else + return (u64)jiffies; +#endif +} + + /* * These inlines deal with timer wrapping correctly. You are * strongly encouraged to use them diff --git a/include/linux/mm.h b/include/linux/mm.h index 50eb18eb0488..d2b99c852301 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -491,7 +491,9 @@ extern int do_munmap(struct mm_struct *, unsigned long, size_t); extern unsigned long do_brk(unsigned long, unsigned long); -static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev) +static inline void +__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev) { prev->vm_next = vma->vm_next; rb_erase(&vma->vm_rb, &mm->mm_rb); @@ -499,7 +501,8 @@ static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * v mm->mmap_cache = prev; } -static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags) +static inline int +can_vma_merge(struct vm_area_struct *vma, unsigned long vm_flags) { if (!vma->vm_file && vma->vm_flags == vm_flags) return 1; diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index bcb57ed21a8d..8db7ca4df8f2 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -257,7 +257,7 @@ static inline struct zone *next_zone(struct zone *zone) #include <asm/topology.h> /* Returns the number of the current Node. */ -#define numa_node_id() (__cpu_to_node(smp_processor_id())) +#define numa_node_id() (cpu_to_node(smp_processor_id())) #ifndef CONFIG_DISCONTIGMEM extern struct pglist_data contig_page_data; diff --git a/include/linux/module.h b/include/linux/module.h index 5b2fb9d19be3..53b4d2ea5987 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -33,12 +33,19 @@ #endif #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) + struct kernel_symbol { unsigned long value; const char *name; }; +struct modversion_info +{ + unsigned long crc; + char name[MODULE_NAME_LEN]; +}; + /* These are either module local, or the kernel's dummy ones. */ extern int init_module(void); extern void cleanup_module(void); @@ -92,7 +99,7 @@ extern const struct gtype##_id __mod_##gtype##_table \ */ #define MODULE_LICENSE(license) \ static const char __module_license[] \ - __attribute__((section(".init.license"))) = license + __attribute__((section(".init.license"), unused)) = license #else /* !MODULE */ @@ -119,6 +126,7 @@ struct kernel_symbol_group unsigned int num_syms; const struct kernel_symbol *syms; + const unsigned long *crcs; }; /* Given an address, look for it in the exception tables */ @@ -134,29 +142,52 @@ struct exception_table #ifdef CONFIG_MODULES + /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#ifdef __GENKSYMS__ + +/* genksyms doesn't handle GPL-only symbols yet */ +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL + +#else + +#ifdef CONFIG_MODVERSIONS +/* Mark the CRC weak since genksyms apparently decides not to + * generate a checksums for some symbols */ +#define __CRC_SYMBOL(sym, sec) \ + extern void *__crc_##sym __attribute__((weak)); \ + static const unsigned long __kcrctab_##sym \ + __attribute__((section("__kcrctab" sec), unused)) \ + = (unsigned long) &__crc_##sym; +#else +#define __CRC_SYMBOL(sym, sec) +#endif + /* For every exported symbol, place a struct in the __ksymtab section */ -#define EXPORT_SYMBOL(sym) \ +#define __EXPORT_SYMBOL(sym, sec) \ + __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__ksymtab"))) \ + __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } -#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL(sym) \ + __EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL_GPL(sym) \ - static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"))) \ - = MODULE_SYMBOL_PREFIX #sym; \ - static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__gpl_ksymtab"))) \ - = { (unsigned long)&sym, __kstrtab_##sym } + __EXPORT_SYMBOL(sym, "_gpl") + +#endif + +/* We don't mangle the actual symbol anymore, so no need for + * special casing EXPORT_SYMBOL_NOVERS */ +#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) struct module_ref { diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index a50e09ff79ea..0327a8421c9d 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -97,15 +97,20 @@ struct page_state { unsigned long pswpin; /* swap reads */ unsigned long pswpout; /* swap writes */ unsigned long pgalloc; /* page allocations */ + unsigned long pgfree; /* page freeings */ unsigned long pgactivate; /* pages moved inactive->active */ unsigned long pgdeactivate; /* pages moved active->inactive */ unsigned long pgfault; /* faults (major+minor) */ unsigned long pgmajfault; /* faults (major only) */ + unsigned long pgscan; /* pages scanned by page reclaim */ unsigned long pgrefill; /* inspected in refill_inactive_zone */ unsigned long pgsteal; /* total pages reclaimed */ + unsigned long pginodesteal; /* pages reclaimed via inode freeing */ unsigned long kswapd_steal; /* pages reclaimed by kswapd */ + + unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */ unsigned long pageoutrun; /* kswapd's calls to page reclaim */ unsigned long allocstall; /* direct reclaim calls */ unsigned long pgrotated; /* pages rotated to tail of the LRU */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 94f9d488c2f7..86016d76a3a1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -582,7 +582,10 @@ #define PCI_DEVICE_ID_SI_7016 0x7016 #define PCI_VENDOR_ID_HP 0x103c -#define PCI_DEVICE_ID_HP_DONNER_GFX 0x1008 +#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a #define PCI_DEVICE_ID_HP_TACHYON 0x1028 #define PCI_DEVICE_ID_HP_TACHLITE 0x1029 #define PCI_DEVICE_ID_HP_J2585A 0x1030 @@ -591,6 +594,7 @@ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A #define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B +#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b #define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 #define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 diff --git a/include/linux/sched.h b/include/linux/sched.h index 15a951d2d27e..3a1367bacd1c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -343,7 +343,7 @@ struct task_struct { unsigned long it_real_incr, it_prof_incr, it_virt_incr; struct timer_list real_timer; unsigned long utime, stime, cutime, cstime; - unsigned long start_time; + u64 start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; /* process credentials */ diff --git a/include/linux/slab.h b/include/linux/slab.h index 997bc710bfb0..220a672af798 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -17,13 +17,12 @@ typedef struct kmem_cache_s kmem_cache_t; /* flags for kmem_cache_alloc() */ #define SLAB_NOFS GFP_NOFS #define SLAB_NOIO GFP_NOIO -#define SLAB_NOHIGHIO GFP_NOHIGHIO #define SLAB_ATOMIC GFP_ATOMIC #define SLAB_USER GFP_USER #define SLAB_KERNEL GFP_KERNEL #define SLAB_DMA GFP_DMA -#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS|__GFP_COLD|__GFP_NOWARN) +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|__GFP_COLD|__GFP_NOWARN) #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ /* flags to pass to kmem_cache_create(). diff --git a/include/linux/times.h b/include/linux/times.h index 1174e9f88ea2..9895fd31bd5f 100644 --- a/include/linux/times.h +++ b/include/linux/times.h @@ -2,7 +2,30 @@ #define _LINUX_TIMES_H #ifdef __KERNEL__ +#include <asm/div64.h> +#include <asm/types.h> + +#if (HZ % USER_HZ)==0 # define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ)) +#else +# define jiffies_to_clock_t(x) ((clock_t) jiffies_64_to_clock_t((u64) x)) +#endif + +static inline u64 jiffies_64_to_clock_t(u64 x) +{ +#if (HZ % USER_HZ)==0 + do_div(x, HZ / USER_HZ); +#else + /* + * There are better ways that don't overflow early, + * but even this doesn't overflow in hundreds of years + * in 64 bits, so.. + */ + x *= USER_HZ; + do_div(x, HZ); +#endif + return x; +} #endif struct tms { diff --git a/include/linux/usb.h b/include/linux/usb.h index 9f465bfd8179..cb5c0db14aa1 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -554,7 +554,6 @@ extern int usb_disabled(void); #define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ -#define URB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */ struct usb_iso_packet_descriptor { unsigned int offset; diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index bac8b2e3e666..7458d1f49472 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -163,6 +163,7 @@ struct xfrm_usersa_info { struct xfrm_usersa_id { xfrm_address_t saddr; __u32 spi; + __u16 family; __u8 proto; }; diff --git a/include/net/route.h b/include/net/route.h index ae62dc4e5683..ba15b5140798 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -167,7 +167,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, ip_rt_put(*rp); *rp = NULL; } - return ip_route_output_flow(rp, &fl, sk, 1); + return ip_route_output_flow(rp, &fl, sk, 0); } static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 82d2187eeb2a..0f331126faa4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -105,7 +105,6 @@ struct xfrm_state u16 family; xfrm_address_t saddr; int header_len; - int trailer_len; } props; struct xfrm_lifetime_cfg lft; diff --git a/init/Kconfig b/init/Kconfig index fcdd9fdb7896..887abc316ee2 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -144,6 +144,18 @@ config OBSOLETE_MODPARM have not been converted to the new module parameter system yet. If unsure, say Y. +config MODVERSIONS + bool "Module versioning support (EXPERIMENTAL)" + depends on MODULES && EXPERIMENTAL + help + Usually, you have to use modules compiled with your kernel. + Saying Y here makes it sometimes possible to use modules + compiled for different kernels, by adding enough information + to the modules to (hopefully) spot any changes which would + make them incompatible with the kernel you are running. If + you say Y here, you will need a copy of genksyms. If + unsure, say N. + config KMOD bool "Kernel module loader" depends on MODULES diff --git a/kernel/Makefile b/kernel/Makefile index 794bc0ac2e47..142a78613066 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,10 +2,6 @@ # Makefile for the linux kernel. # -export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \ - printk.o suspend.o dma.o module.o cpufreq.o \ - profile.o rcupdate.o intermodule.o params.o - obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ sysctl.o capability.o ptrace.o timer.o user.o \ diff --git a/kernel/acct.c b/kernel/acct.c index 8c51231fc0b2..47736b0fb8e5 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -51,7 +51,9 @@ #include <linux/tty.h> #include <linux/security.h> #include <linux/vfs.h> +#include <linux/jiffies.h> #include <asm/uaccess.h> +#include <asm/div64.h> /* * These constants control the amount of freespace that suspend and @@ -306,6 +308,7 @@ static void do_acct_process(long exitcode, struct file *file) mm_segment_t fs; unsigned long vsize; unsigned long flim; + u64 elapsed; /* * First check to see if there is enough free_space to continue @@ -323,9 +326,11 @@ static void do_acct_process(long exitcode, struct file *file) strncpy(ac.ac_comm, current->comm, ACCT_COMM); ac.ac_comm[ACCT_COMM - 1] = '\0'; - ac.ac_btime = CT_TO_SECS(current->start_time) + - (xtime.tv_sec - (jiffies / HZ)); - ac.ac_etime = encode_comp_t(jiffies - current->start_time); + elapsed = get_jiffies_64() - current->start_time; + ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ? + (unsigned long) elapsed : (unsigned long) -1l); + do_div(elapsed, HZ); + ac.ac_btime = xtime.tv_sec - elapsed; ac.ac_utime = encode_comp_t(current->utime); ac.ac_stime = encode_comp_t(current->stime); ac.ac_uid = current->uid; diff --git a/kernel/exit.c b/kernel/exit.c index 743ed76ed243..057c562f62b1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -156,7 +156,7 @@ out: * * "I ask you, have you ever known what it is to be an orphan?" */ -static int __will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) +static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) { struct task_struct *p; struct list_head *l; @@ -177,22 +177,17 @@ static int __will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) return ret; /* (sighing) "Often!" */ } -static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task) +int is_orphaned_pgrp(int pgrp) { int retval; read_lock(&tasklist_lock); - retval = __will_become_orphaned_pgrp(pgrp, ignored_task); + retval = will_become_orphaned_pgrp(pgrp, NULL); read_unlock(&tasklist_lock); return retval; } -int is_orphaned_pgrp(int pgrp) -{ - return will_become_orphaned_pgrp(pgrp, 0); -} - static inline int has_stopped_jobs(int pgrp) { int retval = 0; @@ -495,7 +490,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) (p->session == father->session)) { int pgrp = p->pgrp; - if (__will_become_orphaned_pgrp(pgrp, 0) && has_stopped_jobs(pgrp)) { + if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { __kill_pg_info(SIGHUP, (void *)1, pgrp); __kill_pg_info(SIGCONT, (void *)1, pgrp); } @@ -579,7 +574,7 @@ static void exit_notify(void) if ((t->pgrp != current->pgrp) && (t->session == current->session) && - __will_become_orphaned_pgrp(current->pgrp, current) && + will_become_orphaned_pgrp(current->pgrp, current) && has_stopped_jobs(current->pgrp)) { __kill_pg_info(SIGHUP, (void *)1, current->pgrp); __kill_pg_info(SIGCONT, (void *)1, current->pgrp); diff --git a/kernel/fork.c b/kernel/fork.c index 0ba9e64b5821..4fc3fcd5dacb 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -26,6 +26,7 @@ #include <linux/mman.h> #include <linux/fs.h> #include <linux/security.h> +#include <linux/jiffies.h> #include <linux/futex.h> #include <linux/ptrace.h> #include <linux/mount.h> @@ -814,7 +815,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->cutime = p->cstime = 0; p->array = NULL; p->lock_depth = -1; /* -1 = no lock */ - p->start_time = jiffies; + p->start_time = get_jiffies_64(); p->security = NULL; retval = -ENOMEM; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index d6f67455a7fe..aec2b90e5fe5 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -68,13 +68,6 @@ extern struct timezone sys_tz; extern int panic_timeout; -#ifdef CONFIG_MODVERSIONS -const struct module_symbol __export_Using_Versions -__attribute__((section("__ksymtab"))) = { - 1 /* Version version */, "Using_Versions" -}; -#endif - /* process memory management */ EXPORT_SYMBOL(do_mmap_pgoff); EXPORT_SYMBOL(do_munmap); diff --git a/kernel/module.c b/kernel/module.c index 864828099b36..5b55c21deeaa 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -78,6 +78,7 @@ EXPORT_SYMBOL(init_module); /* Find a symbol, return value and the symbol group */ static unsigned long __find_symbol(const char *name, struct kernel_symbol_group **group, + unsigned int *symidx, int gplok) { struct kernel_symbol_group *ks; @@ -90,6 +91,8 @@ static unsigned long __find_symbol(const char *name, for (i = 0; i < ks->num_syms; i++) { if (strcmp(ks->syms[i].name, name) == 0) { *group = ks; + if (symidx) + *symidx = i; return ks->syms[i].value; } } @@ -520,7 +523,7 @@ void __symbol_put(const char *symbol) unsigned long flags; spin_lock_irqsave(&modlist_lock, flags); - if (!__find_symbol(symbol, &ksg, 1)) + if (!__find_symbol(symbol, &ksg, NULL, 1)) BUG(); module_put(ksg->owner); spin_unlock_irqrestore(&modlist_lock, flags); @@ -722,22 +725,91 @@ static int obsolete_params(const char *name, } #endif /* CONFIG_OBSOLETE_MODPARM */ +#ifdef CONFIG_MODVERSIONS +static int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, + struct kernel_symbol_group *ksg, + unsigned int symidx) +{ + unsigned long crc; + unsigned int i, num_versions; + struct modversion_info *versions; + + /* Exporting module didn't supply crcs? OK, we're already tainted. */ + if (!ksg->crcs) + return 1; + + crc = ksg->crcs[symidx]; + + versions = (void *) sechdrs[versindex].sh_addr; + num_versions = sechdrs[versindex].sh_size + / sizeof(struct modversion_info); + + for (i = 0; i < num_versions; i++) { + if (strcmp(versions[i].name, symname) != 0) + continue; + + if (versions[i].crc == crc) + return 1; + printk("%s: disagrees about version of symbol %s\n", + mod->name, symname); + DEBUGP("Found checksum %lX vs module %lX\n", + crc, versions[i].crc); + return 0; + } + /* Not in module's version table. OK, but that taints the kernel. */ + if (!(tainted & TAINT_FORCED_MODULE)) { + printk("%s: no version for \"%s\" found: kernel tainted.\n", + mod->name, symname); + tainted |= TAINT_FORCED_MODULE; + } + return 1; +} + +/* First part is kernel version, which we ignore. */ +static inline int same_magic(const char *amagic, const char *bmagic) +{ + amagic += strcspn(amagic, " "); + bmagic += strcspn(bmagic, " "); + return strcmp(amagic, bmagic) == 0; +} +#else +static inline int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, + struct kernel_symbol_group *ksg, + unsigned int symidx) +{ + return 1; +} + +static inline int same_magic(const char *amagic, const char *bmagic) +{ + return strcmp(amagic, bmagic) == 0; +} +#endif /* CONFIG_MODVERSIONS */ + /* Resolve a symbol for this module. I.e. if we find one, record usage. Must be holding module_mutex. */ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, - unsigned int symindex, - const char *strtab, + unsigned int versindex, const char *name, struct module *mod) { struct kernel_symbol_group *ksg; unsigned long ret; + unsigned int symidx; spin_lock_irq(&modlist_lock); - ret = __find_symbol(name, &ksg, mod->license_gplok); + ret = __find_symbol(name, &ksg, &symidx, mod->license_gplok); if (ret) { - /* This can fail due to OOM, or module unloading */ - if (!use_module(mod, ksg->owner)) + /* use_module can fail due to OOM, or module unloading */ + if (!check_version(sechdrs, versindex, name, mod, + ksg, symidx) || + !use_module(mod, ksg->owner)) ret = 0; } spin_unlock_irq(&modlist_lock); @@ -772,7 +844,7 @@ void *__symbol_get(const char *symbol) unsigned long value, flags; spin_lock_irqsave(&modlist_lock, flags); - value = __find_symbol(symbol, &ksg, 1); + value = __find_symbol(symbol, &ksg, NULL, 1); if (value && !strong_try_module_get(ksg->owner)) value = 0; spin_unlock_irqrestore(&modlist_lock, flags); @@ -824,6 +896,7 @@ static int handle_section(const char *name, static int simplify_symbols(Elf_Shdr *sechdrs, unsigned int symindex, unsigned int strindex, + unsigned int versindex, struct module *mod) { Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; @@ -848,7 +921,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs, case SHN_UNDEF: sym[i].st_value - = resolve_symbol(sechdrs, symindex, strtab, + = resolve_symbol(sechdrs, versindex, strtab + sym[i].st_name, mod); /* Ok if resolved. */ @@ -916,7 +989,7 @@ static void layout_sections(struct module *mod, || strstr(secstrings + s->sh_name, ".init")) continue; s->sh_entsize = get_offset(&mod->core_size, s); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } @@ -932,7 +1005,7 @@ static void layout_sections(struct module *mod, continue; s->sh_entsize = (get_offset(&mod->init_size, s) | INIT_OFFSET_MASK); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } } @@ -976,7 +1049,8 @@ static struct module *load_module(void *umod, Elf_Shdr *sechdrs; char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, - modindex, obsparmindex, licenseindex, gplindex, vmagindex; + modindex, obsparmindex, licenseindex, gplindex, vmagindex, + crcindex, gplcrcindex, versindex; long arglen; struct module *mod; long err = 0; @@ -1012,7 +1086,8 @@ static struct module *load_module(void *umod, /* May not export symbols, or have setup params, so these may not exist */ - exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0; + exportindex = setupindex = obsparmindex = gplindex = licenseindex + = crcindex = gplcrcindex = versindex = 0; /* And these should exist, but gcc whinges if we don't init them */ symindex = strindex = exindex = modindex = vmagindex = 0; @@ -1040,6 +1115,21 @@ static struct module *load_module(void *umod, /* Exported symbols. */ DEBUGP("EXPORT table in section %u\n", i); exportindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__ksymtab_gpl") == 0) { + /* Exported symbols. (GPL) */ + DEBUGP("GPL symbols found in section %u\n", i); + gplindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab") + == 0) { + /* Exported symbols CRCs. */ + DEBUGP("CRC table in section %u\n", i); + crcindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab_gpl") + == 0) { + /* Exported symbols CRCs. (GPL)*/ + DEBUGP("CRC table in section %u\n", i); + gplcrcindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ @@ -1060,16 +1150,21 @@ static struct module *load_module(void *umod, /* MODULE_LICENSE() */ DEBUGP("Licence found in section %u\n", i); licenseindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; } else if (strcmp(secstrings+sechdrs[i].sh_name, - "__gpl_ksymtab") == 0) { - /* EXPORT_SYMBOL_GPL() */ - DEBUGP("GPL symbols found in section %u\n", i); - gplindex = i; - } else if (strcmp(secstrings+sechdrs[i].sh_name, - "__vermagic") == 0) { + "__vermagic") == 0 && + (sechdrs[i].sh_flags & SHF_ALLOC)) { /* Version magic. */ DEBUGP("Version magic found in section %u\n", i); vmagindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__versions") == 0 && + (sechdrs[i].sh_flags & SHF_ALLOC)) { + /* Module version info (both exported and needed) */ + DEBUGP("Versions found in section %u\n", i); + versindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; } #ifdef CONFIG_KALLSYMS /* symbol and string tables for decoding later. */ @@ -1090,12 +1185,12 @@ static struct module *load_module(void *umod, } mod = (void *)sechdrs[modindex].sh_addr; - /* This is allowed: modprobe --force will strip it. */ + /* This is allowed: modprobe --force will invalidate it. */ if (!vmagindex) { tainted |= TAINT_FORCED_MODULE; printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", mod->name); - } else if (strcmp((char *)sechdrs[vmagindex].sh_addr, vermagic) != 0) { + } else if (!same_magic((char *)sechdrs[vmagindex].sh_addr, vermagic)) { printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic); err = -ENOEXEC; @@ -1181,7 +1276,7 @@ static struct module *load_module(void *umod, set_license(mod, sechdrs, licenseindex); /* Fix up syms, so that st_value is a pointer to location. */ - err = simplify_symbols(sechdrs, symindex, strindex, mod); + err = simplify_symbols(sechdrs, symindex, strindex, versindex, mod); if (err < 0) goto cleanup; @@ -1189,9 +1284,23 @@ static struct module *load_module(void *umod, mod->symbols.num_syms = (sechdrs[exportindex].sh_size / sizeof(*mod->symbols.syms)); mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr; + if (crcindex) + mod->symbols.crcs = (void *)sechdrs[crcindex].sh_addr; + mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size / sizeof(*mod->symbols.syms)); mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr; + if (gplcrcindex) + mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr; + +#ifdef CONFIG_MODVERSIONS + if ((mod->symbols.num_syms && !crcindex) + || (mod->gpl_symbols.num_syms && !gplcrcindex)) { + printk(KERN_WARNING "%s: No versions for exported symbols." + " Tainting kernel.\n", mod->name); + tainted |= TAINT_FORCED_MODULE; + } +#endif /* Set up exception table */ if (exindex) { @@ -1492,8 +1601,12 @@ int module_text_address(unsigned long addr) /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; -extern const struct kernel_symbol __start___gpl_ksymtab[]; -extern const struct kernel_symbol __stop___gpl_ksymtab[]; +extern const struct kernel_symbol __start___ksymtab_gpl[]; +extern const struct kernel_symbol __stop___ksymtab_gpl[]; +extern const unsigned long __start___kcrctab[]; +extern const unsigned long __stop___kcrctab[]; +extern const unsigned long __start___kcrctab_gpl[]; +extern const unsigned long __stop___kcrctab_gpl[]; static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols; @@ -1502,11 +1615,14 @@ static int __init symbols_init(void) /* Add kernel symbols to symbol table */ kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab); kernel_symbols.syms = __start___ksymtab; + kernel_symbols.crcs = __start___kcrctab; kernel_symbols.gplonly = 0; list_add(&kernel_symbols.list, &symbols); - kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab - - __start___gpl_ksymtab); - kernel_gpl_symbols.syms = __start___gpl_ksymtab; + + kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl + - __start___ksymtab_gpl); + kernel_gpl_symbols.syms = __start___ksymtab_gpl; + kernel_gpl_symbols.crcs = __start___kcrctab_gpl; kernel_gpl_symbols.gplonly = 1; list_add(&kernel_gpl_symbols.list, &symbols); diff --git a/kernel/printk.c b/kernel/printk.c index 9a599c57bf9b..9f2eb4b45669 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -243,19 +243,13 @@ int do_syslog(int type, char * buf, int len) break; case 5: /* Clear ring buffer */ - spin_lock_irq(&logbuf_lock); logged_chars = 0; - spin_unlock_irq(&logbuf_lock); break; case 6: /* Disable logging to console */ - spin_lock_irq(&logbuf_lock); console_loglevel = minimum_console_loglevel; - spin_unlock_irq(&logbuf_lock); break; case 7: /* Enable logging to console */ - spin_lock_irq(&logbuf_lock); console_loglevel = default_console_loglevel; - spin_unlock_irq(&logbuf_lock); break; case 8: /* Set level of messages printed to console */ error = -EINVAL; @@ -263,15 +257,11 @@ int do_syslog(int type, char * buf, int len) goto out; if (len < minimum_console_loglevel) len = minimum_console_loglevel; - spin_lock_irq(&logbuf_lock); console_loglevel = len; - spin_unlock_irq(&logbuf_lock); error = 0; break; case 9: /* Number of chars in the log buffer */ - spin_lock_irq(&logbuf_lock); error = log_end - log_start; - spin_unlock_irq(&logbuf_lock); break; default: error = -EINVAL; diff --git a/kernel/sched.c b/kernel/sched.c index d2318d53b087..3e072580a244 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -213,7 +213,7 @@ __init void node_nr_running_init(void) int i; for (i = 0; i < NR_CPUS; i++) - cpu_rq(i)->node_nr_running = &node_nr_running[__cpu_to_node(i)]; + cpu_rq(i)->node_nr_running = &node_nr_running[cpu_to_node(i)]; } #else /* !CONFIG_NUMA */ @@ -715,7 +715,7 @@ static int sched_best_cpu(struct task_struct *p) } minload = 10000000; - cpumask = __node_to_cpu_mask(node); + cpumask = node_to_cpumask(node); for (i = 0; i < NR_CPUS; ++i) { if (!(cpumask & (1UL << i))) continue; @@ -767,7 +767,7 @@ static int find_busiest_node(int this_node) static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq) { - int this_node = __cpu_to_node(this_cpu); + int this_node = cpu_to_node(this_cpu); /* * Avoid rebalancing between nodes too often. * We rebalance globally once every NODE_BALANCE_RATE load balances. @@ -776,9 +776,9 @@ static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq) int node = find_busiest_node(this_node); this_rq->nr_balanced = 0; if (node >= 0) - return (__node_to_cpu_mask(node) | (1UL << this_cpu)); + return (node_to_cpumask(node) | (1UL << this_cpu)); } - return __node_to_cpu_mask(this_node); + return node_to_cpumask(this_node); } #else /* !CONFIG_NUMA */ diff --git a/kernel/timer.c b/kernel/timer.c index 318b61d4e46f..e78ef95d6b64 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -26,8 +26,10 @@ #include <linux/mm.h> #include <linux/notifier.h> #include <linux/thread_info.h> +#include <linux/jiffies.h> #include <asm/uaccess.h> +#include <asm/div64.h> /* * per-CPU timer vector definitions: @@ -1085,13 +1087,16 @@ asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) asmlinkage long sys_sysinfo(struct sysinfo *info) { struct sysinfo val; + u64 uptime; unsigned long mem_total, sav_total; unsigned int mem_unit, bitcount; memset((char *)&val, 0, sizeof(struct sysinfo)); read_lock_irq(&xtime_lock); - val.uptime = jiffies / HZ; + uptime = jiffies_64; + do_div(uptime, HZ); + val.uptime = (unsigned long) uptime; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); diff --git a/lib/Makefile b/lib/Makefile index d9b12140d830..ccccea20ac2d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -8,9 +8,6 @@ L_TARGET := lib.a -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \ - crc32.o rbtree.o radix-tree.o kobject.o - obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ kobject.o diff --git a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile index a006cfbf8d8e..86275e3fdcbc 100644 --- a/lib/zlib_deflate/Makefile +++ b/lib/zlib_deflate/Makefile @@ -6,8 +6,6 @@ # decompression code. # -export-objs := deflate_syms.o - obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o zlib_deflate-objs := deflate.o deftree.o deflate_syms.o diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile index a0a4398fa05f..0408851f67e8 100644 --- a/lib/zlib_inflate/Makefile +++ b/lib/zlib_inflate/Makefile @@ -13,8 +13,6 @@ # uncompression can be done without blocking on allocation). # -export-objs := inflate_syms.o - obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \ diff --git a/mm/Makefile b/mm/Makefile index 1538bd37bce5..a8de64ff3525 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -2,14 +2,12 @@ # Makefile for the linux memory manager. # -export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o - mmu-y := nommu.o mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ shmem.o vmalloc.o -obj-y := bootmem.o filemap.o mempool.o oom_kill.o \ +obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o readahead.o \ slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y) diff --git a/mm/fadvise.c b/mm/fadvise.c new file mode 100644 index 000000000000..9503b65076a1 --- /dev/null +++ b/mm/fadvise.c @@ -0,0 +1,72 @@ +/* + * mm/fadvise.c + * + * Copyright (C) 2002, Linus Torvalds + * + * 11Jan2003 akpm@digeo.com + * Initial version. + */ + +#include <linux/kernel.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/pagemap.h> +#include <linux/backing-dev.h> +#include <linux/pagevec.h> +#include <linux/fadvise.h> + +/* + * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could + * deactivate the pages and clear PG_Referenced. + */ +int sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +{ + struct file *file = fget(fd); + struct inode *inode; + struct address_space *mapping; + struct backing_dev_info *bdi; + int ret = 0; + + if (!file) + return -EBADF; + + inode = file->f_dentry->d_inode; + mapping = inode->i_mapping; + if (!mapping) + return -EINVAL; + + bdi = mapping->backing_dev_info; + + switch (advice) { + case POSIX_FADV_NORMAL: + file->f_ra.ra_pages = bdi->ra_pages; + break; + case POSIX_FADV_RANDOM: + file->f_ra.ra_pages = 0; + break; + case POSIX_FADV_SEQUENTIAL: + file->f_ra.ra_pages = bdi->ra_pages * 2; + break; + case POSIX_FADV_WILLNEED: + case POSIX_FADV_NOREUSE: + if (!mapping->a_ops->readpage) { + ret = -EINVAL; + break; + } + ret = do_page_cache_readahead(mapping, file, + offset >> PAGE_CACHE_SHIFT, + max_sane_readahead(len >> PAGE_CACHE_SHIFT)); + if (ret > 0) + ret = 0; + break; + case POSIX_FADV_DONTNEED: + invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT, + (len >> PAGE_CACHE_SHIFT) + 1); + break; + default: + ret = -EINVAL; + } + fput(file); + return ret; +} diff --git a/mm/highmem.c b/mm/highmem.c index ee5e622dcbfe..33adcf242697 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -366,7 +366,7 @@ static int bounce_end_io_read_isa(struct bio *bio, unsigned int bytes_done, int return 0; } -void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, int bio_gfp, +static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, mempool_t *pool) { struct page *page; @@ -387,7 +387,7 @@ void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, int bio_gfp, * irk, bounce it */ if (!bio) - bio = bio_alloc(bio_gfp, (*bio_orig)->bi_vcnt); + bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt); to = bio->bi_io_vec + i; @@ -447,10 +447,9 @@ void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, int bio_gfp, *bio_orig = bio; } -inline void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) +void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) { mempool_t *pool; - int bio_gfp; /* * for non-isa bounce case, just check if the bounce pfn is equal @@ -460,20 +459,16 @@ inline void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) if (!(q->bounce_gfp & GFP_DMA)) { if (q->bounce_pfn >= blk_max_pfn) return; - - bio_gfp = GFP_NOHIGHIO; pool = page_pool; } else { BUG_ON(!isa_page_pool); - - bio_gfp = GFP_NOIO; pool = isa_page_pool; } /* * slow path */ - __blk_queue_bounce(q, bio_orig, bio_gfp, pool); + __blk_queue_bounce(q, bio_orig, pool); } #if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_HIGHMEM) diff --git a/mm/mmap.c b/mm/mmap.c index a7b229601fe5..61d0dc32646a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -124,6 +124,19 @@ int vm_enough_memory(long pages) } /* + * Requires inode->i_mapping->i_shared_sem + */ +static inline void +__remove_shared_vm_struct(struct vm_area_struct *vma, struct inode *inode) +{ + if (inode) { + if (vma->vm_flags & VM_DENYWRITE) + atomic_inc(&inode->i_writecount); + list_del_init(&vma->shared); + } +} + +/* * Remove one vm structure from the inode's i_mapping address space. */ static void remove_shared_vm_struct(struct vm_area_struct *vma) @@ -134,9 +147,7 @@ static void remove_shared_vm_struct(struct vm_area_struct *vma) struct inode *inode = file->f_dentry->d_inode; down(&inode->i_mapping->i_shared_sem); - if (vma->vm_flags & VM_DENYWRITE) - atomic_inc(&inode->i_writecount); - list_del_init(&vma->shared); + __remove_shared_vm_struct(vma, inode); up(&inode->i_mapping->i_shared_sem); } } @@ -194,7 +205,8 @@ out: * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits * into "VM_xxx". */ -static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags) +static inline unsigned long +calc_vm_flags(unsigned long prot, unsigned long flags) { #define _trans(x,bit1,bit2) \ ((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0) @@ -243,10 +255,10 @@ static void validate_mm(struct mm_struct * mm) { #define validate_mm(mm) do { } while (0) #endif -static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr, - struct vm_area_struct ** pprev, - struct rb_node *** rb_link, - struct rb_node ** rb_parent) +static struct vm_area_struct * +find_vma_prepare(struct mm_struct *mm, unsigned long addr, + struct vm_area_struct **pprev, struct rb_node ***rb_link, + struct rb_node ** rb_parent) { struct vm_area_struct * vma; struct rb_node ** __rb_link, * __rb_parent, * rb_prev; @@ -280,8 +292,9 @@ static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned return vma; } -static inline void __vma_link_list(struct mm_struct * mm, struct vm_area_struct * vma, - struct vm_area_struct * prev, struct rb_node * rb_parent) +static inline void +__vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev, struct rb_node *rb_parent) { if (prev) { vma->vm_next = prev->vm_next; @@ -289,20 +302,21 @@ static inline void __vma_link_list(struct mm_struct * mm, struct vm_area_struct } else { mm->mmap = vma; if (rb_parent) - vma->vm_next = rb_entry(rb_parent, struct vm_area_struct, vm_rb); + vma->vm_next = rb_entry(rb_parent, + struct vm_area_struct, vm_rb); else vma->vm_next = NULL; } } -static void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma, - struct rb_node ** rb_link, struct rb_node * rb_parent) +static void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, + struct rb_node **rb_link, struct rb_node *rb_parent) { rb_link_node(&vma->vm_rb, rb_parent, rb_link); rb_insert_color(&vma->vm_rb, &mm->mm_rb); } -static inline void __vma_link_file(struct vm_area_struct * vma) +static inline void __vma_link_file(struct vm_area_struct *vma) { struct file * file; @@ -321,8 +335,10 @@ static inline void __vma_link_file(struct vm_area_struct * vma) } } -static void __vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev, - struct rb_node ** rb_link, struct rb_node * rb_parent) +static void +__vma_link(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev, struct rb_node **rb_link, + struct rb_node *rb_parent) { __vma_link_list(mm, vma, prev, rb_parent); __vma_link_rb(mm, vma, rb_link, rb_parent); @@ -350,42 +366,119 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma, validate_mm(mm); } -static int vma_merge(struct mm_struct * mm, struct vm_area_struct * prev, - struct rb_node * rb_parent, unsigned long addr, - unsigned long end, unsigned long vm_flags) +/* + * Return true if we can merge this (vm_flags,file,vm_pgoff,size) + * in front of (at a lower virtual address and file offset than) the vma. + * + * We don't check here for the merged mmap wrapping around the end of pagecache + * indices (16TB on ia32) because do_mmap_pgoff() does not permit mmap's which + * wrap, nor mmaps which cover the final page at index -1UL. + */ +static int +can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, + struct file *file, unsigned long vm_pgoff, unsigned long size) +{ + if (vma->vm_file == file && vma->vm_flags == vm_flags) { + if (!file) + return 1; /* anon mapping */ + if (vma->vm_pgoff == vm_pgoff + size) + return 1; + } + return 0; +} + +/* + * Return true if we can merge this (vm_flags,file,vm_pgoff) + * beyond (at a higher virtual address and file offset than) the vma. + */ +static int +can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + struct file *file, unsigned long vm_pgoff) +{ + if (vma->vm_file == file && vma->vm_flags == vm_flags) { + unsigned long vma_size; + + if (!file) + return 1; /* anon mapping */ + + vma_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + if (vma->vm_pgoff + vma_size == vm_pgoff) + return 1; + } + return 0; +} + +/* + * Given a new mapping request (addr,end,vm_flags,file,pgoff), figure out + * whether that can be merged with its predecessor or its successor. Or + * both (it neatly fills a hole). + */ +static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev, + struct rb_node *rb_parent, unsigned long addr, + unsigned long end, unsigned long vm_flags, + struct file *file, unsigned long pgoff) { spinlock_t * lock = &mm->page_table_lock; + if (!prev) { prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb); goto merge_next; } - if (prev->vm_end == addr && can_vma_merge(prev, vm_flags)) { - struct vm_area_struct * next; + /* + * Can it merge with the predecessor? + */ + if (prev->vm_end == addr && + can_vma_merge_after(prev, vm_flags, file, pgoff)) { + struct vm_area_struct *next; + struct inode *inode = file ? file->f_dentry->d_inode : inode; + int need_up = 0; + + if (unlikely(file && prev->vm_next && + prev->vm_next->vm_file == file)) { + down(&inode->i_mapping->i_shared_sem); + need_up = 1; + } spin_lock(lock); prev->vm_end = end; + + /* + * OK, it did. Can we now merge in the successor as well? + */ next = prev->vm_next; - if (next && prev->vm_end == next->vm_start && can_vma_merge(next, vm_flags)) { + if (next && prev->vm_end == next->vm_start && + can_vma_merge_before(next, vm_flags, file, + pgoff, (end - addr) >> PAGE_SHIFT)) { prev->vm_end = next->vm_end; __vma_unlink(mm, next, prev); + __remove_shared_vm_struct(next, inode); spin_unlock(lock); + if (need_up) + up(&inode->i_mapping->i_shared_sem); mm->map_count--; kmem_cache_free(vm_area_cachep, next); return 1; } spin_unlock(lock); + if (need_up) + up(&inode->i_mapping->i_shared_sem); return 1; } + /* + * Can this new request be merged in front of prev->vm_next? + */ prev = prev->vm_next; if (prev) { merge_next: - if (!can_vma_merge(prev, vm_flags)) + if (!can_vma_merge_before(prev, vm_flags, file, + pgoff, (end - addr) >> PAGE_SHIFT)) return 0; if (end == prev->vm_start) { spin_lock(lock); prev->vm_start = addr; + prev->vm_pgoff -= (end - addr) >> PAGE_SHIFT; spin_unlock(lock); return 1; } @@ -404,7 +497,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; - struct inode *inode = NULL; + struct inode *inode; unsigned int vm_flags; int correct_wcount = 0; int error; @@ -441,7 +534,8 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ - vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_LOCKED) { if (!capable(CAP_IPC_LOCK)) @@ -456,18 +550,24 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, return -EAGAIN; } + inode = file ? file->f_dentry->d_inode : NULL; + if (file) { - inode = file->f_dentry->d_inode; switch (flags & MAP_TYPE) { case MAP_SHARED: - if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE)) + if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) return -EACCES; - /* Make sure we don't allow writing to an append-only file.. */ + /* + * Make sure we don't allow writing to an append-only + * file.. + */ if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE)) return -EACCES; - /* make sure there are no mandatory locks on the file. */ + /* + * Make sure there are no mandatory locks on the file. + */ if (locks_verify_locked(inode)) return -EAGAIN; @@ -521,7 +621,9 @@ munmap_back: /* Check memory availability in shmem_file_setup? */ vm_flags |= VM_ACCOUNT; } else if (vm_flags & VM_WRITE) { - /* Private writable mapping: check memory availability */ + /* + * Private writable mapping: check memory availability + */ charged = len >> PAGE_SHIFT; if (!vm_enough_memory(charged)) return -ENOMEM; @@ -531,10 +633,12 @@ munmap_back: /* Can we just expand an old anonymous mapping? */ if (!file && !(vm_flags & VM_SHARED) && rb_parent) - if (vma_merge(mm, prev, rb_parent, addr, addr + len, vm_flags)) + if (vma_merge(mm, prev, rb_parent, addr, addr + len, + vm_flags, NULL, 0)) goto out; - /* Determine the object being mapped and call the appropriate + /* + * Determine the object being mapped and call the appropriate * specific mapper. the address has already been validated, but * not unmapped, but the maps are removed from the list. */ @@ -590,10 +694,19 @@ munmap_back: */ addr = vma->vm_start; - vma_link(mm, vma, prev, rb_link, rb_parent); - if (correct_wcount) - atomic_inc(&inode->i_writecount); - + if (!file || !rb_parent || !vma_merge(mm, prev, rb_parent, addr, + addr + len, vma->vm_flags, file, pgoff)) { + vma_link(mm, vma, prev, rb_link, rb_parent); + if (correct_wcount) + atomic_inc(&inode->i_writecount); + } else { + if (file) { + if (correct_wcount) + atomic_inc(&inode->i_writecount); + fput(file); + } + kmem_cache_free(vm_area_cachep, vma); + } out: mm->total_vm += len >> PAGE_SHIFT; if (vm_flags & VM_LOCKED) { @@ -636,7 +749,9 @@ unacct_error: * This function "knows" that -ENOMEM has the bits set. */ #ifndef HAVE_ARCH_UNMAPPED_AREA -static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +static inline unsigned long +arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -671,10 +786,14 @@ static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned l } } #else -extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +extern unsigned long +arch_get_unmapped_area(struct file *, unsigned long, unsigned long, + unsigned long, unsigned long); #endif -unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +unsigned long +get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) { if (flags & MAP_FIXED) { if (addr > TASK_SIZE - len) @@ -685,7 +804,8 @@ unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned } if (file && file->f_op && file->f_op->get_unmapped_area) - return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags); + return file->f_op->get_unmapped_area(file, addr, len, + pgoff, flags); return arch_get_unmapped_area(file, addr, len, pgoff, flags); } @@ -708,7 +828,8 @@ struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) while (rb_node) { struct vm_area_struct * vma_tmp; - vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb); + vma_tmp = rb_entry(rb_node, + struct vm_area_struct, vm_rb); if (vma_tmp->vm_end > addr) { vma = vma_tmp; @@ -726,8 +847,9 @@ struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) } /* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */ -struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, - struct vm_area_struct **pprev) +struct vm_area_struct * +find_vma_prev(struct mm_struct *mm, unsigned long addr, + struct vm_area_struct **pprev) { struct vm_area_struct *vma = NULL, *prev = NULL; struct rb_node * rb_node; @@ -754,7 +876,7 @@ struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, } } - out: +out: *pprev = prev; return prev ? prev->vm_next : vma; } @@ -801,7 +923,8 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address) return 0; } -struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr) +struct vm_area_struct * +find_extend_vma(struct mm_struct *mm, unsigned long addr) { struct vm_area_struct *vma, *prev; @@ -820,7 +943,7 @@ struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long add /* * vma is the first one with address < vma->vm_start. Have to extend vma. */ -int expand_stack(struct vm_area_struct * vma, unsigned long address) +int expand_stack(struct vm_area_struct *vma, unsigned long address) { unsigned long grow; @@ -855,7 +978,8 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address) return 0; } -struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr) +struct vm_area_struct * +find_extend_vma(struct mm_struct * mm, unsigned long addr) { struct vm_area_struct * vma; unsigned long start; @@ -925,7 +1049,7 @@ static void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *prev, break; } no_mmaps: - if (last < first) /* needed for arches with discontiguous pgd indices */ + if (last < first) /* for arches with discontiguous pgd indices */ return; /* * If the PGD bits are not consecutive in the virtual address, the @@ -1200,7 +1324,8 @@ unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; /* Can we just expand an old anonymous mapping? */ - if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags)) + if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, + flags, NULL, 0)) goto out; /* @@ -1310,7 +1435,7 @@ void insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) struct vm_area_struct * __vma, * prev; struct rb_node ** rb_link, * rb_parent; - __vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent); + __vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent); if (__vma && __vma->vm_start < vma->vm_end) BUG(); vma_link(mm, vma, prev, rb_link, rb_parent); diff --git a/mm/oom_kill.c b/mm/oom_kill.c index fd6788f8fca4..073e24ed7709 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -19,6 +19,7 @@ #include <linux/sched.h> #include <linux/swap.h> #include <linux/timex.h> +#include <linux/jiffies.h> /* #define DEBUG */ @@ -68,11 +69,10 @@ static int badness(struct task_struct *p) /* * CPU time is in seconds and run time is in minutes. There is no * particular reason for this other than that it turned out to work - * very well in practice. This is not safe against jiffie wraps - * but we don't care _that_ much... + * very well in practice. */ cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3); - run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10); + run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10); points /= int_sqrt(cpu_time); points /= int_sqrt(int_sqrt(run_time)); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3969ad493b35..ef7d20c61e46 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1269,7 +1269,7 @@ void __init free_area_init_node(int nid, struct pglist_data *pgdat, pgdat->node_mem_map = node_mem_map; free_area_init_core(pgdat, zones_size, zholes_size); - memblk_set_online(__node_to_memblk(nid)); + memblk_set_online(node_to_memblk(nid)); calculate_zone_bitmap(pgdat, zones_size); } @@ -1379,15 +1379,20 @@ static char *vmstat_text[] = { "pswpin", "pswpout", "pgalloc", + "pgfree", "pgactivate", "pgdeactivate", "pgfault", "pgmajfault", + "pgscan", "pgrefill", "pgsteal", + "pginodesteal", "kswapd_steal", + + "kswapd_inodesteal", "pageoutrun", "allocstall", "pgrotated", diff --git a/mm/readahead.c b/mm/readahead.c index bd28c3b4f1ca..77bd1ff6c630 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -42,6 +42,8 @@ static inline unsigned long get_min_readahead(struct file_ra_state *ra) return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE; } +#define list_to_page(head) (list_entry((head)->prev, struct page, list)) + /** * read_cache_pages - populate an address space with some pages, and * start reads against them. @@ -63,7 +65,7 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages, pagevec_init(&lru_pvec, 0); while (!list_empty(pages)) { - page = list_entry(pages->prev, struct page, list); + page = list_to_page(pages); list_del(&page->list); if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { page_cache_release(page); @@ -72,8 +74,16 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages, ret = filler(data, page); if (!pagevec_add(&lru_pvec, page)) __pagevec_lru_add(&lru_pvec); - if (ret) + if (ret) { + while (!list_empty(pages)) { + struct page *victim; + + victim = list_to_page(pages); + list_del(&victim->list); + page_cache_release(victim); + } break; + } } pagevec_lru_add(&lru_pvec); return ret; @@ -85,13 +95,12 @@ static int read_pages(struct address_space *mapping, struct file *filp, unsigned page_idx; struct pagevec lru_pvec; - pagevec_init(&lru_pvec, 0); - if (mapping->a_ops->readpages) return mapping->a_ops->readpages(filp, mapping, pages, nr_pages); + pagevec_init(&lru_pvec, 0); for (page_idx = 0; page_idx < nr_pages; page_idx++) { - struct page *page = list_entry(pages->prev, struct page, list); + struct page *page = list_to_page(pages); list_del(&page->list); if (!add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { diff --git a/mm/slab.c b/mm/slab.c index 5fa3a4c6862d..87f623dde759 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2048,6 +2048,14 @@ static void enable_cpucache (kmem_cache_t *cachep) int err; int limit; + /* The head array serves three purposes: + * - create a LIFO ordering, i.e. return objects that are cache-warm + * - reduce the number of spinlock operations. + * - reduce the number of linked list operations on the slab and + * bufctl chains: array operations are cheaper. + * The numbers are guessed, we should auto-tune as described by + * Bonwick. + */ if (cachep->objsize > PAGE_SIZE) limit = 8; else if (cachep->objsize > 1024) @@ -2057,6 +2065,14 @@ static void enable_cpucache (kmem_cache_t *cachep) else limit = 248; +#ifndef DEBUG + /* With debugging enabled, large batchcount lead to excessively + * long periods with disabled local interrupts. Limit the + * batchcount + */ + if (limit > 32) + limit = 32; +#endif err = do_tune_cpucache(cachep, limit, limit/2); if (err) printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n", diff --git a/mm/truncate.c b/mm/truncate.c index b1782738666b..56bdd03b1576 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -64,24 +64,25 @@ truncate_complete_page(struct address_space *mapping, struct page *page) * ->page_lock. That provides exclusion against the __set_page_dirty * functions. */ -static void +static int invalidate_complete_page(struct address_space *mapping, struct page *page) { if (page->mapping != mapping) - return; + return 0; if (PagePrivate(page) && !try_to_release_page(page, 0)) - return; + return 0; write_lock(&mapping->page_lock); if (PageDirty(page)) { write_unlock(&mapping->page_lock); - } else { - __remove_from_page_cache(page); - write_unlock(&mapping->page_lock); - ClearPageUptodate(page); - page_cache_release(page); /* pagecache ref */ + return 0; } + __remove_from_page_cache(page); + write_unlock(&mapping->page_lock); + ClearPageUptodate(page); + page_cache_release(page); /* pagecache ref */ + return 1; } /** @@ -177,24 +178,29 @@ void truncate_inode_pages(struct address_space *mapping, loff_t lstart) } /** - * invalidate_inode_pages - Invalidate all the unlocked pages of one inode - * @inode: the inode which pages we want to invalidate + * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode + * @inode: the address_space which holds the pages to invalidate + * @end: the index of the last page to invalidate (inclusive) + * @nr_pages: defines the pagecache span. Invalidate up to @start + @nr_pages * * This function only removes the unlocked pages, if you want to * remove all the pages of one inode, you must call truncate_inode_pages. * - * invalidate_inode_pages() will not block on IO activity. It will not + * invalidate_mapping_pages() will not block on IO activity. It will not * invalidate pages which are dirty, locked, under writeback or mapped into * pagetables. */ -void invalidate_inode_pages(struct address_space *mapping) +unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end) { struct pagevec pvec; - pgoff_t next = 0; + pgoff_t next = start; + unsigned long ret = 0; int i; pagevec_init(&pvec, 0); - while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + while (next <= end && + pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; @@ -209,13 +215,19 @@ void invalidate_inode_pages(struct address_space *mapping) goto unlock; if (page_mapped(page)) goto unlock; - invalidate_complete_page(mapping, page); + ret += invalidate_complete_page(mapping, page); unlock: unlock_page(page); } pagevec_release(&pvec); cond_resched(); } + return ret; +} + +unsigned long invalidate_inode_pages(struct address_space *mapping) +{ + return invalidate_mapping_pages(mapping, 0, ~0UL); } /** diff --git a/mm/vmscan.c b/mm/vmscan.c index a8b9d2c450c4..0fc00047b27c 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -894,9 +894,9 @@ static int balance_pgdat(pg_data_t *pgdat, int nr_pages, struct page_state *ps) max_scan = to_reclaim * 2; if (max_scan < SWAP_CLUSTER_MAX) max_scan = SWAP_CLUSTER_MAX; - to_free -= shrink_zone(zone, max_scan, GFP_KSWAPD, + to_free -= shrink_zone(zone, max_scan, GFP_KERNEL, to_reclaim, &nr_mapped, ps, priority); - shrink_slab(max_scan + nr_mapped, GFP_KSWAPD); + shrink_slab(max_scan + nr_mapped, GFP_KERNEL); if (zone->all_unreclaimable) continue; if (zone->pages_scanned > zone->present_pages * 2) @@ -929,7 +929,7 @@ int kswapd(void *p) DEFINE_WAIT(wait); daemonize(); - set_cpus_allowed(tsk, __node_to_cpu_mask(pgdat->node_id)); + set_cpus_allowed(tsk, node_to_cpumask(pgdat->node_id)); sprintf(tsk->comm, "kswapd%d", pgdat->node_id); sigfillset(&tsk->blocked); diff --git a/net/802/Makefile b/net/802/Makefile index 8abc269996d0..01861929591a 100644 --- a/net/802/Makefile +++ b/net/802/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux 802.x protocol layers. # -export-objs := p8022.o psnap.o - obj-y := p8023.o # Check the p8022 selections against net/core/Makefile. diff --git a/net/Makefile b/net/Makefile index 65f568979501..96b4e9fef0ee 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := netsyms.o - obj-y := socket.o core/ # LLC has to be linked before the files in net/802/ diff --git a/net/appletalk/Makefile b/net/appletalk/Makefile index 3d9c613edce4..cbe8a6a0bef0 100644 --- a/net/appletalk/Makefile +++ b/net/appletalk/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux AppleTalk layer. # -export-objs = ddp.o - obj-$(CONFIG_ATALK) += appletalk.o appletalk-y := aarp.o ddp.o atalk_proc.o diff --git a/net/atm/Makefile b/net/atm/Makefile index 3e4dc2c42692..a3027195a738 100644 --- a/net/atm/Makefile +++ b/net/atm/Makefile @@ -2,8 +2,6 @@ # Makefile for the ATM Protocol Families. # -export-objs := common.o atm_misc.o raw.o resources.o ipcommon.o proc.o - mpoa-objs := mpc.o mpoa_caches.o mpoa_proc.o obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o diff --git a/net/ax25/Makefile b/net/ax25/Makefile index ace7aef9969a..43c46d2cafb6 100644 --- a/net/ax25/Makefile +++ b/net/ax25/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux AX.25 layer. # -export-objs := af_ax25.o - obj-$(CONFIG_AX25) += ax25.o ax25-y := ax25_addr.o ax25_dev.o ax25_iface.o ax25_in.o ax25_ip.o ax25_out.o \ diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 0c7c33c36059..cf5916af802a 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux Bluetooth subsystem. # -export-objs := syms.o - obj-$(CONFIG_BT) += bluetooth.o obj-$(CONFIG_BT_L2CAP) += l2cap.o obj-$(CONFIG_BT_SCO) += sco.o diff --git a/net/bridge/Makefile b/net/bridge/Makefile index 643fb45fb43e..068150c0f923 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -2,8 +2,6 @@ # Makefile for the IEEE 802.1d ethernet bridging layer. # -export-objs := br.o - obj-$(CONFIG_BRIDGE) += bridge.o bridge-objs := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index e285eb04c91c..0989ba8c39ef 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -2,8 +2,6 @@ # Makefile for the netfilter modules for Link Layer filtering on a bridge. # -export-objs := ebtables.o - obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o diff --git a/net/ipv4/ah.c b/net/ipv4/ah.c index b18a8aaf459b..383d77a03c17 100644 --- a/net/ipv4/ah.c +++ b/net/ipv4/ah.c @@ -361,7 +361,7 @@ static int ah_init_state(struct xfrm_state *x, void *args) ahp->icv = ah_hmac_digest; /* - * Lookup the algorithm description maintained by pfkey, + * Lookup the algorithm description maintained by xfrm_algo, * verify crypto transform properties, and store information * we need for AH processing. This lookup cannot fail here * after a successful crypto_alloc_tfm(). diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 4d676060696f..a85769466ca9 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -823,6 +823,34 @@ int unregister_inetaddr_notifier(struct notifier_block *nb) return notifier_chain_unregister(&inetaddr_chain, nb); } +/* Rename ifa_labels for a device name change. Make some effort to preserve existing + * alias numbering and to create unique labels if possible. +*/ +static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) +{ + struct in_ifaddr *ifa; + int named = 0; + + for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { + char old[IFNAMSIZ], *dot; + + memcpy(old, ifa->ifa_label, IFNAMSIZ); + memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); + if (named++ == 0) + continue; + dot = strchr(ifa->ifa_label, ':'); + if (dot == NULL) { + sprintf(old, ":%d", named); + dot = old; + } + if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { + strcat(ifa->ifa_label, dot); + } else { + strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); + } + } +} + /* Called only under RTNL semaphore */ static int inetdev_event(struct notifier_block *this, unsigned long event, @@ -873,14 +901,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, inetdev_destroy(in_dev); break; case NETDEV_CHANGENAME: - if (in_dev->ifa_list) { - struct in_ifaddr *ifa; - for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) - memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); - /* Do not notify about label change, this event is - not interesting to applications using netlink. - */ - } + /* Do not notify about label change, this event is + * not interesting to applications using netlink. + */ + inetdev_changename(dev, in_dev); break; } out: diff --git a/net/ipv4/esp.c b/net/ipv4/esp.c index 466517dd0482..09c8abd6aa8c 100644 --- a/net/ipv4/esp.c +++ b/net/ipv4/esp.c @@ -10,6 +10,9 @@ #define MAX_SG_ONSTACK 4 +typedef void (icv_update_fn_t)(struct crypto_tfm *, + struct scatterlist *, unsigned int); + /* BUGS: * - we assume replay seqno is always present. */ @@ -30,37 +33,40 @@ struct esp_data struct crypto_tfm *tfm; /* crypto handle */ } conf; - /* Integrity. It is active when authlen != 0 */ + /* Integrity. It is active when icv_full_len != 0 */ struct { u8 *key; /* Key */ int key_len; /* Length of the key */ - u8 *work_digest; - /* authlen is length of trailer containing auth token. - * If it is not zero it is assumed to be - * >= crypto_tfm_alg_digestsize(atfm) */ - int authlen; - void (*digest)(struct esp_data*, - struct sk_buff *skb, - int offset, - int len, - u8 *digest); + u8 *work_icv; + int icv_full_len; + int icv_trunc_len; + void (*icv)(struct esp_data*, + struct sk_buff *skb, + int offset, int len, u8 *icv); struct crypto_tfm *tfm; } auth; }; /* Move to common area: it is shared with AH. */ -void skb_digest_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, - int offset, int len) +void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, + int offset, int len, icv_update_fn_t icv_update) { int start = skb->len - skb->data_len; int i, copy = start - offset; + struct scatterlist sg; /* Checksum header. */ if (copy > 0) { if (copy > len) copy = len; - tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, skb->data+offset, copy); + + sg.page = virt_to_page(skb->data + offset); + sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; + sg.length = copy; + + icv_update(tfm, &sg, 1); + if ((len -= copy) == 0) return; offset += copy; @@ -73,14 +79,17 @@ void skb_digest_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { - u8 *vaddr; skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; if (copy > len) copy = len; - vaddr = kmap_skb_frag(frag); - tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, vaddr+frag->page_offset+offset-start, copy); - kunmap_skb_frag(vaddr); + + sg.page = frag->page; + sg.offset = frag->page_offset + offset-start; + sg.length = copy; + + icv_update(tfm, &sg, 1); + if (!(len -= copy)) return; offset += copy; @@ -100,7 +109,7 @@ void skb_digest_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, if ((copy = end - offset) > 0) { if (copy > len) copy = len; - skb_digest_walk(list, tfm, offset-start, copy); + skb_icv_walk(list, tfm, offset-start, copy, icv_update); if ((len -= copy) == 0) return; offset += copy; @@ -188,12 +197,13 @@ esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset, int len, u8 *auth_data) { struct crypto_tfm *tfm = esp->auth.tfm; - char *digest = esp->auth.work_digest; + char *icv = esp->auth.work_icv; + memset(auth_data, 0, esp->auth.icv_trunc_len); crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len); - skb_digest_walk(skb, tfm, offset, len); - crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, digest); - memcpy(auth_data, digest, esp->auth.authlen); + skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update); + crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv); + memcpy(auth_data, icv, esp->auth.icv_trunc_len); } /* Check that skb data bits are writable. If they are not, copy data @@ -317,6 +327,7 @@ int esp_output(struct sk_buff *skb) struct sk_buff *trailer; int blksize; int clen; + int alen; int nfrags; union { struct iphdr iph; @@ -347,13 +358,14 @@ int esp_output(struct sk_buff *skb) clen = skb->len; esp = x->data; + alen = esp->auth.icv_trunc_len; tfm = esp->conf.tfm; blksize = crypto_tfm_alg_blocksize(tfm); clen = (clen + 2 + blksize-1)&~(blksize-1); if (esp->conf.padlen) clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1); - if ((nfrags = skb_cow_data(skb, clen-skb->len+esp->auth.authlen, &trailer)) < 0) + if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) goto error; /* Fill padding... */ @@ -373,7 +385,7 @@ int esp_output(struct sk_buff *skb) top_iph->ihl = 5; top_iph->version = 4; top_iph->tos = iph->tos; /* DS disclosed */ - top_iph->tot_len = htons(skb->len + esp->auth.authlen); + top_iph->tot_len = htons(skb->len + alen); top_iph->frag_off = iph->frag_off&htons(IP_DF); if (!(top_iph->frag_off)) ip_select_ident(top_iph, dst, 0); @@ -388,7 +400,7 @@ int esp_output(struct sk_buff *skb) top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4); memcpy(top_iph, &tmp_iph, iph->ihl*4); iph = &tmp_iph.iph; - top_iph->tot_len = htons(skb->len + esp->auth.authlen); + top_iph->tot_len = htons(skb->len + alen); top_iph->protocol = IPPROTO_ESP; top_iph->check = 0; top_iph->frag_off = iph->frag_off; @@ -411,7 +423,7 @@ int esp_output(struct sk_buff *skb) goto error; } skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); - crypto_cipher_encrypt(tfm, sg, nfrags); + crypto_cipher_encrypt(tfm, sg, sg, clen); if (unlikely(sg != sgbuf)) kfree(sg); } while (0); @@ -421,10 +433,10 @@ int esp_output(struct sk_buff *skb) crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); } - if (esp->auth.authlen) { - esp->auth.digest(esp, skb, (u8*)esph-skb->data, - 8+esp->conf.ivlen+clen, trailer->tail); - pskb_put(skb, trailer, esp->auth.authlen); + if (esp->auth.icv_full_len) { + esp->auth.icv(esp, skb, (u8*)esph-skb->data, + 8+esp->conf.ivlen+clen, trailer->tail); + pskb_put(skb, trailer, alen); } ip_send_check(top_iph); @@ -445,6 +457,11 @@ error_nolock: return err; } +/* + * Note: detecting truncated vs. non-truncated authentication data is very + * expensive, so we only support truncated data, which is the recommended + * and common case. + */ int esp_input(struct xfrm_state *x, struct sk_buff *skb) { struct iphdr *iph; @@ -452,7 +469,8 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb) struct esp_data *esp = x->data; struct sk_buff *trailer; int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); - int elen = skb->len - 8 - esp->conf.ivlen - esp->auth.authlen; + int alen = esp->auth.icv_trunc_len; + int elen = skb->len - 8 - esp->conf.ivlen - alen; int nfrags; if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) @@ -462,17 +480,16 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb) goto out; /* If integrity check is required, do this. */ - if (esp->auth.authlen) { - u8 sum[esp->auth.authlen]; - u8 sum1[esp->auth.authlen]; + if (esp->auth.icv_full_len) { + u8 sum[esp->auth.icv_full_len]; + u8 sum1[alen]; + + esp->auth.icv(esp, skb, 0, skb->len-alen, sum); - esp->auth.digest(esp, skb, 0, skb->len-esp->auth.authlen, sum); - - if (skb_copy_bits(skb, skb->len-esp->auth.authlen, sum1, - esp->auth.authlen)) + if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) BUG(); - if (unlikely(memcmp(sum, sum1, esp->auth.authlen))) { + if (unlikely(memcmp(sum, sum1, alen))) { x->stats.integrity_failed++; goto out; } @@ -503,12 +520,11 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb) goto out; } skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen); - crypto_cipher_decrypt(esp->conf.tfm, sg, nfrags); + crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); if (unlikely(sg != sgbuf)) kfree(sg); - if (skb_copy_bits(skb, skb->len-esp->auth.authlen-2, - nexthdr, 2)) + if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) BUG(); padlen = nexthdr[0]; @@ -518,7 +534,7 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb) /* ... check padding bits here. Silly. :-) */ iph->protocol = nexthdr[1]; - pskb_trim(skb, skb->len - esp->auth.authlen - padlen - 2); + pskb_trim(skb, skb->len - alen - padlen - 2); memcpy(workbuf, skb->nh.raw, iph->ihl*4); skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen); skb->nh.raw += 8 + esp->conf.ivlen; @@ -546,7 +562,7 @@ static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) if (esp->conf.padlen) mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1); - return mtu + x->props.header_len + esp->auth.authlen; + return mtu + x->props.header_len + esp->auth.icv_full_len; } void esp4_err(struct sk_buff *skb, u32 info) @@ -583,9 +599,9 @@ void esp_destroy(struct xfrm_state *x) crypto_free_tfm(esp->auth.tfm); esp->auth.tfm = NULL; } - if (esp->auth.work_digest) { - kfree(esp->auth.work_digest); - esp->auth.work_digest = NULL; + if (esp->auth.work_icv) { + kfree(esp->auth.work_icv); + esp->auth.work_icv = NULL; } } @@ -593,11 +609,12 @@ int esp_init_state(struct xfrm_state *x, void *args) { struct esp_data *esp = NULL; + /* null auth and encryption can have zero length keys */ if (x->aalg) { - if (x->aalg->alg_key_len == 0 || x->aalg->alg_key_len > 512) + if (x->aalg->alg_key_len > 512) goto error; } - if (x->ealg == NULL || x->ealg->alg_key_len == 0) + if (x->ealg == NULL) goto error; esp = kmalloc(sizeof(*esp), GFP_KERNEL); @@ -607,21 +624,32 @@ int esp_init_state(struct xfrm_state *x, void *args) memset(esp, 0, sizeof(*esp)); if (x->aalg) { - int digestsize; + struct xfrm_algo_desc *aalg_desc; esp->auth.key = x->aalg->alg_key; esp->auth.key_len = (x->aalg->alg_key_len+7)/8; esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); if (esp->auth.tfm == NULL) goto error; - esp->auth.digest = esp_hmac_digest; - digestsize = crypto_tfm_alg_digestsize(esp->auth.tfm); - /* XXX RFC2403 and RFC 2404 truncate auth to 96 bit */ - esp->auth.authlen = 12; - if (esp->auth.authlen > digestsize) /* XXX */ - BUG(); - esp->auth.work_digest = kmalloc(digestsize, GFP_KERNEL); - if (!esp->auth.work_digest) + esp->auth.icv = esp_hmac_digest; + + aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name); + BUG_ON(!aalg_desc); + + if (aalg_desc->uinfo.auth.icv_fullbits/8 != + crypto_tfm_alg_digestsize(esp->auth.tfm)) { + printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", + x->aalg->alg_name, + crypto_tfm_alg_digestsize(esp->auth.tfm), + aalg_desc->uinfo.auth.icv_fullbits/8); + goto error; + } + + esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; + esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; + + esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL); + if (!esp->auth.work_icv) goto error; } esp->conf.key = x->ealg->alg_key; @@ -639,7 +667,6 @@ int esp_init_state(struct xfrm_state *x, void *args) x->props.header_len = 8 + esp->conf.ivlen; if (x->props.mode) x->props.header_len += 20; - x->props.trailer_len = esp->auth.authlen + crypto_tfm_alg_blocksize(esp->conf.tfm); x->data = esp; return 0; @@ -647,8 +674,8 @@ error: if (esp) { if (esp->auth.tfm) crypto_free_tfm(esp->auth.tfm); - if (esp->auth.work_digest) - kfree(esp->auth.work_digest); + if (esp->auth.work_icv) + kfree(esp->auth.work_icv); if (esp->conf.tfm) crypto_free_tfm(esp->conf.tfm); kfree(esp); diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 577208adc0ef..1e6682d4b161 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -2,9 +2,6 @@ # Makefile for the netfilter modules on top of IPv4. # -export-objs := ip_conntrack_standalone.o ip_nat_standalone.o \ - ip_tables.o arp_tables.o - # objects for the conntrack and NAT core (used by standalone and backw. compat) ip_nf_conntrack-objs := ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o ip_nf_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o @@ -25,11 +22,9 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o # connection tracking helpers obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o ifdef CONFIG_IP_NF_NAT_FTP - export-objs += ip_conntrack_ftp.o endif obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o ifdef CONFIG_IP_NF_NAT_IRC - export-objs += ip_conntrack_irc.o endif # NAT helpers diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index eae9a90ccd7c..db0614ef8156 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux TCP/IP (INET6) layer. # -export-objs := ipv6_syms.o - obj-$(CONFIG_IPV6) += ipv6.o ipv6-objs := af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \ diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index 11a769c6cb11..56ffe51f76fd 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -2,8 +2,6 @@ # Makefile for the netfilter modules on top of IPv6. # -export-objs := ip6_tables.o - # Link order matters here. obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b9ee209d62b1..18424ac3fe07 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -60,7 +60,7 @@ static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, struct sk_buff *skb); static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -static int tcp_v6_xmit(struct sk_buff *skb); +static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok); static struct tcp_func ipv6_mapped; static struct tcp_func ipv6_specific; diff --git a/net/irda/Makefile b/net/irda/Makefile index b37474c8ee38..bd5f41682c4b 100644 --- a/net/irda/Makefile +++ b/net/irda/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux IrDA protocol layer. # -export-objs := irsyms.o - obj-$(CONFIG_IRDA) += irda.o obj-$(CONFIG_IRLAN) += irlan/ obj-$(CONFIG_IRNET) += irnet/ diff --git a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile index 5f3435ef3be6..48689458c086 100644 --- a/net/irda/ircomm/Makefile +++ b/net/irda/ircomm/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux IrDA IrCOMM protocol layer. # -export-objs := ircomm_core.o - obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o diff --git a/net/lapb/Makefile b/net/lapb/Makefile index e95465fb8c69..53f7c90db163 100644 --- a/net/lapb/Makefile +++ b/net/lapb/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux LAPB layer. # -export-objs := lapb_iface.o - obj-$(CONFIG_LAPB) += lapb.o lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o diff --git a/net/llc/Makefile b/net/llc/Makefile index 30df2cb0b689..73a77522723f 100644 --- a/net/llc/Makefile +++ b/net/llc/Makefile @@ -18,6 +18,3 @@ llc-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \ llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \ llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o llc-$(CONFIG_LLC_UI) += af_llc.o - -# Objects that export symbols. -export-objs := llc_if.o diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile index b5c7ddf0b8c7..18403fe87c15 100644 --- a/net/rxrpc/Makefile +++ b/net/rxrpc/Makefile @@ -2,8 +2,6 @@ # Makefile for Linux kernel Rx RPC # -export-objs := rxrpc_syms.o - rxrpc-objs := \ call.o \ connection.o \ diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index f4bbf7a2596a..a99047e1792d 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -19,7 +19,7 @@ * created test case so that I was able to fix nasty bug * and many others. thanks. * - * $Id: sch_htb.c,v 1.14 2002/09/28 12:55:22 devik Exp devik $ + * $Id: sch_htb.c,v 1.17 2003/01/29 09:22:18 devik Exp devik $ */ #include <linux/config.h> #include <linux/module.h> @@ -71,16 +71,12 @@ #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) -#define HTB_VER 0x30007 /* major must be matched with number suplied by TC as version */ +#define HTB_VER 0x3000a /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER #error "Mismatched sch_htb.c and pkt_sch.h" #endif -/* temporary debug defines to be removed after beta stage */ -#define DEVIK_MEND(N) -#define DEVIK_MSTART(N) - /* debugging support; S is subsystem, these are defined: 0 - netlink messages 1 - enqueue @@ -421,7 +417,6 @@ static void htb_add_to_wait_tree (struct htb_sched *q, if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit()) printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint); #endif - DEVIK_MSTART(9); cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay); if (cl->pq_key == jiffies) cl->pq_key++; @@ -440,7 +435,6 @@ static void htb_add_to_wait_tree (struct htb_sched *q, } rb_link_node(&cl->pq_node, parent, p); rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]); - DEVIK_MEND(9); } /** @@ -678,7 +672,6 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_class *cl = htb_classify(skb,sch); - DEVIK_MSTART(0); if (cl == HTB_DIRECT || !cl) { /* enqueue to helper queue */ if (q->direct_queue.qlen < q->direct_qlen && cl) { @@ -687,25 +680,20 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) } else { kfree_skb (skb); sch->stats.drops++; - DEVIK_MEND(0); return NET_XMIT_DROP; } } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { sch->stats.drops++; cl->stats.drops++; - DEVIK_MEND(0); return NET_XMIT_DROP; } else { cl->stats.packets++; cl->stats.bytes += skb->len; - DEVIK_MSTART(1); htb_activate (q,cl); - DEVIK_MEND(1); } sch->q.qlen++; sch->stats.packets++; sch->stats.bytes += skb->len; HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); - DEVIK_MEND(0); return NET_XMIT_SUCCESS; } @@ -941,7 +929,6 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level) //struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_class *cl,*start; /* look initial class up in the row */ - DEVIK_MSTART(6); start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); do { @@ -960,8 +947,6 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level) cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); } while (cl != start); - DEVIK_MEND(6); - DEVIK_MSTART(7); if (likely(skb != NULL)) { if ((cl->un.leaf.deficit[level] -= skb->len) < 0) { HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n", @@ -973,11 +958,8 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level) gives us slightly better performance */ if (!cl->un.leaf.q->q.qlen) htb_deactivate (q,cl); - DEVIK_MSTART(8); htb_charge_class (q,cl,level,skb->len); - DEVIK_MEND(8); } - DEVIK_MEND(7); return skb; } @@ -1005,6 +987,9 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) struct htb_sched *q = (struct htb_sched *)sch->data; int level; long min_delay; +#ifdef HTB_DEBUG + int evs_used = 0; +#endif HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue), sch->q.qlen); @@ -1016,27 +1001,26 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) return skb; } - DEVIK_MSTART(2); if (!sch->q.qlen) goto fin; PSCHED_GET_TIME(q->now); - min_delay = HZ*5; + min_delay = LONG_MAX; q->nwc_hit = 0; for (level = 0; level < TC_HTB_MAXDEPTH; level++) { /* common case optimization - skip event handler quickly */ int m; long delay; - DEVIK_MSTART(3); if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) { delay = htb_do_events(q,level); q->near_ev_cache[level] += delay ? delay : HZ; +#ifdef HTB_DEBUG + evs_used++; +#endif } else delay = q->near_ev_cache[level] - jiffies; if (delay && min_delay > delay) min_delay = delay; - DEVIK_MEND(3); - DEVIK_MSTART(5); m = ~q->row_mask[level]; while (m != (int)(-1)) { int prio = ffz (m); @@ -1045,24 +1029,24 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) if (likely(skb != NULL)) { sch->q.qlen--; sch->flags &= ~TCQ_F_THROTTLED; - DEVIK_MEND(5); goto fin; } } - DEVIK_MEND(5); } - DEVIK_MSTART(4); #ifdef HTB_DEBUG - if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { - printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay); - htb_debug_dump(q); + if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) { + if (min_delay == LONG_MAX) { + printk(KERN_ERR "HTB: dequeue bug (%d), report it please !\n", + evs_used); + htb_debug_dump(q); + } else + printk(KERN_WARNING "HTB: mindelay=%ld, some class has " + "too small rate\n",min_delay); } #endif - htb_delay_by (sch,min_delay); - DEVIK_MEND(4); + htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay); fin: HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb); - DEVIK_MEND(2); return skb; } @@ -1433,6 +1417,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, if (!rtab || !ctab) goto failure; if (!cl) { /* new class */ + struct Qdisc *new_q; /* check for valid classid */ if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch)) goto failure; @@ -1456,6 +1441,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, cl->magic = HTB_CMAGIC; #endif + /* create leaf qdisc early because it uses kmalloc(GPF_KERNEL) + so that can't be used inside of sch_tree_lock + -- thanks to Karlis Peisenieks */ + new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); sch_tree_lock(sch); if (parent && !parent->level) { /* turn parent into inner node */ @@ -1474,8 +1463,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, memset (&parent->un.inner,0,sizeof(parent->un.inner)); } /* leaf (we) needs elementary qdisc */ - if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) - cl->un.leaf.q = &noop_qdisc; + cl->un.leaf.q = new_q ? new_q : &noop_qdisc; cl->classid = classid; cl->parent = parent; @@ -1503,11 +1491,11 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, if (!cl->level) { cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum; if (!hopt->quantum && cl->un.leaf.quantum < 1000) { - printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid); + printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.\n", cl->classid); cl->un.leaf.quantum = 1000; } if (!hopt->quantum && cl->un.leaf.quantum > 200000) { - printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid); + printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.\n", cl->classid); cl->un.leaf.quantum = 200000; } if (hopt->quantum) diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index ae33217a21fa..526b32aa56ca 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile @@ -6,8 +6,6 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/ obj-$(CONFIG_SUNRPC) += sunrpc.o -export-objs := sunrpc_syms.o - sunrpc-y := clnt.o xprt.o sched.o \ auth.o auth_null.o auth_unix.o \ svc.o svcsock.o svcauth.o svcauth_unix.o \ diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile index 49e465f37637..087ac961de16 100644 --- a/net/sunrpc/auth_gss/Makefile +++ b/net/sunrpc/auth_gss/Makefile @@ -4,8 +4,6 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o -export-objs := sunrpcgss_syms.o - auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \ sunrpcgss_syms.o gss_mech_switch.o diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 512a4d686e5f..84f879595cff 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -78,7 +78,7 @@ krb5_encrypt( sg[0].offset = ((long)out & ~PAGE_MASK); sg[0].length = length; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, length); out: dprintk("gss_k5encrypt returns %d\n",ret); @@ -117,7 +117,7 @@ krb5_decrypt( sg[0].offset = ((long)out & ~PAGE_MASK); sg[0].length = length; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, length); out: dprintk("gss_k5decrypt returns %d\n",ret); diff --git a/net/wanrouter/Makefile b/net/wanrouter/Makefile index 3fe1da0efa7e..9f188ab3dcd0 100644 --- a/net/wanrouter/Makefile +++ b/net/wanrouter/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux WAN router layer. # -export-objs := wanmain.o - obj-$(CONFIG_WAN_ROUTER) += wanrouter.o wanrouter-objs := wanproc.o wanmain.o diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f5886c69a196..b655c60afeee 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -45,11 +45,67 @@ O_TARGET := $(obj)/built-in.o endif endif +ifdef CONFIG_MODVERSIONS +modules := $(obj-m) +touch-module = @mkdir -p $(MODVERDIR)/$(@D); touch $(MODVERDIR)/$(@:.o=.ko) +else +modules := $(obj-m:.o=.ko) +endif + __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \ - $(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \ + $(if $(KBUILD_MODULES),$(modules)) \ $(subdir-ym) $(build-targets) @: +# Module versioning +# --------------------------------------------------------------------------- + +ifdef CONFIG_MODVERSIONS + +# $(call if_changed_rule,vcc_o_c) does essentially the same as the +# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file +# from a C file, keeping track of the command line and dependencies. +# +# However, actually it does: +# o compile a .tmp_<file>.o from <file>.c +# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just rename .tmp_<file>.o to <file>.o and +# are done. +# o otherwise, we calculate symbol versions using the good old +# genksyms on the preprocessed source and postprocess them in a way +# that they are usable as a linker script +# o generate <file>.o from .tmp_<file>.o using the linker to +# replace the unresolved symbols __crc_exported_symbol with +# the actual value of the checksum generated by genksyms + +quiet_cmd_vcc_o_c = CC $(quiet_modtag) $@ +cmd_vcc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< + +define rule_vcc_o_c + $(if $($(quiet)cmd_vcc_o_c),echo ' $($(quiet)cmd_vcc_o_c)';) \ + $(cmd_vcc_o_c); \ + \ + if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + mv $(@D)/.tmp_$(@F) $@; \ + else \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + | $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \ + | grep __ver \ + | sed 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/g' \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + fi; + \ + scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp; \ + rm -f $(depfile); \ + mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +endef + +endif + # Compile C sources (.c) # --------------------------------------------------------------------------- @@ -69,11 +125,6 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M] $(obj-m) : quiet_modtag := [M] -$(export-objs) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.i) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.s) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.lst): export_flags := $(EXPORT_FLAGS) - # Default for not multi-part modules modname = $(*F) @@ -102,7 +153,20 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.o: %.c FORCE +ifdef CONFIG_MODVERSIONS + $(call if_changed_rule,vcc_o_c) +else $(call if_changed_dep,cc_o_c) +endif + +# For modversioning, we need to special case single-part modules +# to mark them in $(MODVERDIR) + +ifdef CONFIG_MODVERSIONS +$(single-used-m): %.o: %.c FORCE + $(touch-module) + $(call if_changed_rule,vcc_o_c) +endif quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ @@ -147,7 +211,7 @@ ifdef O_TARGET quiet_cmd_link_o_target = LD $@ # If the list of objects to link is empty, just create an empty O_TARGET cmd_link_o_target = $(if $(strip $(obj-y)),\ - $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^),\ + $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\ rm -f $@; $(AR) rcs $@) $(O_TARGET): $(obj-y) FORCE @@ -172,19 +236,20 @@ endif # # Rule to link composite objects # +# Composite objects are specified in kbuild makefile as follows: +# <composite-object>-objs := <list of .o files> +# or +# <composite-object>-y := <list of .o files> +link_multi_deps = \ +$(filter $(addprefix $(obj)/, \ +$($(subst $(obj)/,,$(@:.o=-objs))) \ +$($(subst $(obj)/,,$(@:.o=-y)))), $^) + quiet_cmd_link_multi-y = LD $@ -cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^) +cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) quiet_cmd_link_multi-m = LD [M] $@ -cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o - -quiet_cmd_link_single-m = LD [M] $@ -cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o - -# Don't rebuilt vermagic.o unless we actually are in the init/ dir -ifneq ($(obj),init) -init/vermagic.o: ; -endif +cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps) # We would rather have a list of rules like # foo.o: $(foo-objs) @@ -193,13 +258,34 @@ endif $(multi-used-y) : %.o: $(multi-objs-y) FORCE $(call if_changed,link_multi-y) -$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE +$(multi-used-m) : %.o: $(multi-objs-m) FORCE + $(touch-module) $(call if_changed,link_multi-m) -$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE - $(call if_changed,link_single-m) +targets += $(multi-used-y) $(multi-used-m) + +# +# Rule to link modules ( .o -> .ko ) +# + +# With CONFIG_MODVERSIONS, generation of the final .ko is handled +# by scripts/Makefile.modver +ifndef CONFIG_MODVERSIONS + +quiet_cmd_link_module = LD [M] $@ +cmd_link_module = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o -targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko) +# Don't rebuilt vermagic.o unless we actually are in the init/ dir +ifneq ($(obj),init) +init/vermagic.o: ; +endif + +$(single-used-m:.o=.ko) $(multi-used-m:.o=.ko): %.ko: %.o init/vermagic.o FORCE + $(call if_changed,link_module) + +targets += $(single-used-m:.o=.ko) $(multi-used-m:.o=.ko) + +endif # Compile programs on the host # =========================================================================== diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index bc1d58cb93c1..96eef1a89ebc 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -34,14 +34,9 @@ obj-m := $(filter-out %/, $(obj-m)) subdir-ym := $(sort $(subdir-y) $(subdir-m)) -# export.o is never a composite object, since $(export-objs) has a -# fixed meaning (== objects which EXPORT_SYMBOL()) -__obj-y = $(filter-out export.o,$(obj-y)) -__obj-m = $(filter-out export.o,$(obj-m)) - # if $(foo-objs) exists, foo.o is a composite object -multi-used-y := $(sort $(foreach m,$(__obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) -multi-used-m := $(sort $(foreach m,$(__obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) @@ -59,9 +54,6 @@ subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o) real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(EXTRA_TARGETS) real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) -# Only build module versions for files which are selected to be built -export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m)) - # C code # Executables compiled from a single .c file host-csingle := $(foreach m,$(host-progs),$(if $($(m)-objs),,$(m))) @@ -96,7 +88,6 @@ EXTRA_TARGETS := $(addprefix $(obj)/,$(EXTRA_TARGETS)) build-targets := $(addprefix $(obj)/,$(build-targets)) obj-y := $(addprefix $(obj)/,$(obj-y)) obj-m := $(addprefix $(obj)/,$(obj-m)) -export-objs := $(addprefix $(obj)/,$(export-objs)) subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) @@ -130,13 +121,14 @@ basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))) c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \ $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \ - $(basename_flags) $(modname_flags) $(export_flags) + $(basename_flags) $(modname_flags) a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\ $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) hostc_flags = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\ $(HOSTCFLAGS_$(*F).o) hostcxx_flags = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\ $(HOSTCXXFLAGS_$(*F).o) +ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS) # Finds the multi-part object the current object will be linked into modname-multi = $(sort $(foreach m,$(multi-used),\ @@ -217,7 +209,6 @@ if_changed_rule = $(if $(strip $? \ $(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\ @set -e; \ - mkdir -p $(dir $@); \ $(rule_$(1))) # If quiet is set, only print short version of command diff --git a/scripts/Makefile.modver b/scripts/Makefile.modver index 6f9c56dd32a8..95c9a772eda4 100644 --- a/scripts/Makefile.modver +++ b/scripts/Makefile.modver @@ -2,105 +2,82 @@ # Module versions # =========================================================================== -src := $(obj) +.PHONY: __modversions +__modversions: -MODVERDIR := include/linux/modules +include scripts/Makefile.lib -.PHONY: modver -modver: +# -include .config +modules := $(patsubst ./%,%,$(shell cd $(MODVERDIR); find . -name \*.ko)) -include $(obj)/Makefile +__modversions: $(modules) + @: -include scripts/Makefile.lib +# The final module link -# =========================================================================== +quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ + $(filter-out FORCE,$^) -ifeq ($(strip $(export-objs)),) +init/vermagic.o: ; -# If we don't export any symbols in this dir, just descend -# --------------------------------------------------------------------------- +$(modules): %.ko :%.o %.ver.o init/vermagic.o FORCE + $(call if_changed,ld_ko_o) -modver: $(subdir-ym) - @: +targets += $(modules) -else +# Compile version info for unresolved symbols -# This sets version suffixes on exported symbols -# --------------------------------------------------------------------------- +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $< -# -# Added the SMP separator to stop module accidents between uniprocessor -# and SMP Intel boxes - AC - from bits by Michael Chastain -# +$(modules:.ko=.ver.o): %.ver.o: %.ver.c FORCE + $(call if_changed,cc_o_c) -ifdef CONFIG_SMP - genksyms_smp_prefix := -p smp_ -else - genksyms_smp_prefix := -endif +targets += $(modules:.ko=.ver.o) + +# Generate C source with version info for unresolved symbols -# Don't include modversions.h, we're just about to generate it here. - -CFLAGS_MODULE := $(filter-out -include include/linux/modversions.h,$(CFLAGS_MODULE)) - -$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL) -$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE) -$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__ -# Default for not multi-part modules -modname = $(*F) - -$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi) - -# Our objects only depend on modversions.h, not on the individual .ver -# files (fix-dep filters them), so touch modversions.h if any of the .ver -# files changes - -quiet_cmd_cc_ver_c = MKVER include/linux/modules/$*.ver -cmd_cc_ver_c = $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \ - -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp - -# Okay, let's explain what's happening in rule_make_cc_ver_c: -# o echo the command -# o execute the command -# o If the $(CPP) fails, we won't notice because it's output is piped -# to $(GENKSYMS) which does not fail. We recognize this case by -# looking if the generated $(depfile) exists, though. -# o If the .ver file changed, touch modversions.h, which is our marker -# of any changed .ver files. -# o Move command line and deps into their normal .*.cmd place. - -define rule_cc_ver_c - $(if $($(quiet)cmd_cc_ver_c),echo ' $($(quiet)cmd_cc_ver_c)';) \ - $(cmd_cc_ver_c); \ - if [ ! -r $(depfile) ]; then exit 1; fi; \ - scripts/fixdep $(depfile) $@ '$(cmd_cc_ver_c)' > $(@D)/.$(@F).tmp; \ - rm -f $(depfile); \ - if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \ - touch include/linux/modversions.h; \ - fi; \ - mv -f $@.tmp $@ - mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +define rule_mkver_o_c + echo ' MKVER $@'; \ + ( echo "#include <linux/module.h>"; \ + echo ""; \ + echo "static const struct modversion_info ____versions[]"; \ + echo "__attribute__((section(\"__versions\"))) = {"; \ + for sym in `nm -u $<`; do \ + grep "\"$$sym\"" .tmp_all-versions \ + || echo "*** Warning: $(<:.o=.ko): \"$$sym\" unresolved!" >&2;\ + done; \ + echo "};"; \ + ) > $@ endef -targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)) +$(modules:.ko=.ver.c): %.ver.c: %.o .tmp_all-versions FORCE + $(call if_changed_rule,mkver_o_c) -$(MODVERDIR)/%.ver: %.c FORCE - @$(call if_changed_rule,cc_ver_c) +targets += $(modules:.ko=.ver.c)) -modver: $(targets) $(subdir-ym) - @mkdir -p $(dir $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver))) - @touch $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver)) +# Extract all checksums for all exported symbols -endif # export-objs +export-objs := $(shell for m in vmlinux $(modules:.ko=.o); do objdump -h $$m | grep -q __ksymtab && echo $$m; done) -# Descending -# --------------------------------------------------------------------------- +cmd_gen-all-versions = mksyms $(export-objs) +define rule_gen-all-versions + echo ' MKSYMS $@'; \ + for mod in $(export-objs); do \ + modname=`basename $$mod`; \ + nm $$mod \ + | grep ' __crc_' \ + | sed "s/\([^ ]*\) A __crc_\(.*\)/{ 0x\1, \"\2\" }, \/* $$modname *\//g;s/.* w __crc_\(.*\)/{ 0x0 , \"\1\" }, \/* $$modname *\//g"; \ + done > $@; \ + echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd +endef + +.tmp_all-versions: $(export-objs) FORCE + $(call if_changed_rule,gen-all-versions) -.PHONY: $(subdir-ym) -$(subdir-ym): - $(Q)$(MAKE) -f scripts/Makefile.modver obj=$@ +targets += .tmp_all-versions # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/per-cpu-check.awk b/scripts/per-cpu-check.awk index f1b34c42df4b..3be9f0d25ebd 100644 --- a/scripts/per-cpu-check.awk +++ b/scripts/per-cpu-check.awk @@ -6,7 +6,7 @@ IN_PER_CPU=0 } -/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ ) { +/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ || / __kcrctab_/ ) { if (!IN_PER_CPU) { print $$3 " not in per-cpu section" > "/dev/stderr"; FOUND=1; diff --git a/security/Makefile b/security/Makefile index 26d36f11ec2e..2ae9adb62861 100644 --- a/security/Makefile +++ b/security/Makefile @@ -2,9 +2,6 @@ # Makefile for the kernel security code # -# Objects that export symbols -export-objs := security.o capability.o - # if we don't select a security model, use the default capabilities ifneq ($(CONFIG_SECURITY),y) obj-y += capability.o diff --git a/sound/Makefile b/sound/Makefile index 2b797e90744f..b834f731a02b 100644 --- a/sound/Makefile +++ b/sound/Makefile @@ -1,8 +1,6 @@ # Makefile for the Linux sound card driver # -export-objs := sound_core.o - obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ diff --git a/sound/core/Makefile b/sound/core/Makefile index 6c152edc46a2..8fa20c85bb26 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := sound.o pcm.o pcm_lib.o rawmidi.o timer.o hwdep.o - snd-objs := sound.o init.o memory.o info.o control.o misc.o \ device.o wrappers.o ifeq ($(CONFIG_ISA),y) @@ -18,7 +16,6 @@ snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ pcm_memory.o ifeq ($(CONFIG_PCI),y) snd-pcm-objs += pcm_sgbuf.o -export-objs += pcm_sgbuf.o endif snd-rawmidi-objs := rawmidi.o diff --git a/sound/core/oss/Makefile b/sound/core/oss/Makefile index cb58d3719a26..e6d5a045ba27 100644 --- a/sound/core/oss/Makefile +++ b/sound/core/oss/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> # -export-objs := mixer_oss.o - snd-mixer-oss-objs := mixer_oss.o snd-pcm-oss-objs := pcm_oss.o pcm_plugin.o \ diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index b178b9a5063a..abed6d88a5df 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile @@ -8,9 +8,6 @@ ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) obj-$(CONFIG_SND_SEQUENCER) += oss/ endif -export-objs := seq_device.o seq.o seq_instr.o seq_midi_emul.o \ - seq_midi_event.o seq_virmidi.o - snd-seq-device-objs := seq_device.o snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ seq_fifo.o seq_prioq.o seq_timer.o \ diff --git a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile index 16ca46cc6b6b..9310692d9b2d 100644 --- a/sound/core/seq/instr/Makefile +++ b/sound/core/seq/instr/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> # -export-objs := ainstr_fm.o ainstr_simple.o ainstr_gf1.o ainstr_iw.o - snd-ainstr-fm-objs := ainstr_fm.o snd-ainstr-simple-objs := ainstr_simple.o snd-ainstr-gf1-objs := ainstr_gf1.o diff --git a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile index b6a860298098..e4840eb55fc9 100644 --- a/sound/drivers/mpu401/Makefile +++ b/sound/drivers/mpu401/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := mpu401_uart.o - snd-mpu401-objs := mpu401.o snd-mpu401-uart-objs := mpu401_uart.o diff --git a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile index d494e1409f94..064bd8c078b9 100644 --- a/sound/drivers/opl3/Makefile +++ b/sound/drivers/opl3/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := opl3_lib.o - snd-opl3-lib-objs := opl3_lib.o opl3_synth.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) snd-opl3-synth-objs := opl3_seq.o opl3_midi.o opl3_drums.o diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile index 9b168c80358e..54a111b7bafd 100644 --- a/sound/i2c/Makefile +++ b/sound/i2c/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := i2c.o cs8427.o tea6330t.o - snd-i2c-objs := i2c.o snd-cs8427-objs := cs8427.o snd-tea6330t-objs := tea6330t.o diff --git a/sound/i2c/l3/Makefile b/sound/i2c/l3/Makefile index 238c14081792..49455b8dcc04 100644 --- a/sound/i2c/l3/Makefile +++ b/sound/i2c/l3/Makefile @@ -2,8 +2,6 @@ # Makefile for ALSA # -export-objs += uda1341.o - snd-uda1341-objs := uda1341.o # Module Dependency diff --git a/sound/isa/ad1816a/Makefile b/sound/isa/ad1816a/Makefile index e6e5408638fc..a42b29cf8549 100644 --- a/sound/isa/ad1816a/Makefile +++ b/sound/isa/ad1816a/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := ad1816a_lib.o - snd-ad1816a-lib-objs := ad1816a_lib.o snd-ad1816a-objs := ad1816a.o diff --git a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile index f8fdbc4c2b0b..45d59998aa69 100644 --- a/sound/isa/ad1848/Makefile +++ b/sound/isa/ad1848/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := ad1848_lib.o - snd-ad1848-lib-objs := ad1848_lib.o snd-ad1848-objs := ad1848.o diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile index ac5a287000c7..4ba3f2ccf237 100644 --- a/sound/isa/cs423x/Makefile +++ b/sound/isa/cs423x/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := cs4231_lib.o cs4236_lib.o - snd-cs4231-lib-objs := cs4231_lib.o snd-cs4236-lib-objs := cs4236_lib.o snd-cs4231-objs := cs4231.o diff --git a/sound/isa/es1688/Makefile b/sound/isa/es1688/Makefile index 52611f55a2df..501c8bf903af 100644 --- a/sound/isa/es1688/Makefile +++ b/sound/isa/es1688/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := es1688_lib.o - snd-es1688-lib-objs := es1688_lib.o snd-es1688-objs := es1688.o diff --git a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile index a765730bc2fe..12a48b252066 100644 --- a/sound/isa/gus/Makefile +++ b/sound/isa/gus/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := gus_main.o gus_volume.o - snd-gus-lib-objs := gus_main.o \ gus_io.o gus_irq.o gus_timer.o \ gus_mem.o gus_mem_proc.o gus_dram.o gus_dma.o gus_volume.o \ diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index 6a212d188e65..101fe314af80 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := emu8000.o sb_common.o sb8_main.o sb16_main.o sb16_csp.o - snd-sb-common-objs := sb_common.o sb_mixer.o snd-sb8-dsp-objs := sb8_main.o sb8_midi.o snd-sb16-dsp-objs := sb16_main.o diff --git a/sound/oss/Makefile b/sound/oss/Makefile index d84d9dc48a06..f107c75a035d 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile @@ -3,13 +3,6 @@ # 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o ac97_codec.o \ - msnd.o opl3.o sb_common.o sequencer_syms.o ac97.o aci.o \ - sound_syms.o uart401.o - # Each configuration option enables a list of files. obj-$(CONFIG_SOUND_OSS) += sound.o diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile index 7efc193ce455..a1c3dee5e967 100644 --- a/sound/oss/dmasound/Makefile +++ b/sound/oss/dmasound/Makefile @@ -2,8 +2,6 @@ # Makefile for the DMA sound driver # -export-objs := dmasound_core.o - obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o obj-$(CONFIG_DMASOUND_AWACS) += dmasound_core.o dmasound_awacs.o obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 1a54e7bae09f..d7b751cd60f8 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := ac97_codec.o ak4531_codec.o - snd-ac97-codec-objs := ac97_codec.o ac97_patch.o snd-ak4531-codec-objs := ak4531_codec.o diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile index 707243aee54f..5e95f821c93b 100644 --- a/sound/pci/emu10k1/Makefile +++ b/sound/pci/emu10k1/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := emu10k1_main.o - snd-emu10k1-objs := emu10k1.o emu10k1_main.o \ irq.o memory.o voice.o emumpu401.o emupcm.o io.o \ emuproc.o emumixer.o emufx.o diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile index ada825425e91..2a820edd385d 100644 --- a/sound/pci/ice1712/Makefile +++ b/sound/pci/ice1712/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := ice1712.o - snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o amp.o # Toplevel Module Dependency diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile index 84b5dbab6ec5..e26d34ad2b1a 100644 --- a/sound/pci/rme9652/Makefile +++ b/sound/pci/rme9652/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := hammerfall_mem.o - snd-hammerfall-mem-objs := hammerfall_mem.o snd-rme9652-objs := rme9652.o snd-hdsp-objs := hdsp.o diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile index 8defc90462c2..4650f77a3060 100644 --- a/sound/pci/trident/Makefile +++ b/sound/pci/trident/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := trident_main.o - snd-trident-objs := trident.o trident_main.o trident_memory.o snd-trident-synth-objs := trident_synth.o diff --git a/sound/synth/Makefile b/sound/synth/Makefile index 6ce9c8e630d7..d25796c1be1c 100644 --- a/sound/synth/Makefile +++ b/sound/synth/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := util_mem.o - snd-util-mem-objs := util_mem.o # Toplevel Module Dependency diff --git a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile index 099d1d6eaa9e..40f5bdd143fd 100644 --- a/sound/synth/emux/Makefile +++ b/sound/synth/emux/Makefile @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -export-objs := emux.o - snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \ emux_effect.o emux_proc.o soundfont.o \ $(if $(CONFIG_SND_SEQUENCER_OSS),emux_oss.o) |
